Merge from Chromium at DEPS revision r212014

This commit was generated by merge_to_master.py.

Change-Id: Ie0f261e9682cd8abea1eea1e51beab83d5eea21a
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 632d192..8a76397 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -59,10 +59,6 @@
   "+webkit/browser",
   "+webkit/common",
 
-  # TODO(ananta): remove me when
-  # bug https://code.google.com/p/chromium/issues/detail?id=237249 is fixed.
-  "!content/public/child/image_decoder_utils.h",
-
   # webkit/glue files are listed individually since they aren't conceptually
   # grouped like the other webkit/ files, and can therefore be tackled one at
   # a time.
@@ -70,6 +66,8 @@
   # DO NOT ADD ANY MORE ITEMS TO THE ABOVE LIST!
 
   "-chrome/browser/ui/views",
+  "+chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h",
+  "+chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.h",
 
   # Other libraries.
   "+chrome/third_party/mozilla_security_manager",
@@ -88,6 +86,7 @@
   "+third_party/re2",
   "+third_party/sqlite",
   "+third_party/undoview",
+  "+third_party/zlib",
 
   # No inclusion of WebKit from the browser, other than strictly enum/POD,
   # header-only types, and some selected common code.
@@ -114,6 +113,5 @@
   # These should be burned down. http://crbug.com/237267
   "!third_party/WebKit/public/web/WebKit.h",
   "!third_party/WebKit/public/web/WebSecurityOrigin.h",
-  "!third_party/WebKit/public/web/WebSecurityPolicy.h",
   "!third_party/WebKit/public/web/WebView.h",
 ]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 7099dbd..823d2a5 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -118,29 +118,6 @@
   return flags;
 }
 
-const Experiment::Choice
-    kOmniboxHistoryQuickProviderReorderForInliningChoices[] = {
-  { IDS_FLAGS_OMNIBOX_HISTORY_QUICK_PROVIDER_REORDER_FOR_INLINING_AUTOMATIC,
-    "",
-    "" },
-  { IDS_FLAGS_OMNIBOX_HISTORY_QUICK_PROVIDER_REORDER_FOR_INLINING_ENABLED,
-    switches::kOmniboxHistoryQuickProviderReorderForInlining,
-    switches::kOmniboxHistoryQuickProviderReorderForInliningEnabled },
-  { IDS_FLAGS_OMNIBOX_HISTORY_QUICK_PROVIDER_REORDER_FOR_INLINING_DISABLED,
-    switches::kOmniboxHistoryQuickProviderReorderForInlining,
-    switches::kOmniboxHistoryQuickProviderReorderForInliningDisabled }
-};
-
-const Experiment::Choice kOmniboxInlineHistoryQuickProviderChoices[] = {
-  { IDS_FLAGS_OMNIBOX_INLINE_HISTORY_QUICK_PROVIDER_AUTOMATIC, "", "" },
-  { IDS_FLAGS_OMNIBOX_INLINE_HISTORY_QUICK_PROVIDER_ALLOWED,
-    switches::kOmniboxInlineHistoryQuickProvider,
-    switches::kOmniboxInlineHistoryQuickProviderAllowed },
-  { IDS_FLAGS_OMNIBOX_INLINE_HISTORY_QUICK_PROVIDER_PROHIBITED,
-    switches::kOmniboxInlineHistoryQuickProvider,
-    switches::kOmniboxInlineHistoryQuickProviderProhibited }
-};
-
 const Experiment::Choice kEnableCompositingForFixedPositionChoices[] = {
   { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" },
   { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED,
@@ -159,6 +136,14 @@
     switches::kDisableCompositingForTransition, ""},
 };
 
+const Experiment::Choice kEnableAcceleratedFixedRootBackgroundChoices[] = {
+  { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" },
+  { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED,
+    switches::kEnableAcceleratedFixedRootBackground, ""},
+  { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED,
+    switches::kDisableAcceleratedFixedRootBackground, ""},
+};
+
 const Experiment::Choice kGDIPresentChoices[] = {
   { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" },
   { IDS_FLAGS_PRESENT_WITH_GDI_FIRST_SHOW,
@@ -218,6 +203,14 @@
     cc::switches::kDisableImplSidePainting, ""}
 };
 
+const Experiment::Choice kDelegatedRendererChoices[] = {
+  { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" },
+  { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED,
+    switches::kEnableDelegatedRenderer, ""},
+  { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED,
+    switches::kDisableDelegatedRenderer, ""}
+};
+
 const Experiment::Choice kMaxTilesForInterestAreaChoices[] = {
   { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" },
   { IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_SHORT,
@@ -446,6 +439,13 @@
 #endif
   },
   {
+    "enable-d3d11",
+    IDS_FLAGS_ENABLE_D3D11_NAME,
+    IDS_FLAGS_ENABLE_D3D11_DESCRIPTION,
+    kOsWin,
+    SINGLE_VALUE_TYPE(switches::kEnableD3D11)
+  },
+  {
     "disable-webrtc",
     IDS_FLAGS_DISABLE_WEBRTC_NAME,
     IDS_FLAGS_DISABLE_WEBRTC_DESCRIPTION,
@@ -464,6 +464,13 @@
     kOsAll,
     SINGLE_VALUE_TYPE(switches::kEnableSCTPDataChannels)
   },
+  {
+    "enable-device-enumeration",
+    IDS_FLAGS_ENABLE_DEVICE_ENUMERATION_NAME,
+    IDS_FLAGS_ENABLE_DEVICE_ENUMERATION_DESCRIPTION,
+    kOsAll,
+    SINGLE_VALUE_TYPE(switches::kEnableDeviceEnumeration)
+  },
 #endif
 #if defined(OS_ANDROID)
   {
@@ -497,6 +504,13 @@
     kOsAll,
     MULTI_VALUE_TYPE(kEnableCompositingForTransitionChoices)
   },
+  {
+    "enable-accelerated-fixed-root-background",
+    IDS_FLAGS_ACCELERATED_FIXED_ROOT_BACKGROUND_NAME,
+    IDS_FLAGS_ACCELERATED_FIXED_ROOT_BACKGROUND_DESCRIPTION,
+    kOsAll,
+    MULTI_VALUE_TYPE(kEnableAcceleratedFixedRootBackgroundChoices)
+  },
   // TODO(bbudge): When NaCl is on by default, remove this flag entry.
   {
     "enable-nacl",  // FLAGS:RECORD_UMA
@@ -635,6 +649,15 @@
     ENABLE_DISABLE_VALUE_TYPE(switches::kEnableLocalFirstLoadNTP,
                               switches::kDisableLocalFirstLoadNTP)
   },
+#if defined(OS_ANDROID)
+  {
+    "enable-new-ntp",
+    IDS_FLAGS_ENABLE_NEW_NTP,
+    IDS_FLAGS_ENABLE_NEW_NTP_DESCRIPTION,
+    kOsAndroid,
+    SINGLE_VALUE_TYPE(switches::kEnableNewNTP)
+  },
+#endif
   {
     "static-ip-config",
     IDS_FLAGS_STATIC_IP_CONFIG_NAME,
@@ -655,13 +678,6 @@
     SINGLE_VALUE_TYPE(autofill::switches::kShowAutofillTypePredictions)
   },
   {
-    "enable-sync-favicons",
-    IDS_FLAGS_ENABLE_SYNC_FAVICONS_NAME,
-    IDS_FLAGS_ENABLE_SYNC_FAVICONS_DESCRIPTION,
-    kOsAll,
-    SINGLE_VALUE_TYPE(switches::kEnableSyncFavicons)
-  },
-  {
     "enable-gesture-tap-highlight",
     IDS_FLAGS_ENABLE_GESTURE_TAP_HIGHLIGHTING_NAME,
     IDS_FLAGS_ENABLE_GESTURE_TAP_HIGHLIGHTING_DESCRIPTION,
@@ -679,20 +695,6 @@
     SINGLE_VALUE_TYPE(switches::kEnableSmoothScrolling)
   },
   {
-    "omnibox-history-quick-provider-reorder-for-inlining",
-    IDS_FLAGS_OMNIBOX_HISTORY_QUICK_PROVIDER_REORDER_FOR_INLINING_NAME,
-    IDS_FLAGS_OMNIBOX_HISTORY_QUICK_PROVIDER_REORDER_FOR_INLINING_DESCRIPTION,
-    kOsAll,
-    MULTI_VALUE_TYPE(kOmniboxHistoryQuickProviderReorderForInliningChoices)
-  },
-  {
-    "omnibox-inline-history-quick-provider",
-    IDS_FLAGS_OMNIBOX_INLINE_HISTORY_QUICK_PROVIDER_NAME,
-    IDS_FLAGS_OMNIBOX_INLINE_HISTORY_QUICK_PROVIDER_DESCRIPTION,
-    kOsAll,
-    MULTI_VALUE_TYPE(kOmniboxInlineHistoryQuickProviderChoices)
-  },
-  {
     "enable-panels",
     IDS_FLAGS_ENABLE_PANELS_NAME,
     IDS_FLAGS_ENABLE_PANELS_DESCRIPTION,
@@ -723,6 +725,13 @@
                               switches::kDisableQuic)
   },
   {
+    "enable-quic-https",
+    IDS_FLAGS_ENABLE_QUIC_HTTPS_NAME,
+    IDS_FLAGS_ENABLE_QUIC_HTTPS_DESCRIPTION,
+    kOsAll,
+    SINGLE_VALUE_TYPE(switches::kEnableQuicHttps)
+  },
+  {
     "enable-spdy4a2",
     IDS_FLAGS_ENABLE_SPDY4A2_NAME,
     IDS_FLAGS_ENABLE_SPDY4A2_DESCRIPTION,
@@ -859,11 +868,11 @@
     SINGLE_VALUE_TYPE(switches::kDisableSoftwareRasterizer)
   },
   {
-    "enable-experimental-webkit-features",
-    IDS_FLAGS_EXPERIMENTAL_WEBKIT_FEATURES_NAME,
-    IDS_FLAGS_EXPERIMENTAL_WEBKIT_FEATURES_DESCRIPTION,
+    "enable-experimental-web-platform-features",
+    IDS_FLAGS_EXPERIMENTAL_WEB_PLATFORM_FEATURES_NAME,
+    IDS_FLAGS_EXPERIMENTAL_WEB_PLATFORM_FEATURES_DESCRIPTION,
     kOsAll,
-    SINGLE_VALUE_TYPE(switches::kEnableExperimentalWebKitFeatures)
+    SINGLE_VALUE_TYPE(switches::kEnableExperimentalWebPlatformFeatures)
   },
   {
     "enable-css-shaders",
@@ -896,6 +905,13 @@
     SINGLE_VALUE_TYPE(switches::kEnableDevToolsExperiments)
   },
   {
+    "remote-debugging-raw-usb",
+    IDS_FLAGS_REMOTE_DEBUGGING_RAW_USB_NAME,
+    IDS_FLAGS_REMOTE_DEBUGGING_RAW_USB_DESCRIPTION,
+    kOsDesktop,
+    SINGLE_VALUE_TYPE(switches::kRemoteDebuggingRawUSB)
+  },
+  {
     "silent-debugger-extension-api",
     IDS_FLAGS_SILENT_DEBUGGER_EXTENSION_API_NAME,
     IDS_FLAGS_SILENT_DEBUGGER_EXTENSION_API_DESCRIPTION,
@@ -1018,21 +1034,7 @@
     kOsCrOS,
     SINGLE_VALUE_TYPE(chromeos::switches::kEnableTouchpadThreeFingerClick)
   },
-  {
-    "allow-touchpad-three-finger-swipe",
-    IDS_FLAGS_ALLOW_TOUCHPAD_THREE_FINGER_SWIPE_NAME,
-    IDS_FLAGS_ALLOW_TOUCHPAD_THREE_FINGER_SWIPE_DESCRIPTION,
-    kOsCrOS,
-    SINGLE_VALUE_TYPE(chromeos::switches::kEnableTouchpadThreeFingerSwipe)
-  },
 #endif
-  {
-    "enable-desktop-guest-mode",
-    IDS_FLAGS_DESKTOP_GUEST_MODE_NAME,
-    IDS_FLAGS_DESKTOP_GUEST_MODE_DESCRIPTION,
-    kOsMac | kOsWin | kOsLinux,
-    SINGLE_VALUE_TYPE(switches::kEnableDesktopGuestMode)
-  },
 #if defined(USE_ASH)
   {
     "show-launcher-alignment-menu",
@@ -1114,20 +1116,6 @@
     SINGLE_VALUE_TYPE(chromeos::switches::kFileManagerEnableSharing)
   },
   {
-    "disable-app-mode",
-    IDS_FLAGS_DISABLE_KIOSK_APPS_NAME,
-    IDS_FLAGS_DISABLE_KIOSK_APPS_DESCRIPTION,
-    kOsCrOSOwnerOnly,
-    SINGLE_VALUE_TYPE(chromeos::switches::kDisableAppMode),
-  },
-  {
-    "disable-force-fullscreen-app",
-    IDS_FLAGS_DISABLE_FULLSCREEN_APP_NAME,
-    IDS_FLAGS_DISABLE_FULLSCREEN_APP_DESCRIPTION,
-    kOsCrOS,
-    SINGLE_VALUE_TYPE(switches::kDisableFullscreenApp),
-  },
-  {
     "disable-quickoffice-component-app",
     IDS_FLAGS_DISABLE_QUICKOFFICE_COMPONENT_APP_NAME,
     IDS_FLAGS_DISABLE_QUICKOFFICE_COMPONENT_APP_DESCRIPTION,
@@ -1239,7 +1227,7 @@
     IDS_FLAGS_ASH_AUDIO_DEVICE_MENU_NAME,
     IDS_FLAGS_ASH_AUDIO_DEVICE_MENU_DESCRIPTION,
     kOsCrOS,
-    SINGLE_VALUE_TYPE(ash::switches::kAshEnableAudioDeviceMenu)
+    ENABLE_DISABLE_VALUE_TYPE("", ash::switches::kAshDisableAudioDeviceMenu)
   },
   {
     "enable-carrier-switching",
@@ -1388,6 +1376,16 @@
     MULTI_VALUE_TYPE(kImplSidePaintingChoices)
   },
   {
+    "delegated-renderer",
+    IDS_FLAGS_DELEGATED_RENDERER_NAME,
+    IDS_FLAGS_DELEGATED_RENDERER_DESCRIPTION,
+#ifdef USE_AURA
+    kOsWin | kOsLinux |
+#endif
+    kOsAndroid | kOsCrOS,
+    MULTI_VALUE_TYPE(kDelegatedRendererChoices)
+  },
+  {
     "enable-websocket-experimental-implementation",
     IDS_FLAGS_ENABLE_EXPERIMENTAL_WEBSOCKET_NAME,
     IDS_FLAGS_ENABLE_EXPERIMENTAL_WEBSOCKET_DESCRIPTION,
@@ -1494,6 +1492,13 @@
     kOsAll,
     SINGLE_VALUE_TYPE(switches::kEnableResetProfileSettings)
   },
+  {
+    "enable-device-discovery",
+    IDS_FLAGS_ENABLE_DEVICE_DISCOVERY_NAME,
+    IDS_FLAGS_ENABLE_DEVICE_DISCOVERY_DESCRIPTION,
+    kOsDesktop,
+    SINGLE_VALUE_TYPE(switches::kEnableDeviceDiscovery)
+  },
 #if defined(OS_MACOSX)
   {
     "enable-app-list-shim",
@@ -1598,7 +1603,7 @@
     "enable-gaia-profile-info",
     IDS_FLAGS_ENABLE_GAIA_PROFILE_INFO_NAME,
     IDS_FLAGS_ENABLE_GAIA_PROFILE_INFO_DESCRIPTION,
-    kOsMac | kOsWin,
+    kOsMac | kOsWin | kOsLinux,
     SINGLE_VALUE_TYPE(switches::kGaiaProfileInfo)
   },
 #if defined(OS_WIN)
@@ -1610,6 +1615,13 @@
     SINGLE_VALUE_TYPE(switches::kDisableAppList)
   },
 #endif
+  {
+    "enable-device-motion",
+    IDS_FLAGS_ENABLE_DEVICE_MOTION_NAME,
+    IDS_FLAGS_ENABLE_DEVICE_MOTION_DESCRIPTION,
+    kOsAndroid,
+    SINGLE_VALUE_TYPE(switches::kEnableDeviceMotion)
+  },
 };
 
 const Experiment* experiments = kExperiments;
diff --git a/chrome/browser/accessibility/accessibility_events.cc b/chrome/browser/accessibility/accessibility_events.cc
index 9a46ef6..53c8c8d 100644
--- a/chrome/browser/accessibility/accessibility_events.cc
+++ b/chrome/browser/accessibility/accessibility_events.cc
@@ -7,9 +7,9 @@
 #include "base/values.h"
 
 #include "chrome/browser/accessibility/accessibility_extension_api_constants.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
 
diff --git a/chrome/browser/accessibility/accessibility_extension_api.cc b/chrome/browser/accessibility/accessibility_extension_api.cc
index 868b7bd..033a843 100644
--- a/chrome/browser/accessibility/accessibility_extension_api.cc
+++ b/chrome/browser/accessibility/accessibility_extension_api.cc
@@ -8,6 +8,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/accessibility/accessibility_extension_api_constants.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -16,7 +17,6 @@
 #include "chrome/browser/infobars/infobar_delegate.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_accessibility_state.h"
 #include "content/public/browser/notification_service.h"
 #include "extensions/common/error_utils.h"
diff --git a/chrome/browser/accessibility/accessibility_extension_apitest.cc b/chrome/browser/accessibility/accessibility_extension_apitest.cc
index c5d3151..29e54c4 100644
--- a/chrome/browser/accessibility/accessibility_extension_apitest.cc
+++ b/chrome/browser/accessibility/accessibility_extension_apitest.cc
@@ -28,8 +28,7 @@
   const char kAlertMessage[] = "Simple Alert Infobar.";
   SimpleAlertInfoBarDelegate::Create(infobar_service,
                                      InfoBarDelegate::kNoIconID,
-                                     ASCIIToUTF16(kAlertMessage),
-                                     false);
+                                     ASCIIToUTF16(kAlertMessage), false);
   CommandLine::ForCurrentProcess()->AppendSwitch(
       switches::kEnableExperimentalExtensionApis);
   ASSERT_TRUE(RunExtensionTest("accessibility/get_alerts_for_tab")) << message_;
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc
index 379c23d..79bbecf 100644
--- a/chrome/browser/android/chrome_jni_registrar.cc
+++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -14,12 +14,14 @@
 #include "chrome/browser/android/intent_helper.h"
 #include "chrome/browser/android/most_visited_sites.h"
 #include "chrome/browser/android/provider/chrome_browser_provider.h"
+#include "chrome/browser/android/signin/signin_manager_android.h"
 #include "chrome/browser/android/tab_android.h"
 #include "chrome/browser/autofill/android/personal_data_manager_android.h"
 #include "chrome/browser/history/android/sqlite_cursor.h"
 #include "chrome/browser/lifetime/application_lifetime_android.h"
 #include "chrome/browser/profiles/profile_android.h"
 #include "chrome/browser/search_engines/template_url_service_android.h"
+#include "chrome/browser/signin/android_profile_oauth2_token_service.h"
 #include "chrome/browser/speech/tts_android.h"
 #include "chrome/browser/sync/profile_sync_service_android.h"
 #include "chrome/browser/ui/android/autofill/autofill_dialog_view_android.h"
@@ -47,6 +49,8 @@
     web_contents_delegate_android::RegisterWebContentsDelegateAndroidJni },
   { "RegisterAuxiliaryProfileLoader", autofill::RegisterAutofillAndroidJni },
   // Register JNI for chrome classes.
+  { "AndroidProfileOAuth2TokenService",
+    AndroidProfileOAuth2TokenService::Register },
   { "ApplicationLifetime", RegisterApplicationLifetimeAndroid },
   { "AutofillDialog",
     autofill::AutofillDialogViewAndroid::RegisterAutofillDialogViewAndroid },
@@ -71,6 +75,7 @@
     autofill::PersonalDataManagerAndroid::Register },
   { "ProfileAndroid", ProfileAndroid::RegisterProfileAndroid },
   { "ProfileSyncService", ProfileSyncServiceAndroid::Register },
+  { "SigninManager", SigninManagerAndroid::Register },
   { "SqliteCursor", SQLiteCursor::RegisterSqliteCursor },
   { "SSLClientCertificateRequest", RegisterSSLClientCertificateRequestAndroid },
   { "TabAndroid", TabAndroid::RegisterTabAndroid },
diff --git a/chrome/browser/android/chrome_startup_flags.cc b/chrome/browser/android/chrome_startup_flags.cc
index 8d0b2fe..b789424 100644
--- a/chrome/browser/android/chrome_startup_flags.cc
+++ b/chrome/browser/android/chrome_startup_flags.cc
@@ -36,10 +36,6 @@
   // Turn on autologin.
   SetCommandLineSwitch(switches::kEnableAutologin);
 
-  // Use ClientLogin token on android.
-  // TODO(pavely): Remove once sync on android uses oauth2 tokens.
-  SetCommandLineSwitch(switches::kSyncDisableOAuth2Token);
-
   // Enable prerender for the omnibox.
   SetCommandLineSwitchASCII(
       switches::kPrerenderMode, switches::kPrerenderModeSwitchValueEnabled);
diff --git a/chrome/browser/android/chrome_web_contents_delegate_android.cc b/chrome/browser/android/chrome_web_contents_delegate_android.cc
index 5f843db..0e7552a 100644
--- a/chrome/browser/android/chrome_web_contents_delegate_android.cc
+++ b/chrome/browser/android/chrome_web_contents_delegate_android.cc
@@ -7,15 +7,15 @@
 #include "base/android/jni_android.h"
 #include "base/metrics/histogram.h"
 #include "base/strings/string_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/file_select_helper.h"
 #include "chrome/browser/google/google_url_tracker.h"
-#include "chrome/browser/media/media_stream_infobar_delegate.h"
+#include "chrome/browser/media/media_capture_devices_dispatcher.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.h"
 #include "chrome/browser/ui/find_bar/find_match_rects_details.h"
 #include "chrome/browser/ui/find_bar/find_notification_details.h"
 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
@@ -248,7 +248,8 @@
     content::WebContents* web_contents,
     const content::MediaStreamRequest& request,
     const content::MediaResponseCallback& callback) {
-  MediaStreamInfoBarDelegate::Create(web_contents, request, callback);
+  MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
+      web_contents, request, callback, NULL);
 }
 
 bool ChromeWebContentsDelegateAndroid::RequestPpapiBrokerPermission(
diff --git a/chrome/browser/android/crash_dump_manager.cc b/chrome/browser/android/crash_dump_manager.cc
index 6ee4e04..de2923e 100644
--- a/chrome/browser/android/crash_dump_manager.cc
+++ b/chrome/browser/android/crash_dump_manager.cc
@@ -91,7 +91,7 @@
 
   if (file_size == 0) {
     // Empty minidump, this process did not crash. Just remove the file.
-    r = base::Delete(minidump_path, false);
+    r = base::DeleteFile(minidump_path, false);
     DCHECK(r) << "Failed to delete temporary minidump file "
               << minidump_path.value();
     return;
@@ -115,7 +115,7 @@
   if (!r) {
     LOG(ERROR) << "Failed to move crash dump from " << minidump_path.value()
                << " to " << dest_path.value();
-    base::Delete(minidump_path, false);
+    base::DeleteFile(minidump_path, false);
     return;
   }
   LOG(INFO) << "Crash minidump successfully generated: " <<
diff --git a/chrome/browser/android/favicon_helper.cc b/chrome/browser/android/favicon_helper.cc
index 03dc5d0..69de06c 100644
--- a/chrome/browser/android/favicon_helper.cc
+++ b/chrome/browser/android/favicon_helper.cc
@@ -36,8 +36,10 @@
   ScopedJavaLocalRef<jstring> java_icon_url = ConvertUTF8ToJavaString(
       env, favicon_image_result.icon_url.spec());
   SkBitmap favicon_bitmap = favicon_image_result.image.AsBitmap();
-  ScopedJavaLocalRef<jobject> java_favicon_bitmap = gfx::ConvertToJavaBitmap(
-      &favicon_bitmap);
+  ScopedJavaLocalRef<jobject> java_favicon_bitmap;
+  if (!favicon_bitmap.isNull()) {
+    java_favicon_bitmap = gfx::ConvertToJavaBitmap(&favicon_bitmap);
+  }
 
   // Call java side FaviconImageCallback method.
   Java_FaviconImageCallback_onFaviconAvailable(
diff --git a/chrome/browser/android/provider/chrome_browser_provider.cc b/chrome/browser/android/provider/chrome_browser_provider.cc
index 71764ef..8944515 100644
--- a/chrome/browser/android/provider/chrome_browser_provider.cc
+++ b/chrome/browser/android/provider/chrome_browser_provider.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_service.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/history/android/android_history_types.h"
@@ -31,7 +32,6 @@
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/common/cancelable_task_tracker.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "grit/generated_resources.h"
@@ -1154,7 +1154,7 @@
 
 ChromeBrowserProvider::ChromeBrowserProvider(JNIEnv* env, jobject obj)
     : weak_java_provider_(env, obj),
-      template_loaded_event_(true, false) {
+      handling_extensive_changes_(false) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   profile_ = g_browser_process->profile_manager()->GetLastUsedProfile();
   bookmark_model_ = BookmarkModelFactory::GetForProfile(profile_);
@@ -1172,14 +1172,9 @@
   notification_registrar_.Add(this,
       chrome::NOTIFICATION_HISTORY_KEYWORD_SEARCH_TERM_UPDATED,
       content::NotificationService::AllSources());
-  notification_registrar_.Add(this,
-      chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED,
-      content::NotificationService::AllSources());
   TemplateURLService* template_service =
         TemplateURLServiceFactory::GetForProfile(profile_);
-  if (template_service->loaded())
-    template_loaded_event_.Signal();
-  else
+  if (!template_service->loaded())
     template_service->Load();
 }
 
@@ -1580,7 +1575,21 @@
 
 // ------------- Observer-related methods ------------- //
 
+void ChromeBrowserProvider::ExtensiveBookmarkChangesBeginning(
+    BookmarkModel* model) {
+  handling_extensive_changes_ = true;
+}
+
+void ChromeBrowserProvider::ExtensiveBookmarkChangesEnded(
+    BookmarkModel* model) {
+  handling_extensive_changes_ = false;
+  BookmarkModelChanged();
+}
+
 void ChromeBrowserProvider::BookmarkModelChanged() {
+  if (handling_extensive_changes_)
+    return;
+
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> obj = weak_java_provider_.get(env);
   if (obj.is_null())
@@ -1607,7 +1616,5 @@
     if (obj.is_null())
       return;
     Java_ChromeBrowserProvider_onSearchTermChanged(env, obj.obj());
-  } else if (type == chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED) {
-    template_loaded_event_.Signal();
   }
 }
diff --git a/chrome/browser/android/provider/chrome_browser_provider.h b/chrome/browser/android/provider/chrome_browser_provider.h
index 747a4ea..53e5dda 100644
--- a/chrome/browser/android/provider/chrome_browser_provider.h
+++ b/chrome/browser/android/provider/chrome_browser_provider.h
@@ -176,6 +176,8 @@
 
   // Override BaseBookmarkModelObserver.
   virtual void BookmarkModelChanged() OVERRIDE;
+  virtual void ExtensiveBookmarkChangesBeginning(BookmarkModel* model) OVERRIDE;
+  virtual void ExtensiveBookmarkChangesEnded(BookmarkModel* model) OVERRIDE;
 
   // Override NotificationObserver.
   virtual void Observe(int type,
@@ -204,8 +206,7 @@
   // Used to register/unregister notification observer.
   content::NotificationRegistrar notification_registrar_;
 
-  // Signaled if TemplateURLModel has been loaded.
-  base::WaitableEvent template_loaded_event_;
+  bool handling_extensive_changes_;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserProvider);
 };
diff --git a/chrome/browser/android/signin/signin_manager_android.cc b/chrome/browser/android/signin/signin_manager_android.cc
new file mode 100644
index 0000000..5c05939
--- /dev/null
+++ b/chrome/browser/android/signin/signin_manager_android.cc
@@ -0,0 +1,129 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/signin/signin_manager_android.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/common/pref_names.h"
+#include "jni/SigninManager_jni.h"
+
+#if defined(ENABLE_CONFIGURATION_POLICY)
+#include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/cloud/cloud_policy_client.h"
+#include "chrome/browser/policy/cloud/user_policy_signin_service_android.h"
+#include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
+#endif
+
+using base::android::ConvertJavaStringToUTF8;
+
+SigninManagerAndroid::SigninManagerAndroid(JNIEnv* env, jobject obj)
+    : profile_(NULL) {
+  java_signin_manager_.Reset(env, obj);
+  DCHECK(g_browser_process);
+  DCHECK(g_browser_process->profile_manager());
+  profile_ = g_browser_process->profile_manager()->GetDefaultProfile();
+  DCHECK(profile_);
+}
+
+SigninManagerAndroid::~SigninManagerAndroid() {}
+
+void SigninManagerAndroid::CheckPolicyBeforeSignIn(JNIEnv* env,
+                                                   jobject obj,
+                                                   jstring username) {
+#if defined(ENABLE_CONFIGURATION_POLICY)
+  policy::UserPolicySigninService* service =
+      policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
+  service->RegisterPolicyClient(
+      ConvertJavaStringToUTF8(env, username),
+      base::Bind(&SigninManagerAndroid::OnPolicyRegisterDone,
+                 base::Unretained(this)));
+#else
+  // This shouldn't be called when ShouldLoadPolicyForUser() is false.
+  NOTREACHED();
+  const jboolean has_policy_management = false;
+  Java_SigninManager_onPolicyCheckedBeforeSignIn(env,
+                                                 java_signin_manager_.obj(),
+                                                 has_policy_management);
+#endif
+}
+
+void SigninManagerAndroid::FetchPolicyBeforeSignIn(JNIEnv* env, jobject obj) {
+#if defined(ENABLE_CONFIGURATION_POLICY)
+  if (cloud_policy_client_) {
+    policy::UserPolicySigninService* service =
+        policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
+    service->FetchPolicyForSignedInUser(
+        cloud_policy_client_.Pass(),
+        base::Bind(&SigninManagerAndroid::OnPolicyFetchDone,
+                   base::Unretained(this)));
+    return;
+  }
+#endif
+  // This shouldn't be called when ShouldLoadPolicyForUser() is false, or when
+  // CheckPolicyBeforeSignIn() failed.
+  NOTREACHED();
+  Java_SigninManager_onPolicyFetchedBeforeSignIn(env,
+                                                 java_signin_manager_.obj());
+}
+
+void SigninManagerAndroid::OnSignInCompleted(JNIEnv* env,
+                                             jobject obj,
+                                             jstring username) {
+  SigninManagerFactory::GetForProfile(profile_)->OnExternalSigninCompleted(
+      ConvertJavaStringToUTF8(env, username));
+}
+
+void SigninManagerAndroid::SignOut(JNIEnv* env, jobject obj) {
+  SigninManagerFactory::GetForProfile(profile_)->SignOut();
+}
+
+#if defined(ENABLE_CONFIGURATION_POLICY)
+
+void SigninManagerAndroid::OnPolicyRegisterDone(
+    scoped_ptr<policy::CloudPolicyClient> client) {
+  cloud_policy_client_ = client.Pass();
+
+  JNIEnv* env = base::android::AttachCurrentThread();
+  const jboolean has_policy_management = !!cloud_policy_client_;
+  Java_SigninManager_onPolicyCheckedBeforeSignIn(env,
+                                                 java_signin_manager_.obj(),
+                                                 has_policy_management);
+}
+
+void SigninManagerAndroid::OnPolicyFetchDone(bool success) {
+  JNIEnv* env = base::android::AttachCurrentThread();
+  Java_SigninManager_onPolicyFetchedBeforeSignIn(env,
+                                                 java_signin_manager_.obj());
+}
+
+#endif
+
+static int Init(JNIEnv* env, jobject obj) {
+  SigninManagerAndroid* signin_manager_android =
+      new SigninManagerAndroid(env, obj);
+  return reinterpret_cast<jint>(signin_manager_android);
+}
+
+static jboolean ShouldLoadPolicyForUser(JNIEnv* env,
+                                        jobject obj,
+                                        jstring j_username) {
+#if defined(ENABLE_CONFIGURATION_POLICY)
+  std::string username = ConvertJavaStringToUTF8(env, j_username);
+  return !policy::BrowserPolicyConnector::IsNonEnterpriseUser(username);
+#else
+  return false;
+#endif
+}
+
+// static
+bool SigninManagerAndroid::Register(JNIEnv* env) {
+  return RegisterNativesImpl(env);
+}
diff --git a/chrome/browser/android/signin/signin_manager_android.h b/chrome/browser/android/signin/signin_manager_android.h
new file mode 100644
index 0000000..1817b70
--- /dev/null
+++ b/chrome/browser/android/signin/signin_manager_android.h
@@ -0,0 +1,65 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ANDROID_SIGNIN_SIGNIN_MANAGER_ANDROID_H_
+#define CHROME_BROWSER_ANDROID_SIGNIN_SIGNIN_MANAGER_ANDROID_H_
+
+#include <jni.h>
+
+#include "base/android/scoped_java_ref.h"
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+
+class Profile;
+
+namespace policy {
+class CloudPolicyClient;
+}
+
+// Android wrapper of the SigninManager which provides access from the Java
+// layer. Note that on Android, there's only a single profile, and therefore
+// a single instance of this wrapper. The name of the Java class is
+// SigninManager.
+// This class should only be accessed from the UI thread.
+//
+// This class implements parts of the sign-in flow, to make sure that policy
+// is available before sign-in completes.
+class SigninManagerAndroid {
+ public:
+  SigninManagerAndroid(JNIEnv* env, jobject obj);
+
+  // Registers the SigninManagerAndroid's native methods through JNI.
+  static bool Register(JNIEnv* env);
+
+  void CheckPolicyBeforeSignIn(JNIEnv* env, jobject obj, jstring username);
+
+  void FetchPolicyBeforeSignIn(JNIEnv* env, jobject obj);
+
+  void OnSignInCompleted(JNIEnv* env, jobject obj, jstring username);
+
+  void SignOut(JNIEnv* env, jobject obj);
+
+ private:
+  virtual ~SigninManagerAndroid();
+
+#if defined(ENABLE_CONFIGURATION_POLICY)
+  void OnPolicyRegisterDone(scoped_ptr<policy::CloudPolicyClient> client);
+  void OnPolicyFetchDone(bool success);
+#endif
+
+  Profile* profile_;
+
+  // Java-side SigninManager object.
+  base::android::ScopedJavaGlobalRef<jobject> java_signin_manager_;
+
+#if defined(ENABLE_CONFIGURATION_POLICY)
+  // CloudPolicyClient stored during a pending sign-in, awaiting user
+  // confirmation before starting to fetch policies.
+  scoped_ptr<policy::CloudPolicyClient> cloud_policy_client_;
+#endif
+
+  DISALLOW_COPY_AND_ASSIGN(SigninManagerAndroid);
+};
+
+#endif  // CHROME_BROWSER_ANDROID_SIGNIN_SIGNIN_MANAGER_ANDROID_H_
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h
index 7f7d738..9e39a67 100644
--- a/chrome/browser/android/tab_android.h
+++ b/chrome/browser/android/tab_android.h
@@ -81,7 +81,12 @@
   // derived classes may remove their implementation first.
   virtual void RunExternalProtocolDialog(const GURL& url);
 
+  // Used by sync to get/set the sync id of tab.
+  virtual int64 GetSyncId() const = 0;
+  virtual void SetSyncId(int64 sync_id) = 0;
+
   static bool RegisterTabAndroid(JNIEnv* env);
+
  protected:
   virtual ~TabAndroid();
 
diff --git a/chrome/browser/android/tab_android_test_stubs.cc b/chrome/browser/android/tab_android_test_stubs.cc
index b26ae5f..414ca10 100644
--- a/chrome/browser/android/tab_android_test_stubs.cc
+++ b/chrome/browser/android/tab_android_test_stubs.cc
@@ -26,7 +26,7 @@
 AutoLoginInfoBarDelegateAndroid::AutoLoginInfoBarDelegateAndroid(
     InfoBarService* owner,
     const AutoLoginInfoBarDelegate::Params& params)
-    : AutoLoginInfoBarDelegate(owner, params) {}
+    : AutoLoginInfoBarDelegate(owner, params), params_() {}
 
 AutoLoginInfoBarDelegateAndroid::~AutoLoginInfoBarDelegateAndroid() {}
 
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index 3944238..703ae16 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -20,6 +20,7 @@
 #include "chrome/browser/background/background_mode_manager.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/download/download_service.h"
 #include "chrome/browser/download/download_service_factory.h"
@@ -64,7 +65,6 @@
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths_internal.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/cloud_print/cloud_print_class_mac.h"
diff --git a/chrome/browser/app_mode/app_mode_utils.cc b/chrome/browser/app_mode/app_mode_utils.cc
index 971abd9..48e39d9 100644
--- a/chrome/browser/app_mode/app_mode_utils.cc
+++ b/chrome/browser/app_mode/app_mode_utils.cc
@@ -51,10 +51,4 @@
       command_line->HasSwitch(switches::kAppId);
 }
 
-bool ShouldForceFullscreenApp() {
-  CommandLine* command_line = CommandLine::ForCurrentProcess();
-  return IsRunningInForcedAppMode() &&
-      !command_line->HasSwitch(switches::kDisableFullscreenApp);
-}
-
-}  // namespace switches
+}  // namespace chrome
diff --git a/chrome/browser/app_mode/app_mode_utils.h b/chrome/browser/app_mode/app_mode_utils.h
index 65c7565..a591814 100644
--- a/chrome/browser/app_mode/app_mode_utils.h
+++ b/chrome/browser/app_mode/app_mode_utils.h
@@ -16,10 +16,6 @@
 // Return true if browser process is run in forced app mode.
 bool IsRunningInForcedAppMode();
 
-// Return true if browser runs in force app mode and should force app to run
-// in full screen.
-bool ShouldForceFullscreenApp();
-
-}  // namespace switches
+}  // namespace chrome
 
 #endif  // CHROME_BROWSER_APP_MODE_APP_MODE_UTILS_H_
diff --git a/chrome/browser/autocomplete/autocomplete_controller.cc b/chrome/browser/autocomplete/autocomplete_controller.cc
index 3cc8a68..39937f9 100644
--- a/chrome/browser/autocomplete/autocomplete_controller.cc
+++ b/chrome/browser/autocomplete/autocomplete_controller.cc
@@ -24,11 +24,11 @@
 #include "chrome/browser/autocomplete/search_provider.h"
 #include "chrome/browser/autocomplete/shortcuts_provider.h"
 #include "chrome/browser/autocomplete/zero_suggest_provider.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/omnibox/omnibox_field_trial.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/search_engines/template_url.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/notification_service.h"
 #include "grit/generated_resources.h"
@@ -635,21 +635,9 @@
   // come after the user has had to time to read the whole dropdown
   // and doesn't expect it to change.
   const int kStopTimeMS = 1500;
-
-  // Only use the timer if Instant/InstantExtended is disabled.
-  // InstantExtended has its own logic for when to stop updating the
-  // dropdown.  Furthermore, both Instant and InstantExtended expect
-  // all results they inject (regardless of how long they took) to make
-  // it to the edit model / dropdown display code.
-#if defined(HTML_INSTANT_EXTENDED_POPUP)
-  if (!chrome::IsInstantExtendedAPIEnabled() &&
-      !chrome::IsInstantEnabled(profile_))
-#endif
-  {
-    stop_timer_.Start(FROM_HERE,
-                      base::TimeDelta::FromMilliseconds(kStopTimeMS),
-                      base::Bind(&AutocompleteController::Stop,
-                                 base::Unretained(this),
-                                 false));
-  }
+  stop_timer_.Start(FROM_HERE,
+                    base::TimeDelta::FromMilliseconds(kStopTimeMS),
+                    base::Bind(&AutocompleteController::Stop,
+                               base::Unretained(this),
+                               false));
 }
diff --git a/chrome/browser/autocomplete/autocomplete_provider.h b/chrome/browser/autocomplete/autocomplete_provider.h
index ae72f7e..950670d 100644
--- a/chrome/browser/autocomplete/autocomplete_provider.h
+++ b/chrome/browser/autocomplete/autocomplete_provider.h
@@ -50,9 +50,9 @@
 // Search Primary Provider (past query in history older than 2 days)   | 1050--
 // HistoryURL (some inexact matches)                                   |  900++
 // BookmarkProvider (prefix match in bookmark title)                   |  900+-
+// Built-in                                                            |  860++
 // Search Primary Provider (navigational suggestion)                   |  800++
 // Search Primary Provider (suggestion)                                |  600++
-// Built-in                                                            |  575++
 // Keyword (inexact match)                                             |  450
 // Search Secondary Provider (what you typed)                          |  250
 // Search Secondary Provider (past query in history)                   |  200--
@@ -69,11 +69,11 @@
 // Extension App (inexact match)                                       | 1175*~
 // Keyword (substituting, exact match)                                 | 1100
 // HistoryURL (some inexact matches)                                   |  900++
+// Built-in                                                            |  860++
 // Search Primary Provider (what you typed)                            |  850
 // Search Primary Provider (navigational suggestion)                   |  800++
 // Search Primary Provider (past query in history)                     |  750--
 // Keyword (inexact match)                                             |  700
-// Built-in                                                            |  575++
 // Search Primary Provider (suggestion)                                |  300++
 // Search Secondary Provider (what you typed)                          |  250
 // Search Secondary Provider (past query in history)                   |  200--
diff --git a/chrome/browser/autocomplete/autocomplete_provider_unittest.cc b/chrome/browser/autocomplete/autocomplete_provider_unittest.cc
index d7342f5..1d8ed1a 100644
--- a/chrome/browser/autocomplete/autocomplete_provider_unittest.cc
+++ b/chrome/browser/autocomplete/autocomplete_provider_unittest.cc
@@ -18,10 +18,10 @@
 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
 #include "chrome/browser/autocomplete/keyword_provider.h"
 #include "chrome/browser/autocomplete/search_provider.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/autocomplete/autocomplete_result.cc b/chrome/browser/autocomplete/autocomplete_result.cc
index 38a0edf..58a19c9 100644
--- a/chrome/browser/autocomplete/autocomplete_result.cc
+++ b/chrome/browser/autocomplete/autocomplete_result.cc
@@ -33,19 +33,6 @@
 
 AutocompleteResult::~AutocompleteResult() {}
 
-void AutocompleteResult::CopyFrom(const AutocompleteResult& rhs) {
-  if (this == &rhs)
-    return;
-
-  matches_ = rhs.matches_;
-  // Careful!  You can't just copy iterators from another container, you have to
-  // reconstruct them.
-  default_match_ = (rhs.default_match_ == rhs.end()) ?
-      end() : (begin() + (rhs.default_match_ - rhs.begin()));
-
-  alternate_nav_url_ = rhs.alternate_nav_url_;
-}
-
 void AutocompleteResult::CopyOldMatches(const AutocompleteInput& input,
                                         const AutocompleteResult& old_matches,
                                         Profile* profile) {
@@ -99,20 +86,6 @@
   alternate_nav_url_ = GURL();
 }
 
-void AutocompleteResult::AddMatch(const AutocompleteMatch& match) {
-  DCHECK(default_match_ != end());
-  DCHECK_EQ(AutocompleteMatch::SanitizeString(match.contents), match.contents);
-  DCHECK_EQ(AutocompleteMatch::SanitizeString(match.description),
-            match.description);
-  ACMatches::iterator insertion_point =
-      std::upper_bound(begin(), end(), match, &AutocompleteMatch::MoreRelevant);
-  matches_difference_type default_offset = default_match_ - begin();
-  if ((insertion_point - begin()) <= default_offset)
-    ++default_offset;
-  matches_.insert(insertion_point, match);
-  default_match_ = begin() + default_offset;
-}
-
 void AutocompleteResult::SortAndCull(const AutocompleteInput& input,
                                      Profile* profile) {
   for (ACMatches::iterator i(matches_.begin()); i != matches_.end(); ++i)
@@ -214,6 +187,33 @@
       input.canonicalized_url() : GURL();
 }
 
+void AutocompleteResult::CopyFrom(const AutocompleteResult& rhs) {
+  if (this == &rhs)
+    return;
+
+  matches_ = rhs.matches_;
+  // Careful!  You can't just copy iterators from another container, you have to
+  // reconstruct them.
+  default_match_ = (rhs.default_match_ == rhs.end()) ?
+      end() : (begin() + (rhs.default_match_ - rhs.begin()));
+
+  alternate_nav_url_ = rhs.alternate_nav_url_;
+}
+
+void AutocompleteResult::AddMatch(const AutocompleteMatch& match) {
+  DCHECK(default_match_ != end());
+  DCHECK_EQ(AutocompleteMatch::SanitizeString(match.contents), match.contents);
+  DCHECK_EQ(AutocompleteMatch::SanitizeString(match.description),
+            match.description);
+  ACMatches::iterator insertion_point =
+      std::upper_bound(begin(), end(), match, &AutocompleteMatch::MoreRelevant);
+  matches_difference_type default_offset = default_match_ - begin();
+  if ((insertion_point - begin()) <= default_offset)
+    ++default_offset;
+  matches_.insert(insertion_point, match);
+  default_match_ = begin() + default_offset;
+}
+
 void AutocompleteResult::BuildProviderToMatches(
     ProviderToMatches* provider_to_matches) const {
   for (ACMatches::const_iterator i(begin()); i != end(); ++i)
diff --git a/chrome/browser/autocomplete/autocomplete_result.h b/chrome/browser/autocomplete/autocomplete_result.h
index 57660f4..df3ab01 100644
--- a/chrome/browser/autocomplete/autocomplete_result.h
+++ b/chrome/browser/autocomplete/autocomplete_result.h
@@ -66,20 +66,12 @@
   AutocompleteResult();
   ~AutocompleteResult();
 
-  // operator=() by another name.
-  void CopyFrom(const AutocompleteResult& rhs);
-
   // Copies matches from |old_matches| to provide a consistant result set. See
   // comments in code for specifics.
   void CopyOldMatches(const AutocompleteInput& input,
                       const AutocompleteResult& old_matches,
                       Profile* profile);
 
-  // Adds a single match. The match is inserted at the appropriate position
-  // based on relevancy and display order. This is ONLY for use after
-  // SortAndCull() has been invoked, and preserves default_match_.
-  void AddMatch(const AutocompleteMatch& match);
-
   // Adds a new set of matches to the result set.  Does not re-sort.
   void AppendMatches(const ACMatches& matches);
 
@@ -126,6 +118,8 @@
                                      const AutocompleteMatch& match);
 
  private:
+  friend class AutocompleteProviderTest;
+
   typedef std::map<AutocompleteProvider*, ACMatches> ProviderToMatches;
 
 #if defined(OS_ANDROID)
@@ -136,6 +130,14 @@
   typedef ACMatches::iterator::difference_type matches_difference_type;
 #endif
 
+  // operator=() by another name.
+  void CopyFrom(const AutocompleteResult& rhs);
+
+  // Adds a single match. The match is inserted at the appropriate position
+  // based on relevancy and display order. This is ONLY for use after
+  // SortAndCull() has been invoked, and preserves default_match_.
+  void AddMatch(const AutocompleteMatch& match);
+
   // Populates |provider_to_matches| from |matches_|.
   void BuildProviderToMatches(ProviderToMatches* provider_to_matches) const;
 
diff --git a/chrome/browser/autocomplete/builtin_provider.cc b/chrome/browser/autocomplete/builtin_provider.cc
index d05191a..6c5ab97 100644
--- a/chrome/browser/autocomplete/builtin_provider.cc
+++ b/chrome/browser/autocomplete/builtin_provider.cc
@@ -32,7 +32,7 @@
 
 }  // namespace
 
-const int BuiltinProvider::kRelevance = 575;
+const int BuiltinProvider::kRelevance = 860;
 
 BuiltinProvider::BuiltinProvider(AutocompleteProviderListener* listener,
                                  Profile* profile)
diff --git a/chrome/browser/autocomplete/extension_app_provider.cc b/chrome/browser/autocomplete/extension_app_provider.cc
index be923c8..003cdac 100644
--- a/chrome/browser/autocomplete/extension_app_provider.cc
+++ b/chrome/browser/autocomplete/extension_app_provider.cc
@@ -9,6 +9,7 @@
 
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system_factory.h"
 #include "chrome/browser/history/history_service.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/autocomplete/history_provider.cc b/chrome/browser/autocomplete/history_provider.cc
index d09b794..d462c05 100644
--- a/chrome/browser/autocomplete/history_provider.cc
+++ b/chrome/browser/autocomplete/history_provider.cc
@@ -21,8 +21,7 @@
 HistoryProvider::HistoryProvider(AutocompleteProviderListener* listener,
                                  Profile* profile,
                                  AutocompleteProvider::Type type)
-    : AutocompleteProvider(listener, profile, type),
-      always_prevent_inline_autocomplete_(false) {
+    : AutocompleteProvider(listener, profile, type) {
 }
 
 void HistoryProvider::DeleteMatch(const AutocompleteMatch& match) {
@@ -157,7 +156,6 @@
 bool HistoryProvider::PreventInlineAutocomplete(
     const AutocompleteInput& input) {
   return input.prevent_inline_autocomplete() ||
-      always_prevent_inline_autocomplete_ ||
       (!input.text().empty() &&
        IsWhitespace(input.text()[input.text().length() - 1]));
 }
diff --git a/chrome/browser/autocomplete/history_provider.h b/chrome/browser/autocomplete/history_provider.h
index e90f6e4..6be0e2b 100644
--- a/chrome/browser/autocomplete/history_provider.h
+++ b/chrome/browser/autocomplete/history_provider.h
@@ -50,12 +50,9 @@
   // Returns true if inline autocompletion should be prevented. Use this instead
   // of |input.prevent_inline_autocomplete| if the input is passed through
   // FixupUserInput(). This method returns true if
-  // |input.prevent_inline_autocomplete()| is true, or the input text contains
-  // trailing whitespace, or if always_prevent_inline_autocomplete is true.
+  // |input.prevent_inline_autocomplete()| is true or the input text contains
+  // trailing whitespace.
   bool PreventInlineAutocomplete(const AutocompleteInput& input);
-
-  // If true, we always prevent inline autocompletions.
-  bool always_prevent_inline_autocomplete_;
 };
 
 #endif  // CHROME_BROWSER_AUTOCOMPLETE_HISTORY_PROVIDER_H_
diff --git a/chrome/browser/autocomplete/history_quick_provider.cc b/chrome/browser/autocomplete/history_quick_provider.cc
index 1a5eb67..073aa18 100644
--- a/chrome/browser/autocomplete/history_quick_provider.cc
+++ b/chrome/browser/autocomplete/history_quick_provider.cc
@@ -56,68 +56,7 @@
     Profile* profile)
     : HistoryProvider(listener, profile,
           AutocompleteProvider::TYPE_HISTORY_QUICK),
-      languages_(profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)),
-      reorder_for_inlining_(false) {
-  enum InliningOption {
-    INLINING_PROHIBITED = 0,
-    INLINING_ALLOWED = 1,
-    INLINING_AUTO_BUT_NOT_IN_FIELD_TRIAL = 2,
-    INLINING_FIELD_TRIAL_DEFAULT_GROUP = 3,
-    INLINING_FIELD_TRIAL_EXPERIMENT_GROUP = 4,
-    NUM_OPTIONS = 5
-  };
-  // should always be overwritten
-  InliningOption inlining_option = NUM_OPTIONS;
-
-  const std::string switch_value = CommandLine::ForCurrentProcess()->
-      GetSwitchValueASCII(switches::kOmniboxInlineHistoryQuickProvider);
-  if (switch_value == switches::kOmniboxInlineHistoryQuickProviderAllowed) {
-    inlining_option = INLINING_ALLOWED;
-    always_prevent_inline_autocomplete_ = false;
-  } else if (switch_value ==
-             switches::kOmniboxInlineHistoryQuickProviderProhibited) {
-    inlining_option = INLINING_PROHIBITED;
-    always_prevent_inline_autocomplete_ = true;
-  } else {
-    // We'll assume any other flag means automatic.
-    // Automatic means eligible for the field trial.
-
-    // For the field trial stuff to work correctly, we must be running
-    // on the same thread as the thread that created the field trial,
-    // which happens via a call to OmniboxFieldTrial::Active in
-    // chrome_browser_main.cc on the main thread.  Let's check this to
-    // be sure.  We check "if we've heard of the UI thread then we'd better
-    // be on it."  The first part is necessary so unit tests pass.  (Many
-    // unit tests don't set up the threading naming system; hence
-    // CurrentlyOn(UI thread) will fail.)
-    DCHECK(!content::BrowserThread::IsWellKnownThread(
-               content::BrowserThread::UI) ||
-           content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-    if (OmniboxFieldTrial::InDisallowInlineHQPFieldTrial()) {
-      if (OmniboxFieldTrial::InDisallowInlineHQPFieldTrialExperimentGroup()) {
-        always_prevent_inline_autocomplete_ = true;
-        inlining_option = INLINING_FIELD_TRIAL_EXPERIMENT_GROUP;
-      } else {
-        always_prevent_inline_autocomplete_ = false;
-        inlining_option = INLINING_FIELD_TRIAL_DEFAULT_GROUP;
-      }
-    } else {
-      always_prevent_inline_autocomplete_ = false;
-      inlining_option = INLINING_AUTO_BUT_NOT_IN_FIELD_TRIAL;
-    }
-  }
-
-  // Add a beacon to the logs that'll allow us to identify later what
-  // inlining state a user is in.  Do this by incrementing a bucket in
-  // a histogram, where the bucket represents the user's inlining state.
-  UMA_HISTOGRAM_ENUMERATION(
-      "Omnibox.InlineHistoryQuickProviderFieldTrialBeacon",
-      inlining_option, NUM_OPTIONS);
-
-  reorder_for_inlining_ = CommandLine::ForCurrentProcess()->
-      GetSwitchValueASCII(switches::
-                          kOmniboxHistoryQuickProviderReorderForInlining) ==
-      switches::kOmniboxHistoryQuickProviderReorderForInliningEnabled;
+      languages_(profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)) {
 }
 
 void HistoryQuickProvider::Start(const AutocompleteInput& input,
@@ -173,29 +112,6 @@
   if (matches.empty())
     return;
 
-  // If we're allowed to reorder results in order to get an inlineable
-  // result to appear first (and hence have a HistoryQuickProvider
-  // suggestion possibly appear first), find the first inlineable
-  // result and then swap it to the front.  Obviously, don't do this
-  // if we're told to prevent inline autocompletion.  (If we're told
-  // we're going to prevent inline autocompletion, we're going to
-  // later demote the score of all results so none will be inlined.
-  // Hence there's no need to reorder the results so an inlineable one
-  // appears first.)
-  if (reorder_for_inlining_ &&
-      !PreventInlineAutocomplete(autocomplete_input_)) {
-    for (ScoredHistoryMatches::iterator i(matches.begin());
-         (i != matches.end()) &&
-             (i->raw_score >= AutocompleteResult::kLowestDefaultScore);
-         ++i) {
-      if (i->can_inline) {  // this test is only true once because of the break
-        if (i != matches.begin())
-          std::rotate(matches.begin(), i, i + 1);
-        break;
-      }
-    }
-  }
-
   // Figure out if HistoryURL provider has a URL-what-you-typed match
   // that ought to go first and what its score will be.
   bool will_have_url_what_you_typed_match_first = false;
diff --git a/chrome/browser/autocomplete/history_quick_provider.h b/chrome/browser/autocomplete/history_quick_provider.h
index f60ac08..a4208ba 100644
--- a/chrome/browser/autocomplete/history_quick_provider.h
+++ b/chrome/browser/autocomplete/history_quick_provider.h
@@ -79,24 +79,6 @@
   AutocompleteInput autocomplete_input_;
   std::string languages_;
 
-  // True if we're allowed to reorder results depending on
-  // inlineability in order to assign higher relevance scores.
-  // Consider a case where ScoredHistoryMatch provides results x and
-  // y, where x is not inlineable and has a score of 3000 and y is
-  // inlineable and has a score of 2500.  If reorder_for_inlining_ is
-  // false, then x gets demoted to a non-inlineable score (1199) and y
-  // gets demoted to a lower score (1198) because we try to preserve
-  // the order.  On the other hand, if reorder_for_inlining_ is true,
-  // then y keeps its score of 2500 and x gets demoted to 2499 in
-  // order to follow y.  There will not be any problems with an
-  // unexpected inline because the non-inlineable result x scores
-  // lower than the inlineable one.
-  // TODO(mpearson): remove this variable after we're done experimenting.
-  // (This member is meant to only exist for experimentation purposes.
-  // Once we know which behavior is better, we should rip out this variable
-  // and make the best behavior the default.)
-  bool reorder_for_inlining_;
-
   // Only used for testing.
   scoped_ptr<history::InMemoryURLIndex> index_for_testing_;
 
diff --git a/chrome/browser/autocomplete/keyword_provider.cc b/chrome/browser/autocomplete/keyword_provider.cc
index c2759dd..10ae975 100644
--- a/chrome/browser/autocomplete/keyword_provider.cc
+++ b/chrome/browser/autocomplete/keyword_provider.cc
@@ -12,6 +12,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/omnibox/omnibox_api.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -19,7 +20,6 @@
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/generated_resources.h"
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc
index c5861c4..2f30450 100644
--- a/chrome/browser/autocomplete/search_provider.cc
+++ b/chrome/browser/autocomplete/search_provider.cc
@@ -251,7 +251,11 @@
       suggest_results_pending_(0),
       field_trial_triggered_(false),
       field_trial_triggered_in_session_(false),
-      omnibox_start_margin_(-1) {
+      omnibox_start_margin_(-1),
+      prevent_search_history_inlining_(
+          OmniboxFieldTrial::SearchHistoryPreventInlining()),
+      disable_search_history_(
+          OmniboxFieldTrial::SearchHistoryDisable()) {
 }
 
 // static
@@ -627,6 +631,9 @@
   keyword_history_results_.clear();
   default_history_results_.clear();
 
+  if (disable_search_history_)
+    return;
+
   HistoryService* const history_service =
       HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
   history::URLDatabase* url_db = history_service ?
@@ -1336,17 +1343,21 @@
     bool prevent_inline_autocomplete) const {
   // The relevance of past searches falls off over time. There are two distinct
   // equations used. If the first equation is used (searches to the primary
-  // provider that we want to inline autocomplete), the score starts at 1399 and
-  // falls to 1300. If the second equation is used the relevance of a search 15
-  // minutes ago is discounted 50 points, while the relevance of a search two
-  // weeks ago is discounted 450 points.
+  // provider that we want to inline autocomplete), the score is in the range
+  // 1300-1599 (unless |prevent_search_history_inlining_|, in which case
+  // it's in the range 1200-1299). If the second equation is used the
+  // relevance of a search 15 minutes ago is discounted 50 points, while the
+  // relevance of a search two weeks ago is discounted 450 points.
   double elapsed_time = std::max((base::Time::Now() - time).InSecondsF(), 0.0);
   bool is_primary_provider = is_keyword || !providers_.has_keyword_provider();
   if (is_primary_provider && !prevent_inline_autocomplete) {
     // Searches with the past two days get a different curve.
     const double autocomplete_time = 2 * 24 * 60 * 60;
     if (elapsed_time < autocomplete_time) {
-      return (is_keyword ? 1599 : 1399) - static_cast<int>(99 *
+      int max_score = is_keyword ? 1599 : 1399;
+      if (prevent_search_history_inlining_)
+        max_score = 1299;
+      return max_score - static_cast<int>(99 *
           std::pow(elapsed_time / autocomplete_time, 2.5));
     }
     elapsed_time -= autocomplete_time;
diff --git a/chrome/browser/autocomplete/search_provider.h b/chrome/browser/autocomplete/search_provider.h
index 531825d..f01fdb6 100644
--- a/chrome/browser/autocomplete/search_provider.h
+++ b/chrome/browser/autocomplete/search_provider.h
@@ -104,8 +104,8 @@
  private:
   // TODO(hfung): Remove ZeroSuggestProvider as a friend class after
   // refactoring common code to a new base class.
-  friend class ZeroSuggestProvider;
   friend class SearchProviderTest;
+  friend class ZeroSuggestProvider;
   FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationInline);
   FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationInlineDomainClassify);
   FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationInlineSchemeSubstring);
@@ -527,6 +527,13 @@
   // Start margin of the omnibox. Used to construct search URLs.
   int omnibox_start_margin_;
 
+  // If true, search history query suggestions will score low enough that
+  // they will not be inlined.
+  bool prevent_search_history_inlining_;
+
+  // If true, no search history query suggestions will be offered.
+  bool disable_search_history_;
+
   DISALLOW_COPY_AND_ASSIGN(SearchProvider);
 };
 
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc
index 213e79d..fd2f89f 100644
--- a/chrome/browser/autofill/autofill_browsertest.cc
+++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -15,6 +15,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -51,11 +51,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/keycodes/keyboard_codes.h"
 
-using content::RenderViewHost;
-using content::RenderViewHostTester;
-using content::WebContents;
-
-using testing::Invoke;
 
 namespace autofill {
 
@@ -138,7 +133,7 @@
   }
 
   virtual ~WindowedPersonalDataManagerObserver() {
-    if (infobar_service_ && infobar_service_->infobar_count() > 0)
+    if (infobar_service_ && (infobar_service_->infobar_count() > 0))
       infobar_service_->RemoveInfoBar(infobar_service_->infobar_at(0));
   }
 
@@ -168,14 +163,13 @@
   virtual void Observe(int type,
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE {
-    // Accept in the infobar.
+    EXPECT_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, type);
     infobar_service_ = InfoBarService::FromWebContents(
         browser_->tab_strip_model()->GetActiveWebContents());
-    InfoBarDelegate* infobar = infobar_service_->infobar_at(0);
-
-    ConfirmInfoBarDelegate* confirm_infobar =
-        infobar->AsConfirmInfoBarDelegate();
-    confirm_infobar->Accept();
+    ConfirmInfoBarDelegate* infobar_delegate =
+        infobar_service_->infobar_at(0)->AsConfirmInfoBarDelegate();
+    ASSERT_TRUE(infobar_delegate);
+    infobar_delegate->Accept();
   }
 
  private:
@@ -189,8 +183,10 @@
 class TestAutofillExternalDelegate : public AutofillExternalDelegate {
  public:
   TestAutofillExternalDelegate(content::WebContents* web_contents,
-                               AutofillManager* autofill_manager)
-      : AutofillExternalDelegate(web_contents, autofill_manager),
+                               AutofillManager* autofill_manager,
+                               AutofillDriver* autofill_driver)
+      : AutofillExternalDelegate(web_contents, autofill_manager,
+                                 autofill_driver),
         keyboard_listener_(NULL) {
   }
   virtual ~TestAutofillExternalDelegate() {}
@@ -233,7 +229,8 @@
         AutofillDriverImpl::FromWebContents(web_contents);
     AutofillManager* autofill_manager = autofill_driver->autofill_manager();
     scoped_ptr<AutofillExternalDelegate> external_delegate(
-        new TestAutofillExternalDelegate(web_contents, autofill_manager));
+        new TestAutofillExternalDelegate(web_contents, autofill_manager,
+                                         autofill_driver));
     autofill_driver->SetAutofillExternalDelegate(external_delegate.Pass());
     autofill_manager->SetTestDelegate(&test_delegate_);
   }
@@ -384,7 +381,7 @@
     EXPECT_EQ(expected_value, value);
   }
 
-  RenderViewHost* render_view_host() {
+  content::RenderViewHost* render_view_host() {
     return browser()->tab_strip_model()->GetActiveWebContents()->
         GetRenderViewHost();
   }
@@ -899,9 +896,10 @@
 
   // Reload the page.
   LOG(WARNING) << "Reloading the page.";
-  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  tab->GetController().Reload(false);
-  content::WaitForLoadStop(tab);
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  web_contents->GetController().Reload(false);
+  content::WaitForLoadStop(web_contents);
 
   // Invoke Autofill.
   LOG(WARNING) << "Trying to fill the form.";
@@ -948,19 +946,18 @@
   // Get translation bar.
   LanguageDetectionDetails details;
   details.adopted_language = "ja";
-  RenderViewHostTester::TestOnMessageReceived(
+  content::RenderViewHostTester::TestOnMessageReceived(
       render_view_host(),
       ChromeViewHostMsg_TranslateLanguageDetermined(0, details, true));
-  TranslateInfoBarDelegate* infobar = InfoBarService::FromWebContents(
+  TranslateInfoBarDelegate* delegate = InfoBarService::FromWebContents(
       browser()->tab_strip_model()->GetActiveWebContents())->infobar_at(0)->
           AsTranslateInfoBarDelegate();
-
-  ASSERT_TRUE(infobar != NULL);
+  ASSERT_TRUE(delegate);
   EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
-            infobar->infobar_type());
+            delegate->infobar_type());
 
   // Simulate translation button press.
-  infobar->Translate();
+  delegate->Translate();
 
   // Simulate the translate script being retrieved.
   // Pass fake google.translate lib as the translate script.
diff --git a/chrome/browser/autofill/autofill_cc_infobar_delegate.cc b/chrome/browser/autofill/autofill_cc_infobar_delegate.cc
index a55a4d0..ff744d4 100644
--- a/chrome/browser/autofill/autofill_cc_infobar_delegate.cc
+++ b/chrome/browser/autofill/autofill_cc_infobar_delegate.cc
@@ -27,14 +27,12 @@
   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
       new AutofillCCInfoBarDelegate(
           infobar_service, metric_logger, save_card_callback)));
-  metric_logger->LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_SHOWN);
 }
 
 // static
 scoped_ptr<ConfirmInfoBarDelegate> AutofillCCInfoBarDelegate::CreateForTesting(
     const AutofillMetrics* metric_logger,
     const base::Closure& save_card_callback) {
-  metric_logger->LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_SHOWN);
   return scoped_ptr<ConfirmInfoBarDelegate>(
       new AutofillCCInfoBarDelegate(NULL, metric_logger, save_card_callback));
 }
@@ -46,7 +44,9 @@
     : ConfirmInfoBarDelegate(infobar_service),
       metric_logger_(metric_logger),
       save_card_callback_(save_card_callback),
-      had_user_interaction_(false) {}
+      had_user_interaction_(false) {
+  metric_logger->LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_SHOWN);
+}
 
 AutofillCCInfoBarDelegate::~AutofillCCInfoBarDelegate() {
   if (!had_user_interaction_)
diff --git a/chrome/browser/autofill/autofill_driver_impl_browsertest.cc b/chrome/browser/autofill/autofill_driver_impl_browsertest.cc
index fb3e6a7..c6a91f2 100644
--- a/chrome/browser/autofill/autofill_driver_impl_browsertest.cc
+++ b/chrome/browser/autofill/autofill_driver_impl_browsertest.cc
@@ -86,7 +86,7 @@
     web_contents_ = browser()->tab_strip_model()->GetActiveWebContents();
     ASSERT_TRUE(web_contents_ != NULL);
     Observe(web_contents_);
-    AutofillManager::RegisterUserPrefs(manager_delegate_.GetPrefRegistry());
+    AutofillManager::RegisterProfilePrefs(manager_delegate_.GetPrefRegistry());
 
     autofill_driver_.reset(new TestAutofillDriverImpl(web_contents_,
                                                       &manager_delegate_));
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc
index c040136..d241f3f 100644
--- a/chrome/browser/autofill/autofill_interactive_uitest.cc
+++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -5,11 +5,11 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/autofill/content/browser/autofill_driver_impl.h"
@@ -167,8 +167,10 @@
 class TestAutofillExternalDelegate : public AutofillExternalDelegate {
  public:
   TestAutofillExternalDelegate(content::WebContents* web_contents,
-                               AutofillManager* autofill_manager)
-      : AutofillExternalDelegate(web_contents, autofill_manager),
+                               AutofillManager* autofill_manager,
+                               AutofillDriver* autofill_driver)
+      : AutofillExternalDelegate(web_contents, autofill_manager,
+                                 autofill_driver),
         keyboard_listener_(NULL) {
   }
   virtual ~TestAutofillExternalDelegate() {}
@@ -211,7 +213,8 @@
         AutofillDriverImpl::FromWebContents(web_contents);
     AutofillManager* autofill_manager = autofill_driver->autofill_manager();
     scoped_ptr<AutofillExternalDelegate> external_delegate(
-        new TestAutofillExternalDelegate(web_contents, autofill_manager));
+        new TestAutofillExternalDelegate(web_contents, autofill_manager,
+                                         autofill_driver));
     autofill_driver->SetAutofillExternalDelegate(external_delegate.Pass());
     autofill_manager->SetTestDelegate(&test_delegate_);
   }
diff --git a/chrome/browser/automation/automation_browser_tracker.cc b/chrome/browser/automation/automation_browser_tracker.cc
index cb0afe8..8104806 100644
--- a/chrome/browser/automation/automation_browser_tracker.cc
+++ b/chrome/browser/automation/automation_browser_tracker.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/automation/automation_browser_tracker.h"
 
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 
 AutomationBrowserTracker::AutomationBrowserTracker(IPC::Sender* automation)
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index bd66049..7fe896e 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -28,6 +28,7 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_host.h"
@@ -67,7 +68,6 @@
 #include "chrome/browser/ui/webui/ntp/recently_closed_tabs_handler.h"
 #include "chrome/common/automation_constants.h"
 #include "chrome/common/automation_messages.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/content_settings_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/manifest.h"
@@ -1240,9 +1240,8 @@
 }
 
 void InfoBarCountObserver::CheckCount() {
-  InfoBarService* infobar_service =
-      InfoBarService::FromWebContents(web_contents_);
-  if (infobar_service->infobar_count() != target_count_)
+  if (InfoBarService::FromWebContents(web_contents_)->infobar_count() !=
+      target_count_)
     return;
 
   if (automation_.get()) {
diff --git a/chrome/browser/automation/automation_provider_observers_chromeos.cc b/chrome/browser/automation/automation_provider_observers_chromeos.cc
index 621a9ba..3f973ee 100644
--- a/chrome/browser/automation/automation_provider_observers_chromeos.cc
+++ b/chrome/browser/automation/automation_provider_observers_chromeos.cc
@@ -6,7 +6,7 @@
 
 #include "base/values.h"
 #include "chrome/browser/automation/automation_provider.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/authentication_notification_details.h"
 #include "chrome/browser/chromeos/login/enrollment/enrollment_screen_actor.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
@@ -16,10 +16,8 @@
 #include "chrome/browser/chromeos/login/user_image_manager.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 
-using chromeos::CrosLibrary;
 using chromeos::NetworkLibrary;
 using chromeos::WizardController;
 
@@ -36,18 +34,19 @@
 }
 
 NetworkManagerInitObserver::~NetworkManagerInitObserver() {
-    CrosLibrary::Get()->GetNetworkLibrary()->RemoveNetworkManagerObserver(this);
+  NetworkLibrary::Get()->RemoveNetworkManagerObserver(this);
 }
 
 bool NetworkManagerInitObserver::Init() {
-  if (!CrosLibrary::Get()->libcros_loaded()) {
-    // If cros library fails to load, don't wait for the network
-    // library to finish initializing, because it'll wait forever.
+  if (!NetworkLibrary::Get()->IsCros()) {
+    // If the network library is not the production version, don't wait for
+    // the network library to finish initializing, because it'll wait
+    // forever.
     automation_->OnNetworkLibraryInit();
     return false;
   }
 
-  CrosLibrary::Get()->GetNetworkLibrary()->AddNetworkManagerObserver(this);
+  NetworkLibrary::Get()->AddNetworkManagerObserver(this);
   return true;
 }
 
@@ -216,12 +215,12 @@
 NetworkScanObserver::NetworkScanObserver(AutomationProvider* automation,
                                          IPC::Message* reply_message)
     : automation_(automation->AsWeakPtr()), reply_message_(reply_message) {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   network_library->AddNetworkManagerObserver(this);
 }
 
 NetworkScanObserver::~NetworkScanObserver() {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   network_library->RemoveNetworkManagerObserver(this);
 }
 
@@ -241,12 +240,12 @@
     const std::string& device, bool enable)
     : automation_(automation->AsWeakPtr()), reply_message_(reply_message),
       device_(device), enable_(enable) {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   network_library->AddNetworkManagerObserver(this);
 }
 
 ToggleNetworkDeviceObserver::~ToggleNetworkDeviceObserver() {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   network_library->RemoveNetworkManagerObserver(this);
 }
 
@@ -265,12 +264,12 @@
 NetworkStatusObserver::NetworkStatusObserver(AutomationProvider* automation,
                                                IPC::Message* reply_message)
     : automation_(automation->AsWeakPtr()), reply_message_(reply_message) {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   network_library->AddNetworkManagerObserver(this);
 }
 
 NetworkStatusObserver::~NetworkStatusObserver() {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   network_library->RemoveNetworkManagerObserver(this);
 }
 
@@ -373,12 +372,12 @@
     : automation_(automation->AsWeakPtr()),
       reply_message_(reply_message),
       service_name_(service_name) {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   network_library->AddNetworkManagerObserver(this);
 }
 
 VirtualConnectObserver::~VirtualConnectObserver() {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   network_library->RemoveNetworkManagerObserver(this);
 }
 
diff --git a/chrome/browser/automation/automation_tab_tracker.cc b/chrome/browser/automation/automation_tab_tracker.cc
index 3377c8b..b19a855 100644
--- a/chrome/browser/automation/automation_tab_tracker.cc
+++ b/chrome/browser/automation/automation_tab_tracker.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/automation/automation_tab_tracker.h"
 
 #include "base/logging.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/notification_source.h"
 
diff --git a/chrome/browser/automation/automation_window_tracker.cc b/chrome/browser/automation/automation_window_tracker.cc
index e7714a7..0cb28e3 100644
--- a/chrome/browser/automation/automation_window_tracker.cc
+++ b/chrome/browser/automation/automation_window_tracker.cc
@@ -4,8 +4,8 @@
 
 #include "chrome/browser/automation/automation_window_tracker.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/native_window_notification_source.h"
-#include "chrome/common/chrome_notification_types.h"
 
 AutomationWindowTracker::AutomationWindowTracker(IPC::Sender* automation)
     : AutomationResourceTracker<gfx::NativeWindow>(automation) {
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc
index b37e935..6d3e0fe 100644
--- a/chrome/browser/automation/testing_automation_provider.cc
+++ b/chrome/browser/automation/testing_automation_provider.cc
@@ -41,6 +41,7 @@
 #include "chrome/browser/bookmarks/bookmark_storage.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/download/download_prefs.h"
@@ -109,7 +110,6 @@
 #include "chrome/common/automation_id.h"
 #include "chrome/common/automation_messages.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/background_info.h"
@@ -2108,6 +2108,7 @@
     reply.SendError("Invalid or missing args");
     return;
   }
+  size_t infobar_index = static_cast<size_t>(infobar_index_int);
 
   WebContents* web_contents =
       browser->tab_strip_model()->GetWebContentsAt(tab_index);
@@ -2115,37 +2116,32 @@
     reply.SendError(base::StringPrintf("No such tab at index %d", tab_index));
     return;
   }
+
   InfoBarService* infobar_service =
       InfoBarService::FromWebContents(web_contents);
-
-  InfoBarDelegate* infobar = NULL;
-  size_t infobar_index = static_cast<size_t>(infobar_index_int);
   if (infobar_index >= infobar_service->infobar_count()) {
     reply.SendError(base::StringPrintf("No such infobar at index %" PRIuS,
                                        infobar_index));
     return;
   }
-  infobar = infobar_service->infobar_at(infobar_index);
+  InfoBarDelegate* infobar = infobar_service->infobar_at(infobar_index);
 
-  if ("dismiss" == action) {
+  if (action == "dismiss") {
     infobar->InfoBarDismissed();
     infobar_service->RemoveInfoBar(infobar);
     reply.SendSuccess(NULL);
     return;
   }
-  if ("accept" == action || "cancel" == action) {
-    ConfirmInfoBarDelegate* confirm_infobar;
-    if (!(confirm_infobar = infobar->AsConfirmInfoBarDelegate())) {
+  if ((action == "accept") || (action == "cancel")) {
+    ConfirmInfoBarDelegate* delegate = infobar->AsConfirmInfoBarDelegate();
+    if (!delegate) {
       reply.SendError("Not a confirm infobar");
       return;
     }
-    if ("accept" == action) {
-      if (confirm_infobar->Accept())
-        infobar_service->RemoveInfoBar(infobar);
-    } else if ("cancel" == action) {
-      if (confirm_infobar->Cancel())
-        infobar_service->RemoveInfoBar(infobar);
-    }
+    bool remove_infobar = (action == "accept") ?
+        delegate->Accept() : delegate->Cancel();
+    if (remove_infobar)
+      infobar_service->RemoveInfoBar(infobar);
     reply.SendSuccess(NULL);
     return;
   }
diff --git a/chrome/browser/automation/testing_automation_provider_chromeos.cc b/chrome/browser/automation/testing_automation_provider_chromeos.cc
index 0406ea6..a528098 100644
--- a/chrome/browser/automation/testing_automation_provider_chromeos.cc
+++ b/chrome/browser/automation/testing_automation_provider_chromeos.cc
@@ -20,7 +20,6 @@
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
 #include "chrome/browser/chromeos/audio/audio_handler.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/default_user_images.h"
 #include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h"
@@ -53,7 +52,6 @@
 #include "policy/policy_constants.h"
 #include "ui/views/widget/widget.h"
 
-using chromeos::CrosLibrary;
 using chromeos::DBusThreadManager;
 using chromeos::ExistingUserController;
 using chromeos::NetworkLibrary;
@@ -68,7 +66,6 @@
   DictionaryValue* item = new DictionaryValue;
   item->SetString("name", network->name());
   item->SetString("device_path", network->device_path());
-  item->SetString("ip_address", network->ip_address());
   item->SetString("status", network->GetStateString());
   return item;
 }
@@ -525,14 +522,11 @@
 void TestingAutomationProvider::GetNetworkInfo(DictionaryValue* args,
                                                IPC::Message* reply_message) {
   scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
 
   return_value->SetBoolean("offline_mode",
                            net::NetworkChangeNotifier::IsOffline());
 
-  // IP address.
-  return_value->SetString("ip_address", network_library->IPAddress());
-
   // Currently connected networks.
   if (network_library->ethernet_network())
     return_value->SetString(
@@ -629,7 +623,7 @@
 
 void TestingAutomationProvider::NetworkScan(DictionaryValue* args,
                                             IPC::Message* reply_message) {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   network_library->RequestNetworkScan();
 
   // Set up an observer (it will delete itself).
@@ -650,7 +644,7 @@
   // Set up an observer (it will delete itself).
   new ToggleNetworkDeviceObserver(this, reply_message, device, enable);
 
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   if (device == "ethernet") {
     network_library->EnableEthernetNetworkDevice(enable);
   } else if (device == "wifi") {
@@ -719,7 +713,7 @@
     return;
   }
 
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   chromeos::CellularNetwork* cellular =
       network_library->FindCellularNetworkByPath(service_path);
   if (!cellular) {
@@ -737,7 +731,7 @@
 
 void TestingAutomationProvider::DisconnectFromCellularNetwork(
     DictionaryValue* args, IPC::Message* reply_message) {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   const chromeos::CellularNetwork* cellular =
         network_library->cellular_network();
   if (!cellular) {
@@ -764,7 +758,7 @@
     return;
   }
 
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   chromeos::WifiNetwork* wifi =
       network_library->FindWifiNetworkByPath(service_path);
   if (!wifi) {
@@ -795,7 +789,7 @@
     return;
   }
 
-  CrosLibrary::Get()->GetNetworkLibrary()->ForgetNetwork(service_path);
+  NetworkLibrary::Get()->ForgetNetwork(service_path);
   AutomationJSONReply(this, reply_message).SendSuccess(NULL);
 }
 
@@ -827,7 +821,7 @@
   chromeos::ConnectionSecurity connection_security =
       connection_security_map[security];
 
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
 
   // Set up an observer (it will delete itself).
   new SSIDConnectObserver(this, reply_message, ssid);
@@ -894,7 +888,7 @@
 void TestingAutomationProvider::DisconnectFromWifiNetwork(
     DictionaryValue* args, IPC::Message* reply_message) {
   AutomationJSONReply reply(this, reply_message);
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   const chromeos::WifiNetwork* wifi = network_library->wifi_network();
   if (!wifi) {
     reply.SendError("Not connected to any wifi network.");
@@ -919,7 +913,7 @@
     return;
   }
 
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
 
   // Attempt to connect to the VPN based on the provider type.
   if (provider_type == VPNProviderTypeToString(
@@ -991,7 +985,7 @@
 
   // Connect to a remembered VPN by its service_path. Valid service_paths
   // can be found in the dictionary returned by GetPrivateNetworkInfo.
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   chromeos::VirtualNetwork* network =
       network_library->FindVirtualNetworkByPath(service_path);
   if (!network) {
@@ -1012,7 +1006,7 @@
 void TestingAutomationProvider::GetPrivateNetworkInfo(
     DictionaryValue* args, IPC::Message* reply_message) {
   scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   const chromeos::VirtualNetworkVector& virtual_networks =
       network_library->virtual_networks();
 
@@ -1042,7 +1036,7 @@
 void TestingAutomationProvider::DisconnectFromPrivateNetwork(
     DictionaryValue* args, IPC::Message* reply_message) {
   AutomationJSONReply reply(this, reply_message);
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   const chromeos::VirtualNetwork* virt = network_library->virtual_network();
   if (!virt) {
     reply.SendError("Not connected to any virtual network.");
diff --git a/chrome/browser/background/background_application_list_model.cc b/chrome/browser/background/background_application_list_model.cc
index c5d2538..1661b39 100644
--- a/chrome/browser/background/background_application_list_model.cc
+++ b/chrome/browser/background/background_application_list_model.cc
@@ -14,12 +14,12 @@
 #include "chrome/browser/background/background_contents_service_factory.h"
 #include "chrome/browser/background/background_mode_manager.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/image_loader.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
diff --git a/chrome/browser/background/background_contents_service.cc b/chrome/browser/background/background_contents_service.cc
index fc9936f..a9f60a0 100644
--- a/chrome/browser/background/background_contents_service.cc
+++ b/chrome/browser/background/background_contents_service.cc
@@ -15,6 +15,7 @@
 #include "base/values.h"
 #include "chrome/browser/background/background_contents_service_factory.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/host_desktop.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/extensions/extension.h"
diff --git a/chrome/browser/background/background_contents_service_factory.cc b/chrome/browser/background/background_contents_service_factory.cc
index 674c3c1..74e4ffa 100644
--- a/chrome/browser/background/background_contents_service_factory.cc
+++ b/chrome/browser/background/background_contents_service_factory.cc
@@ -42,7 +42,7 @@
                                        CommandLine::ForCurrentProcess());
 }
 
-void BackgroundContentsServiceFactory::RegisterUserPrefs(
+void BackgroundContentsServiceFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* user_prefs) {
   user_prefs->RegisterDictionaryPref(
       prefs::kRegisteredBackgroundContents,
diff --git a/chrome/browser/background/background_contents_service_factory.h b/chrome/browser/background/background_contents_service_factory.h
index 6b40c8a..27ab044 100644
--- a/chrome/browser/background/background_contents_service_factory.h
+++ b/chrome/browser/background/background_contents_service_factory.h
@@ -31,7 +31,7 @@
   // BrowserContextKeyedServiceFactory:
   virtual BrowserContextKeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const OVERRIDE;
diff --git a/chrome/browser/background/background_contents_service_unittest.cc b/chrome/browser/background/background_contents_service_unittest.cc
index 6d3bb26..a58cfbc 100644
--- a/chrome/browser/background/background_contents_service_unittest.cc
+++ b/chrome/browser/background/background_contents_service_unittest.cc
@@ -11,10 +11,10 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/background/background_contents_service.h"
 #include "chrome/browser/background/background_contents_service_factory.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/tab_contents/background_contents.h"
 #include "chrome/browser/ui/browser_list.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/background/background_mode_manager.cc b/chrome/browser/background/background_mode_manager.cc
index 8bb5d71..6bbc13b 100644
--- a/chrome/browser/background/background_mode_manager.cc
+++ b/chrome/browser/background/background_mode_manager.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/background/background_mode_manager.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
@@ -33,7 +34,6 @@
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
diff --git a/chrome/browser/bookmarks/DEPS b/chrome/browser/bookmarks/DEPS
index 0086137..261233b 100644
--- a/chrome/browser/bookmarks/DEPS
+++ b/chrome/browser/bookmarks/DEPS
@@ -6,6 +6,7 @@
   "-chrome/browser",
   "+chrome/browser/bookmarks",
   "+chrome/browser/favicon",
+  "+chrome/browser/chrome_notification_types.h",
 
   # TODO(kaiwang): Bring this list to zero.
   # Do not add to the list of temporarily-allowed dependencies below,
@@ -21,3 +22,10 @@
   # Do not add to the list of temporarily-allowed dependencies above,
   # and please do not introduce more #includes of these files.
 ]
+
+specific_include_rules = {
+  # For unit tests, it's fine to include utility process code.
+  '.*test\.cc': [
+    "+chrome/utility/importer/bookmark_html_reader.h",
+  ],
+}
diff --git a/chrome/browser/bookmarks/bookmark_codec_unittest.cc b/chrome/browser/bookmarks/bookmark_codec_unittest.cc
index e12d11d..9b98001 100644
--- a/chrome/browser/bookmarks/bookmark_codec_unittest.cc
+++ b/chrome/browser/bookmarks/bookmark_codec_unittest.cc
@@ -300,7 +300,7 @@
   ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory));
   base::FilePath test_file = test_data_directory.AppendASCII(
       "bookmarks/model_without_sync.json");
-  ASSERT_TRUE(file_util::PathExists(test_file));
+  ASSERT_TRUE(base::PathExists(test_file));
 
   JSONFileValueSerializer serializer(test_file);
   scoped_ptr<Value> root(serializer.Deserialize(NULL, NULL));
diff --git a/chrome/browser/bookmarks/bookmark_expanded_state_tracker.cc b/chrome/browser/bookmarks/bookmark_expanded_state_tracker.cc
index 11facbf..eda271e 100644
--- a/chrome/browser/bookmarks/bookmark_expanded_state_tracker.cc
+++ b/chrome/browser/bookmarks/bookmark_expanded_state_tracker.cc
@@ -10,13 +10,12 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/common/pref_names.h"
-#include "components/user_prefs/user_prefs.h"
 
 BookmarkExpandedStateTracker::BookmarkExpandedStateTracker(
-    content::BrowserContext* browser_context,
-    BookmarkModel* bookmark_model)
-    : browser_context_(browser_context),
-      bookmark_model_(bookmark_model) {
+    BookmarkModel* bookmark_model,
+    PrefService* pref_service)
+    : bookmark_model_(bookmark_model),
+      pref_service_(pref_service) {
   bookmark_model->AddObserver(this);
 }
 
@@ -33,11 +32,11 @@
   if (!bookmark_model_->loaded())
     return nodes;
 
-  PrefService* prefs = user_prefs::UserPrefs::Get(browser_context_);
-  if (!prefs)
+  if (!pref_service_)
     return nodes;
 
-  const ListValue* value = prefs->GetList(prefs::kBookmarkEditorExpandedNodes);
+  const ListValue* value =
+      pref_service_->GetList(prefs::kBookmarkEditorExpandedNodes);
   if (!value)
     return nodes;
 
@@ -95,8 +94,7 @@
 }
 
 void BookmarkExpandedStateTracker::UpdatePrefs(const Nodes& nodes) {
-  PrefService* prefs = user_prefs::UserPrefs::Get(browser_context_);
-  if (!prefs)
+  if (!pref_service_)
     return;
 
   ListValue values;
@@ -105,5 +103,5 @@
                new StringValue(base::Int64ToString((*i)->id())));
   }
 
-  prefs->Set(prefs::kBookmarkEditorExpandedNodes, values);
+  pref_service_->Set(prefs::kBookmarkEditorExpandedNodes, values);
 }
diff --git a/chrome/browser/bookmarks/bookmark_expanded_state_tracker.h b/chrome/browser/bookmarks/bookmark_expanded_state_tracker.h
index a254770..96ba77f 100644
--- a/chrome/browser/bookmarks/bookmark_expanded_state_tracker.h
+++ b/chrome/browser/bookmarks/bookmark_expanded_state_tracker.h
@@ -9,12 +9,9 @@
 
 #include "chrome/browser/bookmarks/base_bookmark_model_observer.h"
 
-class BookmarkNode;
 class BookmarkModel;
-
-namespace content {
-class BrowserContext;
-}
+class BookmarkNode;
+class PrefService;
 
 // BookmarkExpandedStateTracker is used to track a set of expanded nodes. The
 // nodes are persisted in preferences. If an expanded node is removed from the
@@ -23,8 +20,8 @@
  public:
   typedef std::set<const BookmarkNode*> Nodes;
 
-  BookmarkExpandedStateTracker(content::BrowserContext* browser_context,
-                               BookmarkModel* bookmark_model);
+  BookmarkExpandedStateTracker(BookmarkModel* bookmark_model,
+                               PrefService* pref_service);
   virtual ~BookmarkExpandedStateTracker();
 
   // The set of expanded nodes.
@@ -42,12 +39,12 @@
                                    const BookmarkNode* node) OVERRIDE;
   virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
 
-  // Resets the value in preferences from |expanded_nodes_|.
+  // Updates the value for |prefs::kBookmarkEditorExpandedNodes| from
+  // GetExpandedNodes().
   void UpdatePrefs(const Nodes& nodes);
 
-  content::BrowserContext* browser_context_;
-
   BookmarkModel* bookmark_model_;
+  PrefService* pref_service_;
 
   DISALLOW_COPY_AND_ASSIGN(BookmarkExpandedStateTracker);
 };
diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc
index 47eee0a..b5eace1 100644
--- a/chrome/browser/bookmarks/bookmark_html_writer.cc
+++ b/chrome/browser/bookmarks/bookmark_html_writer.cc
@@ -17,10 +17,10 @@
 #include "chrome/browser/bookmarks/bookmark_codec.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_service.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/favicon/favicon_types.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/generated_resources.h"
diff --git a/chrome/browser/importer/bookmark_html_writer_unittest.cc b/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc
similarity index 99%
rename from chrome/browser/importer/bookmark_html_writer_unittest.cc
rename to chrome/browser/bookmarks/bookmark_html_writer_unittest.cc
index 37beb81..b9c7bed 100644
--- a/chrome/browser/importer/bookmark_html_writer_unittest.cc
+++ b/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc
@@ -18,11 +18,11 @@
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
-#include "chrome/browser/importer/bookmark_html_reader.h"
 #include "chrome/common/importer/imported_bookmark_entry.h"
 #include "chrome/common/importer/imported_favicon_usage.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "chrome/utility/importer/bookmark_html_reader.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "grit/generated_resources.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/bookmarks/bookmark_model.cc b/chrome/browser/bookmarks/bookmark_model.cc
index eff176e..7601834 100644
--- a/chrome/browser/bookmarks/bookmark_model.cc
+++ b/chrome/browser/bookmarks/bookmark_model.cc
@@ -15,13 +15,13 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
-#include "build/build_config.h"
 #include "chrome/browser/bookmarks/bookmark_expanded_state_tracker.h"
 #include "chrome/browser/bookmarks/bookmark_index.h"
 #include "chrome/browser/bookmarks/bookmark_model_observer.h"
 #include "chrome/browser/bookmarks/bookmark_storage.h"
 #include "chrome/browser/bookmarks/bookmark_title_match.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_changed_details.h"
 #include "chrome/browser/favicon/favicon_service.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
@@ -29,7 +29,6 @@
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/generated_resources.h"
@@ -262,8 +261,8 @@
     return;
   }
 
-  expanded_state_tracker_.reset(new BookmarkExpandedStateTracker(
-      profile_, this));
+  expanded_state_tracker_.reset(
+      new BookmarkExpandedStateTracker(this, profile_->GetPrefs()));
 
   // Listen for changes to favicons so that we can update the favicon of the
   // node appropriately.
diff --git a/chrome/browser/bookmarks/bookmark_model_factory.cc b/chrome/browser/bookmarks/bookmark_model_factory.cc
index d81df62..7b13738 100644
--- a/chrome/browser/bookmarks/bookmark_model_factory.cc
+++ b/chrome/browser/bookmarks/bookmark_model_factory.cc
@@ -49,7 +49,7 @@
   return bookmark_model;
 }
 
-void BookmarkModelFactory::RegisterUserPrefs(
+void BookmarkModelFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   // Don't sync this, as otherwise, due to a limitation in sync, it
   // will cause a deadlock (see http://crbug.com/97955).  If we truly
diff --git a/chrome/browser/bookmarks/bookmark_model_factory.h b/chrome/browser/bookmarks/bookmark_model_factory.h
index 0975c14..991b0ff 100644
--- a/chrome/browser/bookmarks/bookmark_model_factory.h
+++ b/chrome/browser/bookmarks/bookmark_model_factory.h
@@ -32,7 +32,7 @@
   // BrowserContextKeyedServiceFactory:
   virtual BrowserContextKeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const OVERRIDE;
diff --git a/chrome/browser/bookmarks/bookmark_prompt_prefs.cc b/chrome/browser/bookmarks/bookmark_prompt_prefs.cc
index 3087675..ffd1ae9 100644
--- a/chrome/browser/bookmarks/bookmark_prompt_prefs.cc
+++ b/chrome/browser/bookmarks/bookmark_prompt_prefs.cc
@@ -33,7 +33,7 @@
 }
 
 // static
-void BookmarkPromptPrefs::RegisterUserPrefs(
+void BookmarkPromptPrefs::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   // We always register preferences without checking FieldTrial, because
   // we may not receive field trial list from the server yet.
diff --git a/chrome/browser/bookmarks/bookmark_prompt_prefs.h b/chrome/browser/bookmarks/bookmark_prompt_prefs.h
index 9bb0a70..884894f 100644
--- a/chrome/browser/bookmarks/bookmark_prompt_prefs.h
+++ b/chrome/browser/bookmarks/bookmark_prompt_prefs.h
@@ -34,7 +34,7 @@
   bool IsBookmarkPromptEnabled() const;
 
   // Registers user preferences used by bookmark prompt feature.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  private:
   PrefService* prefs_;  // Weak.
diff --git a/chrome/browser/bookmarks/bookmark_storage.cc b/chrome/browser/bookmarks/bookmark_storage.cc
index b7b2ce1..79a8528 100644
--- a/chrome/browser/bookmarks/bookmark_storage.cc
+++ b/chrome/browser/bookmarks/bookmark_storage.cc
@@ -33,7 +33,7 @@
 
 void BackupCallback(const base::FilePath& path) {
   base::FilePath backup_path = path.ReplaceExtension(kBackupExtension);
-  file_util::CopyFile(path, backup_path);
+  base::CopyFile(path, backup_path);
 }
 
 // Adds node to the model's index, recursing through all children as well.
@@ -53,7 +53,7 @@
                   BookmarkLoadDetails* details) {
   startup_metric_utils::ScopedSlowStartupUMA
       scoped_timer("Startup.SlowStartupBookmarksLoad");
-  bool bookmark_file_exists = file_util::PathExists(path);
+  bool bookmark_file_exists = base::PathExists(path);
   if (bookmark_file_exists) {
     JSONFileValueSerializer serializer(path);
     scoped_ptr<Value> root(serializer.Deserialize(NULL, NULL));
diff --git a/chrome/browser/bookmarks/bookmark_utils.cc b/chrome/browser/bookmarks/bookmark_utils.cc
index ea04f7f..b05a872 100644
--- a/chrome/browser/bookmarks/bookmark_utils.cc
+++ b/chrome/browser/bookmarks/bookmark_utils.cc
@@ -238,7 +238,7 @@
   return (node->is_url() && DoesBookmarkContainWords(node, words, languages));
 }
 
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kShowBookmarkBar,
       false,
diff --git a/chrome/browser/bookmarks/bookmark_utils.h b/chrome/browser/bookmarks/bookmark_utils.h
index a72e6d8..0bbdcc5 100644
--- a/chrome/browser/bookmarks/bookmark_utils.h
+++ b/chrome/browser/bookmarks/bookmark_utils.h
@@ -76,7 +76,7 @@
                              const std::string& languages);
 
 // Register user preferences for Bookmarks Bar.
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
 // Returns the parent for newly created folders/bookmarks. If |selection| has
 // one element and it is a folder, |selection[0]| is returned, otherwise
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc
index 22c4f92..877dfbf 100644
--- a/chrome/browser/browser_about_handler.cc
+++ b/chrome/browser/browser_about_handler.cc
@@ -98,6 +98,7 @@
   content::kChromeUIBlobInternalsHost,
   content::kChromeUIGpuHost,
   content::kChromeUIHistogramHost,
+  content::kChromeUIIndexedDBInternalsHost,
   content::kChromeUIMediaInternalsHost,
   content::kChromeUINetworkViewCacheHost,
   content::kChromeUITracingHost,
diff --git a/chrome/browser/browser_encoding_browsertest.cc b/chrome/browser/browser_encoding_browsertest.cc
index 976c4b1..e4911db 100644
--- a/chrome/browser/browser_encoding_browsertest.cc
+++ b/chrome/browser/browser_encoding_browsertest.cc
@@ -133,7 +133,7 @@
     base::FilePath expected_file_name = ui_test_utils::GetTestFilePath(
         base::FilePath(kTestDir), expected);
 
-    EXPECT_TRUE(file_util::ContentsEqual(full_file_name, expected_file_name));
+    EXPECT_TRUE(base::ContentsEqual(full_file_name, expected_file_name));
   }
 
   virtual void SetUpOnMainThread() OVERRIDE {
diff --git a/chrome/browser/browser_keyevents_browsertest.cc b/chrome/browser/browser_keyevents_browsertest.cc
index f27f00f..dd2f345 100644
--- a/chrome/browser/browser_keyevents_browsertest.cc
+++ b/chrome/browser/browser_keyevents_browsertest.cc
@@ -10,9 +10,9 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/interactive_test_utils.h"
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 6673807..9dffeab 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -23,6 +23,7 @@
 #include "chrome/browser/background/background_mode_manager.h"
 #include "chrome/browser/chrome_browser_main.h"
 #include "chrome/browser/chrome_content_browser_client.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/component_updater/component_updater_configurator.h"
 #include "chrome/browser/component_updater/component_updater_service.h"
 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h"
@@ -66,7 +67,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/web_resource/promo_resource_service.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/chrome_manifest_handlers.h"
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 749ac3a..c313e6a 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -171,10 +171,6 @@
       <include name="IDR_MOST_VISITED_THUMBNAIL_CSS" file="resources\local_ntp\most_visited_thumbnail.css" type="BINDATA" />
       <include name="IDR_MOST_VISITED_THUMBNAIL_JS" file="resources\local_ntp\most_visited_thumbnail.js" type="BINDATA" />
       <include name="IDR_MOST_VISITED_UTIL_JS" file="resources\local_ntp\most_visited_util.js" type="BINDATA" flattenhtml="true" />
-      <include name="IDR_OMNIBOX_RESULT_LOADER_HTML" file="resources\omnibox_result_loader.html" type="BINDATA" />
-      <include name="IDR_OMNIBOX_RESULT_LOADER_JS" file="resources\omnibox_result_loader.js" type="BINDATA" flattenhtml="true" />
-      <include name="IDR_OMNIBOX_RESULT_HTML" file="resources\omnibox_result.html" type="BINDATA" />
-      <include name="IDR_OMNIBOX_RESULT_JS" file="resources\omnibox_result.js" type="BINDATA" />
 
       <include name="IDR_OMNIBOX_HTML" file="resources\omnibox\omnibox.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_OMNIBOX_CSS" file="resources\omnibox\omnibox.css" type="BINDATA" />
@@ -200,7 +196,12 @@
           <include name="IDR_PLUGIN_DB_JSON" file="resources\plugin_metadata\plugins_linux.json" type="BINDATA" />
         </if>
       </if>
-      <include name="IDR_POLICY_CSS" file="resources\policy.css" type="BINDATA"/>
+      <if expr="is_android">
+        <include name="IDR_POLICY_CSS" file="resources\policy_android.css" type="BINDATA"/>
+      </if>
+      <if expr="not is_android">
+        <include name="IDR_POLICY_CSS" file="resources\policy.css" type="BINDATA"/>
+      </if>
       <include name="IDR_POLICY_HTML" file="resources\policy.html" flattenhtml="true" allowexternalscript="true" type="BINDATA"/>
       <include name="IDR_POLICY_JS" file="resources\policy.js" type="BINDATA"/>
       <include name="IDR_PRERENDER_URL_WHITELIST"
diff --git a/chrome/browser/browser_shutdown.cc b/chrome/browser/browser_shutdown.cc
index 9cc661b..5dc8651 100644
--- a/chrome/browser/browser_shutdown.cc
+++ b/chrome/browser/browser_shutdown.cc
@@ -50,7 +50,6 @@
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/boot_times_loader.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #endif
 
 using base::Time;
@@ -267,7 +266,7 @@
   int64 shutdown_ms = 0;
   if (file_util::ReadFileToString(shutdown_ms_file, &shutdown_ms_str))
     base::StringToInt64(shutdown_ms_str, &shutdown_ms);
-  base::Delete(shutdown_ms_file, false);
+  base::DeleteFile(shutdown_ms_file, false);
 
   if (type == NOT_VALID || shutdown_ms == 0 || num_procs == 0)
     return;
diff --git a/chrome/browser/browsing_data/browsing_data_file_system_helper.cc b/chrome/browser/browsing_data/browsing_data_file_system_helper.cc
index 70a7155..e1ed4b5 100644
--- a/chrome/browser/browsing_data/browsing_data_file_system_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_file_system_helper.cc
@@ -16,7 +16,7 @@
 #include "webkit/browser/fileapi/file_system_context.h"
 #include "webkit/browser/fileapi/file_system_quota_util.h"
 #include "webkit/browser/fileapi/file_system_task_runners.h"
-#include "webkit/browser/fileapi/sandbox_mount_point_provider.h"
+#include "webkit/browser/fileapi/sandbox_file_system_backend.h"
 #include "webkit/common/fileapi/file_system_types.h"
 
 using content::BrowserThread;
diff --git a/chrome/browser/browsing_data/browsing_data_remover.cc b/chrome/browser/browsing_data/browsing_data_remover.cc
index 27e6eed..15b8959 100644
--- a/chrome/browser/browsing_data/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/download/download_service_factory.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -42,7 +43,6 @@
 #include "chrome/browser/sessions/session_service_factory.h"
 #include "chrome/browser/sessions/tab_restore_service.h"
 #include "chrome/browser/sessions/tab_restore_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
index c3ffb2a..eb78cfa 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -7,10 +7,10 @@
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_remover.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
index 43cce41..842b47b 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
@@ -18,11 +18,11 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/mock_extension_special_storage_policy.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/captive_portal/captive_portal_browsertest.cc b/chrome/browser/captive_portal/captive_portal_browsertest.cc
index 5b2d49c..2203fac 100644
--- a/chrome/browser/captive_portal/captive_portal_browsertest.cc
+++ b/chrome/browser/captive_portal/captive_portal_browsertest.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/net/url_request_mock_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/captive_portal/captive_portal_service.cc b/chrome/browser/captive_portal/captive_portal_service.cc
index eb97495..3b17743 100644
--- a/chrome/browser/captive_portal/captive_portal_service.cc
+++ b/chrome/browser/captive_portal/captive_portal_service.cc
@@ -10,8 +10,8 @@
 #include "base/message_loop.h"
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/captive_portal/captive_portal_service_unittest.cc b/chrome/browser/captive_portal/captive_portal_service_unittest.cc
index 3055703..5c87816 100644
--- a/chrome/browser/captive_portal/captive_portal_service_unittest.cc
+++ b/chrome/browser/captive_portal/captive_portal_service_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/test/test_timeouts.h"
 #include "chrome/browser/captive_portal/testing_utils.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/captive_portal/captive_portal_tab_helper.cc b/chrome/browser/captive_portal/captive_portal_tab_helper.cc
index d3bed9a..46c9af1 100644
--- a/chrome/browser/captive_portal/captive_portal_tab_helper.cc
+++ b/chrome/browser/captive_portal/captive_portal_tab_helper.cc
@@ -8,12 +8,12 @@
 #include "chrome/browser/captive_portal/captive_portal_login_detector.h"
 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc b/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc
index 0356315..39c081a 100644
--- a/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc
+++ b/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc
@@ -8,7 +8,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/captive_portal/captive_portal_service.h"
 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/chrome_browser_field_trials.cc b/chrome/browser/chrome_browser_field_trials.cc
index 00256c7..aae3171 100644
--- a/chrome/browser/chrome_browser_field_trials.cc
+++ b/chrome/browser/chrome_browser_field_trials.cc
@@ -11,6 +11,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
+#include "chrome/browser/metrics/gzipped_protobufs_field_trial.h"
 #include "chrome/browser/omnibox/omnibox_field_trial.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
@@ -38,6 +39,7 @@
 
   // Field trials that are shared by all platforms.
   chrome_variations::SetupUniformityFieldTrials(install_time);
+  metrics::CreateGzippedProtobufsFieldTrial();
   InstantiateDynamicTrials();
 
 #if defined(OS_ANDROID) || defined(OS_IOS)
diff --git a/chrome/browser/chrome_browser_field_trials_desktop.cc b/chrome/browser/chrome_browser_field_trials_desktop.cc
index 282fb0b..6ded512 100644
--- a/chrome/browser/chrome_browser_field_trials_desktop.cc
+++ b/chrome/browser/chrome_browser_field_trials_desktop.cc
@@ -23,6 +23,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/metrics/variations/variations_util.h"
+#include "content/public/common/content_constants.h"
 #include "net/spdy/spdy_session.h"
 #include "ui/base/layout.h"
 
@@ -55,7 +56,7 @@
   }
 }
 
-void SetUpInfiniteCacheFieldTrial() {
+void SetupInfiniteCacheFieldTrial() {
   const base::FieldTrial::Probability kDivisor = 100;
 
   base::FieldTrial::Probability infinite_cache_probability = 0;
@@ -83,7 +84,7 @@
   }
 }
 
-void SetUpCacheSensitivityAnalysisFieldTrial() {
+void SetupCacheSensitivityAnalysisFieldTrial() {
   const base::FieldTrial::Probability kDivisor = 100;
 
   base::FieldTrial::Probability sensitivity_analysis_probability = 0;
@@ -141,6 +142,17 @@
 #endif
 }
 
+void SetupLowLatencyFlashAudioFieldTrial() {
+  scoped_refptr<base::FieldTrial> trial(
+      base::FieldTrialList::FactoryGetFieldTrial(
+          content::kLowLatencyFlashAudioFieldTrialName,
+          100, "Standard", 2013, 9, 1, NULL));
+
+  // Trial is enabled for dev / beta / canary users only.
+  if (chrome::VersionInfo::GetChannel() != chrome::VersionInfo::CHANNEL_STABLE)
+    trial->AppendGroup(content::kLowLatencyFlashAudioFieldTrialEnabledName, 25);
+}
+
 }  // namespace
 
 void SetupDesktopFieldTrials(const CommandLine& parsed_command_line,
@@ -150,11 +162,12 @@
   AutoLaunchChromeFieldTrial();
   gpu_util::InitializeCompositingFieldTrial();
   OmniboxFieldTrial::ActivateStaticTrials();
-  SetUpInfiniteCacheFieldTrial();
-  SetUpCacheSensitivityAnalysisFieldTrial();
+  SetupInfiniteCacheFieldTrial();
+  SetupCacheSensitivityAnalysisFieldTrial();
   DisableShowProfileSwitcherTrialIfNecessary();
   WindowsOverlappedTCPReadsFieldTrial(parsed_command_line);
   SetupAppLauncherFieldTrial(local_state);
+  SetupLowLatencyFlashAudioFieldTrial();
 }
 
 }  // namespace chrome
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index a959216..5877511 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -14,6 +14,7 @@
 #include "base/at_exit.h"
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/debug/debugger.h"
 #include "base/debug/trace_event.h"
 #include "base/file_util.h"
 #include "base/files/file_path.h"
@@ -68,6 +69,7 @@
 #include "chrome/browser/metrics/thread_watcher.h"
 #include "chrome/browser/metrics/tracking_synchronizer.h"
 #include "chrome/browser/metrics/variations/variations_service.h"
+#include "chrome/browser/nacl_host/nacl_browser_delegate_impl.h"
 #include "chrome/browser/nacl_host/nacl_process_host.h"
 #include "chrome/browser/net/chrome_net_log.h"
 #include "chrome/browser/net/crl_set_fetcher.h"
@@ -88,10 +90,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/renderer_host/chrome_render_view_host_observer.h"
 #include "chrome/browser/search_engines/search_engine_type.h"
-#include "chrome/browser/search_engines/template_url.h"
-#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
-#include "chrome/browser/search_engines/template_url_service.h"
-#include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/service/service_process_control.h"
 #include "chrome/browser/shell_integration.h"
 #include "chrome/browser/three_d_api_observer.h"
@@ -142,7 +140,9 @@
 #include "ui/base/layout.h"
 #include "ui/base/resource/resource_bundle.h"
 
-#if !defined(OS_ANDROID)
+#if defined(OS_ANDROID)
+#include "chrome/browser/media/media_capture_devices_dispatcher.h"
+#else
 #include "chrome/browser/ui/active_tab_tracker.h"
 #endif
 
@@ -151,7 +151,6 @@
 #endif
 
 #if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
 #include "chromeos/chromeos_switches.h"
@@ -199,10 +198,6 @@
 #include "ui/views/focus/accelerator_handler.h"
 #endif
 
-#if defined(USE_X11)
-#include "chrome/browser/chrome_browser_main_x11.h"
-#endif
-
 using content::BrowserThread;
 
 namespace {
@@ -240,7 +235,7 @@
   TRACE_EVENT0("startup", "ChromeBrowserMainParts::InitializeLocalState")
   base::FilePath local_state_path;
   PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path);
-  bool local_state_file_exists = file_util::PathExists(local_state_path);
+  bool local_state_file_exists = base::PathExists(local_state_path);
 
   // Load local state.  This includes the application locale so we know which
   // locale dll to load.  This also causes local state prefs to be registered.
@@ -557,7 +552,6 @@
       startup_timer_(new performance_monitor::StartupTimer()),
       browser_field_trials_(parameters.command_line),
       rvh_callback_(base::Bind(&RenderViewHostCreated)),
-      record_search_engine_(false),
       translate_manager_(NULL),
       profile_(NULL),
       run_message_loop_(true),
@@ -693,6 +687,65 @@
   return enabled;
 }
 
+void ChromeBrowserMainParts::RecordBrowserStartupTime(bool is_first_run) {
+  // Don't record any metrics if UI was displayed before this point e.g.
+  // warning dialogs.
+  if (startup_metric_utils::WasNonBrowserUIDisplayed())
+    return;
+
+// CurrentProcessInfo::CreationTime() is currently only implemented on Mac and
+// Windows.
+#if defined(OS_MACOSX) || defined(OS_WIN)
+  const base::Time* process_creation_time =
+      base::CurrentProcessInfo::CreationTime();
+
+  if (!is_first_run && process_creation_time) {
+    RecordPreReadExperimentTime("Startup.BrowserMessageLoopStartTime",
+        base::Time::Now() - *process_creation_time);
+  }
+#endif  // defined(OS_MACOSX) || defined(OS_WIN)
+
+  // Record collected startup metrics.
+  startup_metric_utils::OnBrowserStartupComplete(is_first_run);
+
+  // Deletes self.
+  new LoadCompleteListener();
+}
+
+// This code is specific to the Windows-only PreReadExperiment field-trial.
+void ChromeBrowserMainParts::RecordPreReadExperimentTime(const char* name,
+                                                         base::TimeDelta time) {
+  DCHECK(name != NULL);
+
+  // This gets called with different histogram names, so we don't want to use
+  // the UMA_HISTOGRAM_CUSTOM_TIMES macro--it uses a static variable, and the
+  // first call wins.
+  AddPreReadHistogramTime(name, time);
+
+#if defined(OS_WIN)
+#if defined(GOOGLE_CHROME_BUILD)
+  // The pre-read experiment is Windows and Google Chrome specific.
+  scoped_ptr<base::Environment> env(base::Environment::Create());
+
+  // Only record the sub-histogram result if the experiment is running
+  // (environment variable is set, and valid).
+  std::string pre_read_percentage;
+  if (env->GetVar(chrome::kPreReadEnvironmentVariable, &pre_read_percentage)) {
+    std::string uma_name(name);
+
+    // We want XP to record a separate histogram, as the loader on XP
+    // is very different from the Vista and Win7 loaders.
+    if (base::win::GetVersion() <= base::win::VERSION_XP)
+      uma_name += "_XP";
+
+    uma_name += "_PreRead_";
+    uma_name += pre_read_percentage;
+    AddPreReadHistogramTime(uma_name.c_str(), time);
+  }
+#endif
+#endif
+}
+
 // -----------------------------------------------------------------------------
 // TODO(viettrungluu): move more/rest of BrowserMain() into BrowserMainParts.
 
@@ -716,9 +769,6 @@
 // content::BrowserMainParts implementation ------------------------------------
 
 void ChromeBrowserMainParts::PreEarlyInitialization() {
-#if defined(USE_X11)
-  SetBrowserX11ErrorHandlersPreEarlyInitialization();
-#endif
   TRACE_EVENT0("startup", "ChromeBrowserMainParts::PreEarlyInitialization");
   for (size_t i = 0; i < chrome_extra_parts_.size(); ++i)
     chrome_extra_parts_[i]->PreEarlyInitialization();
@@ -746,9 +796,6 @@
   TRACE_EVENT0("startup", "ChromeBrowserMainParts::PostMainMessageLoopStart");
   for (size_t i = 0; i < chrome_extra_parts_.size(); ++i)
     chrome_extra_parts_[i]->PostMainMessageLoopStart();
-#if defined(USE_X11)
-  SetBrowserX11ErrorHandlersPostMainMessageLoopStart();
-#endif
 }
 
 int ChromeBrowserMainParts::PreCreateThreads() {
@@ -782,7 +829,10 @@
   // (i.e., even if --no-first-run is passed).
   bool is_first_run = false;
   // Android's first run is done in Java instead of native.
-#if !defined(OS_ANDROID)
+#if defined(OS_ANDROID)
+  // Force MediaCaptureDevicesDispatcher created on UI thread.
+  MediaCaptureDevicesDispatcher::GetInstance();
+#else
   process_singleton_.reset(new ChromeProcessSingleton(
       user_data_dir_, base::Bind(&ProcessSingletonNotificationCallback)));
 
@@ -881,6 +931,10 @@
     const std::string locale =
         local_state_->GetString(prefs::kApplicationLocale);
 
+#if defined(OS_WIN)
+    ui::EnableHighDPISupport();
+#endif
+
     // On a POSIX OS other than ChromeOS, the parameter that is passed to the
     // method InitSharedInstance is ignored.
 
@@ -976,10 +1030,6 @@
   }
 #endif
 
-  // TODO(viettrungluu): why don't we run this earlier?
-  if (!parsed_command_line().HasSwitch(switches::kNoErrorDialogs))
-    WarnAboutMinimumSystemRequirements();
-
 #if defined(OS_LINUX) || defined(OS_OPENBSD) || defined(OS_MACOSX)
   // Set the product channel for crash reports.
   child_process_logging::SetChannel(
@@ -1424,7 +1474,9 @@
 #endif
 
   HandleTestParameters(parsed_command_line());
-  RecordBreakpadStatusUMA(browser_process_->metrics_service());
+  browser_process_->metrics_service()->RecordBreakpadHasDebugger(
+      base::debug::BeingDebugged());
+
 #if defined(ENABLE_LANGUAGE_DETECTION)
   LanguageUsageMetrics::RecordAcceptLanguages(
       profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
@@ -1456,12 +1508,6 @@
   MetricsService::LogNeedForCleanShutdown();
 #endif
 
-#if defined(OS_WIN)
-  // We check this here because if the profile is OTR (chromeos possibility)
-  // it won't still be accessible after browser is destroyed.
-  record_search_engine_ = do_first_run_tasks_ && !profile_->IsOffTheRecord();
-#endif
-
   // Create the instance of the cloud print proxy service so that it can launch
   // the service process if needed. This is needed because the service process
   // might have shutdown because an update was available.
@@ -1481,7 +1527,7 @@
                           parsed_command_line().GetSwitchValuePath(
                               switches::kPnaclDir));
   }
-  NaClProcessHost::EarlyStartup();
+  NaClProcessHost::EarlyStartup(new NaClBrowserDelegateImpl);
 #endif
 
   PreBrowserStart();
@@ -1639,13 +1685,6 @@
   NOTREACHED();
 #else
 
-#if defined(USE_X11)
-  // Unset the X11 error handlers. The X11 error handlers log the errors using a
-  // |PostTask()| on the message-loop. But since the message-loop is in the
-  // process of terminating, this can cause errors.
-  UnsetBrowserX11ErrorHandlers();
-#endif
-
   // Start watching for jank during shutdown. It gets disarmed when
   // |shutdown_watcher_| object is destructed.
   shutdown_watcher_->Arm(base::TimeDelta::FromSeconds(300));
@@ -1656,25 +1695,6 @@
   for (size_t i = 0; i < chrome_extra_parts_.size(); ++i)
     chrome_extra_parts_[i]->PostMainMessageLoopRun();
 
-#if defined(OS_WIN)
-  // Log the search engine chosen on first run. Do this at shutdown, after any
-  // changes are made from the first run bubble link, etc.
-  if (record_search_engine_) {
-    TemplateURLService* url_service =
-        TemplateURLServiceFactory::GetForProfile(profile_);
-    const TemplateURL* default_search_engine =
-        url_service->GetDefaultSearchProvider();
-    // The default engine can be NULL if the administrator has disabled
-    // default search.
-    SearchEngineType search_engine_type =
-        TemplateURLPrepopulateData::GetEngineType(default_search_engine ?
-            default_search_engine->url() : std::string());
-    // Record the search engine chosen.
-    UMA_HISTOGRAM_ENUMERATION("Chrome.SearchSelectExempt", search_engine_type,
-                              SEARCH_ENGINE_MAX);
-  }
-#endif
-
   // Some tests don't set parameters.ui_task, so they started translate
   // language fetch that was never completed so we need to cleanup here
   // otherwise it will be done by the destructor in a wrong thread.
@@ -1726,63 +1746,3 @@
 void ChromeBrowserMainParts::AddParts(ChromeBrowserMainExtraParts* parts) {
   chrome_extra_parts_.push_back(parts);
 }
-
-// Misc ------------------------------------------------------------------------
-
-void RecordBrowserStartupTime(bool is_first_run) {
-  // Don't record any metrics if UI was displayed before this point e.g.
-  // warning dialogs.
-  if (startup_metric_utils::WasNonBrowserUIDisplayed())
-    return;
-
-// CurrentProcessInfo::CreationTime() is currently only implemented on Mac and
-// Windows.
-#if defined(OS_MACOSX) || defined(OS_WIN)
-  const base::Time* process_creation_time =
-      base::CurrentProcessInfo::CreationTime();
-
-  if (!is_first_run && process_creation_time) {
-    RecordPreReadExperimentTime("Startup.BrowserMessageLoopStartTime",
-        base::Time::Now() - *process_creation_time);
-  }
-#endif  // defined(OS_MACOSX) || defined(OS_WIN)
-
-  // Record collected startup metrics.
-  startup_metric_utils::OnBrowserStartupComplete(is_first_run);
-
-  // Deletes self.
-  new LoadCompleteListener();
-}
-
-// This code is specific to the Windows-only PreReadExperiment field-trial.
-void RecordPreReadExperimentTime(const char* name, base::TimeDelta time) {
-  DCHECK(name != NULL);
-
-  // This gets called with different histogram names, so we don't want to use
-  // the UMA_HISTOGRAM_CUSTOM_TIMES macro--it uses a static variable, and the
-  // first call wins.
-  AddPreReadHistogramTime(name, time);
-
-#if defined(OS_WIN)
-#if defined(GOOGLE_CHROME_BUILD)
-  // The pre-read experiment is Windows and Google Chrome specific.
-  scoped_ptr<base::Environment> env(base::Environment::Create());
-
-  // Only record the sub-histogram result if the experiment is running
-  // (environment variable is set, and valid).
-  std::string pre_read_percentage;
-  if (env->GetVar(chrome::kPreReadEnvironmentVariable, &pre_read_percentage)) {
-    std::string uma_name(name);
-
-    // We want XP to record a separate histogram, as the loader on XP
-    // is very different from the Vista and Win7 loaders.
-    if (base::win::GetVersion() <= base::win::VERSION_XP)
-      uma_name += "_XP";
-
-    uma_name += "_PreRead_";
-    uma_name += pre_read_percentage;
-    AddPreReadHistogramTime(uma_name.c_str(), time);
-  }
-#endif
-#endif
-}
diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h
index 067a616..0e092e4 100644
--- a/chrome/browser/chrome_browser_main.h
+++ b/chrome/browser/chrome_browser_main.h
@@ -101,6 +101,7 @@
   }
 
   Profile* profile() { return profile_; }
+  bool do_first_run_tasks() const { return do_first_run_tasks_; }
 
   const PrefService* local_state() const { return local_state_; }
 
@@ -119,6 +120,15 @@
   // Returns true if the user opted in to sending metric reports.
   bool IsMetricsReportingEnabled();
 
+  // Record time from process startup to present time in an UMA histogram.
+  // |is_first_run| - is the current launch part of a first run.
+  void RecordBrowserStartupTime(bool is_first_run);
+
+  // Records a time value to an UMA histogram in the context of the
+  // PreReadExperiment field-trial. This also reports to the appropriate
+  // sub-histogram (_PreRead(Enabled|Disabled)).
+  void RecordPreReadExperimentTime(const char* name, base::TimeDelta time);
+
   // Methods for Main Message Loop -------------------------------------------
 
   int PreCreateThreadsImpl();
@@ -174,7 +184,6 @@
   scoped_ptr<ChromeProcessSingleton> process_singleton_;
 #endif
   scoped_ptr<first_run::MasterPrefs> master_prefs_;
-  bool record_search_engine_;
   TranslateManager* translate_manager_;
   Profile* profile_;
   bool run_message_loop_;
@@ -204,23 +213,4 @@
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainParts);
 };
 
-// Records the conditions that can prevent Breakpad from generating and
-// sending crash reports.  The presence of a Breakpad handler (after
-// attempting to initialize crash reporting) and the presence of a debugger
-// are registered with the UMA metrics service.
-void RecordBreakpadStatusUMA(MetricsService* metrics);
-
-// Displays a warning message if some minimum level of OS support is not
-// present on the current platform.
-void WarnAboutMinimumSystemRequirements();
-
-// Record time from process startup to present time in an UMA histogram.
-// |is_first_run| - is the current launch part of a first run.
-void RecordBrowserStartupTime(bool is_first_run);
-
-// Records a time value to an UMA histogram in the context of the
-// PreReadExperiment field-trial. This also reports to the appropriate
-// sub-histogram (_PreRead(Enabled|Disabled)).
-void RecordPreReadExperimentTime(const char* name, base::TimeDelta time);
-
 #endif  // CHROME_BROWSER_CHROME_BROWSER_MAIN_H_
diff --git a/chrome/browser/chrome_browser_main_android.cc b/chrome/browser/chrome_browser_main_android.cc
index b83a09e..bf96e89 100644
--- a/chrome/browser/chrome_browser_main_android.cc
+++ b/chrome/browser/chrome_browser_main_android.cc
@@ -28,7 +28,6 @@
 
 void ChromeBrowserMainPartsAndroid::PreProfileInit() {
   TRACE_EVENT0("startup", "ChromeBrowserMainPartsAndroid::PreProfileInit")
-#if defined(USE_LINUX_BREAKPAD)
 #if defined(GOOGLE_CHROME_BUILD)
   // TODO(jcivelli): we should not initialize the crash-reporter when it was not
   // enabled. Right now if it is disabled we still generate the minidumps but we
@@ -47,7 +46,6 @@
     InitCrashReporter();
     crash_dump_manager_.reset(new CrashDumpManager());
   }
-#endif
 
   ChromeBrowserMainParts::PreProfileInit();
 }
@@ -87,11 +85,3 @@
 void ChromeBrowserMainPartsAndroid::ShowMissingLocaleMessageBox() {
   NOTREACHED();
 }
-
-void RecordBreakpadStatusUMA(MetricsService* metrics) {
-  // TODO: crbug.com/139023
-  NOTIMPLEMENTED();
-}
-
-void WarnAboutMinimumSystemRequirements() {
-}
diff --git a/chrome/browser/chrome_browser_main_x11.cc b/chrome/browser/chrome_browser_main_extra_parts_x11.cc
similarity index 70%
rename from chrome/browser/chrome_browser_main_x11.cc
rename to chrome/browser/chrome_browser_main_extra_parts_x11.cc
index a88981b..9731c17 100644
--- a/chrome/browser/chrome_browser_main_x11.cc
+++ b/chrome/browser/chrome_browser_main_extra_parts_x11.cc
@@ -2,23 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/chrome_browser_main.h"
+#include "chrome/browser/chrome_browser_main_extra_parts_x11.h"
 
 #include "base/bind.h"
 #include "base/debug/debugger.h"
 #include "base/message_loop.h"
 #include "chrome/browser/browser_shutdown.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
-#include "chrome/browser/metrics/metrics_service.h"
 #include "chrome/common/chrome_result_codes.h"
 #include "content/public/browser/browser_thread.h"
 #include "ui/base/x/x11_util.h"
 #include "ui/base/x/x11_util_internal.h"
 
-#if defined(USE_LINUX_BREAKPAD)
-#include "chrome/app/breakpad_linux.h"
-#endif
-
 using content::BrowserThread;
 
 namespace {
@@ -77,36 +72,29 @@
 
 }  // namespace
 
-void RecordBreakpadStatusUMA(MetricsService* metrics) {
-#if defined(USE_LINUX_BREAKPAD)
-  metrics->RecordBreakpadRegistration(IsCrashReporterEnabled());
-#else
-  metrics->RecordBreakpadRegistration(false);
-#endif
-  metrics->RecordBreakpadHasDebugger(base::debug::BeingDebugged());
+ChromeBrowserMainExtraPartsX11::ChromeBrowserMainExtraPartsX11() {
 }
 
-void WarnAboutMinimumSystemRequirements() {
-  // Nothing to warn about on X11 right now.
+ChromeBrowserMainExtraPartsX11::~ChromeBrowserMainExtraPartsX11() {
 }
 
-// From browser_main_win.h, stubs until we figure out the right thing...
-
-int DoUninstallTasks(bool chrome_still_running) {
-  return content::RESULT_CODE_NORMAL_EXIT;
-}
-
-void SetBrowserX11ErrorHandlersPreEarlyInitialization() {
-  // Use default error handlers during startup.
+void ChromeBrowserMainExtraPartsX11::PreEarlyInitialization() {
+  // Installs the X11 error handlers for the browser process used during
+  // startup. They simply print error messages and exit because
+  // we can't shutdown properly while creating and initializing services.
   ui::SetX11ErrorHandlers(NULL, NULL);
 }
 
-void SetBrowserX11ErrorHandlersPostMainMessageLoopStart() {
-  // Set up error handlers to make sure profile gets written if X server
-  // goes away.
+void ChromeBrowserMainExtraPartsX11::PostMainMessageLoopStart() {
+  // Installs the X11 error handlers for the browser process after the
+  // main message loop has started. This will allow us to exit cleanly
+  // if X exits before us.
   ui::SetX11ErrorHandlers(BrowserX11ErrorHandler, BrowserX11IOErrorHandler);
 }
 
-void UnsetBrowserX11ErrorHandlers() {
+void ChromeBrowserMainExtraPartsX11::PostMainMessageLoopRun() {
+  // Unset the X11 error handlers. The X11 error handlers log the errors using a
+  // |PostTask()| on the message-loop. But since the message-loop is in the
+  // process of terminating, this can cause errors.
   ui::SetX11ErrorHandlers(X11EmptyErrorHandler, X11EmptyIOErrorHandler);
 }
diff --git a/chrome/browser/chrome_browser_main_extra_parts_x11.h b/chrome/browser/chrome_browser_main_extra_parts_x11.h
new file mode 100644
index 0000000..b3007bc
--- /dev/null
+++ b/chrome/browser/chrome_browser_main_extra_parts_x11.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2011 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.
+
+// Contains functions used by BrowserMain() that are gtk-specific.
+
+#ifndef CHROME_BROWSER_CHROME_BROWSER_MAIN_EXTRA_PARTS_X11_H_
+#define CHROME_BROWSER_CHROME_BROWSER_MAIN_EXTRA_PARTS_X11_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "chrome/browser/chrome_browser_main_extra_parts.h"
+
+class ChromeBrowserMainExtraPartsX11 : public ChromeBrowserMainExtraParts {
+ public:
+  ChromeBrowserMainExtraPartsX11();
+  virtual ~ChromeBrowserMainExtraPartsX11();
+
+ private:
+  // ChromeBrowserMainExtraParts overrides.
+  virtual void PreEarlyInitialization() OVERRIDE;
+  virtual void PostMainMessageLoopStart() OVERRIDE;
+  virtual void PostMainMessageLoopRun() OVERRIDE;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsX11);
+};
+
+#endif  // CHROME_BROWSER_CHROME_BROWSER_MAIN_EXTRA_PARTS_X11_H_
diff --git a/chrome/browser/chrome_browser_main_linux.cc b/chrome/browser/chrome_browser_main_linux.cc
index 3a3ea52..dd83909 100644
--- a/chrome/browser/chrome_browser_main_linux.cc
+++ b/chrome/browser/chrome_browser_main_linux.cc
@@ -4,18 +4,14 @@
 
 #include "chrome/browser/chrome_browser_main_linux.h"
 
-#if !defined(OS_CHROMEOS)
-#include "chrome/browser/storage_monitor/storage_monitor_linux.h"
-#include "content/public/browser/browser_thread.h"
-#endif
-
-#if defined(USE_LINUX_BREAKPAD)
 #include <stdlib.h>
 
 #include "base/command_line.h"
 #include "base/linux_util.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/app/breakpad_linux.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/metrics/metrics_service.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/env_vars.h"
 #include "chrome/common/pref_names.h"
@@ -25,13 +21,13 @@
 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chromeos/chromeos_switches.h"
+#else
+#include "chrome/browser/storage_monitor/storage_monitor_linux.h"
+#include "content/public/browser/browser_thread.h"
 #endif
 
-#endif  // defined(USE_LINUX_BREAKPAD)
-
 namespace {
 
-#if defined(USE_LINUX_BREAKPAD)
 #if !defined(OS_CHROMEOS)
 void GetLinuxDistroCallback() {
   base::GetLinuxDistro();  // Initialize base::linux_distro if needed.
@@ -99,7 +95,6 @@
 
   return breakpad_enabled;
 }
-#endif  // defined(USE_LINUX_BREAKPAD)
 
 }  // namespace
 
@@ -112,7 +107,6 @@
 }
 
 void ChromeBrowserMainPartsLinux::PreProfileInit() {
-#if defined(USE_LINUX_BREAKPAD)
 #if !defined(OS_CHROMEOS)
   // Needs to be called after we have chrome::DIR_USER_DATA and
   // g_browser_process.  This happens in PreCreateThreads.
@@ -123,7 +117,6 @@
 
   if (IsCrashReportingEnabled(local_state()))
     InitCrashReporter();
-#endif
 
 #if !defined(OS_CHROMEOS)
   const base::FilePath kDefaultMtabPath("/etc/mtab");
@@ -133,6 +126,13 @@
   ChromeBrowserMainPartsPosix::PreProfileInit();
 }
 
+void ChromeBrowserMainPartsLinux::PostProfileInit() {
+  ChromeBrowserMainPartsPosix::PostProfileInit();
+
+  g_browser_process->metrics_service()->RecordBreakpadRegistration(
+      IsCrashReporterEnabled());
+}
+
 void ChromeBrowserMainPartsLinux::PostMainMessageLoopRun() {
   ChromeBrowserMainPartsPosix::PostMainMessageLoopRun();
 
diff --git a/chrome/browser/chrome_browser_main_linux.h b/chrome/browser/chrome_browser_main_linux.h
index cba0e1e..3cc5476 100644
--- a/chrome/browser/chrome_browser_main_linux.h
+++ b/chrome/browser/chrome_browser_main_linux.h
@@ -25,6 +25,7 @@
 
   // ChromeBrowserMainParts overrides.
   virtual void PreProfileInit() OVERRIDE;
+  virtual void PostProfileInit() OVERRIDE;
   virtual void PostMainMessageLoopRun() OVERRIDE;
 
  private:
diff --git a/chrome/browser/chrome_browser_main_mac.h b/chrome/browser/chrome_browser_main_mac.h
index bad7bd9..52f6cf1 100644
--- a/chrome/browser/chrome_browser_main_mac.h
+++ b/chrome/browser/chrome_browser_main_mac.h
@@ -22,6 +22,7 @@
   virtual void PreEarlyInitialization() OVERRIDE;
   virtual void PreMainMessageLoopStart() OVERRIDE;
   virtual void PreProfileInit() OVERRIDE;
+  virtual void PostProfileInit() OVERRIDE;
 
   // Perform platform-specific work that needs to be done after the main event
   // loop has ended. The embedder must be sure to call this.
diff --git a/chrome/browser/chrome_browser_main_mac.mm b/chrome/browser/chrome_browser_main_mac.mm
index 156146b..af5ee81 100644
--- a/chrome/browser/chrome_browser_main_mac.mm
+++ b/chrome/browser/chrome_browser_main_mac.mm
@@ -8,7 +8,6 @@
 #include <sys/sysctl.h>
 
 #include "base/command_line.h"
-#include "base/debug/debugger.h"
 #include "base/files/file_path.h"
 #include "base/mac/bundle_locations.h"
 #include "base/mac/mac_util.h"
@@ -17,6 +16,7 @@
 #include "base/path_service.h"
 #include "chrome/app/breakpad_mac.h"
 #import "chrome/browser/app_controller_mac.h"
+#include "chrome/browser/browser_process.h"
 #import "chrome/browser/chrome_browser_application_mac.h"
 #include "chrome/browser/mac/install_from_dmg.h"
 #include "chrome/browser/mac/keychain_reauthorize.h"
@@ -150,21 +150,6 @@
 
 }  // namespace
 
-void RecordBreakpadStatusUMA(MetricsService* metrics) {
-  metrics->RecordBreakpadRegistration(IsCrashReporterEnabled());
-  metrics->RecordBreakpadHasDebugger(base::debug::BeingDebugged());
-}
-
-void WarnAboutMinimumSystemRequirements() {
-  // Nothing to check for on Mac right now.
-}
-
-// From browser_main_win.h, stubs until we figure out the right thing...
-
-int DoUninstallTasks(bool chrome_still_running) {
-  return content::RESULT_CODE_NORMAL_EXIT;
-}
-
 // ChromeBrowserMainPartsMac ---------------------------------------------------
 
 ChromeBrowserMainPartsMac::ChromeBrowserMainPartsMac(
@@ -286,6 +271,12 @@
   ChromeBrowserMainPartsPosix::PreProfileInit();
 }
 
+void ChromeBrowserMainPartsMac::PostProfileInit() {
+  ChromeBrowserMainPartsPosix::PostProfileInit();
+  g_browser_process->metrics_service()->RecordBreakpadRegistration(
+      IsCrashReporterEnabled());
+}
+
 void ChromeBrowserMainPartsMac::DidEndMainMessageLoop() {
   AppController* appController = [NSApp delegate];
   [appController didEndMainMessageLoop];
diff --git a/chrome/browser/chrome_browser_main_posix.cc b/chrome/browser/chrome_browser_main_posix.cc
index cb83f97..9100137 100644
--- a/chrome/browser/chrome_browser_main_posix.cc
+++ b/chrome/browser/chrome_browser_main_posix.cc
@@ -18,9 +18,9 @@
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/sessions/session_restore.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_observer.h"
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index 9fdfc4b..66c615a 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -28,6 +28,10 @@
 #include "chrome/browser/profiles/profile_shortcut_manager.h"
 #include "chrome/browser/shell_integration.h"
 #include "chrome/browser/storage_monitor/storage_monitor_win.h"
+#include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
+#include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/ui/simple_message_box.h"
 #include "chrome/browser/ui/uninstall_browser_prompt.h"
 #include "chrome/common/chrome_constants.h"
@@ -45,6 +49,7 @@
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "installer_util_strings/installer_util_strings.h"
+#include "ui/base/cursor/cursor_loader_win.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/l10n/l10n_util_win.h"
 #include "ui/base/ui_base_switches.h"
@@ -87,19 +92,6 @@
 
 }  // namespace
 
-void RecordBreakpadStatusUMA(MetricsService* metrics) {
-  metrics->RecordBreakpadHasDebugger(TRUE == ::IsDebuggerPresent());
-}
-
-void WarnAboutMinimumSystemRequirements() {
-  if (base::win::GetVersion() < base::win::VERSION_XP) {
-    chrome::ShowMessageBox(NULL,
-        l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
-        l10n_util::GetStringUTF16(IDS_UNSUPPORTED_OS_PRE_WIN_XP),
-        chrome::MESSAGE_BOX_TYPE_WARNING);
-  }
-}
-
 void ShowCloseBrowserFirstMessageBox() {
   int message_id = IDS_UNINSTALL_CLOSE_APP;
   if (base::win::GetVersion() >= base::win::VERSION_WIN8 &&
@@ -185,6 +177,9 @@
   ChromeBrowserMainParts::ToolkitInitialized();
   gfx::PlatformFontWin::adjust_font_callback = &AdjustUIFont;
   gfx::PlatformFontWin::get_minimum_font_size_callback = &GetMinimumFontSize;
+#if defined(USE_AURA)
+  ui::CursorLoaderWin::SetCursorResourceModule(chrome::kBrowserResourcesDll);
+#endif
 }
 
 void ChromeBrowserMainPartsWin::PreMainMessageLoopStart() {
@@ -199,6 +194,42 @@
   }
 }
 
+int ChromeBrowserMainPartsWin::PreCreateThreads() {
+  int rv = ChromeBrowserMainParts::PreCreateThreads();
+
+  // TODO(viettrungluu): why don't we run this earlier?
+  if (!parsed_command_line().HasSwitch(switches::kNoErrorDialogs) &&
+      base::win::GetVersion() < base::win::VERSION_XP) {
+    chrome::ShowMessageBox(NULL,
+        l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
+        l10n_util::GetStringUTF16(IDS_UNSUPPORTED_OS_PRE_WIN_XP),
+        chrome::MESSAGE_BOX_TYPE_WARNING);
+  }
+
+  return rv;
+}
+
+void ChromeBrowserMainPartsWin::PostMainMessageLoopRun() {
+  // Log the search engine chosen on first run. Do this at shutdown, after any
+  // changes are made from the first run bubble link, etc.
+  if (do_first_run_tasks() && !profile()->IsOffTheRecord()) {
+    TemplateURLService* url_service =
+        TemplateURLServiceFactory::GetForProfile(profile());
+    const TemplateURL* default_search_engine =
+        url_service->GetDefaultSearchProvider();
+    // The default engine can be NULL if the administrator has disabled
+    // default search.
+    SearchEngineType search_engine_type =
+        TemplateURLPrepopulateData::GetEngineType(default_search_engine ?
+            default_search_engine->url() : std::string());
+    // Record the search engine chosen.
+    UMA_HISTOGRAM_ENUMERATION("Chrome.SearchSelectExempt", search_engine_type,
+                              SEARCH_ENGINE_MAX);
+  }
+
+  ChromeBrowserMainParts::PostMainMessageLoopRun();
+}
+
 void ChromeBrowserMainPartsWin::PreProfileInit() {
   storage_monitor_.reset(chrome::StorageMonitorWin::Create());
 
diff --git a/chrome/browser/chrome_browser_main_win.h b/chrome/browser/chrome_browser_main_win.h
index e3dabae..6da509e 100644
--- a/chrome/browser/chrome_browser_main_win.h
+++ b/chrome/browser/chrome_browser_main_win.h
@@ -32,6 +32,8 @@
   // BrowserParts overrides.
   virtual void ToolkitInitialized() OVERRIDE;
   virtual void PreMainMessageLoopStart() OVERRIDE;
+  virtual int PreCreateThreads() OVERRIDE;
+  virtual void PostMainMessageLoopRun() OVERRIDE;
   virtual void PreProfileInit() OVERRIDE;
 
   // ChromeBrowserMainParts overrides.
diff --git a/chrome/browser/chrome_browser_main_x11.h b/chrome/browser/chrome_browser_main_x11.h
deleted file mode 100644
index 5255cd1..0000000
--- a/chrome/browser/chrome_browser_main_x11.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2011 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.
-
-// Contains functions used by BrowserMain() that are gtk-specific.
-
-#ifndef CHROME_BROWSER_CHROME_BROWSER_MAIN_X11_H_
-#define CHROME_BROWSER_CHROME_BROWSER_MAIN_X11_H_
-
-// Installs the X11 error handlers for the browser process used during
-// startup. They simply print error messages and exit because
-// we can't shutdown properly while creating and initializing services.
-void SetBrowserX11ErrorHandlersPreEarlyInitialization();
-
-// Installs the X11 error handlers for the browser process after the
-// main message loop has started. This will allow us to exit cleanly
-// if X exits before us.
-void SetBrowserX11ErrorHandlersPostMainMessageLoopStart();
-
-// Installs empty X11 error handlers. This avoids calling into the message-loop
-// in case an X11 erro happens while the message-loop is being destroyed.
-void UnsetBrowserX11ErrorHandlers();
-
-#endif  // CHROME_BROWSER_CHROME_BROWSER_MAIN_X11_H_
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index f2a6ab4..ba3f684 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/app_mode/app_mode_utils.h"
 #include "chrome/browser/browser_about_handler.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_shutdown.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_remover.h"
 #include "chrome/browser/character_encoding.h"
@@ -79,7 +80,6 @@
 #include "chrome/browser/ssl/ssl_blocking_page.h"
 #include "chrome/browser/ssl/ssl_tab_helper.h"
 #include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/browser/toolkit_extra_parts.h"
 #include "chrome/browser/ui/chrome_select_file_policy.h"
 #include "chrome/browser/ui/sync/sync_promo_ui.h"
 #include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h"
@@ -90,7 +90,6 @@
 #include "chrome/common/child_process_logging.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_process_type.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/extensions/extension.h"
@@ -106,6 +105,7 @@
 #include "chrome/common/render_messages.h"
 #include "chrome/common/url_constants.h"
 #include "chromeos/chromeos_constants.h"
+#include "components/nacl/common/nacl_process_type.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/browser_child_process_host.h"
 #include "content/public/browser/browser_main_parts.h"
@@ -148,7 +148,8 @@
 #include "chrome/browser/spellchecker/spellcheck_message_filter_mac.h"
 #elif defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/chrome_browser_main_chromeos.h"
-#include "chrome/browser/chromeos/fileapi/cros_mount_point_provider.h"
+#include "chrome/browser/chromeos/drive/file_system_backend_delegate.h"
+#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/system/statistics_provider.h"
@@ -186,17 +187,41 @@
 #endif
 
 #if !defined(OS_ANDROID)
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #endif
 
 #if defined(ENABLE_WEBRTC)
 #include "chrome/browser/media/webrtc_logging_handler_host.h"
 #endif
 
+#if defined(ENABLE_INPUT_SPEECH)
+#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h"
+#endif
+
 #if defined(FILE_MANAGER_EXTENSION)
 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h"
 #endif
 
+#if defined(TOOLKIT_GTK)
+#include "chrome/browser/ui/gtk/chrome_browser_main_extra_parts_gtk.h"
+#endif
+
+#if defined(TOOLKIT_VIEWS)
+#include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h"
+#endif
+
+#if defined(USE_ASH)
+#include "chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.h"
+#endif
+
+#if defined(USE_AURA)
+#include "chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.h"
+#endif
+
+#if defined(USE_X11)
+#include "chrome/browser/chrome_browser_main_extra_parts_x11.h"
+#endif
+
 using base::FileDescriptor;
 using content::AccessTokenStore;
 using content::BrowserChildProcessHostIterator;
@@ -507,7 +532,7 @@
 }
 
 // static
-void ChromeContentBrowserClient::RegisterUserPrefs(
+void ChromeContentBrowserClient::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kDisable3DAPIs,
@@ -568,19 +593,23 @@
   // Construct additional browser parts. Stages are called in the order in
   // which they are added.
 #if defined(TOOLKIT_GTK)
-  chrome::AddGtkToolkitExtraParts(main_parts);
+  main_parts->AddParts(new ChromeBrowserMainExtraPartsGtk());
 #endif
 
 #if defined(TOOLKIT_VIEWS)
-  chrome::AddViewsToolkitExtraParts(main_parts);
+  main_parts->AddParts(new ChromeBrowserMainExtraPartsViews());
 #endif
 
 #if defined(USE_ASH)
-  chrome::AddAshToolkitExtraParts(main_parts);
+  main_parts->AddParts(new ChromeBrowserMainExtraPartsAsh());
 #endif
 
 #if defined(USE_AURA)
-  chrome::AddAuraToolkitExtraParts(main_parts);
+  main_parts->AddParts(new ChromeBrowserMainExtraPartsAura());
+#endif
+
+#if defined(USE_X11)
+  main_parts->AddParts(new ChromeBrowserMainExtraPartsX11());
 #endif
 
   chrome::AddMetricsExtraParts(main_parts);
@@ -701,6 +730,7 @@
 void ChromeContentBrowserClient::GuestWebContentsCreated(
     WebContents* guest_web_contents,
     WebContents* opener_web_contents,
+    content::BrowserPluginGuestDelegate** guest_delegate,
     scoped_ptr<base::DictionaryValue> extra_params) {
   if (opener_web_contents) {
     GuestView* guest = GuestView::FromWebContents(opener_web_contents);
@@ -711,11 +741,11 @@
 
     switch (guest->GetViewType()) {
       case GuestView::WEBVIEW: {
-        new WebViewGuest(guest_web_contents);
+        *guest_delegate = new WebViewGuest(guest_web_contents);
         break;
       }
       case GuestView::ADVIEW: {
-        new AdViewGuest(guest_web_contents);
+        *guest_delegate = new AdViewGuest(guest_web_contents);
         break;
       }
       default:
@@ -733,9 +763,9 @@
   extra_params->GetString(guestview::kAttributeApi, &api_type);
 
   if (api_type == "adview") {
-    new AdViewGuest(guest_web_contents);
+    *guest_delegate  = new AdViewGuest(guest_web_contents);
   } else if (api_type == "webview") {
-    new WebViewGuest(guest_web_contents);
+    *guest_delegate = new WebViewGuest(guest_web_contents);
   } else {
     NOTREACHED();
   }
@@ -1252,6 +1282,10 @@
       ExtensionURLInfo(current_url), ExtensionURLInfo(new_url), false);
 }
 
+bool ChromeContentBrowserClient::ShouldAssignSiteForURL(const GURL& url) {
+  return !url.SchemeIs(chrome::kChromeNativeScheme);
+}
+
 std::string ChromeContentBrowserClient::GetCanonicalEncodingNameByAliasName(
     const std::string& alias_name) {
   return CharacterEncoding::GetCanonicalEncodingNameByAliasName(alias_name);
@@ -1259,16 +1293,17 @@
 
 void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
     CommandLine* command_line, int child_process_id) {
-#if defined(USE_LINUX_BREAKPAD)
-  if (IsCrashReporterEnabled()) {
-    command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
-        child_process_logging::GetClientId() + "," + base::GetLinuxDistro());
-  }
-#elif defined(OS_MACOSX)
+#if defined(OS_MACOSX)
   if (IsCrashReporterEnabled()) {
     command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
                                     child_process_logging::GetClientId());
   }
+#elif defined(OS_POSIX)
+  if (IsCrashReporterEnabled()) {
+    command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
+        child_process_logging::GetClientId() + "," + base::GetLinuxDistro());
+  }
+
 #endif  // OS_MACOSX
 
   if (logging::DialogsAreSuppressed())
@@ -1400,6 +1435,7 @@
     static const char* const kSwitchNames[] = {
       switches::kAllowHTTPBackgroundPage,
       switches::kEnableExperimentalExtensionApis,
+      switches::kExtensionsOnChromeURLs,
       switches::kWhitelistedExtensionID,
     };
 
@@ -1794,6 +1830,11 @@
         int render_process_id) {
 #if defined(ENABLE_NOTIFICATIONS)
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  // Sometimes a notification may be invoked during the shutdown.
+  // See http://crbug.com/256638
+  if (browser_shutdown::IsTryingToQuit())
+    return WebKit::WebNotificationPresenter::PermissionNotAllowed;
+
   ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
 
   DesktopNotificationService* notification_service =
@@ -1931,12 +1972,12 @@
 // TODO(tommi): Rename from Get to Create.
 content::SpeechRecognitionManagerDelegate*
     ChromeContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
-#if !defined(OS_ANDROID)
-  return new speech::ChromeSpeechRecognitionManagerDelegate();
+#if defined(ENABLE_INPUT_SPEECH)
+  return new speech::ChromeSpeechRecognitionManagerDelegateBubbleUI();
 #else
-  // TODO(janx): Implement speech::AndroidSpeechRecognitionManagerDelegate
-  // (see crbug.com/222352).
-  return NULL;
+  // Platforms who don't implement x-webkit-speech (a.k.a INPUT_SPEECH) just
+  // need the base delegate without the bubble UI.
+  return new speech::ChromeSpeechRecognitionManagerDelegate();
 #endif
 }
 
@@ -2295,28 +2336,30 @@
   additional_allowed_schemes->push_back(extensions::kExtensionScheme);
 }
 
-void ChromeContentBrowserClient::GetAdditionalFileSystemMountPointProviders(
+void ChromeContentBrowserClient::GetAdditionalFileSystemBackends(
+    content::BrowserContext* browser_context,
     const base::FilePath& storage_partition_path,
-    quota::SpecialStoragePolicy* special_storage_policy,
-    fileapi::ExternalMountPoints* external_mount_points,
-    ScopedVector<fileapi::FileSystemMountPointProvider>* additional_providers) {
+    ScopedVector<fileapi::FileSystemBackend>* additional_backends) {
 #if !defined(OS_ANDROID)
   base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
-  additional_providers->push_back(new MediaFileSystemMountPointProvider(
+  additional_backends->push_back(new MediaFileSystemBackend(
       storage_partition_path,
       pool->GetSequencedTaskRunner(pool->GetNamedSequenceToken(
-          MediaFileSystemMountPointProvider::kMediaTaskRunnerName)).get()));
+          MediaFileSystemBackend::kMediaTaskRunnerName)).get()));
 #endif
 #if defined(OS_CHROMEOS)
+  fileapi::ExternalMountPoints* external_mount_points =
+      content::BrowserContext::GetMountPoints(browser_context);
   DCHECK(external_mount_points);
-  chromeos::CrosMountPointProvider* cros_mount_provider =
-      new chromeos::CrosMountPointProvider(
-          special_storage_policy,
+  chromeos::FileSystemBackend* backend =
+      new chromeos::FileSystemBackend(
+          new drive::FileSystemBackendDelegate(browser_context),
+          browser_context->GetSpecialStoragePolicy(),
           external_mount_points,
           fileapi::ExternalMountPoints::GetSystemInstance());
-  cros_mount_provider->AddSystemMountPoints();
-  DCHECK(cros_mount_provider->CanHandleType(fileapi::kFileSystemTypeExternal));
-  additional_providers->push_back(cros_mount_provider);
+  backend->AddSystemMountPoints();
+  DCHECK(backend->CanHandleType(fileapi::kFileSystemTypeExternal));
+  additional_backends->push_back(backend);
 #endif
 }
 
@@ -2360,7 +2403,6 @@
   mappings->push_back(FileDescriptorInfo(kAndroidUIResourcesPakDescriptor,
                                          FileDescriptor(f, true)));
 
-#if defined(USE_LINUX_BREAKPAD)
   if (IsCrashReporterEnabled()) {
     f = CrashDumpManager::GetInstance()->CreateMinidumpFile(child_process_id);
     if (f == base::kInvalidPlatformFileValue) {
@@ -2371,7 +2413,6 @@
                                              FileDescriptor(f, true)));
     }
   }
-#endif  // defined(USE_LINUX_BREAKPAD)
 
 #else
   int crash_signal_fd = GetCrashSignalFD(command_line);
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 0996c6e..adc9a42 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -36,7 +36,7 @@
   ChromeContentBrowserClient();
   virtual ~ChromeContentBrowserClient();
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Notification that the application locale has changed. This allows us to
   // update our I/O thread cache of this value.
@@ -62,6 +62,7 @@
   virtual void GuestWebContentsCreated(
       content::WebContents* guest_web_contents,
       content::WebContents* opener_web_contents,
+      content::BrowserPluginGuestDelegate** guest_delegate,
       scoped_ptr<base::DictionaryValue> extra_params) OVERRIDE;
   virtual void GuestWebContentsAttached(
       content::WebContents* guest_web_contents,
@@ -108,6 +109,7 @@
       content::ResourceContext* resource_context,
       const GURL& current_url,
       const GURL& new_url) OVERRIDE;
+  virtual bool ShouldAssignSiteForURL(const GURL& url) OVERRIDE;
   virtual std::string GetCanonicalEncodingNameByAliasName(
       const std::string& alias_name) OVERRIDE;
   virtual void AppendExtraCommandLineSwitches(CommandLine* command_line,
@@ -240,12 +242,10 @@
       content::WebContents* web_contents) OVERRIDE;
   virtual void GetAdditionalAllowedSchemesForFileSystem(
       std::vector<std::string>* additional_schemes) OVERRIDE;
-  virtual void GetAdditionalFileSystemMountPointProviders(
+  virtual void GetAdditionalFileSystemBackends(
+      content::BrowserContext* browser_context,
       const base::FilePath& storage_partition_path,
-      quota::SpecialStoragePolicy* special_storage_policy,
-      fileapi::ExternalMountPoints* external_mount_points,
-      ScopedVector<fileapi::FileSystemMountPointProvider>*
-          additional_providers) OVERRIDE;
+      ScopedVector<fileapi::FileSystemBackend>* additional_backends) OVERRIDE;
 
 #if defined(OS_POSIX) && !defined(OS_MACOSX)
   virtual void GetAdditionalMappedFilesForChildProcess(
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc
new file mode 100644
index 0000000..66808fa
--- /dev/null
+++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -0,0 +1,22 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chrome_content_browser_client.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace chrome {
+
+typedef testing::Test ChromeContentBrowserClientTest;
+
+
+TEST_F(ChromeContentBrowserClientTest, ShouldAssignSiteForURL) {
+  ChromeContentBrowserClient client;
+  EXPECT_FALSE(client.ShouldAssignSiteForURL(GURL("chrome-native://test")));
+  EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("http://www.google.com")));
+  EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("https://www.google.com")));
+}
+
+}  // namespace chrome
diff --git a/chrome/browser/chrome_main_browsertest.cc b/chrome/browser/chrome_main_browsertest.cc
index 7d14ea8..12ee266 100644
--- a/chrome/browser/chrome_main_browsertest.cc
+++ b/chrome/browser/chrome_main_browsertest.cc
@@ -7,11 +7,11 @@
 #include "base/command_line.h"
 #include "base/path_service.h"
 #include "base/process_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/chrome_notification_types.h b/chrome/browser/chrome_notification_types.h
new file mode 100644
index 0000000..cdb907e
--- /dev/null
+++ b/chrome/browser/chrome_notification_types.h
@@ -0,0 +1,1248 @@
+// Copyright 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROME_NOTIFICATION_TYPES_H_
+#define CHROME_BROWSER_CHROME_NOTIFICATION_TYPES_H_
+
+#include "build/build_config.h"
+#include "content/public/browser/notification_types.h"
+
+namespace chrome {
+
+enum NotificationType {
+  NOTIFICATION_CHROME_START = content::NOTIFICATION_CONTENT_END,
+
+  // Browser-window ----------------------------------------------------------
+
+  // This message is sent after a window has been opened.  The source is a
+  // Source<Browser> containing the affected Browser.  No details are
+  // expected.
+  NOTIFICATION_BROWSER_OPENED = NOTIFICATION_CHROME_START,
+
+  // This message is sent soon after BROWSER_OPENED, and indicates that
+  // the Browser's |window_| is now non-NULL. The source is a Source<Browser>
+  // containing the affected Browser.  No details are expected.
+  NOTIFICATION_BROWSER_WINDOW_READY,
+
+  // This message is sent when a browser is closing. The source is a
+  // Source<Browser> containing the affected Browser. No details are expected.
+  // This is sent prior to BROWSER_CLOSED, and may be sent more than once for a
+  // particular browser.
+  NOTIFICATION_BROWSER_CLOSING,
+
+  // This message is sent after a window has been closed.  The source is a
+  // Source<Browser> containing the affected Browser.  No details are exptected.
+  NOTIFICATION_BROWSER_CLOSED,
+
+  // This message is sent when closing a browser has been cancelled, either by
+  // the user cancelling a beforeunload dialog, or IsClosingPermitted()
+  // disallowing closing. This notification implies that no BROWSER_CLOSING or
+  // BROWSER_CLOSED notification will be sent.
+  // The source is a Source<Browser> containing the affected browser. No details
+  // are expected.
+  NOTIFICATION_BROWSER_CLOSE_CANCELLED,
+
+  // Indicates that a top window has been closed.  The source is the HWND
+  // that was closed, no details are expected.
+  NOTIFICATION_WINDOW_CLOSED,
+
+#if defined(OS_LINUX)
+  // On Linux maximize can be an asynchronous operation. This notification
+  // indicates that the window has been maximized. The source is
+  // a Source<BrowserWindow> containing the BrowserWindow that was maximized.
+  // No details are expected.
+  NOTIFICATION_BROWSER_WINDOW_MAXIMIZED,
+#endif  // defined(OS_LINUX)
+
+  // Sent when the language (English, French...) for a page has been detected.
+  // The details Details<std::string> contain the ISO 639-1 language code and
+  // the source is Source<WebContents>.
+  NOTIFICATION_TAB_LANGUAGE_DETERMINED,
+
+  // Sent when a page has been translated. The source is the tab for that page
+  // (Source<WebContents>) and the details are the language the page was
+  // originally in and the language it was translated to
+  // (std::pair<std::string, std::string>).
+  NOTIFICATION_PAGE_TRANSLATED,
+
+  // Sent after the renderer returns a snapshot of tab contents.
+  // The source (Source<content::WebContents>) is the RenderViewHost for which
+  // the snapshot was generated and the details (Details<const SkBitmap>) is
+  // the actual snapshot.
+  NOTIFICATION_TAB_SNAPSHOT_TAKEN,
+
+  // The user has changed the browser theme. The source is a
+  // Source<ThemeService>. There are no details.
+  NOTIFICATION_BROWSER_THEME_CHANGED,
+
+#if defined(USE_AURA)
+  // The user has changed the fling curve configuration.
+  // Source<GesturePrefsObserver>. There are no details.
+  NOTIFICATION_BROWSER_FLING_CURVE_PARAMETERS_CHANGED,
+#endif  // defined(USE_AURA)
+
+  // Sent when the renderer returns focus to the browser, as part of focus
+  // traversal. The source is the browser, there are no details.
+  NOTIFICATION_FOCUS_RETURNED_TO_BROWSER,
+
+  // A new tab is created from an existing tab to serve as a target of a
+  // navigation that is about to happen. The source will be a Source<Profile>
+  // corresponding to the profile in which the new tab will live.  Details in
+  // the form of a RetargetingDetails object are provided.
+  NOTIFICATION_RETARGETING,
+
+  // Application-wide ----------------------------------------------------------
+
+  // This message is sent when the application is terminating (the last
+  // browser window has shutdown as part of an explicit user-initiated exit,
+  // or the user closed the last browser window on Windows/Linux and there are
+  // no BackgroundContents keeping the browser running). No source or details
+  // are passed.
+  NOTIFICATION_APP_TERMINATING,
+
+#if defined(OS_MACOSX)
+  // This notification is sent when the app has no key window, such as when
+  // all windows are closed but the app is still active. No source or details
+  // are provided.
+  NOTIFICATION_NO_KEY_WINDOW,
+#endif
+
+  // This is sent when the user has chosen to exit the app, but before any
+  // browsers have closed. This is sent if the user chooses to exit (via exit
+  // menu item or keyboard shortcut) or to restart the process (such as in flags
+  // page), not if Chrome exits by some other means (such as the user closing
+  // the last window). No source or details are passed.
+  //
+  // Note that receiving this notification does not necessarily mean the process
+  // will exit because the shutdown process can be cancelled by an unload
+  // handler.  Use APP_TERMINATING for such needs.
+  NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
+
+  // Application-modal dialogs -----------------------------------------------
+
+  // Sent after an application-modal dialog has been shown. The source
+  // is the dialog.
+  NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
+
+  // This message is sent when a new InfoBar has been added to an
+  // InfoBarService.  The source is a Source<InfoBarService> with a pointer to
+  // the InfoBarService the InfoBar was added to.  The details is a
+  // Details<InfoBarDelegate> with a pointer to the delegate that was added.
+  NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
+
+  // This message is sent when an InfoBar is about to be removed from an
+  // InfoBarService.  The source is a Source<InfoBarService> with a pointer to
+  // the InfoBarService the InfoBar was removed from.  The details is a
+  // Details<std::pair<InfoBarDelegate*, bool> > with a pointer to the removed
+  // delegate and whether the removal should be animated.
+  NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
+
+  // This message is sent when an InfoBar is replacing another infobar in an
+  // InfoBarService.  The source is a Source<InfoBarService> with a pointer to
+  // the InfoBarService the InfoBar was removed from.  The details is a
+  // Details<std::pair<InfoBarDelegate*, InfoBarDelegate*> > with pointers to
+  // the old and new delegates, respectively.
+  NOTIFICATION_TAB_CONTENTS_INFOBAR_REPLACED,
+
+  // This is sent when an externally hosted tab is closed.  No details are
+  // expected.
+  NOTIFICATION_EXTERNAL_TAB_CLOSED,
+
+  // Indicates that the new page tab has finished loading. This is used for
+  // performance testing to see how fast we can load it after startup, and is
+  // only called once for the lifetime of the browser. The source is unused.
+  // Details is an integer: the number of milliseconds elapsed between
+  // starting and finishing all painting.
+  NOTIFICATION_INITIAL_NEW_TAB_UI_LOAD,
+
+#if defined(OS_ANDROID)
+  // Indicates that the new tab page is ready.  This is different than
+  // NOTIFICATION_INITIAL_NEW_TAB_UI_LOAD as the NTP might do some more in-page
+  // navigations after it's done loading, potentially causing flakyness in tests
+  // that would navigate as soon as the NTP is done loading.
+  // When this notification happen, it guarantees the page is not going to do
+  // any further navigation.
+  // The source is the WebContents containing the NTP.
+  NOTIFICATION_NEW_TAB_READY,
+#endif
+
+  // Used to fire notifications about how long various events took to
+  // complete.  E.g., this is used to get more fine grained timings from the
+  // new tab page.  The source is a WebContents and the details is a
+  // MetricEventDurationDetails.
+  NOTIFICATION_METRIC_EVENT_DURATION,
+
+  // This notification is sent when extensions::TabHelper::SetExtensionApp is
+  // invoked. The source is the extensions::TabHelper SetExtensionApp was
+  // invoked on.
+  NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED,
+
+  // Notification posted when the element that is focused has been touched. A
+  // bool parameter is passed in this notification which indicates if this node
+  // accepts. The source is the RenderViewHost.
+  NOTIFICATION_FOCUSED_NODE_TOUCHED,
+
+  // Tabs --------------------------------------------------------------------
+
+  // Sent when a tab is added to a WebContentsDelegate. The source is the
+  // WebContentsDelegate and the details is the added WebContents.
+  NOTIFICATION_TAB_ADDED,
+
+  // This notification is sent after a tab has been appended to the tab_strip.
+  // The source is a Source<WebContents> of the tab being added. There
+  // are no details.
+  NOTIFICATION_TAB_PARENTED,
+
+  // This message is sent before a tab has been closed.  The source is a
+  // Source<NavigationController> with a pointer to the controller for the
+  // closed tab.  No details are expected.
+  //
+  // See also content::NOTIFICATION_WEB_CONTENTS_DESTROYED, which is sent when
+  // the WebContents containing the NavigationController is destroyed.
+  NOTIFICATION_TAB_CLOSING,
+
+  // Stuff inside the tabs ---------------------------------------------------
+
+  // This notification is sent when the result of a find-in-page search is
+  // available with the browser process. The source is a Source<WebContents>.
+  // Details encompass a FindNotificationDetail object that tells whether the
+  // match was found or not found.
+  NOTIFICATION_FIND_RESULT_AVAILABLE,
+
+#if defined(OS_ANDROID)
+  // This notification is sent when the match rects of a find-in-page search
+  // are available. The source is a Source<WebContents>. Details encompass a
+  // FindMatchRectsDetails object that contains the result version and the
+  // rects information.
+  NOTIFICATION_FIND_MATCH_RECTS_AVAILABLE,
+#endif
+
+  // BackgroundContents ------------------------------------------------------
+
+  // A new background contents was opened by script. The source is the parent
+  // profile and the details are BackgroundContentsOpenedDetails.
+  NOTIFICATION_BACKGROUND_CONTENTS_OPENED,
+
+  // The background contents navigated to a new location. The source is the
+  // parent Profile, and the details are the BackgroundContents that was
+  // navigated.
+  NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED,
+
+  // The background contents were closed by someone invoking window.close()
+  // or the parent application was uninstalled.
+  // The source is the parent profile, and the details are the
+  // BackgroundContents.
+  NOTIFICATION_BACKGROUND_CONTENTS_CLOSED,
+
+  // The background contents is being deleted. The source is the
+  // parent Profile, and the details are the BackgroundContents being deleted.
+  NOTIFICATION_BACKGROUND_CONTENTS_DELETED,
+
+  // The background contents has crashed. The source is the parent Profile,
+  // and the details are the BackgroundContents.
+  NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED,
+
+  // The background contents associated with a hosted app has changed (either
+  // a new background contents has been created, or an existing background
+  // contents has closed). The source is the parent Profile, and the details
+  // are the BackgroundContentsService.
+  NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED,
+
+  // Chrome has entered/exited background mode. The source is the
+  // BackgroundModeManager and the details are a boolean value which is set to
+  // true if Chrome is now in background mode.
+  NOTIFICATION_BACKGROUND_MODE_CHANGED,
+
+  // This is sent when a login prompt is shown.  The source is the
+  // Source<NavigationController> for the tab in which the prompt is shown.
+  // Details are a LoginNotificationDetails which provide the LoginHandler
+  // that should be given authentication.
+  NOTIFICATION_AUTH_NEEDED,
+
+  // This is sent when authentication credentials have been supplied (either
+  // by the user or by an automation service), but before we've actually
+  // received another response from the server.  The source is the
+  // Source<NavigationController> for the tab in which the prompt was shown.
+  // Details are an AuthSuppliedLoginNotificationDetails which provide the
+  // LoginHandler that should be given authentication as well as the supplied
+  // username and password.
+  NOTIFICATION_AUTH_SUPPLIED,
+
+  // This is sent when an authentication request has been dismissed without
+  // supplying credentials (either by the user or by an automation service).
+  // The source is the Source<NavigationController> for the tab in which the
+  // prompt was shown. Details are a LoginNotificationDetails which provide
+  // the LoginHandler that should be cancelled.
+  NOTIFICATION_AUTH_CANCELLED,
+
+  // History -----------------------------------------------------------------
+
+  // Sent when a history service has finished loading. The source is the
+  // profile that the history service belongs to, and the details is the
+  // HistoryService.
+  NOTIFICATION_HISTORY_LOADED,
+
+  // Sent when a URL has been added or modified. This is used by the in-memory
+  // URL database and the InMemoryURLIndex (both used by autocomplete) to track
+  // changes to the main history system.
+  //
+  // The source is the profile owning the history service that changed, and
+  // the details is history::URLsModifiedDetails that lists the modified or
+  // added URLs.
+  NOTIFICATION_HISTORY_URLS_MODIFIED,
+
+  // Sent when the user visits a URL.
+  //
+  // The source is the profile owning the history service that changed, and
+  // the details is history::URLVisitedDetails.
+  NOTIFICATION_HISTORY_URL_VISITED,
+
+  // Sent when one or more URLs are deleted.
+  //
+  // The source is the profile owning the history service that changed, and
+  // the details is history::URLsDeletedDetails that lists the deleted URLs.
+  NOTIFICATION_HISTORY_URLS_DELETED,
+
+  // Sent when a keyword search term is updated. The source is the Profile and
+  // the details are history::KeywordSearchTermDetails
+  NOTIFICATION_HISTORY_KEYWORD_SEARCH_TERM_UPDATED,
+
+  // Sent by history when the favicon of a URL changes.  The source is the
+  // profile, and the details is FaviconChangedDetails (see
+  // chrome/browser/favicon/favicon_changed_details.h).
+  NOTIFICATION_FAVICON_CHANGED,
+
+  // Sent by FaviconTabHelper when a tab's favicon has been successfully
+  // updated. The details are a bool indicating whether the
+  // NavigationEntry's favicon URL has changed since the previous
+  // NOTIFICATION_FAVICON_UPDATED notification. The details are true if
+  // there was no previous NOTIFICATION_FAVICON_UPDATED notification for the
+  // current NavigationEntry.
+  NOTIFICATION_FAVICON_UPDATED,
+
+  // Profiles -----------------------------------------------------------------
+
+  // Sent after a Profile has been created. This notification is sent both for
+  // normal and OTR profiles.
+  // The details are none and the source is the new profile.
+  NOTIFICATION_PROFILE_CREATED,
+
+  // Sent after a Profile has been added to ProfileManager.
+  // The details are none and the source is the new profile.
+  NOTIFICATION_PROFILE_ADDED,
+
+  // Sent before a Profile is destroyed. This notification is sent both for
+  // normal and OTR profiles.
+  // The details are none and the source is a Profile*.
+  NOTIFICATION_PROFILE_DESTROYED,
+
+  // Sent after the URLRequestContextGetter for a Profile has been initialized.
+  // The details are none and the source is a Profile*.
+  NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED,
+
+  // TopSites ----------------------------------------------------------------
+
+  // Sent by TopSites when it finishes loading. The source is the profile the
+  // details the TopSites.
+  NOTIFICATION_TOP_SITES_LOADED,
+
+  // Sent by TopSites when it has finished updating its most visited URLs
+  // cache after querying the history service. The source is the TopSites and
+  // the details a CancelableRequestProvider::Handle from the history service
+  // query.
+  // Used only in testing.
+  NOTIFICATION_TOP_SITES_UPDATED,
+
+  // Sent by TopSites when the either one of the most visited urls changed, or
+  // one of the images changes. The source is the TopSites, the details not
+  // used.
+  NOTIFICATION_TOP_SITES_CHANGED,
+
+  // Task Manager ------------------------------------------------------------
+
+  // Sent when WebUI TaskManager opens and is ready for showing tasks.
+  NOTIFICATION_TASK_MANAGER_WINDOW_READY,
+
+  // The TaskManagerChildProcessResourceProvider collects the list of child
+  // processes when StartUpdating is called. This data is collected on the IO
+  // thread and passed back to the UI thread. Once all entries are added to the
+  // task manager, this notification is sent.
+  NOTIFICATION_TASK_MANAGER_CHILD_PROCESSES_DATA_READY,
+
+  // Sent when a renderer process is notified of new v8 heap statistics. The
+  // source is the ID of the renderer process, and the details are a
+  // V8HeapStatsDetails object.
+  NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED,
+
+  // Sent when a renderer process is notified of a new FPS value. The source
+  // is the ID of the renderer process, and the details are an FPSDetails
+  // object.
+  NOTIFICATION_RENDERER_FPS_COMPUTED,
+
+  // Non-history storage services --------------------------------------------
+
+  // Notification that the TemplateURLService has finished loading from the
+  // database. The source is the TemplateURLService, and the details are
+  // NoDetails.
+  NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED,
+
+  // Sent when a TemplateURL is removed from the model. The source is the
+  // Profile, and the details the id of the TemplateURL being removed.
+  NOTIFICATION_TEMPLATE_URL_REMOVED,
+
+  // Sent when the prefs relating to the default search engine have changed due
+  // to policy.  Source and details are unused.
+  NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED,
+
+  // The state of a web resource has been changed. A resource may have been
+  // added, removed, or altered. Source is WebResourceService, and the
+  // details are NoDetails.
+  NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED,
+
+  // A safe browsing database update completed.  Source is the
+  // SafeBrowsingService and the details are a bool indicating whether the
+  // update was successful.
+  NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE,
+
+  // Autocomplete ------------------------------------------------------------
+
+  // Sent by the autocomplete controller when done.  The source is the
+  // AutocompleteController, the details not used.
+  NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
+
+  // This is sent when an item of the Omnibox popup is selected. The source
+  // is the profile.
+  NOTIFICATION_OMNIBOX_OPENED_URL,
+
+  // This is sent from Instant when the omnibox focus state changes.
+  NOTIFICATION_OMNIBOX_FOCUS_CHANGED,
+
+  // Sent when the Google URL for a profile has been updated.  Some services
+  // cache this value and need to update themselves when it changes.  See
+  // google_util::GetGoogleURLAndUpdateIfNecessary().  The source is the
+  // Profile, the details a GoogleURLTracker::UpdatedDetails containing the old
+  // and new URLs.
+  //
+  // Note that because incognito mode requests for the GoogleURLTracker are
+  // redirected to the non-incognito profile's copy, this notification will only
+  // ever fire on non-incognito profiles; thus listeners should use
+  // GetOriginalProfile() when constructing a Source to filter against.
+  NOTIFICATION_GOOGLE_URL_UPDATED,
+
+  // Printing ----------------------------------------------------------------
+
+  // Notification from PrintJob that an event occurred. It can be that a page
+  // finished printing or that the print job failed. Details is
+  // PrintJob::EventDetails. Source is a PrintJob.
+  NOTIFICATION_PRINT_JOB_EVENT,
+
+  // Sent when a PrintJob has been released.
+  // Source is the WebContents that holds the print job.
+  NOTIFICATION_PRINT_JOB_RELEASED,
+
+  // Shutdown ----------------------------------------------------------------
+
+  // Sent when WM_ENDSESSION has been received, after the browsers have been
+  // closed but before browser process has been shutdown. The source/details
+  // are all source and no details.
+  NOTIFICATION_SESSION_END,
+
+  // User Scripts ------------------------------------------------------------
+
+  // Sent when there are new user scripts available.  The details are a
+  // pointer to SharedMemory containing the new scripts.
+  NOTIFICATION_USER_SCRIPTS_UPDATED,
+
+#if !defined(OS_ANDROID)
+  // User Style Sheet --------------------------------------------------------
+
+  // Sent when the user style sheet has changed.
+  NOTIFICATION_USER_STYLE_SHEET_UPDATED,
+#endif
+
+  // Extensions --------------------------------------------------------------
+
+  // Sent when a CrxInstaller finishes. Source is the CrxInstaller that
+  // finished. The details are the extension which was installed.
+  NOTIFICATION_CRX_INSTALLER_DONE,
+
+  // Sent when the known installed extensions have all been loaded.  In
+  // testing scenarios this can happen multiple times if extensions are
+  // unloaded and reloaded. The source is a Profile.
+  NOTIFICATION_EXTENSIONS_READY,
+
+  // Sent when an extension icon being displayed in the location bar is updated.
+  // The source is the Profile and the details are the WebContents for
+  // the tab.
+  NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
+
+  // Sent when a new extension is loaded. The details are an Extension, and
+  // the source is a Profile.
+  NOTIFICATION_EXTENSION_LOADED,
+
+  // An error occured while attempting to load an extension. The details are a
+  // string with details about why the load failed.
+  NOTIFICATION_EXTENSION_LOAD_ERROR,
+
+  // Sent when an extension is enabled. Under most circumstances, listeners
+  // will want to use NOTIFICATION_EXTENSION_LOADED. This notification is only
+  // fired when the "Enable" button is hit in the extensions tab.  The details
+  // are an Extension, and the source is a Profile.
+  NOTIFICATION_EXTENSION_ENABLED,
+
+  // Sent when attempting to load a new extension, but they are disabled. The
+  // details are an Extension*, and the source is a Profile*.
+  NOTIFICATION_EXTENSION_UPDATE_DISABLED,
+
+  // Sent when an extension's permissions change. The details are an
+  // UpdatedExtensionPermissionsInfo, and the source is a Profile.
+  NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
+
+  // Sent when an extension install turns out to not be a theme.
+  NOTIFICATION_NO_THEME_DETECTED,
+
+  // Sent when new extensions are installed, or existing extensions are updated.
+  // The details are an InstalledExtensionInfo, and the source is a Profile.
+  NOTIFICATION_EXTENSION_INSTALLED,
+
+  // An error occured during extension install. The details are a string with
+  // details about why the install failed.
+  NOTIFICATION_EXTENSION_INSTALL_ERROR,
+
+  // Sent when an extension install is not allowed, as indicated by
+  // PendingExtensionInfo::ShouldAllowInstall. The details are an Extension,
+  // and the source is a Profile.
+  NOTIFICATION_EXTENSION_INSTALL_NOT_ALLOWED,
+
+  // Sent when an extension has been uninstalled. The details are an Extension,
+  // and the source is a Profile.
+  NOTIFICATION_EXTENSION_UNINSTALLED,
+
+  // Sent when an extension uninstall is not allowed because the extension is
+  // not user manageable.  The details are an Extension, and the source is a
+  // Profile.
+  NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED,
+
+  // Sent when an extension is unloaded. This happens when an extension is
+  // uninstalled or disabled. The details are an UnloadedExtensionInfo, and
+  // the source is a Profile.
+  //
+  // Note that when this notification is sent, ExtensionService has already
+  // removed the extension from its internal state.
+  NOTIFICATION_EXTENSION_UNLOADED,
+
+  // Sent after a new ExtensionHost is created. The details are
+  // an ExtensionHost* and the source is a Profile*.
+  NOTIFICATION_EXTENSION_HOST_CREATED,
+
+  // Sent before an ExtensionHost is destroyed. The details are
+  // an ExtensionHost* and the source is a Profile*.
+  NOTIFICATION_EXTENSION_HOST_DESTROYED,
+
+  // Sent by an ExtensionHost when it has finished its initial page load,
+  // including any external resources.
+  // The details are an ExtensionHost* and the source is a Profile*.
+  NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
+
+  // Sent by an ExtensionHost when its render view requests closing through
+  // window.close(). The details are an ExtensionHost* and the source is a
+  // Profile*.
+  NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
+
+  // Sent when extension render process ends (whether it crashes or closes).
+  // The details are an ExtensionHost* and the source is a Profile*. Not sent
+  // during browser shutdown.
+  NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
+
+  // Sent when a background page is ready so other components can load.
+  NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
+
+  // Sent when a pop-up extension view is ready, so that notification may
+  // be sent to pending callbacks.  Note that this notification is sent
+  // after all onload callbacks have been invoked in the main frame.
+  // The details is the ExtensionHost* hosted within the popup, and the source
+  // is a Profile*.
+  NOTIFICATION_EXTENSION_POPUP_VIEW_READY,
+
+  // Sent when a browser action's state has changed. The source is the
+  // ExtensionAction* that changed.  The details are the Profile* that the
+  // browser action belongs to.
+  NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
+
+  // Sent when the count of page actions has changed. Note that some of them
+  // may not apply to the current page. The source is a LocationBar*. There
+  // are no details.
+  NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED,
+
+  // Sent when a browser action's visibility has changed. The source is the
+  // ExtensionPrefs* that changed, and the details are a std::string with the
+  // extension's ID.
+  NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
+
+  // Sent when a page action's visibility has changed. The source is the
+  // ExtensionAction* that changed. The details are a WebContents*.
+  NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED,
+
+  // Sent when a system indicator action's state has changed. The source is the
+  // Profile* that the browser action belongs to. The details are the
+  // ExtensionAction* that changed.
+  NOTIFICATION_EXTENSION_SYSTEM_INDICATOR_UPDATED,
+
+  // Sent when an extension command has been removed. The source is the profile
+  // and the details is a std::pair of two std::string objects (an extension ID
+  // and the name of the command being removed).
+  NOTIFICATION_EXTENSION_COMMAND_REMOVED,
+
+  // Sent when an extension command has been added. The source is the profile
+  // and the details is a std::pair of two std::string objects (an extension ID
+  // and the name of the command being added).
+  NOTIFICATION_EXTENSION_COMMAND_ADDED,
+
+  // Sent when an extension command shortcut for a browser action is activated
+  // on Mac. The source is the profile and the details is a std::pair of a
+  // std::string containing an extension ID and a gfx::NativeWindow for the
+  // associated window.
+  NOTIFICATION_EXTENSION_COMMAND_BROWSER_ACTION_MAC,
+
+  // Sent when an extension command shortcut for a page action is activated
+  // on Mac. The source is the profile and the details is a std::pair of a
+  // std::string containing an extension ID and a gfx::NativeWindow for the
+  // associated window.
+  NOTIFICATION_EXTENSION_COMMAND_PAGE_ACTION_MAC,
+
+  // Sent when an extension command shortcut for a script badge is activated
+  // on Mac. The source is the profile and the details is a std::pair of a
+  // std::string containing an extension ID and a gfx::NativeWindow for the
+  // associated window.
+  NOTIFICATION_EXTENSION_COMMAND_SCRIPT_BADGE_MAC,
+
+  // A new extension RenderViewHost has been registered. The details are
+  // the RenderViewHost*.
+  NOTIFICATION_EXTENSION_VIEW_REGISTERED,
+
+  // An extension RenderViewHost has been unregistered. The details are
+  // the RenderViewHost*.
+  NOTIFICATION_EXTENSION_VIEW_UNREGISTERED,
+
+  // Sent by an extension to notify the browser about the results of a unit
+  // test.
+  NOTIFICATION_EXTENSION_TEST_PASSED,
+  NOTIFICATION_EXTENSION_TEST_FAILED,
+
+  // Sent by extension test javascript code, typically in a browser test. The
+  // sender is a std::string representing the extension id, and the details
+  // are a std::string with some message. This is particularly useful when you
+  // want to have C++ code wait for javascript code to do something.
+  NOTIFICATION_EXTENSION_TEST_MESSAGE,
+
+  // Sent when an bookmarks extensions API function was successfully invoked.
+  // The source is the id of the extension that invoked the function, and the
+  // details are a pointer to the const BookmarksFunction in question.
+  NOTIFICATION_EXTENSION_BOOKMARKS_API_INVOKED,
+
+  // Sent when a downloads extensions API event is fired. The source is an
+  // ExtensionDownloadsEventRouter::NotificationSource, and the details is a
+  // std::string containing json. Used for testing.
+  NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
+
+  // Sent when an omnibox extension has sent back omnibox suggestions. The
+  // source is the profile, and the details are an
+  // extensions::api::omnibox::SendSuggestions::Params object.
+  NOTIFICATION_EXTENSION_OMNIBOX_SUGGESTIONS_READY,
+
+  // Sent when the user accepts the input in an extension omnibox keyword
+  // session. The source is the profile.
+  NOTIFICATION_EXTENSION_OMNIBOX_INPUT_ENTERED,
+
+  // Sent when an omnibox extension has updated the default suggestion. The
+  // source is the profile.
+  NOTIFICATION_EXTENSION_OMNIBOX_DEFAULT_SUGGESTION_CHANGED,
+
+  // Sent when the extension updater starts checking for updates to installed
+  // extensions. The source is a Profile, and there are no details.
+  NOTIFICATION_EXTENSION_UPDATING_STARTED,
+
+  // The extension updater found an update and will attempt to download and
+  // install it. The source is a Profile, and the details are an
+  // extensions::UpdateDetails object with the extension id and version of the
+  // found update.
+  NOTIFICATION_EXTENSION_UPDATE_FOUND,
+
+  // Component Updater -------------------------------------------------------
+
+  // Sent when the component updater starts doing update checks. If no
+  // component has been registered for update this notification is not
+  // generated. The source is the component updater itself and there are
+  // no details.
+  NOTIFICATION_COMPONENT_UPDATER_STARTED,
+
+  // Sent when the component updater is going to take a long nap. The
+  // source is the component updater itself and there are no details.
+  NOTIFICATION_COMPONENT_UPDATER_SLEEPING,
+
+  // Sent when there is a new version of a registered component. After
+  // the notification is send the component will be downloaded. The source
+  // is the id of the component and there are no details.
+  NOTIFICATION_COMPONENT_UPDATE_FOUND,
+
+  // Send when the new component has been downloaded and an installation
+  // or upgrade is about to be attempted. The source is the id of the
+  // component and there are no details.
+  NOTIFICATION_COMPONENT_UPDATE_READY,
+
+  // Desktop Notifications ---------------------------------------------------
+
+  // This notification is sent when a balloon is connected to a renderer
+  // process to render the balloon contents.  The source is a
+  // Source<BalloonHost> with a pointer to the the balloon.  A
+  // NOTIFY_BALLOON_DISCONNECTED is guaranteed before the source pointer
+  // becomes junk. No details expected.
+  NOTIFICATION_NOTIFY_BALLOON_CONNECTED,
+
+  // This message is sent after a balloon is disconnected from the renderer
+  // process. The source is a Source<BalloonHost> with a pointer to the
+  // balloon host (the pointer is usable). No details are expected.
+  NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
+
+  // Upgrade notifications ---------------------------------------------------
+
+  // Sent when Chrome believes an update has been installed and available for
+  // long enough with the user shutting down to let it take effect. See
+  // upgrade_detector.cc for details on how long it waits. No details are
+  // expected.
+  NOTIFICATION_UPGRADE_RECOMMENDED,
+
+  // Sent when a critical update has been installed. No details are expected.
+  NOTIFICATION_CRITICAL_UPGRADE_INSTALLED,
+
+  // Sent when the current install is outdated. No details are expected.
+  NOTIFICATION_OUTDATED_INSTALL,
+
+  // Software incompatibility notifications ----------------------------------
+
+  // Sent when Chrome has finished compiling the list of loaded modules (and
+  // other modules of interest). No details are expected.
+  NOTIFICATION_MODULE_LIST_ENUMERATED,
+
+  // Sent when Chrome is done scanning the module list and when the user has
+  // acknowledged the module incompatibility. No details are expected.
+  NOTIFICATION_MODULE_INCOMPATIBILITY_BADGE_CHANGE,
+
+  // Accessibility Notifications ---------------------------------------------
+
+  // Notification that a window in the browser UI (not the web content)
+  // was opened, for propagating to an accessibility extension.
+  // Details will be an AccessibilityWindowInfo.
+  NOTIFICATION_ACCESSIBILITY_WINDOW_OPENED,
+
+  // Notification that a window in the browser UI was closed.
+  // Details will be an AccessibilityWindowInfo.
+  NOTIFICATION_ACCESSIBILITY_WINDOW_CLOSED,
+
+  // Notification that a control in the browser UI was focused.
+  // Details will be an AccessibilityControlInfo.
+  NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED,
+
+  // Notification that a control in the browser UI had its action taken,
+  // like pressing a button or toggling a checkbox.
+  // Details will be an AccessibilityControlInfo.
+  NOTIFICATION_ACCESSIBILITY_CONTROL_ACTION,
+
+  // Notification that text box in the browser UI had text change.
+  // Details will be an AccessibilityControlInfo.
+  NOTIFICATION_ACCESSIBILITY_TEXT_CHANGED,
+
+  // Notification that a pop-down menu was opened, for propagating
+  // to an accessibility extension.
+  // Details will be an AccessibilityMenuInfo.
+  NOTIFICATION_ACCESSIBILITY_MENU_OPENED,
+
+  // Notification that a pop-down menu was closed, for propagating
+  // to an accessibility extension.
+  // Details will be an AccessibilityMenuInfo.
+  NOTIFICATION_ACCESSIBILITY_MENU_CLOSED,
+
+  // Content Settings --------------------------------------------------------
+
+  // Sent when content settings change. The source is a HostContentSettings
+  // object, the details are ContentSettingsNotificationsDetails.
+  NOTIFICATION_CONTENT_SETTINGS_CHANGED,
+
+  // Sent when the collect cookies dialog is shown. The source is a
+  // TabSpecificContentSettings object, there are no details.
+  NOTIFICATION_COLLECTED_COOKIES_SHOWN,
+
+  // Sent when a non-default setting in the the notification content settings
+  // map has changed. The source is the DesktopNotificationService, the
+  // details are None.
+  NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED,
+
+  // Sent when content settings change for a tab. The source is a
+  // content::WebContents object, the details are None.
+  NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
+
+  // Sync --------------------------------------------------------------------
+
+  // The sync service has finished the datatype configuration process. The
+  // source is the ProfileSyncService object of the Profile. There are no
+  // details.
+  NOTIFICATION_SYNC_CONFIGURE_DONE,
+
+  // The sync service has started the datatype configuration process. The source
+  // is the ProfileSyncService object of the Profile. There are no details.
+  NOTIFICATION_SYNC_CONFIGURE_START,
+
+  // A service is requesting a sync datatype refresh for the current profile.
+  // The details value is a const syncer::ModelTypeSet.
+  // If the payload map is empty, it should be treated as an invalidation for
+  // all enabled types. This is used by session sync.
+  NOTIFICATION_SYNC_REFRESH_LOCAL,
+
+  // External notification requesting a sync datatype refresh for the current
+  // profile. The details value is a const syncer::ObjectIdInvalidationMap.
+  // If the payload map is empty, it should be treated as an invalidation for
+  // all enabled types. This is used for notifications on Android.
+  NOTIFICATION_SYNC_REFRESH_REMOTE,
+
+  // The session service has been saved.  This notification type is only sent
+  // if there were new SessionService commands to save, and not for no-op save
+  // operations.
+  NOTIFICATION_SESSION_SERVICE_SAVED,
+
+  // A foreign session has been updated.  If a new tab page is open, the
+  // foreign session handler needs to update the new tab page's foreign
+  // session data.
+  NOTIFICATION_FOREIGN_SESSION_UPDATED,
+
+  // Foreign sessions has been disabled. New tabs should not display foreign
+  // session data.
+  NOTIFICATION_FOREIGN_SESSION_DISABLED,
+
+  // All tab metadata has been loaded from disk asynchronously.
+  // Sent on the UI thread.
+  // The source is the Profile. There are no details.
+  NOTIFICATION_SESSION_RESTORE_COMPLETE,
+
+  // Cookies -----------------------------------------------------------------
+
+  // Sent when a cookie changes. The source is a Profile object, the details
+  // are a ChromeCookieDetails object.
+  NOTIFICATION_COOKIE_CHANGED,
+
+  // Token Service -----------------------------------------------------------
+
+  // When the token service has a new token available for a service, one of
+  // these notifications is issued per new token.
+  // The source is a TokenService on the Profile. The details are a
+  // TokenAvailableDetails object.
+  NOTIFICATION_TOKEN_AVAILABLE,
+
+  // When there aren't any additional tokens left to load, this notification
+  // is sent.
+  // The source is a TokenService on the profile. There are no details.
+  NOTIFICATION_TOKEN_LOADING_FINISHED,
+
+  // If a token request failed, one of these is issued per failed request.
+  // The source is a TokenService on the Profile. The details are a
+  // TokenRequestFailedDetails object.
+  NOTIFICATION_TOKEN_REQUEST_FAILED,
+
+  // When a service has a new token they got from a frontend that the
+  // TokenService should know about, fire this notification. The source is the
+  // Profile. The details are a TokenAvailableDetails object.
+  NOTIFICATION_TOKEN_UPDATED,
+
+  // Fired when the TokenService has had all of its tokens removed (such as due
+  // to the user signing out). The source is the TokenService. There are no
+  // details.
+  NOTIFICATION_TOKENS_CLEARED,
+
+  // Sent when a user signs into Google services such as sync.
+  // The source is the Profile. The details are a
+  // GoogleServiceSigninSuccessDetails object.
+  NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
+
+  // Sent when a user fails to sign into Google services such as sync.
+  // The source is the Profile. The details are a GoogleServiceAuthError
+  // object.
+  NOTIFICATION_GOOGLE_SIGNIN_FAILED,
+
+  // Sent when the currently signed-in user for a user has been signed out.
+  // The source is the Profile. The details are a
+  // GoogleServiceSignoutDetails object.
+  NOTIFICATION_GOOGLE_SIGNED_OUT,
+
+  // Download Notifications --------------------------------------------------
+
+  // Sent when a download is initiated. It is possible that the download will
+  // not actually begin due to the DownloadRequestLimiter cancelling it
+  // prematurely.
+  // The source is the corresponding RenderViewHost. There are no details.
+  NOTIFICATION_DOWNLOAD_INITIATED,
+
+  // Misc --------------------------------------------------------------------
+
+  // Sent when PerformanceMonitor has finished all the initial steps of data
+  // collection and has begun passively observing. The source is the
+  // PerformanceMonitor*. No details are expected.
+  NOTIFICATION_PERFORMANCE_MONITOR_INITIALIZED,
+
+#if defined(OS_CHROMEOS)
+  // Sent when a chromium os user logs in.
+  // The details are a chromeos::User object.
+  NOTIFICATION_LOGIN_USER_CHANGED,
+
+  // Sent immediately after the logged-in user's profile is ready.
+  // The details are a Profile object.
+  NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
+
+  // Sent when the chromium session of a particular user is started.
+  // If this is a new user on the machine this will not be sent until a profile
+  // picture has been selected, unlike NOTIFICATION_LOGIN_USER_CHANGED which is
+  // sent immediately after the user has logged in. This will be sent again if
+  // the browser crashes and restarts.
+  // The details are a chromeos::User object.
+  NOTIFICATION_SESSION_STARTED,
+
+  // Sent when user image is updated.
+  NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
+
+  // Sent by UserManager when a profile image download has been completed.
+  NOTIFICATION_PROFILE_IMAGE_UPDATED,
+
+  // Sent by UserManager when profile image download has failed or user has the
+  // default profile image or no profile image at all. No details are expected.
+  NOTIFICATION_PROFILE_IMAGE_UPDATE_FAILED,
+
+  // Sent when a chromium os user attempts to log in.  The source is
+  // all and the details are AuthenticationNotificationDetails.
+  NOTIFICATION_LOGIN_AUTHENTICATION,
+
+  // Sent when webui lock screen is ready.
+  NOTIFICATION_LOCK_WEBUI_READY,
+
+  // Sent when webui lock screen wallpaper is loaded and displayed.
+  NOTIFICATION_LOCK_BACKGROUND_DISPLAYED,
+
+  // Sent when GAIA iframe has been loaded.
+  // First paint event after this fires NOTIFICATION_LOGIN_WEBUI_VISIBLE.
+  // Possible scenarios:
+  // 1. Boot into device that has user pods display disabled or no users.
+  //    Note that booting with network not connected would first generate
+  //    NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN.
+  // 2. From the user pods list, open "Add User" for the second time
+  //    (see below).
+  // TODO(nkostylev): Send this notification any time "Add User" is activated
+  //                  even if it has been silently preloaded on boot.
+  // Not sent on "silent preload" i.e. when booting into login screen
+  // with user pods, GAIA frame is silently preloaded in the background.
+  // Activating it ("Add User") for the first time would not generate this
+  // notification.
+  NOTIFICATION_LOGIN_WEBUI_LOADED,
+
+  // Sent when the login screen has loaded in retail mode. The first paint event
+  // after this fires NOTIFICATION_LOGIN_WEBUI_VISIBLE.
+  NOTIFICATION_DEMO_WEBUI_LOADED,
+
+  // Sent when the user images on the WebUI login screen have all been loaded.
+  // "Normal boot" i.e. for the device with at least one user would generate
+  // this one on boot.
+  // First paint event after this fires NOTIFICATION_LOGIN_WEBUI_VISIBLE.
+  NOTIFICATION_LOGIN_USER_IMAGES_LOADED,
+
+  // Sent when a network error message is displayed on the WebUI login screen.
+  // First paint event of this fires NOTIFICATION_LOGIN_WEBUI_VISIBLE.
+  NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN,
+
+  // Sent when the first OOBE screen has been displayed. Note that the screen
+  // may not be fully rendered at this point.
+  // First paint event after this fires NOTIFICATION_LOGIN_WEBUI_VISIBLE.
+  NOTIFICATION_WIZARD_FIRST_SCREEN_SHOWN,
+
+  // Sent when the specific part of login WebUI is considered to be visible.
+  // That moment is tracked as the first paint event after one of the:
+  // 1. NOTIFICATION_LOGIN_USER_IMAGES_LOADED
+  // 2. NOTIFICATION_LOGIN_WEBUI_LOADED
+  // 3. NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN
+  // 4. NOTIFICATION_WIZARD_FIRST_SCREEN_SHOWN
+  // 5. NOTIFICATION_DEMO_WEBUI_LOADED
+  //
+  // Possible series of notifications:
+  // 1. Boot into fresh OOBE
+  //    NOTIFICATION_WIZARD_FIRST_SCREEN_SHOWN
+  //    NOTIFICATION_LOGIN_WEBUI_VISIBLE
+  // 2. Boot into user pods list (normal boot)
+  //    NOTIFICATION_LOGIN_USER_IMAGES_LOADED
+  //    NOTIFICATION_LOGIN_WEBUI_VISIBLE
+  // 3. Boot into GAIA sign in UI (user pods display disabled or no users):
+  //    if no network is connected or flaky network
+  //    (NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN +
+  //     NOTIFICATION_LOGIN_WEBUI_VISIBLE)
+  //    NOTIFICATION_LOGIN_WEBUI_LOADED
+  //    NOTIFICATION_LOGIN_WEBUI_VISIBLE
+  // 4. Boot into retail mode
+  //    NOTIFICATION_DEMO_WEBUI_LOADED
+  //    NOTIFICATION_LOGIN_WEBUI_VISIBLE
+  // 5. Boot into kiosk mode
+  //    NOTIFICATION_KIOSK_APP_LAUNCHED
+  NOTIFICATION_LOGIN_WEBUI_VISIBLE,
+
+  // Sent when proxy dialog is closed.
+  NOTIFICATION_LOGIN_PROXY_CHANGED,
+
+  // Send when kiosk auto-launch warning screen is visible.
+  NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE,
+
+  // Send when kiosk auto-launch warning screen had completed.
+  NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED,
+
+  // Send when enable consumer kiosk warning screen is visible.
+  NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
+
+  // Send when consumer kiosk has been enabled.
+  NOTIFICATION_KIOSK_ENABLED,
+
+  // Send when enable consumer kiosk warning screen had completed.
+  NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED,
+
+  // Sent when kiosk app list is loaded in UI.
+  NOTIFICATION_KIOSK_APPS_LOADED,
+
+  // Sent when a kiosk app is launched.
+  NOTIFICATION_KIOSK_APP_LAUNCHED,
+
+  // Sent when the user list has changed.
+  NOTIFICATION_USER_LIST_CHANGED,
+
+  // Sent when a panel state changed.
+  NOTIFICATION_PANEL_STATE_CHANGED,
+
+  // Sent when the window manager's layout mode has changed.
+  NOTIFICATION_LAYOUT_MODE_CHANGED,
+
+  // Sent when the screen lock state has changed. The source is
+  // ScreenLocker and the details is a bool specifing that the
+  // screen is locked. When details is a false, the source object
+  // is being deleted, so the receiver shouldn't use the screen locker
+  // object.
+  NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
+
+  // Sent by DeviceSettingsService to indicate that the ownership status
+  // changed. If you can, please use DeviceSettingsService::Observer instead.
+  // Other singleton-based services can't use that because Observer
+  // unregistration is impossible due to unpredictable deletion order.
+  NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
+
+  // This is sent to a ChromeOS settings observer when a system setting is
+  // changed. The source is the CrosSettings and the details a std::string of
+  // the changed setting.
+  NOTIFICATION_SYSTEM_SETTING_CHANGED,
+
+  // Sent by SIM unlock dialog when it has finished with the process of
+  // updating RequirePin setting. RequirePin setting might have been changed
+  // to a new value or update might have been canceled.
+  // In either case notification is sent and details contain a bool
+  // that represents current value.
+  NOTIFICATION_REQUIRE_PIN_SETTING_CHANGE_ENDED,
+
+  // Sent by SIM unlock dialog when it has finished the EnterPin or
+  // EnterPuk dialog, either because the user cancelled, or entered a
+  // PIN or PUK.
+  NOTIFICATION_ENTER_PIN_ENDED,
+
+  // Sent when large cursor is toggled.
+  NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_LARGE_CURSOR,
+
+  // Sent when high contrast mode is toggled.
+  NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE,
+
+  // Sent when screen magnifier is toggled.
+  NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER,
+
+  // Sent when spoken feedback is toggled.
+  NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK,
+
+#endif
+
+#if defined(TOOLKIT_VIEWS)
+  // Sent when a bookmark's context menu is shown. Used to notify
+  // tests that the context menu has been created and shown.
+  NOTIFICATION_BOOKMARK_CONTEXT_MENU_SHOWN,
+
+  // Notification that the nested loop using during tab dragging has returned.
+  // Used for testing.
+  NOTIFICATION_TAB_DRAG_LOOP_DONE,
+#endif
+
+  // Send when a context menu is shown. Used to notify tests that the context
+  // menu has been created and shown.
+  NOTIFICATION_RENDER_VIEW_CONTEXT_MENU_SHOWN,
+
+  // Send when a context menu is closed.
+  NOTIFICATION_RENDER_VIEW_CONTEXT_MENU_CLOSED,
+
+  // Sent when the Instant Controller determines whether an Instant tab supports
+  // the Instant API or not.
+  NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
+
+  // Sent when the Instant Controller determines whether the NTP supports the
+  // Instant API or not.
+  NOTIFICATION_INSTANT_NTP_SUPPORT_DETERMINED,
+
+  // Sent when the Instant Controller has sent the Most Visited Items to the
+  // renderer.
+  NOTIFICATION_INSTANT_SENT_MOST_VISITED_ITEMS,
+
+  // Sent when the CaptivePortalService checks if we're behind a captive portal.
+  // The Source is the Profile the CaptivePortalService belongs to, and the
+  // Details are a Details<CaptivePortalService::CheckResults>.
+  NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
+
+  // Password Store ----------------------------------------------------------
+  // This notification is sent whenenever login entries stored in the password
+  // store are changed. The detail of this notification is a list of changes
+  // represented by a vector of PasswordStoreChange. Each change includes a
+  // change type (ADD, UPDATE, or REMOVE) as well as the
+  // |content::PasswordForm|s that were affected.
+  NOTIFICATION_LOGINS_CHANGED,
+
+  // Sent when an import process has ended.
+  NOTIFICATION_IMPORT_FINISHED,
+
+  // Sent when the applications in the NTP app launcher have been reordered.
+  // The details, if not NoDetails, is the std::string ID of the extension that
+  // was moved.
+  NOTIFICATION_EXTENSION_LAUNCHER_REORDERED,
+
+  // Sent when an app is installed and an NTP has been shown. Source is the
+  // WebContents that was shown, and Details is the string ID of the extension
+  // which was installed.
+  NOTIFICATION_APP_INSTALLED_TO_NTP,
+
+  // Similar to NOTIFICATION_APP_INSTALLED_TO_NTP but used to nofity ash AppList
+  // about installed app. Source is the profile in which the app is installed
+  // and Details is the string ID of the extension.
+  NOTIFICATION_APP_INSTALLED_TO_APPLIST,
+
+#if defined(USE_ASH)
+  // Sent when wallpaper show animation has finished.
+  NOTIFICATION_WALLPAPER_ANIMATION_FINISHED,
+
+  // Sent when the Ash session has started. In its current incantation this is
+  // generated when the metro app has connected to the browser IPC channel.
+  // Used only on Windows.
+  NOTIFICATION_ASH_SESSION_STARTED,
+  // Sent when the Ash session ended. Currently this means the metro app exited.
+  // Used only on Windows.
+  NOTIFICATION_ASH_SESSION_ENDED,
+#endif
+
+#if defined(OS_CHROMEOS)
+  // Sent when WebSocketProxy started accepting connections; details is integer
+  // port on which proxy is listening.
+  NOTIFICATION_WEB_SOCKET_PROXY_STARTED,
+#endif
+
+  // Sent when a new web store promo has been loaded.
+  NOTIFICATION_WEB_STORE_PROMO_LOADED,
+
+  // Protocol Handler Registry -----------------------------------------------
+  // Sent when a ProtocolHandlerRegistry is changed. The source is the profile.
+  NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED,
+
+  // Sent when the cached profile info has changed.
+  NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
+
+  // Sent when the cached profile has finished writing a profile picture to
+  // disk.
+  NOTIFICATION_PROFILE_CACHE_PICTURE_SAVED,
+
+  // Sent when the browser enters or exits fullscreen mode.
+  NOTIFICATION_FULLSCREEN_CHANGED,
+
+  // Sent when the FullscreenController changes, confirms, or denies mouse lock.
+  // The source is the browser's FullscreenController, no details.
+  NOTIFICATION_MOUSE_LOCK_CHANGED,
+
+  // Sent by the PluginPrefs when there is a change of plugin enable/disable
+  // status. The source is the profile.
+  NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
+
+  // Panels Notifications. The Panels are small browser windows near the bottom
+  // of the screen.
+  // Sent when all nonblocking bounds animations are finished across panels.
+  // Used only in unit testing.
+  NOTIFICATION_PANEL_BOUNDS_ANIMATIONS_FINISHED,
+
+  // Sent when panel gains/loses focus.
+  // The source is the Panel, no details.
+  // Used only in unit testing.
+  NOTIFICATION_PANEL_CHANGED_ACTIVE_STATUS,
+
+  // Sent when panel is minimized/restored/shows title only etc.
+  // The source is the Panel, no details.
+  NOTIFICATION_PANEL_CHANGED_EXPANSION_STATE,
+
+  // Sent when panel window size is known. This is for platforms where the
+  // window creation is async and size of the window only becomes known later.
+  // Used only in unit testing.
+  NOTIFICATION_PANEL_WINDOW_SIZE_KNOWN,
+
+  // Sent when panel app icon is loaded.
+  // Used only in unit testing.
+  NOTIFICATION_PANEL_APP_ICON_LOADED,
+
+  // Sent when panel collection get updated.
+  // The source is the PanelCollection, no details.
+  // Used only in coordination with notification balloons.
+  NOTIFICATION_PANEL_COLLECTION_UPDATED,
+
+  // Sent when panel is closed.
+  // The source is the Panel, no details.
+  NOTIFICATION_PANEL_CLOSED,
+
+  // Sent when a global error has changed and the error UI should update it
+  // self. The source is a Source<Profile> containing the profile for the
+  // error. The detail is a GlobalError object that has changed or NULL if
+  // all error UIs should update.
+  NOTIFICATION_GLOBAL_ERRORS_CHANGED,
+
+  // BrowsingDataRemover ----------------------------------------------------
+  // Sent on the UI thread after BrowsingDataRemover has removed browsing data
+  // but before it has notified its explicit observers. The source is a
+  // Source<Profile> containing the profile in which browsing data was removed,
+  // and the detail is a BrowsingDataRemover::NotificationDetail containing the
+  // removal mask and the start of the removal timeframe with which
+  // BrowsingDataRemove::Remove was called.
+  NOTIFICATION_BROWSING_DATA_REMOVED,
+
+  // The user accepted or dismissed a SSL client authentication request.
+  // The source is a Source<net::HttpNetworkSession>.  Details is a
+  // (std::pair<net::SSLCertRequestInfo*, net::X509Certificate*>).
+  NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED,
+
+  // Blocked content.
+  // Sent when content changes to or from the blocked state in
+  // BlockedContentTabHelper.
+  // The source is the WebContents of the blocked content and details
+  // is a boolean: true if the content is entering the blocked state, false
+  // if it is leaving.
+  NOTIFICATION_CONTENT_BLOCKED_STATE_CHANGED,
+
+  // Session Restore --------------------------------------------------------
+
+  // Sent when synchronous (startup) session restore completes. No details or
+  // source.
+  NOTIFICATION_SESSION_RESTORE_DONE,
+
+  // Note:-
+  // Currently only Content and Chrome define and use notifications.
+  // Custom notifications not belonging to Content and Chrome should start
+  // from here.
+  NOTIFICATION_CHROME_END,
+};
+
+}  // namespace chrome
+
+#endif  // CHROME_BROWSER_CHROME_NOTIFICATION_TYPES_H_
diff --git a/chrome/browser/chrome_plugin_browsertest.cc b/chrome/browser/chrome_plugin_browsertest.cc
index fd6af37..d7b76b0 100644
--- a/chrome/browser/chrome_plugin_browsertest.cc
+++ b/chrome/browser/chrome_plugin_browsertest.cc
@@ -15,7 +15,6 @@
 #include "chrome/browser/plugins/plugin_prefs.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_process_type.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/browser_child_process_host_iterator.h"
@@ -23,6 +22,7 @@
 #include "content/public/browser/child_process_data.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/common/content_paths.h"
+#include "content/public/common/process_type.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_utils.h"
 #include "net/base/net_util.h"
@@ -78,7 +78,7 @@
     base::FilePath path;
     PathService::Get(content::DIR_TEST_DATA, &path);
     path = path.AppendASCII("plugin").AppendASCII(filename);
-    CHECK(file_util::PathExists(path));
+    CHECK(base::PathExists(path));
     return net::FilePathToFileURL(path);
   }
 
diff --git a/chrome/browser/chrome_process_finder_win.cc b/chrome/browser/chrome_process_finder_win.cc
index 34f6761..abd6c2b 100644
--- a/chrome/browser/chrome_process_finder_win.cc
+++ b/chrome/browser/chrome_process_finder_win.cc
@@ -16,6 +16,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/win/message_window.h"
 #include "base/win/metro.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/win_util.h"
@@ -98,8 +99,7 @@
 namespace chrome {
 
 HWND FindRunningChromeWindow(const base::FilePath& user_data_dir) {
-  return FindWindowEx(HWND_MESSAGE, NULL, chrome::kMessageWindowClass,
-                      user_data_dir.value().c_str());
+  return base::win::MessageWindow::FindWindow(user_data_dir.value());
 }
 
 NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window,
diff --git a/chrome/browser/chrome_quota_permission_context.cc b/chrome/browser/chrome_quota_permission_context.cc
index 3e3907b..a85b677 100644
--- a/chrome/browser/chrome_quota_permission_context.cc
+++ b/chrome/browser/chrome_quota_permission_context.cc
@@ -24,23 +24,14 @@
 #include "url/gurl.h"
 #include "webkit/common/quota/quota_types.h"
 
-using content::BrowserThread;
-using content::QuotaPermissionContext;
-using content::WebContents;
 
 
 // RequestQuotaInfoBarDelegate ------------------------------------------------
 
 namespace {
 
-// If we requested larger quota than this threshold, show a different
-// message to the user.
-const int64 kRequestLargeQuotaThreshold = 5 * 1024 * 1024;
-
 class RequestQuotaInfoBarDelegate : public ConfirmInfoBarDelegate {
  public:
-  typedef QuotaPermissionContext::PermissionCallback PermissionCallback;
-
   // Creates a request quota infobar delegate and adds it to |infobar_service|.
   static void Create(
       InfoBarService* infobar_service,
@@ -48,7 +39,7 @@
       const GURL& origin_url,
       int64 requested_quota,
       const std::string& display_languages,
-      const PermissionCallback& callback);
+      const content::QuotaPermissionContext::PermissionCallback& callback);
 
  private:
   RequestQuotaInfoBarDelegate(
@@ -57,7 +48,7 @@
       const GURL& origin_url,
       int64 requested_quota,
       const std::string& display_languages,
-      const PermissionCallback& callback);
+      const content::QuotaPermissionContext::PermissionCallback& callback);
   virtual ~RequestQuotaInfoBarDelegate();
 
   // ConfirmInfoBarDelegate:
@@ -72,7 +63,7 @@
   GURL origin_url_;
   std::string display_languages_;
   int64 requested_quota_;
-  PermissionCallback callback_;
+  content::QuotaPermissionContext::PermissionCallback callback_;
 
   DISALLOW_COPY_AND_ASSIGN(RequestQuotaInfoBarDelegate);
 };
@@ -84,7 +75,7 @@
     const GURL& origin_url,
     int64 requested_quota,
     const std::string& display_languages,
-    const QuotaPermissionContext::PermissionCallback& callback) {
+    const content::QuotaPermissionContext::PermissionCallback& callback) {
   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
       new RequestQuotaInfoBarDelegate(infobar_service, context, origin_url,
                                       requested_quota, display_languages,
@@ -97,7 +88,7 @@
     const GURL& origin_url,
     int64 requested_quota,
     const std::string& display_languages,
-    const PermissionCallback& callback)
+    const content::QuotaPermissionContext::PermissionCallback& callback)
     : ConfirmInfoBarDelegate(infobar_service),
       context_(context),
       origin_url_(origin_url),
@@ -110,7 +101,7 @@
   if (!callback_.is_null()) {
     context_->DispatchCallbackOnIOThread(
         callback_,
-        QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
+        content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
   }
 }
 
@@ -120,6 +111,9 @@
 }
 
 string16 RequestQuotaInfoBarDelegate::GetMessageText() const {
+  // If the site requested larger quota than this threshold, show a different
+  // message to the user.
+  const int64 kRequestLargeQuotaThreshold = 5 * 1024 * 1024;
   return l10n_util::GetStringFUTF16(
       (requested_quota_ > kRequestLargeQuotaThreshold ?
           IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION :
@@ -130,14 +124,14 @@
 bool RequestQuotaInfoBarDelegate::Accept() {
   context_->DispatchCallbackOnIOThread(
       callback_,
-      QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
+      content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
   return true;
 }
 
 bool RequestQuotaInfoBarDelegate::Cancel() {
   context_->DispatchCallbackOnIOThread(
       callback_,
-      QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
+      content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
   return true;
 }
 
@@ -146,7 +140,8 @@
 
 // ChromeQuotaPermissionContext -----------------------------------------------
 
-ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {}
+ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {
+}
 
 void ChromeQuotaPermissionContext::RequestQuotaPermission(
     const GURL& origin_url,
@@ -162,16 +157,16 @@
     return;
   }
 
-  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
+  if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
+    content::BrowserThread::PostTask(
+        content::BrowserThread::UI, FROM_HERE,
         base::Bind(&ChromeQuotaPermissionContext::RequestQuotaPermission, this,
                    origin_url, type, requested_quota, render_process_id,
                    render_view_id, callback));
     return;
   }
 
-  WebContents* web_contents =
+  content::WebContents* web_contents =
       tab_util::GetWebContentsByID(render_process_id, render_view_id);
   if (!web_contents) {
     // The tab may have gone away or the request may not be from a tab.
@@ -190,11 +185,10 @@
     DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
     return;
   }
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents->GetBrowserContext());
   RequestQuotaInfoBarDelegate::Create(
       infobar_service, this, origin_url, requested_quota,
-      profile->GetPrefs()->GetString(prefs::kAcceptLanguages),
+      Profile::FromBrowserContext(web_contents->GetBrowserContext())->
+          GetPrefs()->GetString(prefs::kAcceptLanguages),
       callback);
 }
 
@@ -203,9 +197,9 @@
     QuotaPermissionResponse response) {
   DCHECK_EQ(false, callback.is_null());
 
-  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
-    BrowserThread::PostTask(
-        BrowserThread::IO, FROM_HERE,
+  if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
+    content::BrowserThread::PostTask(
+        content::BrowserThread::IO, FROM_HERE,
         base::Bind(&ChromeQuotaPermissionContext::DispatchCallbackOnIOThread,
                    this, callback, response));
     return;
diff --git a/chrome/browser/chrome_to_mobile_service.cc b/chrome/browser/chrome_to_mobile_service.cc
index eebde18..8aafd71 100644
--- a/chrome/browser/chrome_to_mobile_service.cc
+++ b/chrome/browser/chrome_to_mobile_service.cc
@@ -14,6 +14,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chrome_to_mobile_service_factory.h"
 #include "chrome/browser/invalidation/invalidation_service.h"
 #include "chrome/browser/invalidation/invalidation_service_factory.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/cloud_print/cloud_print_constants.h"
 #include "chrome/common/cloud_print/cloud_print_helpers.h"
@@ -205,7 +205,7 @@
 // Call this as a BlockingPoolSequencedTask [after posting SubmitSnapshotFile].
 void DeleteSnapshotFile(const base::FilePath& snapshot) {
   DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-  bool success = base::Delete(snapshot, false);
+  bool success = base::DeleteFile(snapshot, false);
   DCHECK(success);
 }
 
@@ -252,7 +252,7 @@
 }
 
 // static
-void ChromeToMobileService::RegisterUserPrefs(
+void ChromeToMobileService::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(prefs::kChromeToMobileDeviceList,
                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
diff --git a/chrome/browser/chrome_to_mobile_service.h b/chrome/browser/chrome_to_mobile_service.h
index ee18dee..6740352 100644
--- a/chrome/browser/chrome_to_mobile_service.h
+++ b/chrome/browser/chrome_to_mobile_service.h
@@ -101,7 +101,7 @@
   static bool UpdateAndGetCommandState(Browser* browser);
 
   // Register the user prefs associated with this service.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   explicit ChromeToMobileService(Profile* profile);
   virtual ~ChromeToMobileService();
diff --git a/chrome/browser/chrome_to_mobile_service_unittest.cc b/chrome/browser/chrome_to_mobile_service_unittest.cc
index 3cc210ca..670b373 100644
--- a/chrome/browser/chrome_to_mobile_service_unittest.cc
+++ b/chrome/browser/chrome_to_mobile_service_unittest.cc
@@ -6,13 +6,13 @@
 
 #include "base/prefs/pref_service.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chrome_to_mobile_service_factory.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_command_controller.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/feature_switch.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
index f0617f7..f6e412e 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -13,8 +13,10 @@
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_member.h"
 #include "base/prefs/pref_service.h"
+#include "base/values.h"
 #include "chrome/browser/accessibility/accessibility_extension_api.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
 #include "chrome/browser/chromeos/login/login_display_host.h"
 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
@@ -27,11 +29,11 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/speech/tts_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_messages.h"
 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/login/login_state.h"
 #include "content/public/browser/browser_accessibility_state.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
@@ -139,6 +141,45 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 //
+// AccessibilityManager::PrefHandler
+
+AccessibilityManager::PrefHandler::PrefHandler(const char* pref_path)
+    : pref_path_(pref_path) {}
+
+AccessibilityManager::PrefHandler::~PrefHandler() {}
+
+void AccessibilityManager::PrefHandler::HandleProfileChanged(
+    Profile* previous_profile, Profile* current_profile) {
+  // Returns if the current profile is null.
+  if (!current_profile)
+    return;
+
+  // If the user set a pref value on the login screen and is now starting a
+  // session with a new profile, copy the pref value to the profile.
+  if ((previous_profile &&
+       ProfileHelper::IsSigninProfile(previous_profile) &&
+       current_profile->IsNewProfile() &&
+       !ProfileHelper::IsSigninProfile(current_profile)) ||
+      // Special case for Guest mode:
+      // Guest mode launches a guest-mode browser process before session starts,
+      // so the previous profile is null.
+      (!previous_profile &&
+       current_profile->IsGuestSession())) {
+    // Returns if the pref has not been set by the user.
+    const PrefService::Preference* pref = ProfileHelper::GetSigninProfile()->
+        GetPrefs()->FindPreference(pref_path_);
+    if (!pref || !pref->IsUserControlled())
+      return;
+
+    // Copy the pref value from the signin screen.
+    const base::Value* value_on_login = pref->GetValue();
+    PrefService* user_prefs = current_profile->GetPrefs();
+    user_prefs->Set(pref_path_, *value_on_login);
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
 // AccessibilityManager
 
 // static
@@ -161,6 +202,9 @@
 
 AccessibilityManager::AccessibilityManager()
     : profile_(NULL),
+      large_cursor_pref_handler_(prefs::kLargeCursorEnabled),
+      spoken_feedback_pref_handler_(prefs::kSpokenFeedbackEnabled),
+      high_contrast_pref_handler_(prefs::kHighContrastEnabled),
       large_cursor_enabled_(false),
       sticky_keys_enabled_(false),
       spoken_feedback_enabled_(false),
@@ -442,6 +486,7 @@
   local_state_pref_change_registrar_.reset();
 
   if (profile) {
+    // TODO(yoshiki): Move following code to PrefHandler.
     pref_change_registrar_.reset(new PrefChangeRegistrar);
     pref_change_registrar_->Init(profile->GetPrefs());
     pref_change_registrar_->Add(
@@ -474,6 +519,10 @@
             base::Unretained(this)));
   }
 
+  large_cursor_pref_handler_.HandleProfileChanged(profile_, profile);
+  spoken_feedback_pref_handler_.HandleProfileChanged(profile_, profile);
+  high_contrast_pref_handler_.HandleProfileChanged(profile_, profile);
+
   profile_ = profile;
   UpdateLargeCursorFromPref();
   UpdateStickyKeysFromPref();
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.h b/chrome/browser/chromeos/accessibility/accessibility_manager.h
index d181f01..cedfab6 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager.h
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager.h
@@ -43,6 +43,23 @@
   // Returns the existing instance. If there is no instance, returns NULL.
   static AccessibilityManager* Get();
 
+  // On a user's first login into a device, any a11y features enabled/disabled
+  // by the user on the login screen are enabled/disabled in the user's profile.
+  // This class watches for profile changes and copies settings into the user's
+  // profile when it detects a login with a newly created profile.
+  class PrefHandler {
+   public:
+    explicit PrefHandler(const char* pref_path);
+    virtual ~PrefHandler();
+
+    // Should be called from AccessibilityManager::SetProfile().
+    void HandleProfileChanged(Profile* previous_profile,
+                              Profile* current_profile);
+
+   private:
+    const char* pref_path_;
+  };
+
   // Enables or disables the large cursor.
   void EnableLargeCursor(bool enabled);
   // Returns true if the large cursor is enabled, or false if not.
@@ -104,6 +121,10 @@
   scoped_ptr<PrefChangeRegistrar> pref_change_registrar_;
   scoped_ptr<PrefChangeRegistrar> local_state_pref_change_registrar_;
 
+  PrefHandler large_cursor_pref_handler_;
+  PrefHandler spoken_feedback_pref_handler_;
+  PrefHandler high_contrast_pref_handler_;
+
   bool large_cursor_enabled_;
   bool sticky_keys_enabled_;
   bool spoken_feedback_enabled_;
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
index 1828444..8c44adc 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
@@ -9,15 +9,16 @@
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
 #include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
 #include "chrome/browser/chromeos/login/helper.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/user_manager_impl.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/chromeos_switches.h"
@@ -30,6 +31,10 @@
 
 const char kTestUserName[] = "owner@invalid.domain";
 
+// Test user name for locally managed user. The domain part must be matched
+// with UserManager::kLocallyManagedUserDomain.
+const char kTestLocallyManagedUserName[] = "test@locally-managed.localhost";
+
 class MockAccessibilityObserver : public content::NotificationObserver {
  public:
   MockAccessibilityObserver() : observed_(false),
@@ -120,18 +125,30 @@
   return GetProfile()->GetPrefs();
 }
 
-void SetLargeCursorEnabledToPref(bool enabled) {
+void SetLargeCursorEnabledPref(bool enabled) {
   GetPrefs()->SetBoolean(prefs::kLargeCursorEnabled, enabled);
 }
 
-void SetHighContrastEnabledToPref(bool enabled) {
+void SetHighContrastEnabledPref(bool enabled) {
   GetPrefs()->SetBoolean(prefs::kHighContrastEnabled, enabled);
 }
 
-void SetSpokenFeedbackEnabledToPref(bool enabled) {
+void SetSpokenFeedbackEnabledPref(bool enabled) {
   GetPrefs()->SetBoolean(prefs::kSpokenFeedbackEnabled, enabled);
 }
 
+bool GetLargeCursorEnabledFromPref() {
+  return GetPrefs()->GetBoolean(prefs::kLargeCursorEnabled);
+}
+
+bool GetHighContrastEnabledFromPref() {
+  return GetPrefs()->GetBoolean(prefs::kHighContrastEnabled);
+}
+
+bool GetSpokenFeedbackEnabledFromPref() {
+  return GetPrefs()->GetBoolean(prefs::kSpokenFeedbackEnabled);
+}
+
 }  // anonymouse namespace
 
 class AccessibilityManagerTest : public CrosInProcessBrowserTest {
@@ -146,6 +163,9 @@
   }
 
   virtual void SetUpOnMainThread() OVERRIDE {
+    // Sets the login-screen profile.
+    AccessibilityManager::Get()->
+        SetProfileForTest(ProfileHelper::GetSigninProfile());
   }
 
   content::NotificationRegistrar registrar_;
@@ -200,12 +220,12 @@
   EXPECT_FALSE(IsHighContrastEnabled());
 
   // Sets the pref as true to enable the large cursor.
-  SetLargeCursorEnabledToPref(true);
+  SetLargeCursorEnabledPref(true);
   // Confirms that the large cursor is enabled.
   EXPECT_TRUE(IsLargeCursorEnabled());
 
   // Sets the pref as true to enable the spoken feedback.
-  SetSpokenFeedbackEnabledToPref(true);
+  SetSpokenFeedbackEnabledPref(true);
   // Confirms that the spoken feedback is enabled.
   EXPECT_TRUE(IsSpokenFeedbackEnabled());
 
@@ -214,13 +234,13 @@
   // Confirms that the high contrast mode is enabled.
   EXPECT_TRUE(IsHighContrastEnabled());
 
-  SetLargeCursorEnabledToPref(false);
+  SetLargeCursorEnabledPref(false);
   EXPECT_FALSE(IsLargeCursorEnabled());
 
-  SetSpokenFeedbackEnabledToPref(false);
+  SetSpokenFeedbackEnabledPref(false);
   EXPECT_FALSE(IsSpokenFeedbackEnabled());
 
-  SetHighContrastEnabledToPref(false);
+  SetHighContrastEnabledPref(false);
   EXPECT_FALSE(IsHighContrastEnabled());
 }
 
@@ -229,15 +249,15 @@
   UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
 
   // Sets the pref to enable large cursor before login.
-  SetLargeCursorEnabledToPref(true);
+  SetLargeCursorEnabledPref(true);
   EXPECT_FALSE(IsLargeCursorEnabled());
 
   // Sets the pref to enable spoken feedback before login.
-  SetSpokenFeedbackEnabledToPref(true);
+  SetSpokenFeedbackEnabledPref(true);
   EXPECT_FALSE(IsSpokenFeedbackEnabled());
 
   // Sets the pref to enable high contrast before login.
-  SetHighContrastEnabledToPref(true);
+  SetHighContrastEnabledPref(true);
   EXPECT_FALSE(IsHighContrastEnabled());
 
   // Logs in.
@@ -303,7 +323,7 @@
   EXPECT_FALSE(observer.observed());
   observer.reset();
 
-  SetSpokenFeedbackEnabledToPref(true);
+  SetSpokenFeedbackEnabledPref(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
   EXPECT_EQ(observer.observed_type(),
@@ -311,7 +331,7 @@
   EXPECT_TRUE(IsSpokenFeedbackEnabled());
 
   observer.reset();
-  SetSpokenFeedbackEnabledToPref(false);
+  SetSpokenFeedbackEnabledPref(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
   EXPECT_EQ(observer.observed_type(),
@@ -319,7 +339,7 @@
   EXPECT_FALSE(IsSpokenFeedbackEnabled());
 
   observer.reset();
-  SetHighContrastEnabledToPref(true);
+  SetHighContrastEnabledPref(true);
   EXPECT_TRUE(observer.observed());
   EXPECT_TRUE(observer.observed_enabled());
   EXPECT_EQ(observer.observed_type(),
@@ -327,7 +347,7 @@
   EXPECT_TRUE(IsHighContrastEnabled());
 
   observer.reset();
-  SetHighContrastEnabledToPref(false);
+  SetHighContrastEnabledPref(false);
   EXPECT_TRUE(observer.observed());
   EXPECT_FALSE(observer.observed_enabled());
   EXPECT_EQ(observer.observed_type(),
@@ -335,4 +355,57 @@
   EXPECT_FALSE(IsHighContrastEnabled());
 }
 
+class AccessibilityManagerUserTypeTest
+    : public AccessibilityManagerTest,
+      public ::testing::WithParamInterface<const char*> {
+ protected:
+  AccessibilityManagerUserTypeTest() {}
+  virtual ~AccessibilityManagerUserTypeTest() {}
+
+  DISALLOW_COPY_AND_ASSIGN(AccessibilityManagerUserTypeTest);
+};
+
+// TODO(yoshiki): Enable a test for retail mode.
+INSTANTIATE_TEST_CASE_P(
+    UserTypeInstantiation,
+    AccessibilityManagerUserTypeTest,
+    ::testing::Values(kTestUserName,
+                      UserManager::kGuestUserName,
+                      //UserManager::kRetailModeUserName,
+                      kTestLocallyManagedUserName));
+
+IN_PROC_BROWSER_TEST_P(AccessibilityManagerUserTypeTest,
+                       EnableOnLoginScreenAndLogin) {
+  // Enables large cursor.
+  SetLargeCursorEnabled(true);
+  EXPECT_TRUE(IsLargeCursorEnabled());
+  // Enables spoken feedback.
+  SetSpokenFeedbackEnabled(true);
+  EXPECT_TRUE(IsSpokenFeedbackEnabled());
+  // Enables high contrast.
+  SetHighContrastEnabled(true);
+  EXPECT_TRUE(IsHighContrastEnabled());
+
+  // Logs in.
+  const char* user_name = GetParam();
+  UserManager::Get()->UserLoggedIn(user_name, user_name, true);
+
+  // Confirms that the features are still enabled just after login.
+  EXPECT_TRUE(IsLargeCursorEnabled());
+  EXPECT_TRUE(IsSpokenFeedbackEnabled());
+  EXPECT_TRUE(IsHighContrastEnabled());
+
+  UserManager::Get()->SessionStarted();
+
+  // Confirms that the features keep enabled after session starts.
+  EXPECT_TRUE(IsLargeCursorEnabled());
+  EXPECT_TRUE(IsSpokenFeedbackEnabled());
+  EXPECT_TRUE(IsHighContrastEnabled());
+
+  // Confirms that the prefs have been copied to the user's profile.
+  EXPECT_TRUE(GetLargeCursorEnabledFromPref());
+  EXPECT_TRUE(GetSpokenFeedbackEnabledFromPref());
+  EXPECT_TRUE(GetHighContrastEnabledFromPref());
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/accessibility/accessibility_util.cc b/chrome/browser/chromeos/accessibility/accessibility_util.cc
index 81759e6..04379c3 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_util.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_util.cc
@@ -9,7 +9,7 @@
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 // TODO(yoshiki): move the following method to accessibility_manager.cc and
 // remove this file.
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager.cc b/chrome/browser/chromeos/accessibility/magnification_manager.cc
index 84cdc21..b4b3bcb 100644
--- a/chrome/browser/chromeos/accessibility/magnification_manager.cc
+++ b/chrome/browser/chromeos/accessibility/magnification_manager.cc
@@ -15,12 +15,12 @@
 #include "base/memory/singleton.h"
 #include "base/prefs/pref_member.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_observer.h"
@@ -37,10 +37,14 @@
 class MagnificationManagerImpl : public MagnificationManager,
                                  public content::NotificationObserver {
  public:
-  MagnificationManagerImpl() : first_time_update_(true),
-                               profile_(NULL),
-                               type_(ash::kDefaultMagnifierType),
-                               enabled_(false) {
+  MagnificationManagerImpl()
+      : first_time_update_(true),
+        profile_(NULL),
+        magnifier_enabled_pref_handler_(prefs::kScreenMagnifierEnabled),
+        magnifier_type_pref_handler_(prefs::kScreenMagnifierType),
+        magnifier_scale_pref_handler_(prefs::kScreenMagnifierScale),
+        type_(ash::kDefaultMagnifierType),
+        enabled_(false) {
     registrar_.Add(this,
                    chrome::NOTIFICATION_LOGIN_WEBUI_VISIBLE,
                    content::NotificationService::AllSources());
@@ -106,6 +110,7 @@
     pref_change_registrar_.reset();
 
     if (profile) {
+      // TODO(yoshiki): Move following code to PrefHandler.
       pref_change_registrar_.reset(new PrefChangeRegistrar);
       pref_change_registrar_->Init(profile->GetPrefs());
       pref_change_registrar_->Add(
@@ -118,6 +123,10 @@
                      base::Unretained(this)));
     }
 
+    magnifier_enabled_pref_handler_.HandleProfileChanged(profile_, profile);
+    magnifier_type_pref_handler_.HandleProfileChanged(profile_, profile);
+    magnifier_scale_pref_handler_.HandleProfileChanged(profile_, profile);
+
     profile_ = profile;
     UpdateMagnifierFromPrefs();
   }
@@ -213,6 +222,11 @@
 
   bool first_time_update_;
   Profile* profile_;
+
+  AccessibilityManager::PrefHandler magnifier_enabled_pref_handler_;
+  AccessibilityManager::PrefHandler magnifier_type_pref_handler_;
+  AccessibilityManager::PrefHandler magnifier_scale_pref_handler_;
+
   ash::MagnifierType type_;
   bool enabled_;
   content::NotificationRegistrar registrar_;
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc b/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc
index 8a4daa8..d26100f 100644
--- a/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/magnification_manager_browsertest.cc
@@ -2,11 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <string>
+
 #include "ash/magnifier/magnification_controller.h"
 #include "ash/shell.h"
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
 #include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
@@ -16,7 +19,6 @@
 #include "chrome/browser/chromeos/login/user_manager_impl.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
@@ -30,6 +32,8 @@
 
 namespace {
 
+const char kTestUserName[] = "owner@invalid.domain";
+
 void SetMagnifierEnabled(bool enabled) {
   MagnificationManager::Get()->SetMagnifierEnabled(enabled);
 }
@@ -73,19 +77,35 @@
   return user_prefs::UserPrefs::Get(profile());
 }
 
-void EnableScreenManagnifierToPref(bool enabled) {
+void SetScreenMagnifierEnabledPref(bool enabled) {
   prefs()->SetBoolean(prefs::kScreenMagnifierEnabled, enabled);
 }
 
-void SetScreenManagnifierTypeToPref(ash::MagnifierType type) {
+void SetScreenMagnifierTypePref(ash::MagnifierType type) {
   prefs()->SetInteger(prefs::kScreenMagnifierType, type);
 }
 
-void SetFullScreenMagnifierScaleToPref(double scale) {
+void SetFullScreenMagnifierScalePref(double scale) {
   prefs()->SetDouble(prefs::kScreenMagnifierScale, scale);
 }
 
-}  // anonymouse namespace
+bool GetScreenMagnifierEnabledFromPref() {
+  return prefs()->GetBoolean(prefs::kScreenMagnifierEnabled);
+}
+
+// Creates and logs into a profile with account |name|, and makes sure that
+// the profile is regarded as "non new" in the next login. This is used in
+// PRE_XXX cases so that in the main XXX case we can test non new profiles.
+void PrepareNonNewProfile(const std::string& name) {
+  UserManager::Get()->UserLoggedIn(name, name, true);
+  // To prepare a non-new profile for tests, we must ensure the profile
+  // directory and the preference files are created, because that's what
+  // Profile::IsNewProfile() checks. UserLoggedIn(), however, does not yet
+  // create the profile directory until GetDefaultProfile() is called.
+  ProfileManager::GetDefaultProfile();
+}
+
+}  // namespace
 
 class MagnificationManagerTest : public CrosInProcessBrowserTest,
                                  public content::NotificationObserver {
@@ -136,20 +156,31 @@
   DISALLOW_COPY_AND_ASSIGN(MagnificationManagerTest);
 };
 
+IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginOffToOff) {
+  // Create a new profile once, to run the test with non-new profile.
+  PrepareNonNewProfile(kTestUserName);
+
+  // Sets pref to explicitly disable the magnifier.
+  SetScreenMagnifierEnabledPref(false);
+}
+
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginOffToOff) {
   // Confirms that magnifier is disabled on the login screen.
   EXPECT_FALSE(IsMagnifierEnabled());
 
-  // Logs in.
-  UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "owner@invalid.domain", true);
+  // Disables magnifier on login screen.
+  SetMagnifierEnabled(false);
+  EXPECT_FALSE(IsMagnifierEnabled());
+
+  // Logs in with existing profile.
+  UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
 
   // Confirms that magnifier is still disabled just after login.
   EXPECT_FALSE(IsMagnifierEnabled());
 
   UserManager::Get()->SessionStarted();
 
-  // Confirms that magnifier is still disabled just after login.
+  // Confirms that magnifier is still disabled just after session starts.
   EXPECT_FALSE(IsMagnifierEnabled());
 
   // Enables magnifier.
@@ -157,77 +188,196 @@
   // Confirms that magnifier is enabled.
   EXPECT_TRUE(IsMagnifierEnabled());
   EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
+  EXPECT_TRUE(GetScreenMagnifierEnabledFromPref());
+}
+
+IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginFullToOff) {
+  // Create a new profile once, to run the test with non-new profile.
+  PrepareNonNewProfile(kTestUserName);
+
+  // Sets pref to explicitly disable the magnifier.
+  SetScreenMagnifierEnabledPref(false);
 }
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginFullToOff) {
   // Confirms that magnifier is disabled on the login screen.
   EXPECT_FALSE(IsMagnifierEnabled());
 
-  // Enables magnifier on login scren.
+  // Enables magnifier on login screen.
   SetMagnifierEnabled(true);
+  SetMagnifierType(ash::MAGNIFIER_FULL);
+  SetFullScreenMagnifierScale(2.5);
+  EXPECT_TRUE(IsMagnifierEnabled());
+  EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
+  EXPECT_EQ(2.5, GetFullScreenMagnifierScale());
 
   // Logs in (but the session is not started yet).
-  UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "owner@invalid.domain", true);
+  UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
+
   // Confirms that magnifier is keeping enabled.
   EXPECT_TRUE(IsMagnifierEnabled());
   EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
 
   UserManager::Get()->SessionStarted();
 
-  // Confirms that magnifier is disabled just after login.
+  // Confirms that magnifier is disabled just after session start.
   EXPECT_FALSE(IsMagnifierEnabled());
+  EXPECT_FALSE(GetScreenMagnifierEnabledFromPref());
+}
+
+IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginOffToFull) {
+  // Create a new profile once, to run the test with non-new profile.
+  PrepareNonNewProfile(kTestUserName);
+
+  // Sets prefs to explicitly enable the magnifier.
+  SetScreenMagnifierEnabledPref(true);
+  SetScreenMagnifierTypePref(ash::MAGNIFIER_FULL);
+  SetFullScreenMagnifierScalePref(2.5);
 }
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginOffToFull) {
-  // Changes to full screen magnifier again and confirms that.
+  // Disables magnifier on login screen.
   SetMagnifierEnabled(false);
   EXPECT_FALSE(IsMagnifierEnabled());
 
   // Logs in (but the session is not started yet).
-  UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "owner@invalid.domain", true);
+  UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
 
   // Confirms that magnifier is keeping disabled.
   EXPECT_FALSE(IsMagnifierEnabled());
-  // Enable magnifier on the pref.
-  EnableScreenManagnifierToPref(true);
-  SetScreenManagnifierTypeToPref(ash::MAGNIFIER_FULL);
-  SetFullScreenMagnifierScaleToPref(2.5);
 
   UserManager::Get()->SessionStarted();
 
-  // Confirms that the prefs are successfully loaded.
+  // Confirms that the magnifier is enabled and configured according to the
+  // explicitly set prefs just after session start.
   EXPECT_TRUE(IsMagnifierEnabled());
   EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
   EXPECT_EQ(2.5, GetFullScreenMagnifierScale());
+  EXPECT_TRUE(GetScreenMagnifierEnabledFromPref());
+}
+
+IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginFullToFull) {
+  // Create a new profile once, to run the test with non-new profile.
+  PrepareNonNewProfile(kTestUserName);
+
+  // Sets prefs to explicitly enable the magnifier.
+  SetScreenMagnifierEnabledPref(true);
+  SetScreenMagnifierTypePref(ash::MAGNIFIER_FULL);
+  SetFullScreenMagnifierScalePref(2.5);
 }
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginFullToFull) {
-  // Changes to full screen magnifier again and confirms that.
+  // Enables magnifier on login screen.
+  SetMagnifierType(ash::MAGNIFIER_FULL);
+  SetMagnifierEnabled(true);
+  SetFullScreenMagnifierScale(3.0);
+  EXPECT_TRUE(IsMagnifierEnabled());
+  EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
+  EXPECT_EQ(3.0, GetFullScreenMagnifierScale());
+
+  // Logs in (but the session is not started yet).
+  UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
+
+  // Confirms that magnifier is keeping enabled.
+  EXPECT_TRUE(IsMagnifierEnabled());
+  EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
+
+  UserManager::Get()->SessionStarted();
+
+  // Confirms that the magnifier is enabled and configured according to the
+  // explicitly set prefs just after session start.
+  EXPECT_TRUE(IsMagnifierEnabled());
+  EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
+  EXPECT_EQ(2.5, GetFullScreenMagnifierScale());
+  EXPECT_TRUE(GetScreenMagnifierEnabledFromPref());
+}
+
+IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginFullToUnset) {
+  // Creates a new profile once, to run the test with non-new profile.
+  PrepareNonNewProfile(kTestUserName);
+}
+
+IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginFullToUnset) {
+  // Enables full screen magnifier.
   SetMagnifierType(ash::MAGNIFIER_FULL);
   SetMagnifierEnabled(true);
   EXPECT_TRUE(IsMagnifierEnabled());
   EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
 
   // Logs in (but the session is not started yet).
-  UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "owner@invalid.domain", true);
+  UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
 
   // Confirms that magnifier is keeping enabled.
   EXPECT_TRUE(IsMagnifierEnabled());
   EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
-  // Enable magnifier on the pref.
-  EnableScreenManagnifierToPref(true);
-  SetScreenManagnifierTypeToPref(ash::MAGNIFIER_FULL);
-  SetFullScreenMagnifierScaleToPref(2.5);
 
   UserManager::Get()->SessionStarted();
 
-  // Confirms that the prefs are successfully loaded.
+  // Confirms that magnifier is disabled.
+  EXPECT_FALSE(IsMagnifierEnabled());
+  EXPECT_FALSE(GetScreenMagnifierEnabledFromPref());
+}
+
+IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginAsNewUserOff) {
+  // Confirms that magnifier is disabled on the login screen.
+  EXPECT_FALSE(IsMagnifierEnabled());
+
+  // Disables magnifier on login screen explicitly.
+  SetMagnifierEnabled(false);
+
+  // Logs in (but the session is not started yet).
+  UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
+
+  // Confirms that magnifier is keeping disabled.
+  EXPECT_FALSE(IsMagnifierEnabled());
+
+  UserManager::Get()->SessionStarted();
+
+  // Confirms that magnifier is keeping disabled.
+  EXPECT_FALSE(IsMagnifierEnabled());
+  EXPECT_FALSE(GetScreenMagnifierEnabledFromPref());
+}
+
+IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginAsNewUserFull) {
+  // Enables magnifier on login screen.
+  SetMagnifierType(ash::MAGNIFIER_FULL);
+  SetMagnifierEnabled(true);
+  SetFullScreenMagnifierScale(2.5);
   EXPECT_TRUE(IsMagnifierEnabled());
   EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
   EXPECT_EQ(2.5, GetFullScreenMagnifierScale());
+
+  // Logs in (but the session is not started yet).
+  UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
+
+  // Confirms that magnifier is keeping enabled.
+  EXPECT_TRUE(IsMagnifierEnabled());
+  EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
+
+  UserManager::Get()->SessionStarted();
+
+  // Confirms that magnifier keeps enabled.
+  EXPECT_TRUE(IsMagnifierEnabled());
+  EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
+  EXPECT_EQ(2.5, GetFullScreenMagnifierScale());
+  EXPECT_TRUE(GetScreenMagnifierEnabledFromPref());
+}
+
+IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginAsNewUserUnset) {
+  // Confirms that magnifier is disabled on the login screen.
+  EXPECT_FALSE(IsMagnifierEnabled());
+
+  // Logs in (but the session is not started yet).
+  UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
+
+  // Confirms that magnifier is keeping disabled.
+  EXPECT_FALSE(IsMagnifierEnabled());
+
+  UserManager::Get()->SessionStarted();
+
+  // Confirms that magnifier is keeping disabled.
+  EXPECT_FALSE(IsMagnifierEnabled());
+  EXPECT_FALSE(GetScreenMagnifierEnabledFromPref());
 }
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, ChangeMagnifierType) {
@@ -289,38 +439,20 @@
 
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, TypePref) {
   // Logs in
-  UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "owner@invalid.domain", true);
+  UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
   UserManager::Get()->SessionStarted();
 
   // Confirms that magnifier is disabled just after login.
   EXPECT_FALSE(IsMagnifierEnabled());
 
   // Sets the pref as true to enable magnifier.
-  SetScreenManagnifierTypeToPref(ash::MAGNIFIER_FULL);
-  EnableScreenManagnifierToPref(true);
+  SetScreenMagnifierTypePref(ash::MAGNIFIER_FULL);
+  SetScreenMagnifierEnabledPref(true);
   // Confirms that magnifier is enabled.
   EXPECT_TRUE(IsMagnifierEnabled());
   EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
 }
 
-IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, ResumeSavedTypeFullPref) {
-  // Loads the profile of the user.
-  UserManager::Get()->UserLoggedIn(
-      "owner@invalid.domain", "owner@invalid.domain", true);
-
-  // Sets the pref as true to enable magnifier before login.
-  EnableScreenManagnifierToPref(true);
-  SetScreenManagnifierTypeToPref(ash::MAGNIFIER_FULL);
-
-  // Logs in.
-  UserManager::Get()->SessionStarted();
-
-  // Confirms that magnifier is enabled just after login.
-  EXPECT_TRUE(IsMagnifierEnabled());
-  EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType());
-}
-
 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, ScalePref) {
   SetMagnifierEnabled(false);
   EXPECT_FALSE(IsMagnifierEnabled());
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager_unittest.cc b/chrome/browser/chromeos/accessibility/magnification_manager_unittest.cc
index a6b7675..864af45 100644
--- a/chrome/browser/chromeos/accessibility/magnification_manager_unittest.cc
+++ b/chrome/browser/chromeos/accessibility/magnification_manager_unittest.cc
@@ -7,7 +7,7 @@
 #include "ash/magnifier/magnifier_constants.h"
 #include "ash/test/ash_test_base.h"
 #include "base/prefs/pref_service.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc
index 639d07f..524c98b 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc
@@ -52,7 +52,7 @@
   DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
 
   base::FilePath dir = icon_path.DirName();
-  if (!file_util::PathExists(dir))
+  if (!base::PathExists(dir))
     CHECK(file_util::CreateDirectory(dir));
 
   CHECK_EQ(static_cast<int>(raw_icon->size()),
@@ -277,7 +277,7 @@
   if (!icon_path_.empty()) {
     BrowserThread::PostBlockingPoolTask(
         FROM_HERE,
-        base::Bind(base::IgnoreResult(&base::Delete), icon_path_, false));
+        base::Bind(base::IgnoreResult(&base::DeleteFile), icon_path_, false));
   }
 }
 
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
index 8d1ae98..8d81e81 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -15,6 +15,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/stl_util.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_data.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/chromeos/settings/owner_key_util.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chromeos/cryptohome/async_method_caller.h"
 #include "chromeos/cryptohome/cryptohome_library.h"
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
index 51f6b1f..fdb800f 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
@@ -198,14 +198,16 @@
 };
 
 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, Basic) {
-  // Add a couple of apps.
-  manager()->AddApp("app_1");
-  manager()->AddApp("app_2");
-  EXPECT_EQ("app_1,app_2", GetAppIds());
+  // Add a couple of apps. Use "fake_app_x" that do not have data on the test
+  // server to avoid pending data loads that could be lingering on tear down and
+  // cause DCHECK failure in utility_process_host_impl.cc.
+  manager()->AddApp("fake_app_1");
+  manager()->AddApp("fake_app_2");
+  EXPECT_EQ("fake_app_1,fake_app_2", GetAppIds());
 
   // Set an auto launch app.
-  manager()->SetAutoLaunchApp("app_1");
-  EXPECT_EQ("app_1", manager()->GetAutoLaunchApp());
+  manager()->SetAutoLaunchApp("fake_app_1");
+  EXPECT_EQ("fake_app_1", manager()->GetAutoLaunchApp());
 
   // Clear the auto launch app.
   manager()->SetAutoLaunchApp("");
@@ -213,8 +215,8 @@
   EXPECT_FALSE(manager()->IsAutoLaunchEnabled());
 
   // Set another auto launch app.
-  manager()->SetAutoLaunchApp("app_2");
-  EXPECT_EQ("app_2", manager()->GetAutoLaunchApp());
+  manager()->SetAutoLaunchApp("fake_app_2");
+  EXPECT_EQ("fake_app_2", manager()->GetAutoLaunchApp());
 
   // Check auto launch permissions.
   EXPECT_FALSE(manager()->IsAutoLaunchEnabled());
@@ -222,20 +224,18 @@
   EXPECT_TRUE(manager()->IsAutoLaunchEnabled());
 
   // Remove the auto launch app.
-  manager()->RemoveApp("app_2");
-  EXPECT_EQ("app_1", GetAppIds());
+  manager()->RemoveApp("fake_app_2");
+  EXPECT_EQ("fake_app_1", GetAppIds());
   EXPECT_EQ("", manager()->GetAutoLaunchApp());
 
   // Set a none exist app as auto launch.
-  TestKioskAppManagerObserver observer(manager());
   manager()->SetAutoLaunchApp("none_exist_app");
   EXPECT_EQ("", manager()->GetAutoLaunchApp());
   EXPECT_FALSE(manager()->IsAutoLaunchEnabled());
 
-  // Add an exist app again.
-  observer.Reset();
-  manager()->AddApp("app_1");
-  EXPECT_EQ("app_1", GetAppIds());
+  // Add an existing app again.
+  manager()->AddApp("fake_app_1");
+  EXPECT_EQ("fake_app_1", GetAppIds());
 }
 
 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, LoadCached) {
diff --git a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
index b1d38b4..b0ee4e9 100644
--- a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
+++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
@@ -11,6 +11,7 @@
 #include "base/path_service.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/app_mode/app_session_lifetime.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
@@ -22,7 +23,6 @@
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/signin/token_service_factory.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
diff --git a/chrome/browser/chromeos/attestation/attestation_ca_client.cc b/chrome/browser/chromeos/attestation/attestation_ca_client.cc
index 69d162e..4a9aca6 100644
--- a/chrome/browser/chromeos/attestation/attestation_ca_client.cc
+++ b/chrome/browser/chromeos/attestation/attestation_ca_client.cc
@@ -7,11 +7,11 @@
 #include <string>
 
 #include "chrome/browser/browser_process.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/load_flags.h"
 #include "net/http/http_status_code.h"
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_request_status.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/chromeos/attestation/attestation_policy_observer.cc b/chrome/browser/chromeos/attestation/attestation_policy_observer.cc
index 7028f5c..04df748 100644
--- a/chrome/browser/chromeos/attestation/attestation_policy_observer.cc
+++ b/chrome/browser/chromeos/attestation/attestation_policy_observer.cc
@@ -10,12 +10,12 @@
 #include "base/callback.h"
 #include "base/location.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h"
 #include "chrome/browser/chromeos/attestation/attestation_key_payload.pb.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/policy/cloud/cloud_policy_client.h"
 #include "chrome/browser/policy/cloud/cloud_policy_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chromeos/attestation/attestation_flow.h"
 #include "chromeos/cryptohome/async_method_caller.h"
 #include "chromeos/dbus/cryptohome_client.h"
diff --git a/chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.cc b/chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.cc
index b43afdb..fcd602a 100644
--- a/chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.cc
+++ b/chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.cc
@@ -12,8 +12,8 @@
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/audio/audio_device.h"
 #include "chromeos/audio/cras_audio_handler.h"
diff --git a/chrome/browser/chromeos/audio/audio_handler.cc b/chrome/browser/chromeos/audio/audio_handler.cc
index cab32bb..b45ea0d 100644
--- a/chrome/browser/chromeos/audio/audio_handler.cc
+++ b/chrome/browser/chromeos/audio/audio_handler.cc
@@ -19,7 +19,7 @@
 #endif
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/audio/audio_pref_handler.h"
 
diff --git a/chrome/browser/chromeos/audio/audio_pref_handler_impl.cc b/chrome/browser/chromeos/audio/audio_pref_handler_impl.cc
index 71b53a0..2cc885e 100644
--- a/chrome/browser/chromeos/audio/audio_pref_handler_impl.cc
+++ b/chrome/browser/chromeos/audio/audio_pref_handler_impl.cc
@@ -12,7 +12,7 @@
 #include "base/logging.h"
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 
 using std::max;
diff --git a/chrome/browser/chromeos/background/ash_user_wallpaper_delegate.cc b/chrome/browser/chromeos/background/ash_user_wallpaper_delegate.cc
index 8e2cb65..16709fb 100644
--- a/chrome/browser/chromeos/background/ash_user_wallpaper_delegate.cc
+++ b/chrome/browser/chromeos/background/ash_user_wallpaper_delegate.cc
@@ -9,6 +9,7 @@
 #include "ash/wm/window_animations.h"
 #include "base/command_line.h"
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/extensions/wallpaper_manager_util.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/wallpaper_manager.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/chrome_pages.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/login/login_state.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/chromeos/boot_times_loader.cc b/chrome/browser/chromeos/boot_times_loader.cc
index a9919ae..12c3ce3 100644
--- a/chrome/browser/chromeos/boot_times_loader.cc
+++ b/chrome/browser/chromeos/boot_times_loader.cc
@@ -23,11 +23,11 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/authentication_notification_details.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_controller.h"
@@ -198,7 +198,7 @@
   static const base::FilePath::CharType kBootTimesSent[] =
       FPL("/tmp/boot-times-sent");
   base::FilePath sent(kBootTimesSent);
-  if (file_util::PathExists(sent))
+  if (base::PathExists(sent))
     return;
 
   UMA_HISTOGRAM_TIMES("BootTime.Total",
@@ -228,7 +228,7 @@
                                                    boot_times.system,
                                                    boot_times.chrome);
   file_util::WriteFile(sent, boot_times_text.data(), boot_times_text.size());
-  DCHECK(file_util::PathExists(sent));
+  DCHECK(base::PathExists(sent));
 }
 
 void BootTimesLoader::Backend::GetBootTimesAndRunCallback(
@@ -250,7 +250,7 @@
   // Wait until firmware-boot-time file exists by reposting.
   base::FilePath log_dir(kLogPath);
   base::FilePath log_file = log_dir.Append(kFirmwareBootTime);
-  if (!file_util::PathExists(log_file)) {
+  if (!base::PathExists(log_file)) {
     BrowserThread::PostDelayedTask(
         BrowserThread::FILE,
         FROM_HERE,
diff --git a/chrome/browser/chromeos/camera_detector.cc b/chrome/browser/chromeos/camera_detector.cc
index 9737884..f790667 100644
--- a/chrome/browser/chromeos/camera_detector.cc
+++ b/chrome/browser/chromeos/camera_detector.cc
@@ -48,7 +48,7 @@
   presence_check_in_progress_ = true;
   base::PostTaskAndReplyWithResult(
       BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
-          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN),
+          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN).get(),
       FROM_HERE,
       base::Bind(&CameraDetector::CheckPresence),
       base::Bind(&CameraDetector::OnPresenceCheckDone, callback));
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index 834916c..e857e2d 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -23,6 +23,7 @@
 #include "base/strings/string_split.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part_chromeos.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
@@ -32,7 +33,6 @@
 #include "chrome/browser/chromeos/boot_times_loader.h"
 #include "chrome/browser/chromeos/contacts/contact_manager.h"
 #include "chrome/browser/chromeos/cros/cert_library.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/dbus/cros_dbus_service.h"
 #include "chrome/browser/chromeos/display/display_configuration_observer.h"
 #include "chrome/browser/chromeos/extensions/default_app_order.h"
@@ -71,7 +71,6 @@
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chrome/browser/chromeos/settings/owner_key_util.h"
 #include "chrome/browser/chromeos/swap_metrics.h"
-#include "chrome/browser/chromeos/system/device_change_handler.h"
 #include "chrome/browser/chromeos/system/statistics_provider.h"
 #include "chrome/browser/chromeos/system_key_event_listener.h"
 #include "chrome/browser/chromeos/upgrade_detector_chromeos.h"
@@ -85,7 +84,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/rlz/rlz.h"
 #include "chrome/browser/storage_monitor/storage_monitor_chromeos.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
@@ -125,13 +123,10 @@
 
 namespace {
 
-#if defined(USE_LINUX_BREAKPAD)
 void ChromeOSVersionCallback(const std::string& version) {
   base::SetLinuxDistro(std::string("CrOS ") + version);
 }
 
-#endif
-
 class MessageLoopObserver : public base::MessageLoopForUI::Observer {
   virtual base::EventStatus WillProcessEvent(
       const base::NativeEvent& event) OVERRIDE {
@@ -161,9 +156,7 @@
         g_browser_process->profile_manager()->GetDefaultProfile(),
         UserContext(username,
                     password,
-                    std::string()),  // auth_code
-        std::string(),   // login_token
-        std::string());  // login_captcha
+                    std::string()));  // auth_code
   }
 
   virtual ~StubLogin() {
@@ -207,8 +200,7 @@
 
 bool ShouldAutoLaunchKioskApp(const CommandLine& command_line) {
   KioskAppManager* app_manager = KioskAppManager::Get();
-  return !command_line.HasSwitch(switches::kDisableAppMode) &&
-      command_line.HasSwitch(switches::kLoginManager) &&
+  return command_line.HasSwitch(switches::kLoginManager) &&
       !command_line.HasSwitch(switches::kForceLoginManagerInTests) &&
       app_manager->IsAutoLaunchEnabled() &&
       KioskAppLaunchError::Get() == KioskAppLaunchError::NONE;
@@ -225,14 +217,11 @@
     if (KioskModeSettings::Get()->IsKioskModeEnabled())
       InitializeKioskModeScreensaver();
 
-    // If app mode is enabled, reset reboot after update flag when login
-    // screen is shown.
-    if (!parsed_command_line.HasSwitch(switches::kDisableAppMode)) {
-      if (!g_browser_process->browser_policy_connector()->
-          IsEnterpriseManaged()) {
-        PrefService* local_state = g_browser_process->local_state();
-        local_state->ClearPref(prefs::kRebootAfterUpdate);
-      }
+    // Reset reboot after update flag when login screen is shown.
+    if (!g_browser_process->browser_policy_connector()->
+        IsEnterpriseManaged()) {
+      PrefService* local_state = g_browser_process->local_state();
+      local_state->ClearPref(prefs::kRebootAfterUpdate);
     }
   } else if (parsed_command_line.HasSwitch(switches::kLoginUser) &&
              parsed_command_line.HasSwitch(switches::kLoginPassword)) {
@@ -270,15 +259,7 @@
 class DBusServices {
  public:
   explicit DBusServices(const content::MainFunctionParams& parameters)
-      : cros_initialized_(false) {
-    // Initialize CrosLibrary only for the browser, unless running tests
-    // (which do their own CrosLibrary setup).
-    if (!parameters.ui_task) {
-      const bool use_stub = !base::chromeos::IsRunningOnChromeOS();
-      CrosLibrary::Initialize(use_stub);
-      cros_initialized_ = true;
-    }
-
+      : network_library_initialized_(false) {
     if (!base::chromeos::IsRunningOnChromeOS()) {
       // Override this path on the desktop, so that the user policy key can be
       // stored by the stub SessionManagerClient.
@@ -306,6 +287,15 @@
     disks::DiskMountManager::Initialize();
     cryptohome::AsyncMethodCaller::Initialize();
 
+    // Initialize NetworkLibrary only for the browser, unless running tests
+    // (which do their own NetworkLibrary setup with
+    // ScopedStubNetworkLibraryEnabler in InProcessBrowserTest).
+    if (!parameters.ui_task) {
+      const bool use_stub = !base::chromeos::IsRunningOnChromeOS();
+      NetworkLibrary::Initialize(use_stub);
+      network_library_initialized_ = true;
+    }
+
     // Always initialize these handlers which should not conflict with
     // NetworkLibrary.
     NetworkHandler::Initialize();
@@ -343,16 +333,11 @@
 
   ~DBusServices() {
     ConnectivityStateHelper::Shutdown();
-    // CrosLibrary is shut down before DBusThreadManager even though it
-    // is initialized first becuase some of its libraries depend on DBus
-    // clients.
-    // TODO(hashimoto): Resolve this situation by removing CrosLibrary.
-    // (crosbug.com/26160)
-    if (cros_initialized_ && CrosLibrary::Get())
-      CrosLibrary::Shutdown();
 
     CertLibrary::Shutdown();
     NetworkHandler::Shutdown();
+    if (network_library_initialized_)
+      NetworkLibrary::Shutdown();
 
     cryptohome::AsyncMethodCaller::Shutdown();
     disks::DiskMountManager::Shutdown();
@@ -368,7 +353,7 @@
   }
 
  private:
-  bool cros_initialized_;
+  bool network_library_initialized_;
 
   DISALLOW_COPY_AND_ASSIGN(DBusServices);
 };
@@ -564,11 +549,9 @@
   // TimezoneSettings and CrosSettings.
   WallpaperManager::Get()->AddObservers();
 
-#if defined(USE_LINUX_BREAKPAD)
   cros_version_loader_.GetVersion(VersionLoader::VERSION_FULL,
                                   base::Bind(&ChromeOSVersionCallback),
                                   &tracker_);
-#endif
 
   storage_monitor_.reset(new StorageMonitorCros());
 
@@ -607,13 +590,6 @@
   //    i.e. not on Chrome OS device w/o login flow.
   if (parsed_command_line().HasSwitch(switches::kLoginUser) &&
       !parsed_command_line().HasSwitch(switches::kLoginPassword)) {
-    // Make sure we flip every profile to not share proxies if the user hasn't
-    // specified so explicitly.
-    const PrefService::Preference* use_shared_proxies_pref =
-        profile()->GetPrefs()->FindPreference(prefs::kUseSharedProxies);
-    if (use_shared_proxies_pref->IsDefaultValue())
-      profile()->GetPrefs()->SetBoolean(prefs::kUseSharedProxies, false);
-
     // This is done in LoginUtils::OnProfileCreated during normal login.
     LoginUtils::Get()->InitRlzDelayed(profile());
 
@@ -698,9 +674,6 @@
   // available.
   idle_action_warning_observer_.reset(new IdleActionWarningObserver());
 
-  // Listen to changes in device hierarchy.
-  device_change_handler_.reset(new system::DeviceChangeHandler());
-
   ChromeBrowserMainPartsLinux::PostProfileInit();
 }
 
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
index fbcba38..97e0310 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
@@ -44,10 +44,6 @@
 class DBusServices;
 }
 
-namespace system {
-class DeviceChangeHandler;
-}
-
 class ChromeBrowserMainPartsChromeos : public ChromeBrowserMainPartsLinux {
  public:
   explicit ChromeBrowserMainPartsChromeos(
@@ -87,7 +83,6 @@
   scoped_ptr<VideoActivityNotifier> video_activity_notifier_;
   scoped_ptr<StorageMonitorCros> storage_monitor_;
   scoped_ptr<IdleActionWarningObserver> idle_action_warning_observer_;
-  scoped_ptr<system::DeviceChangeHandler> device_change_handler_;
   scoped_ptr<SwapMetrics> swap_metrics_;
 
   scoped_ptr<internal::DBusServices> dbus_services_;
diff --git a/chrome/browser/chromeos/contacts/contact_database.cc b/chrome/browser/chromeos/contacts/contact_database.cc
index cfff9b2..04eb2e8 100644
--- a/chrome/browser/chromeos/contacts/contact_database.cc
+++ b/chrome/browser/chromeos/contacts/contact_database.cc
@@ -181,6 +181,7 @@
 
   leveldb::Options options;
   options.create_if_missing = true;
+  options.max_open_files = 0;  // Use minimum.
   bool delete_and_retry_on_corruption = true;
 
   while (true) {
@@ -200,7 +201,7 @@
     // Delete the existing database and try again (just once, though).
     if (status.IsCorruption() && delete_and_retry_on_corruption) {
       LOG(WARNING) << "Deleting possibly-corrupt database";
-      base::Delete(database_dir, true);
+      base::DeleteFile(database_dir, true);
       delete_and_retry_on_corruption = false;
       histogram_result = HISTOGRAM_INIT_RESULT_DELETED_CORRUPTED;
     } else {
diff --git a/chrome/browser/chromeos/contacts/contact_manager.cc b/chrome/browser/chromeos/contacts/contact_manager.cc
index 100ebd0..76694e0 100644
--- a/chrome/browser/chromeos/contacts/contact_manager.cc
+++ b/chrome/browser/chromeos/contacts/contact_manager.cc
@@ -6,13 +6,13 @@
 
 #include "base/logging.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/contacts/contact.pb.h"
 #include "chrome/browser/chromeos/contacts/contact_manager_observer.h"
 #include "chrome/browser/chromeos/contacts/contact_store.h"
 #include "chrome/browser/chromeos/contacts/google_contact_store.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/chromeos/contacts/contact_manager_unittest.cc b/chrome/browser/chromeos/contacts/contact_manager_unittest.cc
index 237ae7a..6f07354 100644
--- a/chrome/browser/chromeos/contacts/contact_manager_unittest.cc
+++ b/chrome/browser/chromeos/contacts/contact_manager_unittest.cc
@@ -9,11 +9,11 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/contacts/contact.pb.h"
 #include "chrome/browser/chromeos/contacts/contact_manager_observer.h"
 #include "chrome/browser/chromeos/contacts/contact_test_util.h"
 #include "chrome/browser/chromeos/contacts/fake_contact_store.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/chromeos/contacts/gdata_contacts_service.cc b/chrome/browser/chromeos/contacts/gdata_contacts_service.cc
index 12e4161..d95f66d 100644
--- a/chrome/browser/chromeos/contacts/gdata_contacts_service.cc
+++ b/chrome/browser/chromeos/contacts/gdata_contacts_service.cc
@@ -16,6 +16,7 @@
 #include "base/metrics/histogram.h"
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
+#include "base/threading/sequenced_worker_pool.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "base/values.h"
@@ -856,10 +857,12 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   std::vector<std::string> scopes;
   scopes.push_back(kContactsScope);
-  sender_.reset(new google_apis::RequestSender(profile,
-                                               url_request_context_getter,
-                                               scopes,
-                                               "" /* custom_user_agent */));
+  sender_.reset(new google_apis::RequestSender(
+      profile,
+      url_request_context_getter,
+      content::BrowserThread::GetBlockingPool(),
+      scopes,
+      "" /* custom_user_agent */));
 }
 
 GDataContactsService::~GDataContactsService() {
diff --git a/chrome/browser/chromeos/contacts/gdata_contacts_service.h b/chrome/browser/chromeos/contacts/gdata_contacts_service.h
index 47f30ef..36b61d1 100644
--- a/chrome/browser/chromeos/contacts/gdata_contacts_service.h
+++ b/chrome/browser/chromeos/contacts/gdata_contacts_service.h
@@ -14,7 +14,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
 #include "base/time/time.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Profile;
 
diff --git a/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc b/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc
index 07375ca..e83174f 100644
--- a/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc
+++ b/chrome/browser/chromeos/cros/cros_in_process_browser_test.cc
@@ -3,19 +3,169 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
+#include "chrome/browser/chromeos/cros/mock_network_library.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "testing/gmock/include/gmock/gmock.h"
 
 namespace chromeos {
 
-CrosInProcessBrowserTest::CrosInProcessBrowserTest() {
-  cros_mock_.reset(new CrosMock());
+using ::testing::AnyNumber;
+using ::testing::AtMost;
+using ::testing::InSequence;
+using ::testing::InvokeWithoutArgs;
+using ::testing::Return;
+using ::testing::ReturnRef;
+using ::testing::StrictMock;
+using ::testing::_;
+
+CrosInProcessBrowserTest::CrosInProcessBrowserTest() :
+    mock_network_library_(NULL) {
 }
 
 CrosInProcessBrowserTest::~CrosInProcessBrowserTest() {
 }
 
+void CrosInProcessBrowserTest::InitStatusAreaMocks() {
+  if (mock_network_library_)
+    return;
+  mock_network_library_ = new StrictMock<MockNetworkLibrary>();
+  NetworkLibrary::SetForTesting(mock_network_library_);
+}
+
+void CrosInProcessBrowserTest::SetStatusAreaMocksExpectations() {
+  // We don't care how often these are called, just set their return values:
+  EXPECT_CALL(*mock_network_library_, AddNetworkProfileObserver(_))
+      .Times(AnyNumber());
+  EXPECT_CALL(*mock_network_library_, AddNetworkManagerObserver(_))
+      .Times(AnyNumber());
+  EXPECT_CALL(*mock_network_library_, AddNetworkDeviceObserver(_, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*mock_network_library_, RemoveNetworkProfileObserver(_))
+      .Times(AnyNumber());
+  EXPECT_CALL(*mock_network_library_, RemoveNetworkManagerObserver(_))
+      .Times(AnyNumber());
+  EXPECT_CALL(*mock_network_library_, RemoveNetworkDeviceObserver(_, _))
+      .Times(AnyNumber());
+  EXPECT_CALL(*mock_network_library_, RemoveObserverForAllNetworks(_))
+      .Times(AnyNumber());
+  EXPECT_CALL(*mock_network_library_, FindCellularDevice())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return((const NetworkDevice*)(NULL))));
+  EXPECT_CALL(*mock_network_library_, FindEthernetDevice())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return((const NetworkDevice*)(NULL))));
+  EXPECT_CALL(*mock_network_library_, ethernet_available())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(true)));
+  EXPECT_CALL(*mock_network_library_, wifi_available())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)));
+  EXPECT_CALL(*mock_network_library_, wimax_available())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)));
+  EXPECT_CALL(*mock_network_library_, cellular_available())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)));
+  EXPECT_CALL(*mock_network_library_, ethernet_enabled())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(true)));
+  EXPECT_CALL(*mock_network_library_, wifi_enabled())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)));
+  EXPECT_CALL(*mock_network_library_, wimax_enabled())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)));
+  EXPECT_CALL(*mock_network_library_, cellular_enabled())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)));
+  EXPECT_CALL(*mock_network_library_, active_network())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return((const Network*)(NULL))));
+  EXPECT_CALL(*mock_network_library_, active_nonvirtual_network())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return((const Network*)(NULL))));
+  EXPECT_CALL(*mock_network_library_, ethernet_network())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return((const EthernetNetwork*)(NULL))));
+  EXPECT_CALL(*mock_network_library_, wifi_network())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return((const WifiNetwork*)(NULL))));
+  EXPECT_CALL(*mock_network_library_, wimax_network())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return((const WimaxNetwork*)(NULL))));
+  EXPECT_CALL(*mock_network_library_, cellular_network())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return((const CellularNetwork*)(NULL))));
+  EXPECT_CALL(*mock_network_library_, virtual_network())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return((const VirtualNetwork*)(NULL))));
+  EXPECT_CALL(*mock_network_library_, wifi_networks())
+      .Times(AnyNumber())
+      .WillRepeatedly((ReturnRef(wifi_networks_)));
+  EXPECT_CALL(*mock_network_library_, wimax_networks())
+      .Times(AnyNumber())
+      .WillRepeatedly((ReturnRef(wimax_networks_)));
+  EXPECT_CALL(*mock_network_library_, cellular_networks())
+      .Times(AnyNumber())
+      .WillRepeatedly((ReturnRef(cellular_networks_)));
+  EXPECT_CALL(*mock_network_library_, virtual_networks())
+      .Times(AnyNumber())
+      .WillRepeatedly((ReturnRef(virtual_networks_)));
+  EXPECT_CALL(*mock_network_library_, connected_network())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return((const Network*)(NULL))));
+  EXPECT_CALL(*mock_network_library_, connecting_network())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return((const Network*)(NULL))));
+  EXPECT_CALL(*mock_network_library_, virtual_network_connected())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)));
+  EXPECT_CALL(*mock_network_library_, wifi_scanning())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)));
+  EXPECT_CALL(*mock_network_library_, cellular_initializing())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)));
+  EXPECT_CALL(*mock_network_library_, LoadOncNetworks(_, _))
+        .Times(AnyNumber());
+
+  // Set specific expectations for interesting functions:
+
+  // NetworkMenuButton::OnNetworkChanged() calls:
+  EXPECT_CALL(*mock_network_library_, Connected())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*mock_network_library_, Connecting())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*mock_network_library_, cellular_connected())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)))
+      .RetiresOnSaturation();
+
+  // NetworkMenu::InitMenuItems() calls:
+  EXPECT_CALL(*mock_network_library_, ethernet_connected())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*mock_network_library_, ethernet_connecting())
+      .Times(AnyNumber())
+      .WillRepeatedly((Return(false)))
+      .RetiresOnSaturation();
+}
+
+void CrosInProcessBrowserTest::SetUpInProcessBrowserTestFixture() {
+  InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
+
+  InitStatusAreaMocks();
+  SetStatusAreaMocksExpectations();
+}
+
 void CrosInProcessBrowserTest::TearDownInProcessBrowserTestFixture() {
-  cros_mock_->TearDownMocks();
+  // Prevent bogus gMock leak check from firing.
+  NetworkLibrary::Shutdown();
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/cros/cros_in_process_browser_test.h b/chrome/browser/chromeos/cros/cros_in_process_browser_test.h
index 77b2ca3..f75a973 100644
--- a/chrome/browser/chromeos/cros/cros_in_process_browser_test.h
+++ b/chrome/browser/chromeos/cros/cros_in_process_browser_test.h
@@ -5,31 +5,45 @@
 #ifndef CHROME_BROWSER_CHROMEOS_CROS_CROS_IN_PROCESS_BROWSER_TEST_H_
 #define CHROME_BROWSER_CHROMEOS_CROS_CROS_IN_PROCESS_BROWSER_TEST_H_
 
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/chromeos/cros/cros_mock.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/test/base/in_process_browser_test.h"
 
 namespace chromeos {
 
+class MockNetworkLibrary;
+
 // Base class for Chromium OS tests wanting to bring up a browser in the
-// unit test process and mock some parts of CrosLibrary. Once you mock part of
-// CrosLibrary it will be considered as successfully loaded and libraries
-// that compose CrosLibrary will be created. Use CrosMock to specify minimum
-// set of mocks for you test to succeed.
-// See comments for InProcessBrowserTest base class too.
+// browser test process and provide MockNetworkLibrary with preset behaviors.
 class CrosInProcessBrowserTest : public InProcessBrowserTest {
  public:
   CrosInProcessBrowserTest();
   virtual ~CrosInProcessBrowserTest();
 
- protected:
-  scoped_ptr<CrosMock> cros_mock_;
-
-  // Overriden for things you would normally override TearDown for.
+  // InProcessBrowserTest overrides:
+  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE;
   virtual void TearDownInProcessBrowserTestFixture() OVERRIDE;
 
  private:
+  // Sets up basic mocks that are used by status area items.
+  void InitStatusAreaMocks();
+
+  // Sets up corresponding expectations for basic mocks that
+  // are used by status area items.
+  // Make sure that InitStatusAreaMocks was called before.
+  // They are all configured with RetiresOnSaturation().
+  // Once such expectation is used it won't block expectations you've defined.
+  void SetStatusAreaMocksExpectations();
+
+  // Destroyed by NetworkLibrary::Shutdown().
+  MockNetworkLibrary* mock_network_library_;
+
+  // Stuff used for mock_network_library_.
+  WifiNetworkVector wifi_networks_;
+  WimaxNetworkVector wimax_networks_;
+  CellularNetworkVector cellular_networks_;
+  VirtualNetworkVector virtual_networks_;
+  std::string empty_string_;
+
   DISALLOW_COPY_AND_ASSIGN(CrosInProcessBrowserTest);
 };
 
diff --git a/chrome/browser/chromeos/cros/cros_library.cc b/chrome/browser/chromeos/cros/cros_library.cc
deleted file mode 100644
index abe5095..0000000
--- a/chrome/browser/chromeos/cros/cros_library.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/cros/cros_library.h"
-
-#include "chrome/browser/chromeos/cros/network_library.h"
-
-#define DEFINE_GET_LIBRARY_METHOD(class_prefix, var_prefix)                    \
-class_prefix##Library* CrosLibrary::Get##class_prefix##Library() {             \
-  return var_prefix##_lib_.GetDefaultImpl(use_stub_impl_);                     \
-}
-
-#define DEFINE_SET_LIBRARY_METHOD(class_prefix, var_prefix)                    \
-void CrosLibrary::TestApi::Set##class_prefix##Library(                         \
-    class_prefix##Library* library, bool own) {                                \
-  library_->var_prefix##_lib_.SetImpl(library, own);                           \
-}
-
-namespace chromeos {
-
-static CrosLibrary* g_cros_library = NULL;
-
-CrosLibrary::CrosLibrary(bool use_stub) : use_stub_impl_(use_stub) {}
-
-CrosLibrary::~CrosLibrary() {
-}
-
-// static
-void CrosLibrary::Initialize(bool use_stub) {
-  CHECK(!g_cros_library) << "CrosLibrary: Multiple calls to Initialize().";
-  g_cros_library = new CrosLibrary(use_stub);
-  VLOG_IF(1, use_stub) << "CrosLibrary Initialized with Stub Impl.";
-}
-
-// static
-void CrosLibrary::Shutdown() {
-  CHECK(g_cros_library) << "CrosLibrary::Shutdown() called with NULL library";
-  VLOG(1) << "CrosLibrary Shutting down...";
-  delete g_cros_library;
-  g_cros_library = NULL;
-  VLOG(1) << "  CrosLibrary Shutdown completed.";
-}
-
-// static
-CrosLibrary* CrosLibrary::Get() {
-  return g_cros_library;
-}
-
-DEFINE_GET_LIBRARY_METHOD(Network, network);
-
-CrosLibrary::TestApi* CrosLibrary::GetTestApi() {
-  if (!test_api_.get())
-    test_api_.reset(new TestApi(this));
-  return test_api_.get();
-}
-
-DEFINE_SET_LIBRARY_METHOD(Network, network);
-
-} // namespace chromeos
diff --git a/chrome/browser/chromeos/cros/cros_library.h b/chrome/browser/chromeos/cros/cros_library.h
deleted file mode 100644
index 2200938..0000000
--- a/chrome/browser/chromeos/cros/cros_library.h
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_CHROMEOS_CROS_CROS_LIBRARY_H_
-#define CHROME_BROWSER_CHROMEOS_CROS_CROS_LIBRARY_H_
-
-#include <string>
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace base {
-template <typename T> struct DefaultLazyInstanceTraits;
-}
-
-namespace chromeos {
-
-class NetworkLibrary;
-
-// This class handles access to sub-parts of ChromeOS library. it provides
-// a level of indirection so individual libraries that it exposes can
-// be mocked for testing.
-class CrosLibrary {
- public:
-  // This class provides access to internal members of CrosLibrary class for
-  // purpose of testing (i.e. replacement of members' implementation with
-  // mock objects).
-  class TestApi {
-   public:
-    // Passing true for own for these setters will cause them to be deleted
-    // when the CrosLibrary is deleted (or other mocks are set).
-    void SetNetworkLibrary(NetworkLibrary* library, bool own);
-
-   private:
-    friend class CrosLibrary;
-    explicit TestApi(CrosLibrary* library) : library_(library) {}
-    CrosLibrary* library_;
-  };
-
-  // Sets the global instance. Must be called before any calls to Get().
-  static void Initialize(bool use_stub);
-
-  // Destroys the global instance. Must be called before AtExitManager is
-  // destroyed to ensure a clean shutdown.
-  static void Shutdown();
-
-  // Gets the global instance. Returns NULL if Initialize() has not been
-  // called (or Shutdown() has been called).
-  static CrosLibrary* Get();
-
-  NetworkLibrary* GetNetworkLibrary();
-
-  // Getter for Test API that gives access to internal members of this class.
-  TestApi* GetTestApi();
-
-  // Note: Since we are no longer loading Libcros, we can return true here
-  // whenever the used libraries are not stub.
-  // TODO(hashimoto): Remove this method.
-  bool libcros_loaded() { return !use_stub_impl_; }
-
- private:
-  friend struct base::DefaultLazyInstanceTraits<chromeos::CrosLibrary>;
-  friend class CrosLibrary::TestApi;
-
-  explicit CrosLibrary(bool use_stub);
-  virtual ~CrosLibrary();
-
-  // This template supports the creation, setting and optional deletion of
-  // the cros libraries.
-  template <class L>
-  class Library {
-   public:
-    Library() : library_(NULL), own_(true) {}
-
-    ~Library() {
-      if (own_)
-        delete library_;
-    }
-
-    L* GetDefaultImpl(bool use_stub_impl) {
-      if (!library_) {
-        own_ = true;
-        library_ = L::GetImpl(use_stub_impl);
-      }
-      return library_;
-    }
-
-    void SetImpl(L* library, bool own) {
-      if (library != library_) {
-        if (own_)
-          delete library_;
-        library_ = library;
-        own_ = own;
-      }
-    }
-
-   private:
-    L* library_;
-    bool own_;
-  };
-
-  Library<NetworkLibrary> network_lib_;
-
-  // Stub implementations of the libraries should be used.
-  bool use_stub_impl_;
-  scoped_ptr<TestApi> test_api_;
-
-  DISALLOW_COPY_AND_ASSIGN(CrosLibrary);
-};
-
-// The class is used for enabling the stub libcros, and cleaning it up at
-// the end of the object lifetime. Useful for testing.
-class ScopedStubCrosEnabler {
- public:
-  ScopedStubCrosEnabler() {
-    chromeos::CrosLibrary::Initialize(true);
-  }
-
-  ~ScopedStubCrosEnabler() {
-    chromeos::CrosLibrary::Shutdown();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ScopedStubCrosEnabler);
-};
-
-}  // namespace chromeos
-
-#endif  // CHROME_BROWSER_CHROMEOS_CROS_CROS_LIBRARY_H_
diff --git a/chrome/browser/chromeos/cros/cros_mock.cc b/chrome/browser/chromeos/cros/cros_mock.cc
deleted file mode 100644
index 7e7f71d..0000000
--- a/chrome/browser/chromeos/cros/cros_mock.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/cros/cros_mock.h"
-
-#include "base/memory/ref_counted.h"
-#include "base/message_loop.h"
-#include "base/time/time.h"
-#include "chrome/browser/chromeos/cros/mock_network_library.h"
-#include "chrome/browser/chromeos/login/screens/wizard_screen.h"
-#include "chrome/browser/chromeos/login/wizard_controller.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace chromeos {
-
-using ::testing::AnyNumber;
-using ::testing::AtMost;
-using ::testing::InSequence;
-using ::testing::InvokeWithoutArgs;
-using ::testing::Return;
-using ::testing::ReturnRef;
-using ::testing::StrictMock;
-using ::testing::_;
-
-CrosMock::CrosMock() : mock_network_library_(NULL) {
-}
-
-CrosMock::~CrosMock() {
-}
-
-chromeos::CrosLibrary::TestApi* CrosMock::test_api() {
-  return chromeos::CrosLibrary::Get()->GetTestApi();
-}
-
-void CrosMock::InitStatusAreaMocks() {
-  InitMockNetworkLibrary();
-}
-
-void CrosMock::InitMockNetworkLibrary() {
-  if (mock_network_library_)
-    return;
-  mock_network_library_ = new StrictMock<MockNetworkLibrary>();
-  test_api()->SetNetworkLibrary(mock_network_library_, true);
-}
-
-// Initialization of mocks.
-MockNetworkLibrary* CrosMock::mock_network_library() {
-  return mock_network_library_;
-}
-
-void CrosMock::SetStatusAreaMocksExpectations() {
-  SetNetworkLibraryStatusAreaExpectations();
-}
-
-void CrosMock::SetNetworkLibraryStatusAreaExpectations() {
-  // We don't care how often these are called, just set their return values:
-  EXPECT_CALL(*mock_network_library_, AddNetworkProfileObserver(_))
-      .Times(AnyNumber());
-  EXPECT_CALL(*mock_network_library_, AddNetworkManagerObserver(_))
-      .Times(AnyNumber());
-  EXPECT_CALL(*mock_network_library_, AddNetworkDeviceObserver(_, _))
-      .Times(AnyNumber());
-  EXPECT_CALL(*mock_network_library_, RemoveNetworkProfileObserver(_))
-      .Times(AnyNumber());
-  EXPECT_CALL(*mock_network_library_, RemoveNetworkManagerObserver(_))
-      .Times(AnyNumber());
-  EXPECT_CALL(*mock_network_library_, RemoveNetworkDeviceObserver(_, _))
-      .Times(AnyNumber());
-  EXPECT_CALL(*mock_network_library_, RemoveObserverForAllNetworks(_))
-      .Times(AnyNumber());
-  EXPECT_CALL(*mock_network_library_, FindCellularDevice())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const NetworkDevice*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, FindEthernetDevice())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const NetworkDevice*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, ethernet_available())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(true)));
-  EXPECT_CALL(*mock_network_library_, wifi_available())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)));
-  EXPECT_CALL(*mock_network_library_, wimax_available())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)));
-  EXPECT_CALL(*mock_network_library_, cellular_available())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)));
-  EXPECT_CALL(*mock_network_library_, ethernet_enabled())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(true)));
-  EXPECT_CALL(*mock_network_library_, wifi_enabled())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)));
-  EXPECT_CALL(*mock_network_library_, wimax_enabled())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)));
-  EXPECT_CALL(*mock_network_library_, cellular_enabled())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)));
-  EXPECT_CALL(*mock_network_library_, active_network())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const Network*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, active_nonvirtual_network())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const Network*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, ethernet_network())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const EthernetNetwork*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, wifi_network())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const WifiNetwork*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, wimax_network())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const WimaxNetwork*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, mobile_network())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const Network*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, cellular_network())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const CellularNetwork*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, virtual_network())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const VirtualNetwork*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, wifi_networks())
-      .Times(AnyNumber())
-      .WillRepeatedly((ReturnRef(wifi_networks_)));
-  EXPECT_CALL(*mock_network_library_, wimax_networks())
-      .Times(AnyNumber())
-      .WillRepeatedly((ReturnRef(wimax_networks_)));
-  EXPECT_CALL(*mock_network_library_, cellular_networks())
-      .Times(AnyNumber())
-      .WillRepeatedly((ReturnRef(cellular_networks_)));
-  EXPECT_CALL(*mock_network_library_, virtual_networks())
-      .Times(AnyNumber())
-      .WillRepeatedly((ReturnRef(virtual_networks_)));
-  EXPECT_CALL(*mock_network_library_, connected_network())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const Network*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, connecting_network())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return((const Network*)(NULL))));
-  EXPECT_CALL(*mock_network_library_, virtual_network_connected())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)));
-  EXPECT_CALL(*mock_network_library_, wifi_scanning())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)));
-  EXPECT_CALL(*mock_network_library_, cellular_initializing())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)));
-  EXPECT_CALL(*mock_network_library_, AddUserActionObserver(_))
-        .Times(AnyNumber());
-  EXPECT_CALL(*mock_network_library_, LoadOncNetworks(_, _))
-        .Times(AnyNumber());
-
-  // Set specific expectations for interesting functions:
-
-  // NetworkMenuButton::OnNetworkChanged() calls:
-  EXPECT_CALL(*mock_network_library_, Connected())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*mock_network_library_, Connecting())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*mock_network_library_, cellular_connected())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)))
-      .RetiresOnSaturation();
-
-  // NetworkMenu::InitMenuItems() calls:
-  EXPECT_CALL(*mock_network_library_, ethernet_connected())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*mock_network_library_, ethernet_connecting())
-      .Times(AnyNumber())
-      .WillRepeatedly((Return(false)))
-      .RetiresOnSaturation();
-}
-
-void CrosMock::TearDownMocks() {
-  // Prevent bogus gMock leak check from firing.
-  if (mock_network_library_)
-    test_api()->SetNetworkLibrary(NULL, false);
-}
-
-}  // namespace chromeos
diff --git a/chrome/browser/chromeos/cros/cros_mock.h b/chrome/browser/chromeos/cros/cros_mock.h
deleted file mode 100644
index 52b4340..0000000
--- a/chrome/browser/chromeos/cros/cros_mock.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_CHROMEOS_CROS_CROS_MOCK_H_
-#define CHROME_BROWSER_CHROMEOS_CROS_CROS_MOCK_H_
-
-#include "chrome/browser/chromeos/cros/cros_library.h"
-#include "chrome/browser/chromeos/cros/network_library.h"
-#include "chrome/test/base/in_process_browser_test.h"
-
-namespace chromeos {
-
-class MockLibraryLoader;
-class MockNetworkLibrary;
-
-// Class for initializing mocks for some parts of CrosLibrary. Once you mock
-// part of CrosLibrary it will be considered as successfully loaded and
-// libraries that compose CrosLibrary will be created. CrosMock also defines a
-// minimum set of mocks that is used by status area elements (network,
-// input language, power).
-class CrosMock {
- public:
-  CrosMock();
-  virtual ~CrosMock();
-
-  // This method sets up basic mocks that are used by status area items:
-  // LibraryLoader, Language, Network, Power, libraries.
-  // Add a call to this method at the beginning of your
-  // SetUpInProcessBrowserTestFixture.
-  void InitStatusAreaMocks();
-
-  // Initialization of CrosLibrary mock loader. If you intend calling
-  // separate init methods for mocks call this one first.
-  void InitMockLibraryLoader();
-
-  // Initialization of mocks.
-  void InitMockNetworkLibrary();
-
-  // Get mocks.
-  MockNetworkLibrary* mock_network_library();
-
-  // This method sets up corresponding expectations for basic mocks that
-  // are used by status area items.
-  // Make sure that InitStatusAreaMocks was called before.
-  // Add a call to this method in your SetUpInProcessBrowserTestFixture.
-  // They are all configured with RetiresOnSaturation().
-  // Once such expectation is used it won't block expectations you've defined.
-  void SetStatusAreaMocksExpectations();
-
-  // Methods to setup minimal mocks expectations for status area.
-  void SetNetworkLibraryStatusAreaExpectations();
-
-  void TearDownMocks();
-
-  // TestApi gives access to CrosLibrary private members.
-  chromeos::CrosLibrary::TestApi* test_api();
-
- private:
-  // Mocks, destroyed by CrosLibrary class.
-  MockLibraryLoader* loader_;
-  MockNetworkLibrary* mock_network_library_;
-
-  WifiNetworkVector wifi_networks_;
-  WimaxNetworkVector wimax_networks_;
-  CellularNetworkVector cellular_networks_;
-  VirtualNetworkVector virtual_networks_;
-  std::string empty_string_;
-
-  DISALLOW_COPY_AND_ASSIGN(CrosMock);
-};
-
-}  // namespace chromeos
-
-#endif  // CHROME_BROWSER_CHROMEOS_CROS_CROS_MOCK_H_
diff --git a/chrome/browser/chromeos/cros/mock_network_library.h b/chrome/browser/chromeos/cros/mock_network_library.h
index d9144c5..7acb510 100644
--- a/chrome/browser/chromeos/cros/mock_network_library.h
+++ b/chrome/browser/chromeos/cros/mock_network_library.h
@@ -35,8 +35,6 @@
                                                  NetworkDeviceObserver*));
   MOCK_METHOD1(AddPinOperationObserver, void(PinOperationObserver*));
   MOCK_METHOD1(RemovePinOperationObserver, void(PinOperationObserver*));
-  MOCK_METHOD1(AddUserActionObserver, void(UserActionObserver*));
-  MOCK_METHOD1(RemoveUserActionObserver, void(UserActionObserver*));
   MOCK_CONST_METHOD0(ethernet_network, const EthernetNetwork*(void));
   MOCK_CONST_METHOD0(ethernet_connecting, bool(void));
   MOCK_CONST_METHOD0(ethernet_connected, bool(void));
@@ -53,10 +51,6 @@
   MOCK_CONST_METHOD0(wimax_connecting, bool(void));
   MOCK_CONST_METHOD0(wimax_connected, bool(void));
 
-  MOCK_CONST_METHOD0(mobile_network, const Network*(void));
-  MOCK_CONST_METHOD0(mobile_connecting, bool(void));
-  MOCK_CONST_METHOD0(mobile_connected, bool(void));
-
   MOCK_CONST_METHOD0(virtual_network, const VirtualNetwork*(void));
   MOCK_CONST_METHOD0(virtual_network_connecting, bool(void));
   MOCK_CONST_METHOD0(virtual_network_connected, bool(void));
@@ -64,7 +58,6 @@
   MOCK_CONST_METHOD0(Connected, bool(void));
   MOCK_CONST_METHOD0(Connecting, bool(void));
 
-  MOCK_CONST_METHOD0(IPAddress, const std::string&(void));
   MOCK_CONST_METHOD0(wifi_networks, const WifiNetworkVector&(void));
   MOCK_CONST_METHOD0(remembered_wifi_networks, const WifiNetworkVector&(void));
   MOCK_CONST_METHOD0(cellular_networks, const CellularNetworkVector&(void));
@@ -104,13 +97,10 @@
   MOCK_METHOD1(SetCellularDataRoamingAllowed, void(bool));
   MOCK_METHOD2(SetCarrier, void(const std::string&,
                                 const NetworkOperationCallback&));
-  MOCK_METHOD0(ResetModem, void());
   MOCK_METHOD0(IsCellularAlwaysInRoaming, bool());
 
   MOCK_METHOD0(RequestNetworkScan, void(void));
-  MOCK_CONST_METHOD1(HasProfileType, bool(NetworkProfileType));
   MOCK_CONST_METHOD1(CanConnectToNetwork, bool(const Network*));
-  MOCK_METHOD1(RefreshIPConfig, void(Network*));
   MOCK_METHOD1(ConnectToWifiNetwork, void(WifiNetwork*));
   MOCK_METHOD2(ConnectToWifiNetwork, void(WifiNetwork*, bool));
   MOCK_METHOD1(ConnectToWimaxNetwork, void(WimaxNetwork*));
@@ -141,13 +131,11 @@
   MOCK_CONST_METHOD0(wifi_available, bool(void));
   MOCK_CONST_METHOD0(cellular_available, bool(void));
   MOCK_CONST_METHOD0(wimax_available, bool(void));
-  MOCK_CONST_METHOD0(mobile_available, bool(void));
 
   MOCK_CONST_METHOD0(ethernet_enabled, bool(void));
   MOCK_CONST_METHOD0(wifi_enabled, bool(void));
   MOCK_CONST_METHOD0(cellular_enabled, bool(void));
   MOCK_CONST_METHOD0(wimax_enabled, bool(void));
-  MOCK_CONST_METHOD0(mobile_enabled, bool(void));
 
   MOCK_CONST_METHOD0(active_network, const Network*(void));
   MOCK_CONST_METHOD0(active_nonvirtual_network, const Network*(void));
@@ -156,14 +144,11 @@
 
   MOCK_CONST_METHOD0(wifi_scanning, bool(void));
   MOCK_CONST_METHOD0(cellular_initializing, bool(void));
-  MOCK_CONST_METHOD0(offline_mode, bool(void));
 
   MOCK_METHOD1(EnableEthernetNetworkDevice, void(bool));
   MOCK_METHOD1(EnableWifiNetworkDevice, void(bool));
   MOCK_METHOD1(EnableCellularNetworkDevice, void(bool));
   MOCK_METHOD1(EnableWimaxNetworkDevice, void(bool));
-  MOCK_METHOD1(EnableMobileNetworkDevice, void(bool));
-  MOCK_METHOD1(EnableOfflineMode, void(bool));
   MOCK_METHOD3(GetIPConfigs, void(const std::string&,
                                   HardwareAddressFormat,
                                   const NetworkGetIPConfigsCallback&));
@@ -176,7 +161,6 @@
   MOCK_METHOD2(RequestNetworkServiceProperties,
                void(const std::string&,
                     const NetworkServicePropertiesCallback&));
-  MOCK_METHOD0(SwitchToPreferredNetwork, void(void));
   MOCK_METHOD2(LoadOncNetworks, void(const base::ListValue&,
                                      onc::ONCSource));
   MOCK_METHOD2(SetActiveNetwork, bool(ConnectionType, const std::string&));
diff --git a/chrome/browser/chromeos/cros/native_network_parser.cc b/chrome/browser/chromeos/cros/native_network_parser.cc
index fc729d7..8686cca 100644
--- a/chrome/browser/chromeos/cros/native_network_parser.cc
+++ b/chrome/browser/chromeos/cros/native_network_parser.cc
@@ -102,7 +102,6 @@
   { flimflam::kMdnProperty, PROPERTY_INDEX_MDN },
   { flimflam::kMeidProperty, PROPERTY_INDEX_MEID },
   { flimflam::kMinProperty, PROPERTY_INDEX_MIN },
-  { flimflam::kModeProperty, PROPERTY_INDEX_MODE },
   { flimflam::kModelIDProperty, PROPERTY_INDEX_MODEL_ID },
   { flimflam::kNameProperty, PROPERTY_INDEX_NAME },
   { flimflam::kNetworkTechnologyProperty, PROPERTY_INDEX_NETWORK_TECHNOLOGY },
@@ -737,14 +736,6 @@
       }
       break;
     }
-    case PROPERTY_INDEX_MODE: {
-      std::string mode_string;
-      if (value.GetAsString(&mode_string)) {
-        network->set_mode(ParseMode(mode_string));
-        return true;
-      }
-      break;
-    }
     case PROPERTY_INDEX_ERROR: {
       std::string error_string;
       if (value.GetAsString(&error_string)) {
@@ -798,16 +789,6 @@
   return ParseType(type_string);
 }
 
-ConnectionMode NativeNetworkParser::ParseMode(const std::string& mode) {
-  static EnumMapper<ConnectionMode>::Pair table[] = {
-    { flimflam::kModeManaged, MODE_MANAGED },
-    { flimflam::kModeAdhoc, MODE_ADHOC },
-  };
-  CR_DEFINE_STATIC_LOCAL(EnumMapper<ConnectionMode>, parser,
-      (table, arraysize(table), MODE_UNKNOWN));
-  return parser.Get(mode);
-}
-
 ConnectionState NativeNetworkParser::ParseState(const std::string& state) {
   static EnumMapper<ConnectionState>::Pair table[] = {
     { flimflam::kStateIdle, STATE_IDLE },
diff --git a/chrome/browser/chromeos/cros/native_network_parser.h b/chrome/browser/chromeos/cros/native_network_parser.h
index e80e4d6..4efd2e1 100644
--- a/chrome/browser/chromeos/cros/native_network_parser.h
+++ b/chrome/browser/chromeos/cros/native_network_parser.h
@@ -75,7 +75,6 @@
   virtual ConnectionType ParseTypeFromDictionary(
       const base::DictionaryValue& info) OVERRIDE;
 
-  ConnectionMode ParseMode(const std::string& mode);
   ConnectionState ParseState(const std::string& state);
   ConnectionError ParseError(const std::string& error);
 
diff --git a/chrome/browser/chromeos/cros/network_constants.h b/chrome/browser/chromeos/cros/network_constants.h
index 35f6ce6..0f5aa18 100644
--- a/chrome/browser/chromeos/cros/network_constants.h
+++ b/chrome/browser/chromeos/cros/network_constants.h
@@ -82,7 +82,6 @@
   PROPERTY_INDEX_MDN,
   PROPERTY_INDEX_MEID,
   PROPERTY_INDEX_MIN,
-  PROPERTY_INDEX_MODE,
   PROPERTY_INDEX_MODEL_ID,
   PROPERTY_INDEX_NAME,
   PROPERTY_INDEX_NETWORKS,
@@ -177,12 +176,6 @@
   TYPE_VPN       = 6,
 };
 
-enum ConnectionMode {
-  MODE_UNKNOWN = 0,
-  MODE_MANAGED = 1,
-  MODE_ADHOC   = 2,
-};
-
 enum ConnectionSecurity {
   SECURITY_UNKNOWN = 0,
   SECURITY_NONE    = 1,
diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc
index 8db027b..2980a8b 100644
--- a/chrome/browser/chromeos/cros/network_library.cc
+++ b/chrome/browser/chromeos/cros/network_library.cc
@@ -4,13 +4,13 @@
 
 #include "chrome/browser/chromeos/cros/network_library.h"
 
+#include "base/chromeos/chromeos_version.h"
 #include "base/i18n/icu_encoding_detection.h"
 #include "base/i18n/icu_string_conversions.h"
 #include "base/i18n/time_formatting.h"
 #include "base/json/json_writer.h"  // for debug output only.
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversion_utils.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/native_network_constants.h"
 #include "chrome/browser/chromeos/cros/native_network_parser.h"
 #include "chrome/browser/chromeos/cros/network_library_impl_cros.h"
@@ -89,9 +89,10 @@
 
 namespace chromeos {
 
-// Local constants.
 namespace {
 
+static NetworkLibrary* g_network_library = NULL;
+
 // Default value of the SIM unlock retries count. It is updated to the real
 // retries count once cellular device with SIM card is initialized.
 // If cellular device doesn't have SIM card, then retries are never used.
@@ -106,8 +107,8 @@
   str->clear();
 }
 
-bool EnsureCrosLoaded() {
-  if (!CrosLibrary::Get()->libcros_loaded()) {
+bool EnsureRunningOnChromeOS() {
+  if (!base::chromeos::IsRunningOnChromeOS()) {
     return false;
   } else {
     CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI))
@@ -227,56 +228,16 @@
       notify_failure_(false),
       profile_type_(PROFILE_NONE),
       service_path_(service_path),
-      type_(type),
-      is_behind_portal_for_testing_(false) {
+      type_(type) {
 }
 
 Network::~Network() {
-  for (PropertyMap::const_iterator props = property_map_.begin();
-       props != property_map_.end(); ++props) {
-     delete props->second;
-  }
 }
 
 void Network::SetNetworkParser(NetworkParser* parser) {
   network_parser_.reset(parser);
 }
 
-void Network::UpdatePropertyMap(PropertyIndex index, const base::Value* value) {
-  if (!value) {
-    // Clear the property if |value| is NULL.
-    PropertyMap::iterator iter(property_map_.find(index));
-    if (iter != property_map_.end()) {
-      delete iter->second;
-      property_map_.erase(iter);
-    }
-    return;
-  }
-
-  // Add the property to property_map_.  Delete previous value if necessary.
-  Value*& entry = property_map_[index];
-  delete entry;
-  entry = value->DeepCopy();
-  if (VLOG_IS_ON(3)) {
-    std::string value_json;
-    base::JSONWriter::WriteWithOptions(value,
-                                       base::JSONWriter::OPTIONS_PRETTY_PRINT,
-                                       &value_json);
-    VLOG(3) << "Updated property map on network: "
-            << unique_id() << "[" << index << "] = " << value_json;
-  }
-}
-
-bool Network::GetProperty(PropertyIndex index,
-                          const base::Value** value) const {
-  PropertyMap::const_iterator i = property_map_.find(index);
-  if (i == property_map_.end())
-    return false;
-  if (value != NULL)
-    *value = i->second;
-  return true;
-}
-
 // static
 Network* Network::CreateForTesting(ConnectionType type) {
   return new Network("fake_service_path", type);
@@ -373,7 +334,7 @@
 
 void Network::SetValueProperty(const char* prop, const base::Value& value) {
   DCHECK(prop);
-  if (!EnsureCrosLoaded())
+  if (!EnsureRunningOnChromeOS())
     return;
   CrosSetNetworkServiceProperty(service_path_, prop, value);
   // Ensure NetworkStateHandler properties are up-to-date.
@@ -385,7 +346,7 @@
 
 void Network::ClearProperty(const char* prop) {
   DCHECK(prop);
-  if (!EnsureCrosLoaded())
+  if (!EnsureRunningOnChromeOS())
     return;
   CrosClearNetworkServiceProperty(service_path_, prop);
   // Ensure NetworkStateHandler properties are up-to-date.
@@ -535,7 +496,7 @@
 
 void Network::InitIPAddress() {
   ip_address_.clear();
-  if (!EnsureCrosLoaded())
+  if (!EnsureRunningOnChromeOS())
     return;
   // If connected, get IPConfig.
   if (connected() && !device_path_.empty()) {
@@ -551,7 +512,7 @@
     const NetworkIPConfigVector& ip_configs,
     const std::string& hardware_address) {
   Network* network =
-      CrosLibrary::Get()->GetNetworkLibrary()->FindNetworkByPath(service_path);
+      NetworkLibrary::Get()->FindNetworkByPath(service_path);
   if (!network)
     return;
   for (size_t i = 0; i < ip_configs.size(); ++i) {
@@ -900,7 +861,7 @@
 }
 
 bool CellularNetwork::StartActivation() {
-  if (!EnsureCrosLoaded())
+  if (!EnsureRunningOnChromeOS())
     return false;
   if (!CrosActivateCellularModem(service_path(), ""))
     return false;
@@ -912,7 +873,7 @@
 }
 
 void CellularNetwork::CompleteActivation() {
-  if (!EnsureCrosLoaded())
+  if (!EnsureRunningOnChromeOS())
     return;
   CrosCompleteCellularActivation(service_path());
 }
@@ -1121,14 +1082,6 @@
   WipeString(&eap_passphrase_);
 }
 
-void WifiNetwork::SetIdentity(const std::string& identity) {
-  SetStringProperty(flimflam::kIdentityProperty, identity, &identity_);
-}
-
-void WifiNetwork::SetHiddenSSID(bool hidden_ssid) {
-  SetBooleanProperty(flimflam::kWifiHiddenSsid, hidden_ssid, &hidden_ssid_);
-}
-
 void WifiNetwork::SetEAPMethod(EAPMethod method) {
   eap_method_ = method;
   switch (method) {
@@ -1412,4 +1365,32 @@
   return impl;
 }
 
+// static
+void NetworkLibrary::Initialize(bool use_stub) {
+  CHECK(!g_network_library)
+      << "NetworkLibrary: Multiple calls to Initialize().";
+  g_network_library = NetworkLibrary::GetImpl(use_stub);
+  VLOG_IF(1, use_stub) << "NetworkLibrary Initialized with Stub Impl.";
+}
+
+// static
+void NetworkLibrary::Shutdown() {
+  VLOG(1) << "NetworkLibrary Shutting down...";
+  delete g_network_library;
+  g_network_library = NULL;
+  VLOG(1) << "  NetworkLibrary Shutdown completed.";
+}
+
+// static
+NetworkLibrary* NetworkLibrary::Get() {
+  return g_network_library;
+}
+
+// static
+void NetworkLibrary::SetForTesting(NetworkLibrary* library) {
+  if (g_network_library)
+    delete g_network_library;
+  g_network_library = library;
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/cros/network_library.h b/chrome/browser/chromeos/cros/network_library.h
index f5cee29..ba7a6d3 100644
--- a/chrome/browser/chromeos/cros/network_library.h
+++ b/chrome/browser/chromeos/cros/network_library.h
@@ -324,12 +324,7 @@
   class TestApi {
    public:
     explicit TestApi(Network* network) : network_(network) {}
-    void SetBehindPortal() {
-      network_->set_is_behind_portal_for_testing(true);
-      network_->set_behind_portal();
-    }
     void SetConnected() {
-      network_->set_is_behind_portal_for_testing(false);
       network_->set_connected();
     }
     void SetConnecting() {
@@ -352,7 +347,6 @@
   const std::string& device_path() const { return device_path_; }
   const std::string& ip_address() const { return ip_address_; }
   ConnectionType type() const { return type_; }
-  ConnectionMode mode() const { return mode_; }
   ConnectionState connection_state() const { return state_; }
   bool connecting() const { return IsConnectingState(state_); }
   bool configuring() const { return state_ == STATE_CONFIGURATION; }
@@ -365,7 +359,6 @@
   UserConnectState user_connect_state() const { return user_connect_state_; }
   bool failed() const { return state_ == STATE_FAILURE; }
   bool disconnected() const { return IsDisconnectedState(state_); }
-  bool ready() const { return state_ == STATE_READY; }
   bool online() const { return state_ == STATE_ONLINE; }
   bool restricted_pool() const { return state_ == STATE_PORTAL; }
   ConnectionError error() const { return error_; }
@@ -451,10 +444,6 @@
                             const base::Value& value,
                             PropertyIndex* index);
 
-  // Retrieves a property from the property_map_.  If |value| is NULL,
-  // just returns whether or not the given property was found.
-  bool GetProperty(PropertyIndex index, const base::Value** value) const;
-
   // Creates a Network object for the given type for testing.
   static Network* CreateForTesting(ConnectionType type);
 
@@ -465,10 +454,6 @@
   NetworkParser* network_parser() { return network_parser_.get(); }
   void SetNetworkParser(NetworkParser* parser);
 
-  // Updates |property_map_| for the corresponding property |index|. If |value|
-  // is non-NULL, it's put into the map. Otherwise, the entry is removed.
-  void UpdatePropertyMap(PropertyIndex index, const base::Value* value);
-
   // Set the state and update flags if necessary.
   void SetState(ConnectionState state);
 
@@ -511,8 +496,6 @@
   }
 
  private:
-  typedef std::map<PropertyIndex, base::Value*> PropertyMap;
-
   // This allows NetworkParser and its subclasses access to device
   // privates so that they can be reconstituted during parsing.  The
   // parsers only access things through the private set_ functions so
@@ -534,14 +517,7 @@
     device_path_ = device_path;
   }
   void set_name(const std::string& name) { name_ = name; }
-  void set_mode(ConnectionMode mode) { mode_ = mode; }
   void set_connecting();
-  void set_is_behind_portal_for_testing(bool value) {
-    is_behind_portal_for_testing_ = value;
-  }
-  bool is_behind_portal_for_testing() const {
-    return is_behind_portal_for_testing_;
-  }
   void set_behind_portal() {
     state_ = STATE_PORTAL;
   }
@@ -588,7 +564,6 @@
   std::string device_path_;
   std::string name_;
   std::string ip_address_;
-  ConnectionMode mode_;
   ConnectionState state_;
   ConnectionError error_;
   bool connectable_;
@@ -630,12 +605,6 @@
   // network layer.
   scoped_ptr<NetworkParser> network_parser_;
 
-  // This map stores the set of properties for the network.
-  // Not all properties in this map are exposed via get methods.
-  PropertyMap property_map_;
-
-  bool is_behind_portal_for_testing_;
-
   DISALLOW_COPY_AND_ASSIGN(Network);
 };
 
@@ -660,11 +629,9 @@
   ProviderType provider_type() const { return provider_type_; }
   const std::string& ca_cert_pem() const { return ca_cert_pem_; }
   const std::string& psk_passphrase() const { return psk_passphrase_; }
-  bool psk_passphrase_required() const { return psk_passphrase_required_; }
   const std::string& client_cert_id() const { return client_cert_id_; }
   const std::string& username() const { return username_; }
   const std::string& user_passphrase() const { return user_passphrase_; }
-  bool user_passphrase_required() const { return user_passphrase_required_; }
   const std::string& group_name() const { return group_name_; }
 
   // Sets the well-known PKCS#11 slot and PIN for accessing certificates.
@@ -758,9 +725,6 @@
   virtual void EraseCredentials() OVERRIDE;
   virtual void CalculateUniqueId() OVERRIDE;
 
-  // VirtualNetwork private methods.
-  bool ParseProviderValue(int index, const base::Value* value);
-
   std::string server_hostname_;
   ProviderType provider_type_;
   std::string ca_cert_pem_;
@@ -1013,8 +977,6 @@
   // Set property and call SetNetworkServiceProperty:
 
   void SetPassphrase(const std::string& passphrase);
-  void SetIdentity(const std::string& identity);
-  void SetHiddenSSID(bool hidden_ssid);
 
   // 802.1x properties
   void SetEAPMethod(EAPMethod method);
@@ -1216,7 +1178,7 @@
 
 // This class handles the interaction with the ChromeOS network library APIs.
 // Classes can add themselves as observers. Users can get an instance of the
-// library like this: chromeos::CrosLibrary::Get()->GetNetworkLibrary()
+// library like this: chromeos::NetworkLibrary::Get()
 class NetworkLibrary {
  public:
   enum HardwareAddressFormat {
@@ -1266,10 +1228,6 @@
 
   class NetworkDeviceObserver {
    public:
-    // Called when the state of a single device has changed.
-    virtual void OnNetworkDeviceChanged(NetworkLibrary* cros,
-                                        const NetworkDevice* device) {}
-
     // Called when |device| got notification about new networks available.
     virtual void OnNetworkDeviceFoundNetworks(NetworkLibrary* cros,
                                               const NetworkDevice* device) {}
@@ -1291,16 +1249,6 @@
     virtual ~PinOperationObserver() {}
   };
 
-  class UserActionObserver {
-   public:
-    // Called when user initiates a new connection.
-    // Network is NULL when we don't have an associated Network object.
-    virtual void OnConnectionInitiated(NetworkLibrary* cros,
-                                       const Network* network) = 0;
-   protected:
-    virtual ~UserActionObserver() {}
-  };
-
   virtual ~NetworkLibrary() {}
 
   virtual void Init() = 0;
@@ -1336,9 +1284,6 @@
   virtual void AddPinOperationObserver(PinOperationObserver* observer) = 0;
   virtual void RemovePinOperationObserver(PinOperationObserver* observer) = 0;
 
-  virtual void AddUserActionObserver(UserActionObserver* observer) = 0;
-  virtual void RemoveUserActionObserver(UserActionObserver* observer) = 0;
-
   // Return the active or default Ethernet network (or NULL if none).
   virtual const EthernetNetwork* ethernet_network() const = 0;
   virtual bool ethernet_connecting() const = 0;
@@ -1359,12 +1304,6 @@
   virtual bool wimax_connecting() const = 0;
   virtual bool wimax_connected() const = 0;
 
-  // Return the active mobile (cellular or WiMax) network
-  // (or NULL if none active).
-  virtual const Network* mobile_network() const = 0;
-  virtual bool mobile_connecting() const = 0;
-  virtual bool mobile_connected() const = 0;
-
   // Return the active virtual network (or NULL if none active).
   virtual const VirtualNetwork* virtual_network() const = 0;
   virtual bool virtual_network_connecting() const = 0;
@@ -1403,20 +1342,14 @@
   virtual bool wifi_available() const = 0;
   virtual bool wimax_available() const = 0;
   virtual bool cellular_available() const = 0;
-  virtual bool mobile_available() const = 0;
 
   virtual bool ethernet_enabled() const = 0;
   virtual bool wifi_enabled() const = 0;
   virtual bool wimax_enabled() const = 0;
   virtual bool cellular_enabled() const = 0;
-  virtual bool mobile_enabled() const = 0;
 
   virtual bool wifi_scanning() const = 0;
   virtual bool cellular_initializing() const = 0;
-  virtual bool offline_mode() const = 0;
-
-  // Returns the current IP address if connected. If not, returns empty string.
-  virtual const std::string& IPAddress() const = 0;
 
   // Return a pointer to the device, if it exists, or NULL.
   virtual const NetworkDevice* FindNetworkDeviceByPath(
@@ -1426,18 +1359,9 @@
   // Returns NULL if none exists.
   virtual const NetworkDevice* FindMobileDevice() const = 0;
 
-  // Returns device with TYPE_WIMAX. Returns NULL if none exists.
-  virtual const NetworkDevice* FindWimaxDevice() const = 0;
-
   // Returns device with TYPE_CELLULAR. Returns NULL if none exists.
   virtual const NetworkDevice* FindCellularDevice() const = 0;
 
-  // Returns device with TYPE_ETHERNET. Returns NULL if none exists.
-  virtual const NetworkDevice* FindEthernetDevice() const = 0;
-
-  // Returns device with TYPE_WIFI. Returns NULL if none exists.
-  virtual const NetworkDevice* FindWifiDevice() const = 0;
-
   // Return a pointer to the network, if it exists, or NULL.
   // NOTE: Never store these results, store service paths instead.
   // The pattern for doing an operation on a Network is:
@@ -1513,10 +1437,6 @@
   virtual void SetCarrier(const std::string& carrier,
                           const NetworkOperationCallback& completed) = 0;
 
-  // Resets the cellular device, calls the closure once the transition is
-  // complete.
-  virtual void ResetModem() = 0;
-
   // Return true if GSM SIM card can work only with enabled roaming.
   virtual bool IsCellularAlwaysInRoaming() = 0;
 
@@ -1525,17 +1445,10 @@
 
   // TODO(joth): Add GetCellTowers to retrieve a CellTowerVector.
 
-  // Return true if a profile matching |type| is loaded.
-  virtual bool HasProfileType(NetworkProfileType type) const = 0;
-
   // Returns false if there is no way to connect to this network, even with
   // user input (e.g. it requires a user profile but none is available).
   virtual bool CanConnectToNetwork(const Network* network) const = 0;
 
-  // Refresh the IP configuration of the given network after changes.  Puts
-  // newly configured properties into effect and renews DHCP lease.
-  virtual void RefreshIPConfig(Network* network) = 0;
-
   // Connect to the specified wireless network.
   virtual void ConnectToWifiNetwork(WifiNetwork* network) = 0;
 
@@ -1610,18 +1523,12 @@
   // Enables/disables the wifi network device.
   virtual void EnableWifiNetworkDevice(bool enable) = 0;
 
-  // Enables/disables mobile (cellular, wimax) network device.
-  virtual void EnableMobileNetworkDevice(bool enable) = 0;
-
   // Enables/disables the wimax network device.
   virtual void EnableWimaxNetworkDevice(bool enable) = 0;
 
   // Enables/disables the cellular network device.
   virtual void EnableCellularNetworkDevice(bool enable) = 0;
 
-  // Enables/disables offline mode.
-  virtual void EnableOfflineMode(bool enable) = 0;
-
   // Fetches IP configs and hardware address for a given device_path and returns
   // them via the given callback.
   virtual void GetIPConfigs(const std::string& device_path,
@@ -1650,11 +1557,6 @@
       const std::string& service_path,
       const NetworkServicePropertiesCallback& callback) = 0;
 
-  // This will connect to a preferred network if the currently connected
-  // network is not preferred. This should be called when the active profile
-  // changes.
-  virtual void SwitchToPreferredNetwork() = 0;
-
   // Load networks from a list of NetworkConfigurations of ONC.
   virtual void LoadOncNetworks(const base::ListValue& network_configs,
                                onc::ONCSource source) = 0;
@@ -1668,8 +1570,39 @@
                                 const std::string& service_path) = 0;
 
   // Factory function, creates a new instance and returns ownership.
-  // For normal usage, access the singleton via CrosLibrary::Get().
+  // For normal usage, access the singleton via NetworkLibrary::Get().
   static NetworkLibrary* GetImpl(bool stub);
+
+  // Initializes the global instance.
+  static void Initialize(bool use_stub);
+
+  // Destroys the global instance. Must be called before AtExitManager is
+  // destroyed to ensure a clean shutdown.
+  static void Shutdown();
+
+  // Gets the global instance. Returns NULL if Initialize() has not been
+  // called (or Shutdown() has been called).
+  static NetworkLibrary* Get();
+
+  // Sets the network library to be returned from Get(). The existing network
+  // library will be deleted.
+  static void SetForTesting(NetworkLibrary* network_library);
+};
+
+// The class is used for enabling the stub libcros, and cleaning it up at
+// the end of the object lifetime. Useful for testing.
+class ScopedStubNetworkLibraryEnabler {
+ public:
+  ScopedStubNetworkLibraryEnabler() {
+    NetworkLibrary::Initialize(true);
+  }
+
+  ~ScopedStubNetworkLibraryEnabler() {
+    NetworkLibrary::Shutdown();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ScopedStubNetworkLibraryEnabler);
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/cros/network_library_impl_base.cc b/chrome/browser/chromeos/cros/network_library_impl_base.cc
index 22ca01b..f5a872c 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_base.cc
+++ b/chrome/browser/chromeos/cros/network_library_impl_base.cc
@@ -63,7 +63,6 @@
       enabled_devices_(0),
       busy_devices_(0),
       wifi_scanning_(false),
-      offline_mode_(false),
       is_locked_(false),
       sim_operation_(SIM_OPERATION_NONE),
       notify_manager_weak_factory_(this) {
@@ -75,7 +74,6 @@
   network_profile_observers_.Clear();
   network_manager_observers_.Clear();
   pin_operation_observers_.Clear();
-  user_action_observers_.Clear();
   STLDeleteValues(&network_map_);
   ClearNetworks();
   DeleteRememberedNetworks();
@@ -207,17 +205,6 @@
   pin_operation_observers_.RemoveObserver(observer);
 }
 
-void NetworkLibraryImplBase::AddUserActionObserver(
-    UserActionObserver* observer) {
-  if (!user_action_observers_.HasObserver(observer))
-    user_action_observers_.AddObserver(observer);
-}
-
-void NetworkLibraryImplBase::RemoveUserActionObserver(
-    UserActionObserver* observer) {
-  user_action_observers_.RemoveObserver(observer);
-}
-
 const EthernetNetwork* NetworkLibraryImplBase::ethernet_network() const {
   return ethernet_;
 }
@@ -255,17 +242,6 @@
 bool NetworkLibraryImplBase::wimax_connected() const {
   return active_wimax_ ? active_wimax_->connected() : false;
 }
-const Network* NetworkLibraryImplBase::mobile_network() const {
-  return active_cellular_ ?
-      static_cast<Network*>(active_cellular_) :
-      static_cast<Network*>(active_wimax_);
-}
-bool NetworkLibraryImplBase::mobile_connecting() const {
-  return cellular_connecting() || wimax_connecting();
-}
-bool NetworkLibraryImplBase::mobile_connected() const {
-  return wimax_connecting() || wimax_connected();
-}
 const VirtualNetwork* NetworkLibraryImplBase::virtual_network() const {
   return active_virtual_;
 }
@@ -383,10 +359,6 @@
   return available_devices_ & (1 << TYPE_CELLULAR);
 }
 
-bool NetworkLibraryImplBase::mobile_available() const {
-  return cellular_available() || wimax_available();
-}
-
 bool NetworkLibraryImplBase::ethernet_enabled() const {
   return enabled_devices_ & (1 << TYPE_ETHERNET);
 }
@@ -403,10 +375,6 @@
   return enabled_devices_ & (1 << TYPE_CELLULAR);
 }
 
-bool NetworkLibraryImplBase::mobile_enabled() const {
-  return cellular_enabled() || wimax_enabled();
-}
-
 bool NetworkLibraryImplBase::wifi_scanning() const {
   return wifi_scanning_;
 }
@@ -420,22 +388,6 @@
   return false;
 }
 
-bool NetworkLibraryImplBase::offline_mode() const { return offline_mode_; }
-
-// Returns the IP address for the active network.
-// TODO(stevenjb): Fix this for VPNs. See chromium-os:13972.
-const std::string& NetworkLibraryImplBase::IPAddress() const {
-  const Network* result = active_network();
-  if (!result)
-    result = connected_network();  // happens if we are connected to a VPN.
-  if (!result)
-    result = ethernet_;  // Use non active ethernet addr if no active network.
-  if (result)
-    return result->ip_address();
-  CR_DEFINE_STATIC_LOCAL(std::string, null_address, ("0.0.0.0"));
-  return null_address;
-}
-
 /////////////////////////////////////////////////////////////////////////////
 
 const NetworkDevice* NetworkLibraryImplBase::FindNetworkDeviceByPath(
@@ -460,18 +412,6 @@
   return FindDeviceByType(TYPE_CELLULAR);
 }
 
-const NetworkDevice* NetworkLibraryImplBase::FindEthernetDevice() const {
-  return FindDeviceByType(TYPE_ETHERNET);
-}
-
-const NetworkDevice* NetworkLibraryImplBase::FindWifiDevice() const {
-  return FindDeviceByType(TYPE_WIFI);
-}
-
-const NetworkDevice* NetworkLibraryImplBase::FindWimaxDevice() const {
-  return FindDeviceByType(TYPE_WIMAX);
-}
-
 const NetworkDevice* NetworkLibraryImplBase::FindMobileDevice() const {
   const NetworkDevice* device = FindDeviceByType(TYPE_CELLULAR);
   if (device)
@@ -780,7 +720,6 @@
 
   // Notify observers.
   NotifyNetworkManagerChanged(true);  // Forced update.
-  NotifyUserConnectionInitiated(network);
   NotifyNetworkChanged(network);
 }
 
@@ -962,11 +901,6 @@
   CallEnableNetworkDeviceType(TYPE_WIFI, enable);
 }
 
-void NetworkLibraryImplBase::EnableMobileNetworkDevice(bool enable) {
-  EnableWimaxNetworkDevice(enable);
-  EnableCellularNetworkDevice(enable);
-}
-
 void NetworkLibraryImplBase::EnableWimaxNetworkDevice(bool enable) {
   if (is_locked_)
     return;
@@ -1629,9 +1563,6 @@
                         *device_observer_list,
                         OnNetworkDeviceSimLockChanged(this, device));
     }
-    FOR_EACH_OBSERVER(NetworkDeviceObserver,
-                      *device_observer_list,
-                      OnNetworkDeviceChanged(this, device));
   } else {
     LOG(ERROR) << "Unexpected signal for unobserved device: "
                << device->name();
@@ -1646,13 +1577,6 @@
   sim_operation_ = SIM_OPERATION_NONE;
 }
 
-void NetworkLibraryImplBase::NotifyUserConnectionInitiated(
-    const Network* network) {
-  FOR_EACH_OBSERVER(UserActionObserver,
-                    user_action_observers_,
-                    OnConnectionInitiated(this, network));
-}
-
 //////////////////////////////////////////////////////////////////////////////
 // Pin related functions.
 
diff --git a/chrome/browser/chromeos/cros/network_library_impl_base.h b/chrome/browser/chromeos/cros/network_library_impl_base.h
index 75e9fac..e0519c4 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_base.h
+++ b/chrome/browser/chromeos/cros/network_library_impl_base.h
@@ -90,10 +90,6 @@
       PinOperationObserver* observer) OVERRIDE;
   virtual void RemovePinOperationObserver(
       PinOperationObserver* observer) OVERRIDE;
-  virtual void AddUserActionObserver(
-      UserActionObserver* observer) OVERRIDE;
-  virtual void RemoveUserActionObserver(
-      UserActionObserver* observer) OVERRIDE;
 
   virtual const EthernetNetwork* ethernet_network() const OVERRIDE;
   virtual bool ethernet_connecting() const OVERRIDE;
@@ -107,9 +103,6 @@
   virtual const WimaxNetwork* wimax_network() const OVERRIDE;
   virtual bool wimax_connecting() const OVERRIDE;
   virtual bool wimax_connected() const OVERRIDE;
-  virtual const Network* mobile_network() const OVERRIDE;
-  virtual bool mobile_connecting() const OVERRIDE;
-  virtual bool mobile_connected() const OVERRIDE;
   virtual const VirtualNetwork* virtual_network() const OVERRIDE;
   virtual bool virtual_network_connecting() const OVERRIDE;
   virtual bool virtual_network_connected() const OVERRIDE;
@@ -130,25 +123,18 @@
   virtual bool wifi_available() const OVERRIDE;
   virtual bool wimax_available() const OVERRIDE;
   virtual bool cellular_available() const OVERRIDE;
-  virtual bool mobile_available() const OVERRIDE;
   virtual bool ethernet_enabled() const OVERRIDE;
   virtual bool wifi_enabled() const OVERRIDE;
   virtual bool wimax_enabled() const OVERRIDE;
   virtual bool cellular_enabled() const OVERRIDE;
-  virtual bool mobile_enabled() const OVERRIDE;
   virtual bool wifi_scanning() const OVERRIDE;
   virtual bool cellular_initializing() const OVERRIDE;
-  virtual bool offline_mode() const OVERRIDE;
-  virtual const std::string& IPAddress() const OVERRIDE;
 
   virtual const NetworkDevice* FindNetworkDeviceByPath(
       const std::string& path) const OVERRIDE;
   NetworkDevice* FindNetworkDeviceByPath(const std::string& path);
   virtual const NetworkDevice* FindMobileDevice() const OVERRIDE;
-  virtual const NetworkDevice* FindWimaxDevice() const OVERRIDE;
   virtual const NetworkDevice* FindCellularDevice() const OVERRIDE;
-  virtual const NetworkDevice* FindEthernetDevice() const OVERRIDE;
-  virtual const NetworkDevice* FindWifiDevice() const OVERRIDE;
   virtual Network* FindNetworkByPath(const std::string& path) const OVERRIDE;
   virtual Network* FindNetworkByUniqueId(
       const std::string& unique_id) const OVERRIDE;
@@ -182,11 +168,9 @@
   // virtual RequestCellularRegister implemented in derived classes.
   // virtual SetCellularDataRoamingAllowed implemented in derived classes.
   // virtual SetCarrier implemented in derived classes.
-  // virtual ResetModem implemented in derived classes.
   // virtual IsCellularAlwaysInRoaming implemented in derived classes.
   // virtual RequestNetworkScan implemented in derived classes.
 
-  virtual bool HasProfileType(NetworkProfileType type) const OVERRIDE;
   virtual bool CanConnectToNetwork(const Network* network) const OVERRIDE;
 
   // Connect to an existing network.
@@ -216,13 +200,10 @@
   virtual void ForgetNetwork(const std::string& service_path) OVERRIDE;
   virtual void EnableEthernetNetworkDevice(bool enable) OVERRIDE;
   virtual void EnableWifiNetworkDevice(bool enable) OVERRIDE;
-  virtual void EnableMobileNetworkDevice(bool enable) OVERRIDE;
   virtual void EnableWimaxNetworkDevice(bool enable) OVERRIDE;
   virtual void EnableCellularNetworkDevice(bool enable) OVERRIDE;
-  // virtual EnableOfflineMode implemented in derived classes.
   // virtual GetIPConfigs implemented in derived classes.
   // virtual SetIPConfig implemented in derived classes.
-  virtual void SwitchToPreferredNetwork() OVERRIDE;
   virtual void LoadOncNetworks(const base::ListValue& network_configs,
                                onc::ONCSource source) OVERRIDE;
   virtual bool SetActiveNetwork(ConnectionType type,
@@ -281,6 +262,14 @@
     CONNECT_FAILED
   };
 
+  // Return true if a profile matching |type| is loaded.
+  bool HasProfileType(NetworkProfileType type) const;
+
+  // This will connect to a preferred network if the currently connected
+  // network is not preferred. This should be called when the active profile
+  // changes.
+  void SwitchToPreferredNetwork();
+
   // Finds device by connection type.
   const NetworkDevice* FindDeviceByType(ConnectionType type) const;
   // Called from ConnectTo*Network.
@@ -341,7 +330,6 @@
   void NotifyNetworkChanged(const Network* network);
   void NotifyNetworkDeviceChanged(NetworkDevice* device, PropertyIndex index);
   void NotifyPinOperationCompleted(PinOperationError error);
-  void NotifyUserConnectionInitiated(const Network* network);
 
   // TPM related functions.
   void GetTpmInfo();
@@ -357,9 +345,6 @@
   // PIN operation observer list.
   ObserverList<PinOperationObserver> pin_operation_observers_;
 
-  // User action observer list.
-  ObserverList<UserActionObserver> user_action_observers_;
-
   // Network observer map.
   NetworkObserverMap network_observers_;
 
@@ -439,9 +424,6 @@
   // True if we are currently scanning for wifi networks.
   bool wifi_scanning_;
 
-  // Currently not implemented. TODO(stevenjb): implement or eliminate.
-  bool offline_mode_;
-
   // List of interfaces for which portal check is enabled.
   std::string check_portal_list_;
 
diff --git a/chrome/browser/chromeos/cros/network_library_impl_cros.cc b/chrome/browser/chromeos/cros/network_library_impl_cros.cc
index 6109aa7..f3510c9 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_cros.cc
+++ b/chrome/browser/chromeos/cros/network_library_impl_cros.cc
@@ -10,7 +10,6 @@
 #include "base/metrics/histogram.h"
 #include "base/stl_util.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/native_network_constants.h"
 #include "chrome/browser/chromeos/cros/native_network_parser.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
@@ -48,8 +47,6 @@
 }
 
 void NetworkLibraryImplCros::Init() {
-  CHECK(CrosLibrary::Get()->libcros_loaded())
-      << "libcros must be loaded before NetworkLibraryImplCros::Init()";
   // First, get the currently available networks. This data is cached
   // on the connman side, so the call should be quick.
   VLOG(1) << "Requesting initial network manager info from libcros.";
@@ -201,7 +198,6 @@
     const std::string& service_path,
     NetworkMethodErrorType error,
     const std::string& error_message) {
-  DCHECK(CrosLibrary::Get()->libcros_loaded());
   NetworkConnectStatus status;
   if (error == NETWORK_METHOD_ERROR_NONE) {
     status = CONNECT_SUCCESS;
@@ -347,7 +343,6 @@
     const std::string& path,
     NetworkMethodErrorType error,
     const std::string& error_message) {
-  DCHECK(CrosLibrary::Get()->libcros_loaded());
   PinOperationError pin_error;
   VLOG(1) << "PinOperationCallback, error: " << error
           << " error_msg: " << error_message;
@@ -394,7 +389,6 @@
     const std::string& path,
     NetworkMethodErrorType error,
     const std::string& error_message) {
-  DCHECK(CrosLibrary::Get()->libcros_loaded());
   // TODO(dpolukhin): Notify observers about network registration status
   // but not UI doesn't assume such notification so just ignore result.
 }
@@ -423,15 +417,6 @@
   CrosSetCarrier(cellular->device_path(), carrier, completed);
 }
 
-void NetworkLibraryImplCros::ResetModem() {
-  const NetworkDevice* cellular = FindCellularDevice();
-  if (!cellular) {
-    NOTREACHED() << "Calling ResetModem method w/o cellular device.";
-    return;
-  }
-  CrosReset(cellular->device_path());
-}
-
 bool NetworkLibraryImplCros::IsCellularAlwaysInRoaming() {
   const NetworkDevice* cellular = FindCellularDevice();
   if (!cellular) {
@@ -502,13 +487,6 @@
   CrosRequestRemoveNetworkService(service_path);
 }
 
-void NetworkLibraryImplCros::EnableOfflineMode(bool enable) {
-  // If network device is already enabled/disabled, then don't do anything.
-  if (CrosSetOfflineMode(enable))
-    offline_mode_ = enable;
-}
-
-
 void NetworkLibraryImplCros::GetIPConfigsCallback(
     const NetworkGetIPConfigsCallback& callback,
     HardwareAddressFormat format,
@@ -636,12 +614,6 @@
     case PROPERTY_INDEX_DEFAULT_TECHNOLOGY:
       // Currently we ignore DefaultTechnology.
       break;
-    case PROPERTY_INDEX_OFFLINE_MODE: {
-      DCHECK_EQ(value->GetType(), Value::TYPE_BOOLEAN);
-      value->GetAsBoolean(&offline_mode_);
-      NotifyNetworkManagerChanged(false);  // Not forced.
-      break;
-    }
     case PROPERTY_INDEX_ACTIVE_PROFILE: {
       std::string prev = active_profile_path_;
       DCHECK_EQ(value->GetType(), Value::TYPE_STRING);
diff --git a/chrome/browser/chromeos/cros/network_library_impl_cros.h b/chrome/browser/chromeos/cros/network_library_impl_cros.h
index c81c1c9..c8aa59e 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_cros.h
+++ b/chrome/browser/chromeos/cros/network_library_impl_cros.h
@@ -58,19 +58,14 @@
   virtual void SetCellularDataRoamingAllowed(bool new_value) OVERRIDE;
   virtual void SetCarrier(const std::string& carrier,
                           const NetworkOperationCallback& completed) OVERRIDE;
-  virtual void ResetModem() OVERRIDE;
   virtual bool IsCellularAlwaysInRoaming() OVERRIDE;
   virtual void RequestNetworkScan() OVERRIDE;
 
-  virtual void RefreshIPConfig(Network* network) OVERRIDE;
-
   virtual void DisconnectFromNetwork(const Network* network) OVERRIDE;
   virtual void CallEnableNetworkDeviceType(
       ConnectionType device, bool enable) OVERRIDE;
   virtual void CallRemoveNetwork(const Network* network) OVERRIDE;
 
-  virtual void EnableOfflineMode(bool enable) OVERRIDE;
-
   virtual void GetIPConfigs(
       const std::string& device_path,
       HardwareAddressFormat format,
@@ -137,6 +132,10 @@
   // since Bind only takes up to six parameters.
   struct IPParameterInfo;
 
+  // Refresh the IP configuration of the given network after changes.  Puts
+  // newly configured properties into effect and renews DHCP lease.
+  void RefreshIPConfig(Network* network);
+
   // Second half of setting IP Parameters.  SetIPParameters above kicks off
   // an async information fetch, and this completes the operation when that
   // fetch is complete.
@@ -183,8 +182,6 @@
   class NetworkLibraryDeviceObserver : public NetworkDeviceObserver {
    public:
     virtual ~NetworkLibraryDeviceObserver() {}
-    virtual void OnNetworkDeviceChanged(
-        NetworkLibrary* cros, const NetworkDevice* device) OVERRIDE {}
   };
 
   typedef std::map<std::string, CrosNetworkWatcher*> NetworkWatcherMap;
diff --git a/chrome/browser/chromeos/cros/network_library_impl_stub.cc b/chrome/browser/chromeos/cros/network_library_impl_stub.cc
index 3df19fb..af7ec44 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_stub.cc
+++ b/chrome/browser/chromeos/cros/network_library_impl_stub.cc
@@ -231,7 +231,6 @@
   AddStubNetwork(vpn_cert_pattern, PROFILE_USER);
 
   wifi_scanning_ = false;
-  offline_mode_ = false;
 
   // Ensure our active network is connected and vice versa, otherwise our
   // autotest browser_tests sometimes conclude the device is offline.
@@ -471,10 +470,7 @@
   }
 
   // Set connected state.
-  if (network->is_behind_portal_for_testing())
-    network->set_behind_portal();
-  else
-    network->set_connected();
+  network->set_connected();
   network->set_user_connect_state(USER_CONNECT_CONNECTED);
 
   // Make the connected network the highest priority network.
@@ -684,9 +680,6 @@
       base::TimeDelta::FromMilliseconds(delay_ms));
 }
 
-void NetworkLibraryImplStub::ResetModem() {
-}
-
 bool NetworkLibraryImplStub::IsCellularAlwaysInRoaming() {
   return false;
 }
@@ -702,9 +695,6 @@
       base::TimeDelta::FromMilliseconds(scan_delay_ms));
 }
 
-void NetworkLibraryImplStub::RefreshIPConfig(Network* network) {
-}
-
 void NetworkLibraryImplStub::DisconnectFromNetwork(const Network* network) {
   // Update the network state here since no network manager in stub impl.
   Network* modify_network = const_cast<Network*>(network);
@@ -720,14 +710,6 @@
   NotifyNetworkChanged(network);
 }
 
-void NetworkLibraryImplStub::EnableOfflineMode(bool enable) {
-  if (enable != offline_mode_) {
-    offline_mode_ = enable;
-    CallEnableNetworkDeviceType(TYPE_WIFI, !enable);
-    CallEnableNetworkDeviceType(TYPE_CELLULAR, !enable);
-  }
-}
-
 void NetworkLibraryImplStub::GetIPConfigs(
     const std::string& device_path,
     HardwareAddressFormat format,
diff --git a/chrome/browser/chromeos/cros/network_library_impl_stub.h b/chrome/browser/chromeos/cros/network_library_impl_stub.h
index 3501a8b..c7d6075 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_stub.h
+++ b/chrome/browser/chromeos/cros/network_library_impl_stub.h
@@ -61,16 +61,11 @@
   virtual void SetCellularDataRoamingAllowed(bool new_value) OVERRIDE;
   virtual void SetCarrier(const std::string& carrier,
                           const NetworkOperationCallback& completed) OVERRIDE;
-  virtual void ResetModem() OVERRIDE;
   virtual bool IsCellularAlwaysInRoaming() OVERRIDE;
   virtual void RequestNetworkScan() OVERRIDE;
 
-  virtual void RefreshIPConfig(Network* network) OVERRIDE;
-
   virtual void DisconnectFromNetwork(const Network* network) OVERRIDE;
 
-  virtual void EnableOfflineMode(bool enable) OVERRIDE;
-
   virtual void GetIPConfigs(
       const std::string& device_path,
       HardwareAddressFormat format,
diff --git a/chrome/browser/chromeos/cros/network_library_unittest.cc b/chrome/browser/chromeos/cros/network_library_unittest.cc
index 2ba7361..6f3731a 100644
--- a/chrome/browser/chromeos/cros/network_library_unittest.cc
+++ b/chrome/browser/chromeos/cros/network_library_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/json/json_reader.h"
 #include "base/lazy_instance.h"
 #include "base/path_service.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/cros/network_library_impl_stub.h"
 #include "chrome/browser/chromeos/login/mock_user_manager.h"
@@ -138,8 +137,7 @@
 
  protected:
   virtual void SetUp() {
-    cros_ = static_cast<NetworkLibraryImplStub*>(
-        CrosLibrary::Get()->GetNetworkLibrary());
+    cros_ = static_cast<NetworkLibraryImplStub*>(NetworkLibrary::Get());
     ASSERT_TRUE(cros_) << "GetNetworkLibrary() Failed!";
   }
 
@@ -197,7 +195,7 @@
     }
   }
 
-  ScopedStubCrosEnabler cros_stub_;
+  ScopedStubNetworkLibraryEnabler cros_stub_;
   NetworkLibraryImplStub* cros_;
 
  protected:
diff --git a/chrome/browser/chromeos/cros/network_parser.cc b/chrome/browser/chromeos/cros/network_parser.cc
index c1cb5b5..e769a82 100644
--- a/chrome/browser/chromeos/cros/network_parser.cc
+++ b/chrome/browser/chromeos/cros/network_parser.cc
@@ -121,7 +121,6 @@
   PropertyIndex found_index = mapper().Get(key);
   if (index)
     *index = found_index;
-  network->UpdatePropertyMap(found_index, &value);
   if (!ParseValue(found_index, value, network)) {
     VLOG(3) << "Unhandled key '" << key << "' in Network: " << network->name()
             << " ID: " << network->unique_id()
diff --git a/chrome/browser/chromeos/customization_document.h b/chrome/browser/chromeos/customization_document.h
index 7f33edb..09b0b56 100644
--- a/chrome/browser/chromeos/customization_document.h
+++ b/chrome/browser/chromeos/customization_document.h
@@ -13,8 +13,8 @@
 #include "base/memory/singleton.h"
 #include "base/timer/timer.h"
 #include "base/values.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_fetcher_delegate.h"
+#include "url/gurl.h"
 
 class PrefRegistrySimple;
 
diff --git a/chrome/browser/chromeos/device_uma.cc b/chrome/browser/chromeos/device_uma.cc
index 2f852bb..2bba70e 100644
--- a/chrome/browser/chromeos/device_uma.cc
+++ b/chrome/browser/chromeos/device_uma.cc
@@ -98,7 +98,8 @@
 void DeviceUMA::CheckIncomingEvent(const base::NativeEvent& event) {
   switch (event->type) {
     case GenericEvent: {
-      if (ui::IsTouchpadEvent(event))
+      if (ui::DeviceDataManager::GetInstance()->IsXIDeviceEvent(event) &&
+          ui::IsTouchpadEvent(event))
         CheckTouchpadEvent(event);
       break;
     }
diff --git a/chrome/browser/chromeos/display/display_preferences.cc b/chrome/browser/chromeos/display/display_preferences.cc
index 33c4581..2650909 100644
--- a/chrome/browser/chromeos/display/display_preferences.cc
+++ b/chrome/browser/chromeos/display/display_preferences.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/chromeos/display/display_preferences.h"
 
 #include "ash/display/display_controller.h"
+#include "ash/display/display_layout_store.h"
 #include "ash/display/display_manager.h"
 #include "ash/display/display_pref_util.h"
 #include "ash/shell.h"
@@ -20,12 +21,12 @@
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/display/output_configurator.h"
-#include "googleurl/src/url_canon.h"
-#include "googleurl/src/url_util.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 #include "ui/gfx/display.h"
 #include "ui/gfx/insets.h"
 #include "ui/gfx/screen.h"
+#include "url/url_canon.h"
+#include "url/url_util.h"
 
 namespace chromeos {
 namespace {
@@ -82,7 +83,8 @@
 
 void LoadDisplayLayouts() {
   PrefService* local_state = g_browser_process->local_state();
-  ash::DisplayController* display_controller = GetDisplayController();
+  ash::internal::DisplayLayoutStore* layout_store =
+      GetDisplayManager()->layout_store();
 
   const base::DictionaryValue* layouts = local_state->GetDictionary(
       prefs::kSecondaryDisplays);
@@ -104,7 +106,7 @@
           id2 == gfx::Display::kInvalidDisplayID) {
         continue;
       }
-      display_controller->RegisterLayoutForDisplayIdPair(id1, id2, layout);
+      layout_store->RegisterLayoutForDisplayIdPair(id1, id2, layout);
     }
   }
 }
@@ -165,10 +167,9 @@
   if (!IsValidUser() || GetDisplayManager()->num_connected_displays() < 2)
     return;
 
-  ash::DisplayController* display_controller = GetDisplayController();
-  ash::DisplayIdPair pair = display_controller->GetCurrentDisplayIdPair();
+  ash::DisplayIdPair pair = GetDisplayController()->GetCurrentDisplayIdPair();
   ash::DisplayLayout display_layout =
-      display_controller->GetRegisteredDisplayLayout(pair);
+      GetDisplayManager()->layout_store()->GetRegisteredDisplayLayout(pair);
   StoreDisplayLayoutPref(pair, display_layout);
 }
 
diff --git a/chrome/browser/chromeos/display/display_preferences_unittest.cc b/chrome/browser/chromeos/display/display_preferences_unittest.cc
index a87a628..023cfdf 100644
--- a/chrome/browser/chromeos/display/display_preferences_unittest.cc
+++ b/chrome/browser/chromeos/display/display_preferences_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/chromeos/display/display_preferences.h"
 
 #include "ash/display/display_controller.h"
+#include "ash/display/display_layout_store.h"
 #include "ash/display/display_manager.h"
 #include "ash/screen_ash.h"
 #include "ash/shell.h"
@@ -130,7 +131,7 @@
     ash::DisplayIdPair pair;
     pair.first = id1;
     pair.second = id2;
-    return ash::Shell::GetInstance()->display_controller()->
+    return ash::Shell::GetInstance()->display_manager()->layout_store()->
         GetRegisteredDisplayLayout(pair).ToString();
   }
 
@@ -271,7 +272,7 @@
   SetCurrentDisplayLayout(
       ash::DisplayLayout(ash::DisplayLayout::BOTTOM, 20));
 
-  UpdateDisplay("200x200*2,1+0-200x200");
+  UpdateDisplay("1+0-200x200*2,1+0-200x200");
   // Mirrored.
   int offset = 0;
   std::string position;
diff --git a/chrome/browser/chromeos/drive/async_file_util.cc b/chrome/browser/chromeos/drive/async_file_util.cc
new file mode 100644
index 0000000..e385033
--- /dev/null
+++ b/chrome/browser/chromeos/drive/async_file_util.cc
@@ -0,0 +1,431 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/drive/async_file_util.h"
+
+#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/platform_file.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "chrome/browser/chromeos/drive/file_system_util.h"
+#include "chrome/browser/chromeos/drive/fileapi_worker.h"
+#include "chrome/browser/google_apis/task_util.h"
+#include "content/public/browser/browser_thread.h"
+#include "webkit/browser/fileapi/file_system_operation_context.h"
+#include "webkit/browser/fileapi/file_system_url.h"
+#include "webkit/common/blob/shareable_file_reference.h"
+
+using content::BrowserThread;
+
+namespace drive {
+namespace internal {
+namespace {
+
+// Posts fileapi_internal::RunFileSystemCallback to UI thread.
+// This function must be called on IO thread.
+// The |on_error_callback| will be called (on error case) on IO thread.
+void PostFileSystemCallback(
+    const fileapi_internal::FileSystemGetter& file_system_getter,
+    const base::Callback<void(FileSystemInterface*)>& function,
+    const base::Closure& on_error_callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  BrowserThread::PostTask(
+      BrowserThread::UI,
+      FROM_HERE,
+      base::Bind(&fileapi_internal::RunFileSystemCallback,
+                 file_system_getter, function,
+                 on_error_callback.is_null() ?
+                 base::Closure() :
+                 base::Bind(&google_apis::RunTaskOnThread,
+                            base::MessageLoopProxy::current(),
+                            on_error_callback)));
+}
+
+// Runs CreateOrOpenFile callback based on the given |error| and |file|.
+void RunCreateOrOpenFileCallback(
+    const AsyncFileUtil::FileSystemGetter& file_system_getter,
+    const base::FilePath& file_path,
+    const AsyncFileUtil::CreateOrOpenCallback& callback,
+    base::PlatformFileError error,
+    base::PlatformFile file) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  // It is necessary to make a closure, which runs on file closing here.
+  // It will be provided as a FileSystem::OpenFileCallback's argument later.
+  // (crbug.com/259184).
+  callback.Run(
+      error, base::PassPlatformFile(&file),
+      base::Bind(&PostFileSystemCallback,
+                 file_system_getter,
+                 base::Bind(&fileapi_internal::CloseFile, file_path),
+                 base::Closure()));
+}
+
+// Runs CreateOrOpenFile when the error happens.
+void RunCreateOrOpenFileCallbackOnError(
+    const AsyncFileUtil::CreateOrOpenCallback& callback,
+    base::PlatformFileError error) {
+  // Because the |callback| takes PassPlatformFile as its argument, and
+  // it is necessary to garantee the pointer passed to PassPlatformFile is
+  // alive during the |callback| invocation, here we prepare a thin adapter
+  // to have PlatformFile on stack frame.
+  base::PlatformFile file = base::kInvalidPlatformFileValue;
+  callback.Run(error, base::PassPlatformFile(&file), base::Closure());
+}
+
+// Runs EnsureFileExistsCallback based on the given |error|.
+void RunEnsureFileExistsCallback(
+    const AsyncFileUtil::EnsureFileExistsCallback& callback,
+    base::PlatformFileError error) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  // Remember if the file is actually created or not.
+  bool created = (error == base::PLATFORM_FILE_OK);
+
+  // PLATFORM_FILE_ERROR_EXISTS is not an actual error here.
+  if (error == base::PLATFORM_FILE_ERROR_EXISTS)
+    error = base::PLATFORM_FILE_OK;
+
+  callback.Run(error, created);
+}
+
+
+// Runs |callback| with the arguments based on the given arguments.
+void RunCreateSnapshotFileCallback(
+    const AsyncFileUtil::CreateSnapshotFileCallback& callback,
+    base::PlatformFileError error,
+    const base::PlatformFileInfo& file_info,
+    const base::FilePath& local_path,
+    webkit_blob::ScopedFile::ScopeOutPolicy scope_out_policy) {
+  // ShareableFileReference is thread *unsafe* class. So it is necessary to
+  // create the instance (by invoking GetOrCreate) on IO thread, though
+  // most drive file system related operations run on UI thread.
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  scoped_refptr<webkit_blob::ShareableFileReference> file_reference =
+      webkit_blob::ShareableFileReference::GetOrCreate(webkit_blob::ScopedFile(
+          local_path,
+          scope_out_policy,
+          BrowserThread::GetBlockingPool()));
+  callback.Run(error, file_info, local_path, file_reference);
+}
+
+}  // namespace
+
+AsyncFileUtil::AsyncFileUtil(const FileSystemGetter& file_system_getter)
+    : file_system_getter_(file_system_getter) {
+}
+
+AsyncFileUtil::~AsyncFileUtil() {
+}
+
+void AsyncFileUtil::CreateOrOpen(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    int file_flags,
+    const CreateOrOpenCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty()) {
+    base::PlatformFile platform_file = base::kInvalidPlatformFileValue;
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND,
+                 base::PassPlatformFile(&platform_file),
+                 base::Closure());
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::OpenFile,
+                 file_path, file_flags,
+                 google_apis::CreateRelayCallback(
+                     base::Bind(&RunCreateOrOpenFileCallback,
+                                file_system_getter_, file_path, callback))),
+      base::Bind(&RunCreateOrOpenFileCallbackOnError,
+                 callback, base::PLATFORM_FILE_ERROR_FAILED));
+}
+
+void AsyncFileUtil::EnsureFileExists(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    const EnsureFileExistsCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND, false);
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::CreateFile,
+                 file_path, true /* is_exlusive */,
+                 google_apis::CreateRelayCallback(
+                     base::Bind(&RunEnsureFileExistsCallback, callback))),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, false));
+}
+
+void AsyncFileUtil::CreateDirectory(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    bool exclusive,
+    bool recursive,
+    const StatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::CreateDirectory,
+                 file_path, exclusive, recursive,
+                 google_apis::CreateRelayCallback(callback)),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
+}
+
+void AsyncFileUtil::GetFileInfo(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    const GetFileInfoCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND, base::PlatformFileInfo());
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::GetFileInfo,
+                 file_path, google_apis::CreateRelayCallback(callback)),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED,
+                 base::PlatformFileInfo()));
+}
+
+void AsyncFileUtil::ReadDirectory(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    const ReadDirectoryCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND, EntryList(), false);
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::ReadDirectory,
+                 file_path, google_apis::CreateRelayCallback(callback)),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED,
+                 EntryList(), false));
+}
+
+void AsyncFileUtil::Touch(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    const base::Time& last_access_time,
+    const base::Time& last_modified_time,
+    const StatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::TouchFile,
+                 file_path, last_access_time, last_modified_time,
+                 google_apis::CreateRelayCallback(callback)),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
+}
+
+void AsyncFileUtil::Truncate(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    int64 length,
+    const StatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::Truncate,
+                 file_path, length, google_apis::CreateRelayCallback(callback)),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
+}
+
+void AsyncFileUtil::CopyFileLocal(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& src_url,
+    const fileapi::FileSystemURL& dest_url,
+    const StatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath src_path = util::ExtractDrivePathFromFileSystemUrl(src_url);
+  base::FilePath dest_path = util::ExtractDrivePathFromFileSystemUrl(dest_url);
+  if (src_path.empty() || dest_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::Copy,
+                 src_path, dest_path,
+                 google_apis::CreateRelayCallback(callback)),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
+}
+
+void AsyncFileUtil::MoveFileLocal(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& src_url,
+    const fileapi::FileSystemURL& dest_url,
+    const StatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath src_path = util::ExtractDrivePathFromFileSystemUrl(src_url);
+  base::FilePath dest_path = util::ExtractDrivePathFromFileSystemUrl(dest_url);
+  if (src_path.empty() || dest_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::Move,
+                 src_path, dest_path,
+                 google_apis::CreateRelayCallback(callback)),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
+}
+
+void AsyncFileUtil::CopyInForeignFile(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const base::FilePath& src_file_path,
+    const fileapi::FileSystemURL& dest_url,
+    const StatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath dest_path = util::ExtractDrivePathFromFileSystemUrl(dest_url);
+  if (dest_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::CopyInForeignFile,
+                 src_file_path, dest_path,
+                 google_apis::CreateRelayCallback(callback)),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
+}
+
+void AsyncFileUtil::DeleteFile(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    const StatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::Remove,
+                 file_path, false /* not recursive */,
+                 google_apis::CreateRelayCallback(callback)),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
+}
+
+void AsyncFileUtil::DeleteDirectory(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    const StatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::Remove,
+                 file_path, false /* not recursive */,
+                 google_apis::CreateRelayCallback(callback)),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
+}
+
+void AsyncFileUtil::DeleteRecursively(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    const StatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND);
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::Remove,
+                 file_path, true /* recursive */,
+                 google_apis::CreateRelayCallback(callback)),
+      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
+}
+
+void AsyncFileUtil::CreateSnapshotFile(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    const CreateSnapshotFileCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty()) {
+    callback.Run(base::PLATFORM_FILE_ERROR_NOT_FOUND,
+                 base::PlatformFileInfo(),
+                 base::FilePath(),
+                 scoped_refptr<webkit_blob::ShareableFileReference>());
+    return;
+  }
+
+  PostFileSystemCallback(
+      file_system_getter_,
+      base::Bind(&fileapi_internal::CreateSnapshotFile,
+                 file_path,
+                 google_apis::CreateRelayCallback(
+                     base::Bind(&RunCreateSnapshotFileCallback, callback))),
+      base::Bind(callback,
+                 base::PLATFORM_FILE_ERROR_FAILED,
+                 base::PlatformFileInfo(),
+                 base::FilePath(),
+                 scoped_refptr<webkit_blob::ShareableFileReference>()));
+}
+
+}  // namespace internal
+}  // namespace drive
diff --git a/chrome/browser/chromeos/drive/async_file_util.h b/chrome/browser/chromeos/drive/async_file_util.h
new file mode 100644
index 0000000..dfbe2d7
--- /dev/null
+++ b/chrome/browser/chromeos/drive/async_file_util.h
@@ -0,0 +1,106 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_ASYNC_FILE_UTIL_H_
+#define CHROME_BROWSER_CHROMEOS_DRIVE_ASYNC_FILE_UTIL_H_
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "webkit/browser/fileapi/async_file_util.h"
+
+namespace drive {
+
+class FileSystemInterface;
+
+namespace internal {
+
+// The implementation of fileapis::AsyncFileUtil for Drive File System.
+class AsyncFileUtil : public fileapi::AsyncFileUtil {
+ public:
+  // Callback to return the FileSystemInterface instance. This is an
+  // injecting point for testing.
+  // Note that the callback will be copied between threads (IO and UI), and
+  // will be called on UI thread.
+  typedef base::Callback<FileSystemInterface*()> FileSystemGetter;
+
+  explicit AsyncFileUtil(const FileSystemGetter& file_system_getter);
+  virtual ~AsyncFileUtil();
+
+  // fileapi::AsyncFileUtil overrides.
+  virtual void CreateOrOpen(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& url,
+      int file_flags,
+      const CreateOrOpenCallback& callback) OVERRIDE;
+  virtual void EnsureFileExists(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& url,
+      const EnsureFileExistsCallback& callback) OVERRIDE;
+  virtual void CreateDirectory(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& url,
+      bool exclusive,
+      bool recursive,
+      const StatusCallback& callback) OVERRIDE;
+  virtual void GetFileInfo(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& url,
+      const GetFileInfoCallback& callback) OVERRIDE;
+  virtual void ReadDirectory(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& url,
+      const ReadDirectoryCallback& callback) OVERRIDE;
+  virtual void Touch(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& url,
+      const base::Time& last_access_time,
+      const base::Time& last_modified_time,
+      const StatusCallback& callback) OVERRIDE;
+  virtual void Truncate(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& url,
+      int64 length,
+      const StatusCallback& callback) OVERRIDE;
+  virtual void CopyFileLocal(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& src_url,
+      const fileapi::FileSystemURL& dest_url,
+      const StatusCallback& callback) OVERRIDE;
+  virtual void MoveFileLocal(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& src_url,
+      const fileapi::FileSystemURL& dest_url,
+      const StatusCallback& callback) OVERRIDE;
+  virtual void CopyInForeignFile(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const base::FilePath& src_file_path,
+      const fileapi::FileSystemURL& dest_url,
+      const StatusCallback& callback) OVERRIDE;
+  virtual void DeleteFile(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& url,
+      const StatusCallback& callback) OVERRIDE;
+  virtual void DeleteDirectory(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& url,
+      const StatusCallback& callback) OVERRIDE;
+  virtual void DeleteRecursively(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& url,
+      const StatusCallback& callback) OVERRIDE;
+  virtual void CreateSnapshotFile(
+      scoped_ptr<fileapi::FileSystemOperationContext> context,
+      const fileapi::FileSystemURL& url,
+      const CreateSnapshotFileCallback& callback) OVERRIDE;
+
+ private:
+  FileSystemGetter file_system_getter_;
+
+  DISALLOW_COPY_AND_ASSIGN(AsyncFileUtil);
+};
+
+}  // namespace internal
+}  // namespace drive
+
+#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_ASYNC_FILE_UTIL_H_
diff --git a/chrome/browser/chromeos/drive/change_list_loader.cc b/chrome/browser/chromeos/drive/change_list_loader.cc
index 99548da..e9ede35 100644
--- a/chrome/browser/chromeos/drive/change_list_loader.cc
+++ b/chrome/browser/chromeos/drive/change_list_loader.cc
@@ -19,7 +19,7 @@
 #include "chrome/browser/drive/drive_api_util.h"
 #include "chrome/browser/google_apis/drive_api_parser.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
@@ -97,22 +97,6 @@
   Load(directory_fetch_info, callback);
 }
 
-void ChangeListLoader::LoadDirectoryFromServer(
-    const std::string& directory_resource_id,
-    const FileOperationCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  // First fetch the latest changestamp to see if this directory needs to be
-  // updated.
-  scheduler_->GetAboutResource(
-      base::Bind(
-          &ChangeListLoader::LoadDirectoryFromServerAfterGetAbout,
-          weak_ptr_factory_.GetWeakPtr(),
-          directory_resource_id,
-          callback));
-}
-
 void ChangeListLoader::Load(const DirectoryFetchInfo& directory_fetch_info,
                             const FileOperationCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -442,25 +426,6 @@
                     OnLoadFromServerComplete());
 }
 
-void ChangeListLoader::LoadDirectoryFromServerAfterGetAbout(
-      const std::string& directory_resource_id,
-      const FileOperationCallback& callback,
-      google_apis::GDataErrorCode status,
-      scoped_ptr<google_apis::AboutResource> about_resource) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  if (util::GDataToFileError(status) == FILE_ERROR_OK) {
-    DCHECK(about_resource);
-    last_known_remote_changestamp_ = about_resource->largest_change_id();
-  }
-
-  const DirectoryFetchInfo directory_fetch_info(
-      directory_resource_id,
-      last_known_remote_changestamp_);
-  DoLoadDirectoryFromServer(directory_fetch_info, callback);
-}
-
 void ChangeListLoader::CheckChangestampAndLoadDirectoryIfNeeded(
     const DirectoryFetchInfo& directory_fetch_info,
     int64 local_changestamp,
diff --git a/chrome/browser/chromeos/drive/change_list_loader.h b/chrome/browser/chromeos/drive/change_list_loader.h
index a476dff..cb12079 100644
--- a/chrome/browser/chromeos/drive/change_list_loader.h
+++ b/chrome/browser/chromeos/drive/change_list_loader.h
@@ -92,20 +92,6 @@
   void LoadIfNeeded(const DirectoryFetchInfo& directory_fetch_info,
                     const FileOperationCallback& callback);
 
-  // Initiates the directory contents loading. This function first obtains
-  // the changestamp from the server in order to set the per-directory
-  // changestamp for the directory.
-  //
-  // Upon completion, |callback| is invoked. On success, the changestamp of
-  // the directory is updated. |callback| must not be null.
-  //
-  // Note that This function initiates the loading without comparing the
-  // directory changestamp against the server changestamp. The primary
-  // purpose of this function is to update parts of entries in the directory
-  // which can stale over time, such as thumbnail URLs.
-  void LoadDirectoryFromServer(const std::string& directory_resource_id,
-                               const FileOperationCallback& callback);
-
  private:
   // Starts the resource metadata loading and calls |callback| when it's
   // done. |directory_fetch_info| is used for fast fetch. If there is already
@@ -186,17 +172,6 @@
 
   // ================= Implementation for directory loading =================
 
-  // Part of LoadDirectoryFromServer().
-  // Called after GetAboutResource() for getting remote changestamp is complete.
-  // Note that it directly proceeds to DoLoadDirectoryFromServer() not going
-  // through CheckChangestampAndLoadDirectoryIfNeeded, because the purpose of
-  // LoadDirectoryFromServer is to force reloading regardless of changestamp.
-  void LoadDirectoryFromServerAfterGetAbout(
-      const std::string& directory_resource_id,
-      const FileOperationCallback& callback,
-      google_apis::GDataErrorCode status,
-      scoped_ptr<google_apis::AboutResource> about_resource);
-
   // Compares the directory's changestamp and |last_known_remote_changestamp_|.
   // Starts DoLoadDirectoryFromServer() if the local data is old and runs
   // |callback| when finished. If it is up to date, calls back immediately.
diff --git a/chrome/browser/chromeos/drive/change_list_loader_unittest.cc b/chrome/browser/chromeos/drive/change_list_loader_unittest.cc
index 303845d..1a0d7dc 100644
--- a/chrome/browser/chromeos/drive/change_list_loader_unittest.cc
+++ b/chrome/browser/chromeos/drive/change_list_loader_unittest.cc
@@ -6,15 +6,16 @@
 
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/prefs/testing_pref_service.h"
 #include "base/run_loop.h"
 #include "chrome/browser/chromeos/drive/change_list_loader_observer.h"
 #include "chrome/browser/chromeos/drive/file_cache.h"
+#include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/browser/chromeos/drive/job_scheduler.h"
 #include "chrome/browser/chromeos/drive/resource_metadata.h"
 #include "chrome/browser/chromeos/drive/test_util.h"
 #include "chrome/browser/drive/fake_drive_service.h"
 #include "chrome/browser/google_apis/test_util.h"
-#include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -69,7 +70,8 @@
  protected:
   virtual void SetUp() OVERRIDE {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-    profile_.reset(new TestingProfile);
+    pref_service_.reset(new TestingPrefServiceSimple);
+    test_util::RegisterDrivePrefs(pref_service_->registry());
 
     drive_service_.reset(new FakeDriveService);
     ASSERT_TRUE(drive_service_->LoadResourceListForWapi(
@@ -77,29 +79,32 @@
     ASSERT_TRUE(drive_service_->LoadAccountMetadataForWapi(
         "gdata/account_metadata.json"));
 
-    scheduler_.reset(new JobScheduler(profile_.get(), drive_service_.get(),
-                                      base::MessageLoopProxy::current()));
+    scheduler_.reset(new JobScheduler(pref_service_.get(),
+                                      drive_service_.get(),
+                                      base::MessageLoopProxy::current().get()));
     metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.path(), base::MessageLoopProxy::current()));
+        temp_dir_.path(), base::MessageLoopProxy::current().get()));
     ASSERT_TRUE(metadata_storage_->Initialize());
 
-    metadata_.reset(new ResourceMetadata(metadata_storage_.get(),
-                                         base::MessageLoopProxy::current()));
+    metadata_.reset(new ResourceMetadata(
+        metadata_storage_.get(), base::MessageLoopProxy::current().get()));
     ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());
 
     cache_.reset(new FileCache(metadata_storage_.get(),
                                temp_dir_.path(),
-                               base::MessageLoopProxy::current(),
+                               base::MessageLoopProxy::current().get(),
                                NULL /* free_disk_space_getter */));
     ASSERT_TRUE(cache_->Initialize());
 
-    change_list_loader_.reset(new ChangeListLoader(
-        base::MessageLoopProxy::current(), metadata_.get(), scheduler_.get()));
+    change_list_loader_.reset(
+        new ChangeListLoader(base::MessageLoopProxy::current().get(),
+                             metadata_.get(),
+                             scheduler_.get()));
   }
 
   content::TestBrowserThreadBundle thread_bundle_;
   base::ScopedTempDir temp_dir_;
-  scoped_ptr<TestingProfile> profile_;
+  scoped_ptr<TestingPrefServiceSimple> pref_service_;
   scoped_ptr<FakeDriveService> drive_service_;
   scoped_ptr<JobScheduler> scheduler_;
   scoped_ptr<ResourceMetadataStorage,
@@ -147,5 +152,83 @@
             drive_service_->resource_list_load_count());
 }
 
+TEST_F(ChangeListLoaderTest, CheckForUpdates) {
+  // CheckForUpdates() results in no-op before load.
+  FileError check_for_updates_error = FILE_ERROR_FAILED;
+  change_list_loader_->CheckForUpdates(
+      google_apis::test_util::CreateCopyResultCallback(
+          &check_for_updates_error));
+  EXPECT_FALSE(change_list_loader_->IsRefreshing());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(FILE_ERROR_FAILED,
+            check_for_updates_error);  // Callback was not run.
+  EXPECT_EQ(0, metadata_->GetLargestChangestamp());
+  EXPECT_EQ(0, drive_service_->resource_list_load_count());
+
+  // Start initial load.
+  FileError load_error = FILE_ERROR_FAILED;
+  change_list_loader_->LoadIfNeeded(
+      DirectoryFetchInfo(),
+      google_apis::test_util::CreateCopyResultCallback(&load_error));
+  EXPECT_TRUE(change_list_loader_->IsRefreshing());
+
+  // CheckForUpdates() while loading.
+  change_list_loader_->CheckForUpdates(
+      google_apis::test_util::CreateCopyResultCallback(
+          &check_for_updates_error));
+
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(change_list_loader_->IsRefreshing());
+  EXPECT_EQ(FILE_ERROR_OK, load_error);
+  EXPECT_EQ(FILE_ERROR_OK, check_for_updates_error);
+  EXPECT_LT(0, metadata_->GetLargestChangestamp());
+  EXPECT_EQ(1, drive_service_->resource_list_load_count());
+
+  int64 previous_changestamp = metadata_->GetLargestChangestamp();
+  // CheckForUpdates() results in no update.
+  change_list_loader_->CheckForUpdates(
+      google_apis::test_util::CreateCopyResultCallback(
+          &check_for_updates_error));
+  EXPECT_TRUE(change_list_loader_->IsRefreshing());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(change_list_loader_->IsRefreshing());
+  EXPECT_EQ(previous_changestamp, metadata_->GetLargestChangestamp());
+
+  // Add a file to the service.
+  google_apis::GDataErrorCode gdata_error = google_apis::GDATA_FILE_ERROR;
+  scoped_ptr<google_apis::ResourceEntry> gdata_entry;
+  drive_service_->AddNewFile(
+      "text/plain",
+      "content text",
+      drive_service_->GetRootResourceId(),
+      "New File",
+      false,  // shared_with_me
+      google_apis::test_util::CreateCopyResultCallback(&gdata_error,
+                                                       &gdata_entry));
+  base::RunLoop().RunUntilIdle();
+  ASSERT_EQ(google_apis::HTTP_CREATED, gdata_error);
+  ASSERT_TRUE(gdata_entry);
+
+  // CheckForUpdates() results in update.
+  TestChangeListLoaderObserver observer(change_list_loader_.get());
+  change_list_loader_->CheckForUpdates(
+      google_apis::test_util::CreateCopyResultCallback(
+          &check_for_updates_error));
+  EXPECT_TRUE(change_list_loader_->IsRefreshing());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(change_list_loader_->IsRefreshing());
+  EXPECT_LT(previous_changestamp, metadata_->GetLargestChangestamp());
+  EXPECT_EQ(1, observer.load_from_server_complete_count());
+  EXPECT_EQ(1U, observer.changed_directories().count(
+      util::GetDriveMyDriveRootPath()));
+
+  // The new file is found in the local metadata.
+  base::FilePath new_file_path =
+      util::GetDriveMyDriveRootPath().AppendASCII(gdata_entry->title());
+  ResourceEntry entry;
+  EXPECT_EQ(FILE_ERROR_OK,
+            metadata_->GetResourceEntryByPath(new_file_path, &entry));
+}
+
 }  // namespace internal
 }  // namespace drive
diff --git a/chrome/browser/chromeos/drive/change_list_processor.h b/chrome/browser/chromeos/drive/change_list_processor.h
index fb8d20a..a80e3c7 100644
--- a/chrome/browser/chromeos/drive/change_list_processor.h
+++ b/chrome/browser/chromeos/drive/change_list_processor.h
@@ -13,7 +13,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
 #include "chrome/browser/chromeos/drive/file_errors.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace google_apis {
 class AboutResource;
diff --git a/chrome/browser/chromeos/drive/change_list_processor_unittest.cc b/chrome/browser/chromeos/drive/change_list_processor_unittest.cc
index 1495563..6f9d756 100644
--- a/chrome/browser/chromeos/drive/change_list_processor_unittest.cc
+++ b/chrome/browser/chromeos/drive/change_list_processor_unittest.cc
@@ -43,7 +43,7 @@
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
 
     metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.path(), base::MessageLoopProxy::current()));
+        temp_dir_.path(), base::MessageLoopProxy::current().get()));
     ASSERT_TRUE(metadata_storage_->Initialize());
 
     metadata_.reset(new internal::ResourceMetadata(
diff --git a/chrome/browser/chromeos/drive/download_handler_unittest.cc b/chrome/browser/chromeos/drive/download_handler_unittest.cc
index b828c1d..ce069be 100644
--- a/chrome/browser/chromeos/drive/download_handler_unittest.cc
+++ b/chrome/browser/chromeos/drive/download_handler_unittest.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/chromeos/drive/dummy_file_system.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/browser/chromeos/drive/file_write_helper.h"
-#include "chrome/browser/google_apis/test_util.h"
+#include "chrome/browser/chromeos/drive/test_util.h"
 #include "content/public/test/mock_download_item.h"
 #include "content/public/test/mock_download_manager.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -103,7 +103,7 @@
       non_drive_path,
       &download_item_,
       google_apis::test_util::CreateCopyResultCallback(&substituted_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // Check the result.
   EXPECT_EQ(non_drive_path, substituted_path);
@@ -123,7 +123,7 @@
       drive_path,
       &download_item_,
       google_apis::test_util::CreateCopyResultCallback(&substituted_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // Check the result.
   EXPECT_TRUE(temp_dir_.path().IsParent(substituted_path));
@@ -145,7 +145,7 @@
       drive_path,
       &download_item_,
       google_apis::test_util::CreateCopyResultCallback(&substituted_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // Check the result.
   EXPECT_TRUE(substituted_path.empty());
@@ -165,7 +165,7 @@
       drive_path,
       &download_item_,
       google_apis::test_util::CreateCopyResultCallback(&substituted_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // Check the result.
   EXPECT_TRUE(temp_dir_.path().IsParent(substituted_path));
@@ -188,7 +188,7 @@
       drive_path,
       &download_item_,
       google_apis::test_util::CreateCopyResultCallback(&substituted_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // Check the result.
   EXPECT_TRUE(substituted_path.empty());
@@ -207,7 +207,7 @@
       drive_path,
       NULL,  // DownloadItem is not available at this moment.
       google_apis::test_util::CreateCopyResultCallback(&substituted_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // Check the result of SubstituteDriveDownloadPath().
   EXPECT_TRUE(temp_dir_.path().IsParent(substituted_path));
@@ -240,7 +240,7 @@
   download_handler_->CheckForFileExistence(
       &download_item_,
       google_apis::test_util::CreateCopyResultCallback(&file_exists));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // Check the result.
   EXPECT_TRUE(file_exists);
@@ -252,7 +252,7 @@
   download_handler_->CheckForFileExistence(
       &download_item_,
       google_apis::test_util::CreateCopyResultCallback(&file_exists));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // Check the result.
   EXPECT_FALSE(file_exists);
diff --git a/chrome/browser/chromeos/drive/drive_app_registry.h b/chrome/browser/chromeos/drive/drive_app_registry.h
index b4cba84..935c61a 100644
--- a/chrome/browser/chromeos/drive/drive_app_registry.h
+++ b/chrome/browser/chromeos/drive/drive_app_registry.h
@@ -14,7 +14,7 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/google_apis/gdata_errorcode.h"
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace base {
 class FilePath;
diff --git a/chrome/browser/chromeos/drive/drive_app_registry_unittest.cc b/chrome/browser/chromeos/drive/drive_app_registry_unittest.cc
index 941cc77..6228f42 100644
--- a/chrome/browser/chromeos/drive/drive_app_registry_unittest.cc
+++ b/chrome/browser/chromeos/drive/drive_app_registry_unittest.cc
@@ -5,11 +5,12 @@
 #include "chrome/browser/chromeos/drive/drive_app_registry.h"
 
 #include "base/files/file_path.h"
+#include "base/prefs/testing_pref_service.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/drive/job_scheduler.h"
+#include "chrome/browser/chromeos/drive/test_util.h"
 #include "chrome/browser/drive/fake_drive_service.h"
-#include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -18,13 +19,15 @@
 class DriveAppRegistryTest : public testing::Test {
  protected:
   virtual void SetUp() OVERRIDE {
-    profile_.reset(new TestingProfile);
+    pref_service_.reset(new TestingPrefServiceSimple);
+    test_util::RegisterDrivePrefs(pref_service_->registry());
 
     fake_drive_service_.reset(new FakeDriveService);
     fake_drive_service_->LoadAppListForDriveApi("drive/applist.json");
 
-    scheduler_.reset(new JobScheduler(profile_.get(), fake_drive_service_.get(),
-                                      base::MessageLoopProxy::current()));
+    scheduler_.reset(new JobScheduler(pref_service_.get(),
+                                      fake_drive_service_.get(),
+                                      base::MessageLoopProxy::current().get()));
 
     web_apps_registry_.reset(new DriveAppRegistry(scheduler_.get()));
     web_apps_registry_->Update();
@@ -56,7 +59,7 @@
   }
 
   content::TestBrowserThreadBundle thread_bundle_;
-  scoped_ptr<TestingProfile> profile_;
+  scoped_ptr<TestingPrefServiceSimple> pref_service_;
   scoped_ptr<FakeDriveService> fake_drive_service_;
   scoped_ptr<JobScheduler> scheduler_;
   scoped_ptr<DriveAppRegistry> web_apps_registry_;
diff --git a/chrome/browser/chromeos/drive/drive_file_stream_reader_unittest.cc b/chrome/browser/chromeos/drive/drive_file_stream_reader_unittest.cc
index c0c3de1..2f4b1fb 100644
--- a/chrome/browser/chromeos/drive/drive_file_stream_reader_unittest.cc
+++ b/chrome/browser/chromeos/drive/drive_file_stream_reader_unittest.cc
@@ -63,7 +63,7 @@
 TEST_F(LocalReaderProxyTest, Read) {
   // Open the file first.
   scoped_ptr<util::LocalFileReader> file_reader(
-      new util::LocalFileReader(worker_thread_->message_loop_proxy()));
+      new util::LocalFileReader(worker_thread_->message_loop_proxy().get()));
   net::TestCompletionCallback callback;
   file_reader->Open(file_path_, 0, callback.callback());
   ASSERT_EQ(net::OK, callback.WaitForResult());
@@ -84,7 +84,7 @@
 
   // Open the file first.
   scoped_ptr<util::LocalFileReader> file_reader(
-      new util::LocalFileReader(worker_thread_->message_loop_proxy()));
+      new util::LocalFileReader(worker_thread_->message_loop_proxy().get()));
   net::TestCompletionCallback callback;
   file_reader->Open(file_path_, 0, callback.callback());
   ASSERT_EQ(net::OK, callback.WaitForResult());
@@ -330,8 +330,7 @@
   // Create the reader, and initialize it.
   // In this case, the file is not yet locally cached.
   scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
-      GetFileSystemGetter(),
-      worker_thread_->message_loop_proxy()));
+      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
   EXPECT_FALSE(reader->IsInitialized());
 
   int error = net::ERR_FAILED;
@@ -358,9 +357,8 @@
 
   // Create second instance and initialize it.
   // In this case, the file should be cached one.
-  reader.reset(
-      new DriveFileStreamReader(GetFileSystemGetter(),
-                                worker_thread_->message_loop_proxy()));
+  reader.reset(new DriveFileStreamReader(
+      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
   EXPECT_FALSE(reader->IsInitialized());
 
   error = net::ERR_FAILED;
@@ -400,8 +398,7 @@
   // Create the reader, and initialize it.
   // In this case, the file is not yet locally cached.
   scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
-      GetFileSystemGetter(),
-      worker_thread_->message_loop_proxy()));
+      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
   EXPECT_FALSE(reader->IsInitialized());
 
   int error = net::ERR_FAILED;
@@ -433,9 +430,8 @@
 
   // Create second instance and initialize it.
   // In this case, the file should be cached one.
-  reader.reset(
-      new DriveFileStreamReader(GetFileSystemGetter(),
-                                worker_thread_->message_loop_proxy()));
+  reader.reset(new DriveFileStreamReader(
+      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
   EXPECT_FALSE(reader->IsInitialized());
 
   error = net::ERR_FAILED;
@@ -471,8 +467,7 @@
   // Create the reader, and initialize it.
   // In this case, the file is not yet locally cached.
   scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
-      GetFileSystemGetter(),
-      worker_thread_->message_loop_proxy()));
+      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
   EXPECT_FALSE(reader->IsInitialized());
 
   int error = net::ERR_FAILED;
diff --git a/chrome/browser/chromeos/drive/drive_integration_service.cc b/chrome/browser/chromeos/drive/drive_integration_service.cc
index 7978b72..d4e6c53 100644
--- a/chrome/browser/chromeos/drive/drive_integration_service.cc
+++ b/chrome/browser/chromeos/drive/drive_integration_service.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/file_util.h"
 #include "base/prefs/pref_service.h"
+#include "base/strings/stringprintf.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/drive/debug_info_collector.h"
@@ -157,20 +158,22 @@
   } else if (util::IsDriveV2ApiEnabled()) {
     drive_service_.reset(new DriveAPIService(
         g_browser_process->system_request_context(),
-        blocking_task_runner_,
+        blocking_task_runner_.get(),
         GURL(google_apis::DriveApiUrlGenerator::kBaseUrlForProduction),
         GURL(google_apis::DriveApiUrlGenerator::kBaseDownloadUrlForProduction),
         GetDriveUserAgent()));
   } else {
     drive_service_.reset(new GDataWapiService(
         g_browser_process->system_request_context(),
-        blocking_task_runner_,
+        blocking_task_runner_.get(),
         GURL(google_apis::GDataWapiUrlGenerator::kBaseUrlForProduction),
         GURL(google_apis::GDataWapiUrlGenerator::kBaseDownloadUrlForProduction),
         GetDriveUserAgent()));
   }
   scheduler_.reset(new JobScheduler(
-      profile_, drive_service_.get(), blocking_task_runner_.get()));
+      profile_->GetPrefs(),
+      drive_service_.get(),
+      blocking_task_runner_.get()));
   metadata_storage_.reset(new internal::ResourceMetadataStorage(
       cache_root_directory_.Append(util::kMetadataDirectory),
       blocking_task_runner_.get()));
@@ -186,7 +189,7 @@
 
   file_system_.reset(
       test_file_system ? test_file_system : new FileSystem(
-          profile_,
+          profile_->GetPrefs(),
           cache_.get(),
           drive_service_.get(),
           scheduler_.get(),
@@ -210,7 +213,7 @@
   file_system_->Initialize();
 
   base::PostTaskAndReplyWithResult(
-      blocking_task_runner_,
+      blocking_task_runner_.get(),
       FROM_HERE,
       base::Bind(&InitializeMetadata,
                  cache_root_directory_,
@@ -273,6 +276,11 @@
   DCHECK(!callback.is_null());
 
   RemoveDriveMountPoint();
+  // Reloading the file system will clear the resource metadata.
+  file_system_->Reload();
+  // Reload the Drive app registry too.
+  drive_app_registry_->Update();
+
   cache_->ClearAllOnUIThread(base::Bind(
       &DriveIntegrationService::AddBackDriveMountPoint,
       weak_ptr_factory_.GetWeakPtr(),
@@ -297,18 +305,6 @@
   callback.Run(true);
 }
 
-void DriveIntegrationService::ReloadAndRemountFileSystem() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  RemoveDriveMountPoint();
-  file_system_->Reload();
-  drive_app_registry_->Update();
-
-  // Reload() is asynchronous. But we can add back the mount point right away
-  // because every operation waits until loading is complete.
-  AddDriveMountPoint();
-}
-
 void DriveIntegrationService::AddDriveMountPoint() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!file_system_proxy_.get());
diff --git a/chrome/browser/chromeos/drive/drive_integration_service.h b/chrome/browser/chromeos/drive/drive_integration_service.h
index ef954d3..ac29cf9 100644
--- a/chrome/browser/chromeos/drive/drive_integration_service.h
+++ b/chrome/browser/chromeos/drive/drive_integration_service.h
@@ -105,16 +105,13 @@
   DriveAppRegistry* drive_app_registry() { return drive_app_registry_.get(); }
   JobListInterface* job_list() { return scheduler_.get(); }
 
-  // Clears all the local cache files and in-memory data, and remounts the
-  // file system. |callback| is called with true when this operation is done
-  // successfully. Otherwise, |callback| is called with false.
-  // |callback| must not be null.
+  // Clears all the local cache file, the local resource metadata, and
+  // in-memory Drive app registry, and remounts the file system. |callback|
+  // is called with true when this operation is done successfully. Otherwise,
+  // |callback| is called with false. |callback| must not be null.
   void ClearCacheAndRemountFileSystem(
       const base::Callback<void(bool)>& callback);
 
-  // Reloads and remounts the file system.
-  void ReloadAndRemountFileSystem();
-
  private:
   // Returns true if Drive is enabled.
   // Must be called on UI thread.
diff --git a/chrome/browser/chromeos/drive/drive_integration_service_unittest.cc b/chrome/browser/chromeos/drive/drive_integration_service_unittest.cc
index bc20801..9861c84 100644
--- a/chrome/browser/chromeos/drive/drive_integration_service_unittest.cc
+++ b/chrome/browser/chromeos/drive/drive_integration_service_unittest.cc
@@ -32,7 +32,7 @@
 
 TEST_F(DriveIntegrationServiceTest, InitializeAndShutdown) {
   integration_service_->Initialize();
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   integration_service_->Shutdown();
 }
 
diff --git a/chrome/browser/chromeos/drive/drive_protocol_handler.cc b/chrome/browser/chromeos/drive/drive_protocol_handler.cc
index 441b582..227fc7a 100644
--- a/chrome/browser/chromeos/drive/drive_protocol_handler.cc
+++ b/chrome/browser/chromeos/drive/drive_protocol_handler.cc
@@ -6,37 +6,16 @@
 
 #include "base/logging.h"
 #include "base/threading/sequenced_worker_pool.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/drive/drive_integration_service.h"
 #include "chrome/browser/chromeos/drive/drive_url_request_job.h"
-#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_request.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
 namespace drive {
 
-namespace {
-
-// Helper function to get FileSystemInterface from Profile.
-FileSystemInterface* GetFileSystem(void* profile_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  // |profile_id| needs to be checked with ProfileManager::IsValidProfile
-  // before using it.
-  Profile* profile = reinterpret_cast<Profile*>(profile_id);
-  if (!g_browser_process->profile_manager()->IsValidProfile(profile))
-    return NULL;
-
-  DriveIntegrationService* integration_service =
-      DriveIntegrationServiceFactory::FindForProfile(profile);
-  return integration_service ? integration_service->file_system() : NULL;
-}
-
-}  // namespace
-
 DriveProtocolHandler::DriveProtocolHandler(void* profile_id)
     : profile_id_(profile_id) {
   scoped_refptr<base::SequencedWorkerPool> blocking_pool =
@@ -51,10 +30,11 @@
 net::URLRequestJob* DriveProtocolHandler::MaybeCreateJob(
     net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
   DVLOG(1) << "Handling url: " << request->url().spec();
-  return new DriveURLRequestJob(base::Bind(&GetFileSystem, profile_id_),
-                                blocking_task_runner_.get(),
-                                request,
-                                network_delegate);
+  return new DriveURLRequestJob(
+      base::Bind(&util::GetFileSystemByProfileId, profile_id_),
+      blocking_task_runner_.get(),
+      request,
+      network_delegate);
 }
 
 }  // namespace drive
diff --git a/chrome/browser/chromeos/drive/drive_url_request_job_unittest.cc b/chrome/browser/chromeos/drive/drive_url_request_job_unittest.cc
index 95dd8dc..f644e51 100644
--- a/chrome/browser/chromeos/drive/drive_url_request_job_unittest.cc
+++ b/chrome/browser/chromeos/drive/drive_url_request_job_unittest.cc
@@ -20,11 +20,11 @@
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread_bundle.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/test_completion_callback.h"
 #include "net/http/http_byte_range.h"
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace drive {
 namespace {
@@ -122,7 +122,7 @@
         base::Bind(&DriveURLRequestJobTest::GetFileSystem,
                    base::Unretained(this)),
         blocking_pool->GetSequencedTaskRunner(
-            blocking_pool->GetSequenceToken())));
+            blocking_pool->GetSequenceToken()).get()));
     url_request_context_.reset(new net::URLRequestContext());
     url_request_context_->set_job_factory(test_url_request_job_factory_.get());
     url_request_context_->set_network_delegate(test_network_delegate_.get());
@@ -143,7 +143,7 @@
     scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
         base::Bind(&DriveURLRequestJobTest::GetFileSystem,
                    base::Unretained(this)),
-        worker_thread->message_loop_proxy()));
+        worker_thread->message_loop_proxy().get()));
     int error = net::ERR_FAILED;
     scoped_ptr<ResourceEntry> entry;
     {
diff --git a/chrome/browser/chromeos/drive/dummy_file_system.h b/chrome/browser/chromeos/drive/dummy_file_system.h
index e9743a9..e9b95b5 100644
--- a/chrome/browser/chromeos/drive/dummy_file_system.h
+++ b/chrome/browser/chromeos/drive/dummy_file_system.h
@@ -17,9 +17,6 @@
   virtual void AddObserver(FileSystemObserver* observer) OVERRIDE {}
   virtual void RemoveObserver(FileSystemObserver* observer) OVERRIDE {}
   virtual void CheckForUpdates() OVERRIDE {}
-  virtual void GetResourceEntryById(
-      const std::string& resource_id,
-      const GetResourceEntryCallback& callback) OVERRIDE {}
   virtual void TransferFileFromRemoteToLocal(
       const base::FilePath& remote_src_file_path,
       const base::FilePath& local_dest_file_path,
@@ -29,6 +26,7 @@
       const base::FilePath& remote_dest_file_path,
       const FileOperationCallback& callback) OVERRIDE {}
   virtual void OpenFile(const base::FilePath& file_path,
+                        OpenMode open_mode,
                         const OpenFileCallback& callback) OVERRIDE {}
   virtual void CloseFile(const base::FilePath& file_path,
                          const FileOperationCallback& callback) OVERRIDE {}
@@ -62,29 +60,17 @@
                      const FileOperationCallback& callback) OVERRIDE {}
   virtual void GetFileByPath(const base::FilePath& file_path,
                              const GetFileCallback& callback) OVERRIDE {}
-  virtual void GetFileByResourceId(
-      const std::string& resource_id,
-      const ClientContext& context,
-      const GetFileCallback& get_file_callback,
-      const google_apis::GetContentCallback& get_content_callback) OVERRIDE {}
   virtual void GetFileContentByPath(
       const base::FilePath& file_path,
       const GetFileContentInitializedCallback& initialized_callback,
       const google_apis::GetContentCallback& get_content_callback,
       const FileOperationCallback& completion_callback) OVERRIDE {}
-  virtual void UpdateFileByResourceId(
-      const std::string& resource_id,
-      const ClientContext& context,
-      const FileOperationCallback& callback) OVERRIDE {}
   virtual void GetResourceEntryByPath(
       const base::FilePath& file_path,
       const GetResourceEntryCallback& callback) OVERRIDE {}
   virtual void ReadDirectoryByPath(
       const base::FilePath& file_path,
       const ReadDirectoryCallback& callback) OVERRIDE {}
-  virtual void RefreshDirectory(
-      const base::FilePath& file_path,
-      const FileOperationCallback& callback) OVERRIDE {}
   virtual void Search(const std::string& search_query,
                       const GURL& next_url,
                       const SearchCallback& callback) OVERRIDE {}
diff --git a/chrome/browser/chromeos/drive/fake_file_system.cc b/chrome/browser/chromeos/drive/fake_file_system.cc
index c477e98..7f49b9c 100644
--- a/chrome/browser/chromeos/drive/fake_file_system.cc
+++ b/chrome/browser/chromeos/drive/fake_file_system.cc
@@ -54,18 +54,6 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
 
-void FakeFileSystem::GetResourceEntryById(
-    const std::string& resource_id,
-    const GetResourceEntryCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  drive_service_->GetResourceEntry(
-      resource_id,
-      base::Bind(
-          &FakeFileSystem::GetResourceEntryByIdAfterGetResourceEntry,
-          weak_ptr_factory_.GetWeakPtr(), callback));
-}
-
 void FakeFileSystem::TransferFileFromRemoteToLocal(
     const base::FilePath& remote_src_file_path,
     const base::FilePath& local_dest_file_path,
@@ -81,6 +69,7 @@
 }
 
 void FakeFileSystem::OpenFile(const base::FilePath& file_path,
+                              OpenMode open_mode,
                               const OpenFileCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
@@ -150,14 +139,6 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
 
-void FakeFileSystem::GetFileByResourceId(
-    const std::string& resource_id,
-    const ClientContext& context,
-    const GetFileCallback& get_file_callback,
-    const google_apis::GetContentCallback& get_content_callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-}
-
 void FakeFileSystem::GetFileContentByPath(
     const base::FilePath& file_path,
     const GetFileContentInitializedCallback& initialized_callback,
@@ -173,13 +154,6 @@
                  completion_callback));
 }
 
-void FakeFileSystem::UpdateFileByResourceId(
-    const std::string& resource_id,
-    const ClientContext& context,
-    const FileOperationCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-}
-
 void FakeFileSystem::GetResourceEntryByPath(
     const base::FilePath& file_path,
     const GetResourceEntryCallback& callback) {
@@ -210,12 +184,6 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
 
-void FakeFileSystem::RefreshDirectory(
-    const base::FilePath& file_path,
-    const FileOperationCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-}
-
 void FakeFileSystem::Search(const std::string& search_query,
                             const GURL& next_url,
                             const SearchCallback& callback) {
@@ -262,22 +230,6 @@
 void FakeFileSystem::Reload() {
 }
 
-// Implementation of GetResourceEntryById.
-void FakeFileSystem::GetResourceEntryByIdAfterGetResourceEntry(
-    const GetResourceEntryCallback& callback,
-    google_apis::GDataErrorCode error_in,
-    scoped_ptr<google_apis::ResourceEntry> resource_entry) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  FileError error = util::GDataToFileError(error_in);
-  scoped_ptr<ResourceEntry> entry;
-  if (error == FILE_ERROR_OK) {
-    DCHECK(resource_entry);
-    entry.reset(new ResourceEntry(ConvertToResourceEntry(*resource_entry)));
-  }
-  callback.Run(error, entry.Pass());
-}
-
 // Implementation of GetFileContentByPath.
 void FakeFileSystem::GetFileContentByPathAfterGetResourceEntry(
     const GetFileContentInitializedCallback& initialized_callback,
@@ -330,7 +282,7 @@
 
   base::FilePath cache_path =
       cache_dir_.path().AppendASCII(entry->resource_id());
-  if (file_util::PathExists(cache_path)) {
+  if (base::PathExists(cache_path)) {
     // Cache file is found.
     initialized_callback.Run(FILE_ERROR_OK, entry.Pass(), cache_path,
                              base::Closure());
diff --git a/chrome/browser/chromeos/drive/fake_file_system.h b/chrome/browser/chromeos/drive/fake_file_system.h
index fc1c587..501cf14 100644
--- a/chrome/browser/chromeos/drive/fake_file_system.h
+++ b/chrome/browser/chromeos/drive/fake_file_system.h
@@ -51,9 +51,6 @@
   virtual void AddObserver(FileSystemObserver* observer) OVERRIDE;
   virtual void RemoveObserver(FileSystemObserver* observer) OVERRIDE;
   virtual void CheckForUpdates() OVERRIDE;
-  virtual void GetResourceEntryById(
-      const std::string& resource_id,
-      const GetResourceEntryCallback& callback) OVERRIDE;
   virtual void TransferFileFromRemoteToLocal(
       const base::FilePath& remote_src_file_path,
       const base::FilePath& local_dest_file_path,
@@ -63,6 +60,7 @@
       const base::FilePath& remote_dest_file_path,
       const FileOperationCallback& callback) OVERRIDE;
   virtual void OpenFile(const base::FilePath& file_path,
+                        OpenMode open_mode,
                         const OpenFileCallback& callback) OVERRIDE;
   virtual void CloseFile(const base::FilePath& file_path,
                          const FileOperationCallback& callback) OVERRIDE;
@@ -95,29 +93,17 @@
                      const FileOperationCallback& callback) OVERRIDE;
   virtual void GetFileByPath(const base::FilePath& file_path,
                              const GetFileCallback& callback) OVERRIDE;
-  virtual void GetFileByResourceId(
-      const std::string& resource_id,
-      const ClientContext& context,
-      const GetFileCallback& get_file_callback,
-      const google_apis::GetContentCallback& get_content_callback) OVERRIDE;
   virtual void GetFileContentByPath(
       const base::FilePath& file_path,
       const GetFileContentInitializedCallback& initialized_callback,
       const google_apis::GetContentCallback& get_content_callback,
       const FileOperationCallback& completion_callback) OVERRIDE;
-  virtual void UpdateFileByResourceId(
-      const std::string& resource_id,
-      const ClientContext& context,
-      const FileOperationCallback& callback) OVERRIDE;
   virtual void GetResourceEntryByPath(
       const base::FilePath& file_path,
       const GetResourceEntryCallback& callback) OVERRIDE;
   virtual void ReadDirectoryByPath(
       const base::FilePath& file_path,
       const ReadDirectoryCallback& callback) OVERRIDE;
-  virtual void RefreshDirectory(
-      const base::FilePath& file_path,
-      const FileOperationCallback& callback) OVERRIDE;
   virtual void Search(const std::string& search_query,
                       const GURL& next_url,
                       const SearchCallback& callback) OVERRIDE;
diff --git a/chrome/browser/chromeos/drive/fake_file_system_unittest.cc b/chrome/browser/chromeos/drive/fake_file_system_unittest.cc
index 43011e3..be15012 100644
--- a/chrome/browser/chromeos/drive/fake_file_system_unittest.cc
+++ b/chrome/browser/chromeos/drive/fake_file_system_unittest.cc
@@ -35,20 +35,6 @@
   scoped_ptr<FakeFileSystem> fake_file_system_;
 };
 
-TEST_F(FakeFileSystemTest, GetResourceEntryById) {
-  FileError error = FILE_ERROR_FAILED;
-  scoped_ptr<ResourceEntry> entry;
-  const std::string resource_id = "folder:sub_dir_folder_resource_id";
-
-  fake_file_system_->GetResourceEntryById(
-      resource_id,
-      google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  base::RunLoop().RunUntilIdle();
-
-  ASSERT_EQ(FILE_ERROR_OK, error);
-  EXPECT_EQ(resource_id, entry->resource_id());
-}
-
 TEST_F(FakeFileSystemTest, GetFileContentByPath) {
   FileError initialize_error = FILE_ERROR_FAILED;
   scoped_ptr<ResourceEntry> entry;
diff --git a/chrome/browser/chromeos/drive/file_cache.cc b/chrome/browser/chromeos/drive/file_cache.cc
index 2fbce21..32455e9 100644
--- a/chrome/browser/chromeos/drive/file_cache.cc
+++ b/chrome/browser/chromeos/drive/file_cache.cc
@@ -51,6 +51,11 @@
   return false;
 }
 
+// Returns resource ID extracted from the path.
+std::string GetResourceIdFromPath(const base::FilePath& path) {
+  return util::UnescapeCacheFileName(path.BaseName().AsUTF8Unsafe());
+}
+
 // Scans cache subdirectory and insert found files to |cache_map|.
 void ScanCacheDirectory(const base::FilePath& directory_path,
                         CacheMap* cache_map) {
@@ -59,84 +64,28 @@
                                   base::FileEnumerator::FILES);
   for (base::FilePath current = enumerator.Next(); !current.empty();
        current = enumerator.Next()) {
-    // Extract resource_id and md5 from filename.
-    std::string resource_id;
-    std::string md5;
-    util::ParseCacheFilePath(current, &resource_id, &md5);
+    std::string resource_id = GetResourceIdFromPath(current);
+
+    // Calculate MD5.
+    std::string md5 = util::GetMd5Digest(current);
+    if (md5.empty())
+      continue;
 
     // Determine cache state.
     FileCacheEntry cache_entry;
     cache_entry.set_md5(md5);
     cache_entry.set_is_present(true);
 
-    // Add the dirty bit if |md5| indicates that the file is dirty.
-    if (md5 == util::kLocallyModifiedFileExtension)
-      cache_entry.set_is_dirty(true);
-
     // Create and insert new entry into cache map.
     cache_map->insert(std::make_pair(resource_id, cache_entry));
   }
 }
 
-// Moves the file.
-bool MoveFile(const base::FilePath& source_path,
-              const base::FilePath& dest_path) {
-  if (!base::Move(source_path, dest_path)) {
-    LOG(ERROR) << "Failed to move " << source_path.value()
-               << " to " << dest_path.value();
-    return false;
-  }
-  DVLOG(1) << "Moved " << source_path.value() << " to " << dest_path.value();
-  return true;
-}
-
-// Copies the file.
-bool CopyFile(const base::FilePath& source_path,
-              const base::FilePath& dest_path) {
-  if (!file_util::CopyFile(source_path, dest_path)) {
-    LOG(ERROR) << "Failed to copy " << source_path.value()
-               << " to " << dest_path.value();
-    return false;
-  }
-  DVLOG(1) << "Copied " << source_path.value() << " to " << dest_path.value();
-  return true;
-}
-
-// Deletes all files that match |path_to_delete_pattern| except for
-// |path_to_keep| on blocking pool.
-// If |path_to_keep| is empty, all files in |path_to_delete_pattern| are
-// deleted.
-void DeleteFilesSelectively(const base::FilePath& path_to_delete_pattern,
-                            const base::FilePath& path_to_keep) {
-  // Enumerate all files in directory of |path_to_delete_pattern| that match
-  // base name of |path_to_delete_pattern|.
-  // If a file is not |path_to_keep|, delete it.
-  bool success = true;
-  base::FileEnumerator enumerator(
-      path_to_delete_pattern.DirName(),
-      false,  // not recursive
-      base::FileEnumerator::FILES,
-      path_to_delete_pattern.BaseName().value());
-  for (base::FilePath current = enumerator.Next(); !current.empty();
-       current = enumerator.Next()) {
-    // If |path_to_keep| is not empty and same as current, don't delete it.
-    if (!path_to_keep.empty() && current == path_to_keep)
-      continue;
-
-    success = base::Delete(current, false);
-    if (!success)
-      DVLOG(1) << "Error deleting " << current.value();
-    else
-      DVLOG(1) << "Deleted " << current.value();
-  }
-}
-
 // Runs callback with pointers dereferenced.
 // Used to implement GetFile, MarkAsMounted.
-void RunGetFileFromCacheCallback(
-    const GetFileFromCacheCallback& callback,
-    base::FilePath* file_path,
-    FileError error) {
+void RunGetFileFromCacheCallback(const GetFileFromCacheCallback& callback,
+                                 base::FilePath* file_path,
+                                 FileError error) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
   DCHECK(file_path);
@@ -187,22 +136,10 @@
   AssertOnSequencedWorkerPool();
 }
 
-base::FilePath FileCache::GetCacheFilePath(const std::string& resource_id,
-                                           const std::string& md5,
-                                           CachedFileOrigin file_origin) const {
-  // Runs on any thread.
-  // Filename is formatted as resource_id.md5, i.e. resource_id is the base
-  // name and md5 is the extension.
-  std::string base_name = util::EscapeCacheFileName(resource_id);
-  if (file_origin == CACHED_FILE_LOCALLY_MODIFIED) {
-    base_name += base::FilePath::kExtensionSeparator;
-    base_name += util::kLocallyModifiedFileExtension;
-  } else if (!md5.empty()) {
-    base_name += base::FilePath::kExtensionSeparator;
-    base_name += util::EscapeCacheFileName(md5);
-  }
+base::FilePath FileCache::GetCacheFilePath(
+    const std::string& resource_id) const {
   return cache_file_directory_.Append(
-      base::FilePath::FromUTF8Unsafe(base_name));
+      base::FilePath::FromUTF8Unsafe(util::EscapeCacheFileName(resource_id)));
 }
 
 void FileCache::AssertOnSequencedWorkerPool() {
@@ -262,21 +199,6 @@
   return storage_->GetCacheEntryIterator();
 }
 
-void FileCache::FreeDiskSpaceIfNeededForOnUIThread(
-    int64 num_bytes,
-    const InitializeCacheCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  base::PostTaskAndReplyWithResult(
-      blocking_task_runner_.get(),
-      FROM_HERE,
-      base::Bind(&FileCache::FreeDiskSpaceIfNeededFor,
-                 base::Unretained(this),
-                 num_bytes),
-      callback);
-}
-
 bool FileCache::FreeDiskSpaceIfNeededFor(int64 num_bytes) {
   AssertOnSequencedWorkerPool();
 
@@ -303,14 +225,12 @@
   base::FileEnumerator enumerator(cache_file_directory_,
                                   false,  // not recursive
                                   base::FileEnumerator::FILES);
-  std::string resource_id;
-  std::string md5;
   FileCacheEntry entry;
   for (base::FilePath current = enumerator.Next(); !current.empty();
        current = enumerator.Next()) {
-    util::ParseCacheFilePath(current, &resource_id, &md5);
-    if (!GetCacheEntry(resource_id, md5, &entry))
-      base::Delete(current, false /* recursive */);
+    std::string resource_id = GetResourceIdFromPath(current);
+    if (!storage_->GetCacheEntry(resource_id, &entry))
+      base::DeleteFile(current, false /* recursive */);
   }
 
   // Check the disk space again.
@@ -347,10 +267,7 @@
       !cache_entry.is_present())
     return FILE_ERROR_NOT_FOUND;
 
-  CachedFileOrigin file_origin = cache_entry.is_dirty() ?
-      CACHED_FILE_LOCALLY_MODIFIED : CACHED_FILE_FROM_SERVER;
-  *cache_file_path = GetCacheFilePath(resource_id, cache_entry.md5(),
-                                      file_origin);
+  *cache_file_path = GetCacheFilePath(resource_id);
   return FILE_ERROR_OK;
 }
 
@@ -399,8 +316,8 @@
   FileCacheEntry cache_entry;
   storage_->GetCacheEntry(resource_id, &cache_entry);
   cache_entry.set_is_pinned(true);
-  storage_->PutCacheEntry(resource_id, cache_entry);
-  return FILE_ERROR_OK;
+  return storage_->PutCacheEntry(resource_id, cache_entry) ?
+      FILE_ERROR_OK : FILE_ERROR_FAILED;
 }
 
 void FileCache::UnpinOnUIThread(const std::string& resource_id,
@@ -426,10 +343,12 @@
   // Now that file operations have completed, update metadata.
   if (cache_entry.is_present()) {
     cache_entry.set_is_pinned(false);
-    storage_->PutCacheEntry(resource_id, cache_entry);
+    if (!storage_->PutCacheEntry(resource_id, cache_entry))
+      return FILE_ERROR_FAILED;
   } else {
     // Remove the existing entry if we are unpinning a non-present file.
-    storage_->RemoveCacheEntry(resource_id);
+    if  (!storage_->RemoveCacheEntry(resource_id))
+      return FILE_ERROR_FAILED;
   }
 
   // Now it's a chance to free up space if needed.
@@ -496,7 +415,7 @@
   // Marking a file dirty means its entry and actual file blob must exist in
   // cache.
   FileCacheEntry cache_entry;
-  if (!storage_->GetCacheEntry(resource_id, &cache_entry) ||
+  if (!GetCacheEntry(resource_id, md5, &cache_entry) ||
       !cache_entry.is_present()) {
     LOG(WARNING) << "Can't mark dirty a file that wasn't cached: res_id="
                  << resource_id
@@ -507,21 +426,10 @@
   if (cache_entry.is_dirty())
     return FILE_ERROR_OK;
 
-  // Get the current path of the file in cache.
-  base::FilePath source_path = GetCacheFilePath(resource_id, md5,
-                                                CACHED_FILE_FROM_SERVER);
-  // Determine destination path.
-  base::FilePath cache_file_path = GetCacheFilePath(
-      resource_id, md5, CACHED_FILE_LOCALLY_MODIFIED);
-
-  if (!MoveFile(source_path, cache_file_path))
-    return FILE_ERROR_FAILED;
-
   // Now that file operations have completed, update metadata.
-  cache_entry.set_md5(md5);
   cache_entry.set_is_dirty(true);
-  storage_->PutCacheEntry(resource_id, cache_entry);
-  return FILE_ERROR_OK;
+  return storage_->PutCacheEntry(resource_id, cache_entry) ?
+      FILE_ERROR_OK : FILE_ERROR_FAILED;
 }
 
 FileError FileCache::ClearDirty(const std::string& resource_id,
@@ -551,18 +459,11 @@
     return FILE_ERROR_INVALID_OPERATION;
   }
 
-  base::FilePath source_path = GetCacheFilePath(resource_id, md5,
-                                                CACHED_FILE_LOCALLY_MODIFIED);
-  base::FilePath dest_path = GetCacheFilePath(resource_id, md5,
-                                              CACHED_FILE_FROM_SERVER);
-  if (!MoveFile(source_path, dest_path))
-    return FILE_ERROR_FAILED;
-
   // Now that file operations have completed, update metadata.
   cache_entry.set_md5(md5);
   cache_entry.set_is_dirty(false);
-  storage_->PutCacheEntry(resource_id, cache_entry);
-  return FILE_ERROR_OK;
+  return storage_->PutCacheEntry(resource_id, cache_entry) ?
+      FILE_ERROR_OK : FILE_ERROR_FAILED;
 }
 
 void FileCache::RemoveOnUIThread(const std::string& resource_id,
@@ -580,33 +481,27 @@
 FileError FileCache::Remove(const std::string& resource_id) {
   AssertOnSequencedWorkerPool();
 
-  // MD5 is not passed into RemoveCacheEntry because we would delete all
-  // cache files corresponding to <resource_id> regardless of the md5.
-  // So, search for entry in cache without taking md5 into account.
   FileCacheEntry cache_entry;
 
   // If entry doesn't exist, nothing to do.
   if (!storage_->GetCacheEntry(resource_id, &cache_entry))
     return FILE_ERROR_OK;
 
-  // Cannot delete a dirty or mounted file.
-  if (cache_entry.is_dirty() || mounted_files_.count(resource_id))
+  // Cannot delete a mounted file.
+  if (mounted_files_.count(resource_id))
     return FILE_ERROR_IN_USE;
 
-  // Delete files that match "<resource_id>.*" unless modified locally.
-  base::FilePath path_to_delete = GetCacheFilePath(resource_id, util::kWildCard,
-                                                   CACHED_FILE_FROM_SERVER);
-  base::FilePath path_to_keep = GetCacheFilePath(resource_id, std::string(),
-                                                 CACHED_FILE_LOCALLY_MODIFIED);
-  DeleteFilesSelectively(path_to_delete, path_to_keep);
+  // Delete the file.
+  base::FilePath path = GetCacheFilePath(resource_id);
+  if (!base::DeleteFile(path, false /* recursive */))
+    return FILE_ERROR_FAILED;
 
   // Now that all file operations have completed, remove from metadata.
-  storage_->RemoveCacheEntry(resource_id);
-
-  return FILE_ERROR_OK;
+  return storage_->RemoveCacheEntry(resource_id) ?
+      FILE_ERROR_OK : FILE_ERROR_FAILED;
 }
 
-void FileCache::ClearAllOnUIThread(const InitializeCacheCallback& callback) {
+void FileCache::ClearAllOnUIThread(const ClearAllCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
@@ -620,6 +515,8 @@
 bool FileCache::Initialize() {
   AssertOnSequencedWorkerPool();
 
+  RenameCacheFilesToNewFormat();
+
   if (!ImportOldDB(storage_->directory_path().Append(
           kOldCacheMetadataDBName)) &&
       !storage_->opened_existing_db()) {
@@ -675,51 +572,33 @@
   if (cache_entry.is_dirty() || mounted_files_.count(resource_id))
     return FILE_ERROR_IN_USE;
 
-  base::FilePath dest_path = GetCacheFilePath(resource_id, md5,
-                                              CACHED_FILE_FROM_SERVER);
+  base::FilePath dest_path = GetCacheFilePath(resource_id);
   bool success = false;
   switch (file_operation_type) {
     case FILE_OPERATION_MOVE:
-      success = MoveFile(source_path, dest_path);
+      success = base::Move(source_path, dest_path);
       break;
     case FILE_OPERATION_COPY:
-      success = CopyFile(source_path, dest_path);
+      success = base::CopyFile(source_path, dest_path);
       break;
     default:
       NOTREACHED();
   }
 
-  // Determine search pattern for stale filenames corresponding to resource_id,
-  // either "<resource_id>*" or "<resource_id>.*".
-  base::FilePath stale_filenames_pattern;
-  if (md5.empty()) {
-    // No md5 means no extension, append '*' after base name, i.e.
-    // "<resource_id>*".
-    // Cannot call |dest_path|.ReplaceExtension when there's no md5 extension:
-    // if base name of |dest_path| (i.e. escaped resource_id) contains the
-    // extension separator '.', ReplaceExtension will remove it and everything
-    // after it.  The result will be nothing like the escaped resource_id.
-    stale_filenames_pattern =
-        base::FilePath(dest_path.value() + util::kWildCard);
-  } else {
-    // Replace md5 extension with '*' i.e. "<resource_id>.*".
-    // Note that ReplaceExtension automatically prefixes the extension with the
-    // extension separator '.'.
-    stale_filenames_pattern = dest_path.ReplaceExtension(util::kWildCard);
+  if (!success) {
+    LOG(ERROR) << "Failed to store: "
+               << "source_path = " << source_path.value() << ", "
+               << "dest_path = " << dest_path.value() << ", "
+               << "file_operation_type = " << file_operation_type;
+    return FILE_ERROR_FAILED;
   }
 
-  // Delete files that match |stale_filenames_pattern| except for |dest_path|.
-  DeleteFilesSelectively(stale_filenames_pattern, dest_path);
-
-  if (success) {
-    // Now that file operations have completed, update metadata.
-    cache_entry.set_md5(md5);
-    cache_entry.set_is_present(true);
-    cache_entry.set_is_dirty(false);
-    storage_->PutCacheEntry(resource_id, cache_entry);
-  }
-
-  return success ? FILE_ERROR_OK : FILE_ERROR_FAILED;
+  // Now that file operations have completed, update metadata.
+  cache_entry.set_md5(md5);
+  cache_entry.set_is_present(true);
+  cache_entry.set_is_dirty(false);
+  return storage_->PutCacheEntry(resource_id, cache_entry) ?
+      FILE_ERROR_OK : FILE_ERROR_FAILED;
 }
 
 FileError FileCache::MarkAsMounted(const std::string& resource_id,
@@ -736,14 +615,14 @@
     return FILE_ERROR_INVALID_OPERATION;
 
   // Ensure the file is readable to cros_disks. See crbug.com/236994.
-  base::FilePath path = GetCacheFilePath(
-      resource_id, cache_entry.md5(), CACHED_FILE_FROM_SERVER);
-  file_util::SetPosixFilePermissions(
-      path,
-      file_util::FILE_PERMISSION_READ_BY_USER |
-      file_util::FILE_PERMISSION_WRITE_BY_USER |
-      file_util::FILE_PERMISSION_READ_BY_GROUP |
-      file_util::FILE_PERMISSION_READ_BY_OTHERS);
+  base::FilePath path = GetCacheFilePath(resource_id);
+  if (!file_util::SetPosixFilePermissions(
+          path,
+          file_util::FILE_PERMISSION_READ_BY_USER |
+          file_util::FILE_PERMISSION_WRITE_BY_USER |
+          file_util::FILE_PERMISSION_READ_BY_GROUP |
+          file_util::FILE_PERMISSION_READ_BY_OTHERS))
+    return FILE_ERROR_FAILED;
 
   mounted_files_.insert(resource_id);
 
@@ -755,14 +634,11 @@
   AssertOnSequencedWorkerPool();
   DCHECK(IsUnderFileCacheDirectory(file_path));
 
-  // Parse file path to obtain resource_id, md5 and extra_extension.
-  std::string resource_id;
-  std::string md5;
-  util::ParseCacheFilePath(file_path, &resource_id, &md5);
+  std::string resource_id = GetResourceIdFromPath(file_path);
 
   // Get cache entry associated with the resource_id and md5
   FileCacheEntry cache_entry;
-  if (!GetCacheEntry(resource_id, md5, &cache_entry))
+  if (!storage_->GetCacheEntry(resource_id, &cache_entry))
     return FILE_ERROR_NOT_FOUND;
 
   std::set<std::string>::iterator it = mounted_files_.find(resource_id);
@@ -779,8 +655,10 @@
   // Remove entries on the metadata.
   scoped_ptr<ResourceMetadataStorage::CacheEntryIterator> it =
       storage_->GetCacheEntryIterator();
-  for (; !it->IsAtEnd(); it->Advance())
-    storage_->RemoveCacheEntry(it->GetID());
+  for (; !it->IsAtEnd(); it->Advance()) {
+    if (!storage_->RemoveCacheEntry(it->GetID()))
+      return false;
+  }
 
   if (it->HasError())
     return false;
@@ -791,7 +669,7 @@
                                   base::FileEnumerator::FILES);
   for (base::FilePath file = enumerator.Next(); !file.empty();
        file = enumerator.Next())
-    base::Delete(file, false /* recursive */);
+    base::DeleteFile(file, false /* recursive */);
 
   return true;
 }
@@ -810,13 +688,13 @@
 }
 
 bool FileCache::ImportOldDB(const base::FilePath& old_db_path) {
-  if (!file_util::PathExists(old_db_path))  // Old DB is not there, do nothing.
+  if (!base::PathExists(old_db_path))  // Old DB is not there, do nothing.
     return false;
 
   // Copy all entries stored in the old DB.
   bool imported = false;
   {
-    FileCacheMetadata old_data(blocking_task_runner_);
+    FileCacheMetadata old_data(blocking_task_runner_.get());
     if (old_data.Initialize(old_db_path) ==
         FileCacheMetadata::INITIALIZE_OPENED) {
       scoped_ptr<FileCacheMetadata::Iterator> it = old_data.GetIterator();
@@ -832,9 +710,32 @@
   }
 
   // Delete old DB.
-  base::Delete(old_db_path, true /* recursive */ );
+  base::DeleteFile(old_db_path, true /* recursive */ );
   return imported;
 }
 
+void FileCache::RenameCacheFilesToNewFormat() {
+  // First, remove all files with multiple extensions just in case.
+  {
+    base::FileEnumerator enumerator(cache_file_directory_,
+                                    false,  // not recursive
+                                    base::FileEnumerator::FILES,
+                                    "*.*.*");
+    for (base::FilePath current = enumerator.Next(); !current.empty();
+         current = enumerator.Next())
+      base::DeleteFile(current, false /* recursive */);
+  }
+
+  // Rename files.
+  {
+    base::FileEnumerator enumerator(cache_file_directory_,
+                                    false,  // not recursive
+                                    base::FileEnumerator::FILES);
+    for (base::FilePath current = enumerator.Next(); !current.empty();
+         current = enumerator.Next())
+      base::Move(current, current.RemoveExtension());
+  }
+}
+
 }  // namespace internal
 }  // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_cache.h b/chrome/browser/chromeos/drive/file_cache.h
index 398e193..7777077 100644
--- a/chrome/browser/chromeos/drive/file_cache.h
+++ b/chrome/browser/chromeos/drive/file_cache.h
@@ -47,11 +47,10 @@
                             const base::FilePath& cache_file_path)>
     GetFileFromCacheCallback;
 
-// Callback for RequestInitialize.
+// Callback for ClearAllOnUIThread.
 // |success| indicates if the operation was successful.
 // TODO(satorux): Change this to FileError when it becomes necessary.
-typedef base::Callback<void(bool success)>
-    InitializeCacheCallback;
+typedef base::Callback<void(bool success)> ClearAllCallback;
 
 // Interface class used for getting the free disk space. Tests can inject an
 // implementation that reports fake free disk space.
@@ -124,15 +123,6 @@
   // Returns an object to iterate over entries.
   scoped_ptr<Iterator> GetIterator();
 
-
-  // Runs FreeDiskSpaceIfNeededFor() on |blocking_task_runner_|, and calls
-  // |callback| with the result asynchronously.
-  // |callback| must not be null.
-  // Must be called on the UI thread.
-  void FreeDiskSpaceIfNeededForOnUIThread(
-      int64 num_bytes,
-      const InitializeCacheCallback& callback);
-
   // Frees up disk space to store a file with |num_bytes| size content, while
   // keeping kMinFreeSpace bytes on the disk, if needed.
   // Returns true if we successfully manage to have enough space, otherwise
@@ -236,7 +226,7 @@
   // - re-create the |metadata_| instance.
   // |callback| must not be null.
   // Must be called on the UI thread.
-  void ClearAllOnUIThread(const InitializeCacheCallback& callback);
+  void ClearAllOnUIThread(const ClearAllCallback& callback);
 
   // Initializes the cache. Returns true on success.
   bool Initialize();
@@ -250,21 +240,12 @@
   friend class FileCacheTest;
   friend class FileCacheTestOnUIThread;
 
-  // Enum defining origin of a cached file.
-  enum CachedFileOrigin {
-    CACHED_FILE_FROM_SERVER = 0,
-    CACHED_FILE_LOCALLY_MODIFIED,
-  };
-
   ~FileCache();
 
   // Returns absolute path of the file if it were cached or to be cached.
   //
   // Can be called on any thread.
-  base::FilePath GetCacheFilePath(const std::string& resource_id,
-                                  const std::string& md5,
-                                  CachedFileOrigin file_origin) const;
-
+  base::FilePath GetCacheFilePath(const std::string& resource_id) const;
 
   // Checks whether the current thread is on the right sequenced worker pool
   // with the right sequence ID. If not, DCHECK will fail.
@@ -299,6 +280,10 @@
   // TODO(hashimoto): Remove this method and FileCacheMetadata at some point.
   bool ImportOldDB(const base::FilePath& old_db_path);
 
+  // Renames cache files from old "resource_id.md5" format to the new format.
+  // TODO(hashimoto): Remove this method at some point.
+  void RenameCacheFilesToNewFormat();
+
   const base::FilePath cache_file_directory_;
 
   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
diff --git a/chrome/browser/chromeos/drive/file_cache_metadata.cc b/chrome/browser/chromeos/drive/file_cache_metadata.cc
index b421b43..3213512 100644
--- a/chrome/browser/chromeos/drive/file_cache_metadata.cc
+++ b/chrome/browser/chromeos/drive/file_cache_metadata.cc
@@ -95,11 +95,12 @@
     const base::FilePath& db_path) {
   AssertOnSequencedWorkerPool();
 
-  bool created = !file_util::PathExists(db_path);
+  bool created = !base::PathExists(db_path);
 
   leveldb::DB* level_db = NULL;
   leveldb::Options options;
   options.create_if_missing = true;
+  options.max_open_files = 0;  // Use minimum.
   leveldb::Status db_status = leveldb::DB::Open(options, db_path.AsUTF8Unsafe(),
                                                 &level_db);
 
@@ -110,7 +111,7 @@
     LOG(WARNING) << "Cache db failed to open: " << db_status.ToString();
     uma_status = db_status.IsCorruption() ?
         DB_OPEN_FAILURE_CORRUPTION : DB_OPEN_FAILURE_OTHER;
-    const bool deleted = base::Delete(db_path, true);
+    const bool deleted = base::DeleteFile(db_path, true);
     DCHECK(deleted);
     db_status = leveldb::DB::Open(options, db_path.value(), &level_db);
     if (!db_status.ok()) {
diff --git a/chrome/browser/chromeos/drive/file_cache_unittest.cc b/chrome/browser/chromeos/drive/file_cache_unittest.cc
index 8a8e37b..6f70aca 100644
--- a/chrome/browser/chromeos/drive/file_cache_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_cache_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/file_util.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/md5.h"
 #include "base/run_loop.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/chromeos/drive/drive.pb.h"
@@ -77,16 +78,16 @@
         pool->GetSequencedTaskRunner(pool->GetSequenceToken());
 
     metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.path(), blocking_task_runner_));
+        temp_dir_.path(), blocking_task_runner_.get()));
 
     bool success = false;
     base::PostTaskAndReplyWithResult(
-        blocking_task_runner_,
+        blocking_task_runner_.get(),
         FROM_HERE,
         base::Bind(&ResourceMetadataStorage::Initialize,
                    base::Unretained(metadata_storage_.get())),
         google_apis::test_util::CreateCopyResultCallback(&success));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     ASSERT_TRUE(success);
 
     cache_.reset(new FileCache(
@@ -97,12 +98,11 @@
 
     success = false;
     base::PostTaskAndReplyWithResult(
-        blocking_task_runner_,
+        blocking_task_runner_.get(),
         FROM_HERE,
-        base::Bind(&FileCache::Initialize,
-                   base::Unretained(cache_.get())),
+        base::Bind(&FileCache::Initialize, base::Unretained(cache_.get())),
         google_apis::test_util::CreateCopyResultCallback(&success));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     ASSERT_TRUE(success);
   }
 
@@ -116,18 +116,13 @@
     cache_->GetFileOnUIThread(resource_id, md5,
                               google_apis::test_util::CreateCopyResultCallback(
                                   &error, &cache_file_path));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
 
     EXPECT_EQ(expected_error, error);
     if (error == FILE_ERROR_OK) {
       // Verify filename of |cache_file_path|.
-      base::FilePath base_name = cache_file_path.BaseName();
-      EXPECT_EQ(util::EscapeCacheFileName(resource_id) +
-                base::FilePath::kExtensionSeparator +
-                util::EscapeCacheFileName(
-                    expected_file_extension.empty() ?
-                    md5 : expected_file_extension),
-                base_name.value());
+      EXPECT_EQ(util::EscapeCacheFileName(resource_id),
+                cache_file_path.BaseName().AsUTF8Unsafe());
     } else {
       EXPECT_TRUE(cache_file_path.empty());
     }
@@ -146,7 +141,7 @@
         resource_id, md5, source_path,
         FileCache::FILE_OPERATION_COPY,
         google_apis::test_util::CreateCopyResultCallback(&error));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     VerifyCacheFileState(error, resource_id, md5);
   }
 
@@ -158,23 +153,10 @@
     cache_->RemoveOnUIThread(
         resource_id,
         google_apis::test_util::CreateCopyResultCallback(&error));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     VerifyRemoveFromCache(error, resource_id, "");
   }
 
-  // Returns number of files matching to |path_pattern|.
-  int CountFilesWithPathPattern(const base::FilePath& path_pattern) {
-    int result = 0;
-    base::FileEnumerator enumerator(
-        path_pattern.DirName(), false /* not recursive*/,
-        base::FileEnumerator::FILES,
-        path_pattern.BaseName().value());
-    for (base::FilePath current = enumerator.Next(); !current.empty();
-         current = enumerator.Next())
-      ++result;
-    return result;
-  }
-
   void VerifyRemoveFromCache(FileError error,
                              const std::string& resource_id,
                              const std::string& md5) {
@@ -184,10 +166,8 @@
     if (!GetCacheEntryFromOriginThread(resource_id, md5, &cache_entry)) {
       EXPECT_EQ(FILE_ERROR_OK, error);
 
-      // Verify that no files with "<resource_id>.*" exist.
-      const base::FilePath path_pattern = cache_->GetCacheFilePath(
-          resource_id, util::kWildCard, FileCache::CACHED_FILE_FROM_SERVER);
-      EXPECT_EQ(0, CountFilesWithPathPattern(path_pattern));
+      const base::FilePath path = cache_->GetCacheFilePath(resource_id);
+      EXPECT_FALSE(base::PathExists(path));
     }
   }
 
@@ -201,7 +181,7 @@
     cache_->PinOnUIThread(
         resource_id,
         google_apis::test_util::CreateCopyResultCallback(&error));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     VerifyCacheFileState(error, resource_id, std::string());
   }
 
@@ -215,7 +195,7 @@
     cache_->UnpinOnUIThread(
         resource_id,
         google_apis::test_util::CreateCopyResultCallback(&error));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     VerifyCacheFileState(error, resource_id, std::string());
   }
 
@@ -230,7 +210,7 @@
     cache_->MarkDirtyOnUIThread(
         resource_id, md5,
         google_apis::test_util::CreateCopyResultCallback(&error));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
 
     VerifyCacheFileState(error, resource_id, md5);
 
@@ -241,14 +221,11 @@
           resource_id, md5,
           google_apis::test_util::CreateCopyResultCallback(
               &error, &cache_file_path));
-      google_apis::test_util::RunBlockingPoolTask();
+      test_util::RunBlockingPoolTask();
 
       EXPECT_EQ(FILE_ERROR_OK, error);
-      base::FilePath base_name = cache_file_path.BaseName();
-      EXPECT_EQ(util::EscapeCacheFileName(resource_id) +
-                base::FilePath::kExtensionSeparator +
-                "local",
-                base_name.value());
+      EXPECT_EQ(util::EscapeCacheFileName(resource_id),
+                cache_file_path.BaseName().AsUTF8Unsafe());
     }
   }
 
@@ -268,7 +245,7 @@
                    resource_id,
                    md5),
         google_apis::test_util::CreateCopyResultCallback(&error));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     VerifyCacheFileState(error, resource_id, md5);
   }
 
@@ -288,12 +265,10 @@
         resource_id,
         google_apis::test_util::CreateCopyResultCallback(
             &error, &cache_file_path));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
 
-    EXPECT_TRUE(file_util::PathExists(cache_file_path));
-    EXPECT_EQ(cache_file_path,
-              cache_->GetCacheFilePath(resource_id, entry.md5(),
-                                       FileCache::CACHED_FILE_FROM_SERVER));
+    EXPECT_TRUE(base::PathExists(cache_file_path));
+    EXPECT_EQ(cache_file_path, cache_->GetCacheFilePath(resource_id));
   }
 
   void TestMarkAsUnmounted(const std::string& resource_id,
@@ -308,20 +283,18 @@
     cache_->MarkAsUnmountedOnUIThread(
         file_path,
         google_apis::test_util::CreateCopyResultCallback(&error));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
 
     base::FilePath cache_file_path;
     cache_->GetFileOnUIThread(
         resource_id, md5,
         google_apis::test_util::CreateCopyResultCallback(
             &error, &cache_file_path));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     EXPECT_EQ(FILE_ERROR_OK, error);
 
-    EXPECT_TRUE(file_util::PathExists(cache_file_path));
-    EXPECT_EQ(cache_file_path,
-              cache_->GetCacheFilePath(resource_id, md5,
-                                       FileCache::CACHED_FILE_FROM_SERVER));
+    EXPECT_TRUE(base::PathExists(cache_file_path));
+    EXPECT_EQ(cache_file_path, cache_->GetCacheFilePath(resource_id));
   }
 
   void VerifyCacheFileState(FileError error,
@@ -347,20 +320,9 @@
     }
 
     // Verify actual cache file.
-    base::FilePath dest_path = cache_->GetCacheFilePath(
-        resource_id,
-        cache_entry.md5(),
-        (expected_cache_state_ & TEST_CACHE_STATE_DIRTY) ?
-            FileCache::CACHED_FILE_LOCALLY_MODIFIED :
-        FileCache::CACHED_FILE_FROM_SERVER);
+    base::FilePath dest_path = cache_->GetCacheFilePath(resource_id);
     EXPECT_EQ((expected_cache_state_ & TEST_CACHE_STATE_PRESENT) != 0,
-              file_util::PathExists(dest_path));
-  }
-
-  base::FilePath GetCacheFilePath(const std::string& resource_id,
-                                  const std::string& md5,
-                                  FileCache::CachedFileOrigin file_origin) {
-    return cache_->GetCacheFilePath(resource_id, md5, file_origin);
+              base::PathExists(dest_path));
   }
 
   // Helper function to call GetCacheEntry from origin thread.
@@ -371,7 +333,7 @@
     cache_->GetCacheEntryOnUIThread(
         resource_id, md5,
         google_apis::test_util::CreateCopyResultCallback(&result, cache_entry));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     return result;
   }
 
@@ -382,45 +344,21 @@
     return GetCacheEntryFromOriginThread(resource_id, md5, &cache_entry);
   }
 
-  void TestGetCacheFilePath(const std::string& resource_id,
-                            const std::string& md5,
-                            const std::string& expected_filename) {
-    base::FilePath actual_path = cache_->GetCacheFilePath(
-        resource_id, md5, FileCache::CACHED_FILE_FROM_SERVER);
-    base::FilePath expected_path =
-        temp_dir_.path().Append(util::kCacheFileDirectory);
-    expected_path = expected_path.Append(
-        base::FilePath::FromUTF8Unsafe(expected_filename));
-    EXPECT_EQ(expected_path, actual_path);
-
-    base::FilePath base_name = actual_path.BaseName();
-
-    // base::FilePath::Extension returns ".", so strip it.
-    std::string unescaped_md5 = util::UnescapeCacheFileName(
-        base_name.Extension().substr(1));
-    EXPECT_EQ(md5, unescaped_md5);
-    std::string unescaped_resource_id = util::UnescapeCacheFileName(
-        base_name.RemoveExtension().value());
-    EXPECT_EQ(resource_id, unescaped_resource_id);
-  }
-
   // Returns the number of the cache files with name <resource_id>, and Confirm
   // that they have the <md5>. This should return 1 or 0.
   size_t CountCacheFiles(const std::string& resource_id,
                          const std::string& md5) {
-    base::FilePath path = GetCacheFilePath(
-        resource_id, util::kWildCard, FileCache::CACHED_FILE_FROM_SERVER);
-    base::FileEnumerator enumerator(path.DirName(), false,
+    base::FilePath path = cache_->GetCacheFilePath(resource_id);
+    base::FileEnumerator enumerator(path.DirName(),
+                                    false,  // recursive
                                     base::FileEnumerator::FILES,
                                     path.BaseName().value());
     size_t num_files_found = 0;
     for (base::FilePath current = enumerator.Next(); !current.empty();
          current = enumerator.Next()) {
       ++num_files_found;
-      EXPECT_EQ(util::EscapeCacheFileName(resource_id) +
-                base::FilePath::kExtensionSeparator +
-                util::EscapeCacheFileName(md5),
-                current.BaseName().value());
+      EXPECT_EQ(util::EscapeCacheFileName(resource_id),
+                current.BaseName().AsUTF8Unsafe());
     }
     return num_files_found;
   }
@@ -440,23 +378,6 @@
   std::string expected_file_extension_;
 };
 
-TEST_F(FileCacheTestOnUIThread, GetCacheFilePath) {
-  // Use alphanumeric characters for resource id.
-  std::string resource_id("pdf:1a2b");
-  std::string md5("abcdef0123456789");
-  TestGetCacheFilePath(resource_id, md5,
-                       resource_id + base::FilePath::kExtensionSeparator + md5);
-
-  // Use non-alphanumeric characters for resource id, including '.' which is an
-  // extension separator, to test that the characters are escaped and unescaped
-  // correctly, and '.' doesn't mess up the filename format and operations.
-  resource_id = "pdf:`~!@#$%^&*()-_=+[{|]}\\;',<.>/?";
-  std::string escaped_resource_id = util::EscapeCacheFileName(resource_id);
-  std::string escaped_md5 = util::EscapeCacheFileName(md5);
-  TestGetCacheFilePath(resource_id, md5, escaped_resource_id +
-                       base::FilePath::kExtensionSeparator + escaped_md5);
-}
-
 TEST_F(FileCacheTestOnUIThread, StoreToCacheSimple) {
   std::string resource_id("pdf:1a2b");
   std::string md5("abcdef0123456789");
@@ -677,9 +598,9 @@
   cache_->GetFileOnUIThread(
       resource_id, md5,
       google_apis::test_util::CreateCopyResultCallback(&error, &dirty_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
-  EXPECT_TRUE(file_util::PathExists(dirty_path));
+  EXPECT_TRUE(base::PathExists(dirty_path));
 
   // Pin the dirty file.
   TestPin(resource_id, FILE_ERROR_OK,
@@ -688,14 +609,14 @@
           TEST_CACHE_STATE_PINNED);
 
   // Verify dirty file still exist at the same pathname.
-  EXPECT_TRUE(file_util::PathExists(dirty_path));
+  EXPECT_TRUE(base::PathExists(dirty_path));
 
   // Unpin the dirty file.
   TestUnpin(resource_id, FILE_ERROR_OK,
             TEST_CACHE_STATE_PRESENT | TEST_CACHE_STATE_DIRTY);
 
   // Verify dirty file still exist at the same pathname.
-  EXPECT_TRUE(file_util::PathExists(dirty_path));
+  EXPECT_TRUE(base::PathExists(dirty_path));
 }
 
 TEST_F(FileCacheTestOnUIThread, DirtyCacheRepetitive) {
@@ -764,8 +685,11 @@
                 TEST_CACHE_STATE_PINNED |
                 TEST_CACHE_STATE_DIRTY);
 
-  // Try to remove the file.  Since file is dirty, it should not be removed.
-  TestRemoveFromCache(resource_id, FILE_ERROR_IN_USE);
+  // Try to remove the file.  Dirty caches can be removed at the level of
+  // FileCache::Remove. Upper layer cache clearance functions like
+  // FreeDiskSpaceIfNeededFor() and RemoveStaleCacheFiles() takes care of
+  // securing dirty files.
+  TestRemoveFromCache(resource_id, FILE_ERROR_OK);
 }
 
 TEST_F(FileCacheTestOnUIThread, MountUnmount) {
@@ -789,7 +713,7 @@
   cache_->GetFileOnUIThread(
       resource_id, md5,
       google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   TestMarkAsUnmounted(resource_id, md5, file_path, FILE_ERROR_OK,
@@ -812,7 +736,7 @@
   cache_->IterateOnUIThread(
       base::Bind(&OnIterate, &resource_ids, &cache_entries),
       base::Bind(&OnIterateCompleted, &completed));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   ASSERT_TRUE(completed);
 
@@ -843,7 +767,7 @@
   bool success = false;
   cache_->ClearAllOnUIThread(
       google_apis::test_util::CreateCopyResultCallback(&success));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_TRUE(success);
 
   // Verify that all the cache is removed.
@@ -898,13 +822,13 @@
 
     metadata_storage_.reset(new ResourceMetadataStorage(
         temp_dir_.path().Append(util::kMetadataDirectory),
-        base::MessageLoopProxy::current()));
+        base::MessageLoopProxy::current().get()));
     ASSERT_TRUE(metadata_storage_->Initialize());
 
     cache_.reset(new FileCache(
         metadata_storage_.get(),
         temp_dir_.path().Append(util::kCacheFileDirectory),
-        base::MessageLoopProxy::current(),
+        base::MessageLoopProxy::current().get(),
         fake_free_disk_space_getter_.get()));
     ASSERT_TRUE(cache_->Initialize());
   }
@@ -913,6 +837,10 @@
     return cache->ImportOldDB(old_db_path);
   }
 
+  static void RenameCacheFilesToNewFormat(FileCache* cache) {
+    cache->RenameCacheFilesToNewFormat();
+  }
+
   content::TestBrowserThreadBundle thread_bundle_;
   base::ScopedTempDir temp_dir_;
 
@@ -927,14 +855,12 @@
   const base::FilePath file_directory =
       temp_dir_.path().Append(util::kCacheFileDirectory);
   ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
-      file_directory.AppendASCII("id_foo.md5foo"), "foo"));
-  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
-      file_directory.AppendASCII("id_bar.local"), "bar"));
+      file_directory.AppendASCII("id_foo"), "foo"));
 
   // Remove the existing DB.
   const base::FilePath metadata_directory =
       temp_dir_.path().Append(util::kMetadataDirectory);
-  ASSERT_TRUE(base::Delete(metadata_directory, true /* recursive */));
+  ASSERT_TRUE(base::DeleteFile(metadata_directory, true /* recursive */));
 
   // Put an empty file with the same name as old DB.
   // This file cannot be opened by ImportOldDB() and will be dismissed.
@@ -944,12 +870,12 @@
 
   // Create a new cache and initialize it.
   metadata_storage_.reset(new ResourceMetadataStorage(
-      metadata_directory, base::MessageLoopProxy::current()));
+      metadata_directory, base::MessageLoopProxy::current().get()));
   ASSERT_TRUE(metadata_storage_->Initialize());
 
   cache_.reset(new FileCache(metadata_storage_.get(),
                              temp_dir_.path().Append(util::kCacheFileDirectory),
-                             base::MessageLoopProxy::current(),
+                             base::MessageLoopProxy::current().get(),
                              fake_free_disk_space_getter_.get()));
   ASSERT_TRUE(cache_->Initialize());
 
@@ -957,11 +883,7 @@
   FileCacheEntry cache_entry;
   EXPECT_TRUE(cache_->GetCacheEntry("id_foo", std::string(), &cache_entry));
   EXPECT_TRUE(cache_entry.is_present());
-  EXPECT_EQ("md5foo", cache_entry.md5());
-
-  EXPECT_TRUE(cache_->GetCacheEntry("id_bar", std::string(), &cache_entry));
-  EXPECT_TRUE(cache_entry.is_present());
-  EXPECT_TRUE(cache_entry.is_dirty());
+  EXPECT_EQ(base::MD5String("foo"), cache_entry.md5());
 }
 
 TEST_F(FileCacheTest, FreeDiskSpaceIfNeededFor) {
@@ -996,10 +918,10 @@
   // Only 'temporary' file gets removed.
   FileCacheEntry entry;
   EXPECT_FALSE(cache_->GetCacheEntry(resource_id_tmp, md5_tmp, &entry));
-  EXPECT_FALSE(file_util::PathExists(tmp_path));
+  EXPECT_FALSE(base::PathExists(tmp_path));
 
   EXPECT_TRUE(cache_->GetCacheEntry(resource_id_pinned, md5_pinned, &entry));
-  EXPECT_TRUE(file_util::PathExists(pinned_path));
+  EXPECT_TRUE(base::PathExists(pinned_path));
 
   // Returns false when disk space cannot be freed.
   fake_free_disk_space_getter_->set_default_value(0);
@@ -1026,13 +948,13 @@
     entry.set_md5(md5_2);
     old_metadata.AddOrUpdateCacheEntry(key2, entry);
   }
-  EXPECT_TRUE(file_util::PathExists(old_db_path));
+  EXPECT_TRUE(base::PathExists(old_db_path));
 
   // Do import.
   EXPECT_TRUE(ImportOldDB(cache_.get(), old_db_path));
 
   // Old DB should be removed.
-  EXPECT_FALSE(file_util::PathExists(old_db_path));
+  EXPECT_FALSE(base::PathExists(old_db_path));
 
   // Data is imported correctly.
   FileCacheEntry entry;
@@ -1042,5 +964,44 @@
   EXPECT_EQ(md5_2, entry.md5());
 }
 
+TEST_F(FileCacheTest, RenameCacheFilesToNewFormat) {
+  const base::FilePath file_directory =
+      temp_dir_.path().Append(util::kCacheFileDirectory);
+
+  // File with an old style "<resource ID>.<MD5>" name.
+  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
+      file_directory.AppendASCII("id_koo.md5"), "koo"));
+
+  // File with multiple extensions should be removed.
+  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
+      file_directory.AppendASCII("id_kyu.md5.mounted"), "kyu (mounted)"));
+  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
+      file_directory.AppendASCII("id_kyu.md5"), "kyu"));
+
+  // Rename and verify the result.
+  RenameCacheFilesToNewFormat(cache_.get());
+  std::string contents;
+  EXPECT_TRUE(file_util::ReadFileToString(file_directory.AppendASCII("id_koo"),
+                                          &contents));
+  EXPECT_EQ("koo", contents);
+  contents.clear();
+  EXPECT_TRUE(file_util::ReadFileToString(file_directory.AppendASCII("id_kyu"),
+                                          &contents));
+  EXPECT_EQ("kyu", contents);
+
+  // Rename again.
+  RenameCacheFilesToNewFormat(cache_.get());
+
+  // Files with new style names are not affected.
+  contents.clear();
+  EXPECT_TRUE(file_util::ReadFileToString(file_directory.AppendASCII("id_koo"),
+                                          &contents));
+  EXPECT_EQ("koo", contents);
+  contents.clear();
+  EXPECT_TRUE(file_util::ReadFileToString(file_directory.AppendASCII("id_kyu"),
+                                          &contents));
+  EXPECT_EQ("kyu", contents);
+}
+
 }  // namespace internal
 }  // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system.cc b/chrome/browser/chromeos/drive/file_system.cc
index 53c2e9d..4909ccd 100644
--- a/chrome/browser/chromeos/drive/file_system.cc
+++ b/chrome/browser/chromeos/drive/file_system.cc
@@ -16,11 +16,13 @@
 #include "chrome/browser/chromeos/drive/change_list_processor.h"
 #include "chrome/browser/chromeos/drive/drive.pb.h"
 #include "chrome/browser/chromeos/drive/file_cache.h"
+#include "chrome/browser/chromeos/drive/file_system/close_file_operation.h"
 #include "chrome/browser/chromeos/drive/file_system/copy_operation.h"
 #include "chrome/browser/chromeos/drive/file_system/create_directory_operation.h"
 #include "chrome/browser/chromeos/drive/file_system/create_file_operation.h"
 #include "chrome/browser/chromeos/drive/file_system/download_operation.h"
 #include "chrome/browser/chromeos/drive/file_system/move_operation.h"
+#include "chrome/browser/chromeos/drive/file_system/open_file_operation.h"
 #include "chrome/browser/chromeos/drive/file_system/remove_operation.h"
 #include "chrome/browser/chromeos/drive/file_system/search_operation.h"
 #include "chrome/browser/chromeos/drive/file_system/touch_operation.h"
@@ -35,7 +37,6 @@
 #include "chrome/browser/drive/drive_api_util.h"
 #include "chrome/browser/drive/drive_service_interface.h"
 #include "chrome/browser/google_apis/drive_api_parser.h"
-#include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -71,14 +72,14 @@
 }  // namespace
 
 FileSystem::FileSystem(
-    Profile* profile,
+    PrefService* pref_service,
     internal::FileCache* cache,
     DriveServiceInterface* drive_service,
     JobScheduler* scheduler,
     internal::ResourceMetadata* resource_metadata,
     base::SequencedTaskRunner* blocking_task_runner,
     const base::FilePath& temporary_file_directory)
-    : profile_(profile),
+    : pref_service_(pref_service),
       cache_(cache),
       drive_service_(drive_service),
       scheduler_(scheduler),
@@ -104,6 +105,11 @@
   SetupChangeListLoader();
 
   file_system::OperationObserver* observer = this;
+  close_file_operation_.reset(
+      new file_system::CloseFileOperation(blocking_task_runner_.get(),
+                                          observer,
+                                          resource_metadata_,
+                                          &open_files_));
   copy_operation_.reset(
       new file_system::CopyOperation(blocking_task_runner_.get(),
                                      observer,
@@ -122,6 +128,14 @@
                                            cache_));
   move_operation_.reset(
       new file_system::MoveOperation(observer, scheduler_, resource_metadata_));
+  open_file_operation_.reset(
+      new file_system::OpenFileOperation(blocking_task_runner_.get(),
+                                         observer,
+                                         scheduler_,
+                                         resource_metadata_,
+                                         cache_,
+                                         temporary_file_directory_,
+                                         &open_files_));
   remove_operation_.reset(
       new file_system::RemoveOperation(blocking_task_runner_.get(),
                                        observer,
@@ -159,8 +173,8 @@
                                               cache_,
                                               temporary_file_directory_));
 
-  PrefService* pref_service = profile_->GetPrefs();
-  hide_hosted_docs_ = pref_service->GetBoolean(prefs::kDisableDriveHostedFiles);
+  hide_hosted_docs_ =
+      pref_service_->GetBoolean(prefs::kDisableDriveHostedFiles);
 
   InitializePreferenceObserver();
 }
@@ -222,36 +236,6 @@
   observers_.RemoveObserver(observer);
 }
 
-void FileSystem::GetResourceEntryById(
-    const std::string& resource_id,
-    const GetResourceEntryCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!resource_id.empty());
-  DCHECK(!callback.is_null());
-
-  resource_metadata_->GetResourceEntryByIdOnUIThread(
-      resource_id,
-      base::Bind(&FileSystem::GetResourceEntryByIdAfterGetEntry,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 callback));
-}
-
-void FileSystem::GetResourceEntryByIdAfterGetEntry(
-    const GetResourceEntryCallback& callback,
-    FileError error,
-    scoped_ptr<ResourceEntry> entry) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  if (error != FILE_ERROR_OK) {
-    callback.Run(error, scoped_ptr<ResourceEntry>());
-    return;
-  }
-  DCHECK(entry.get());
-
-  CheckLocalModificationAndRun(entry.Pass(), callback);
-}
-
 void FileSystem::TransferFileFromRemoteToLocal(
     const base::FilePath& remote_src_file_path,
     const base::FilePath& local_dest_file_path,
@@ -465,23 +449,6 @@
       callback);
 }
 
-void FileSystem::GetFileByResourceId(
-    const std::string& resource_id,
-    const ClientContext& context,
-    const GetFileCallback& get_file_callback,
-    const google_apis::GetContentCallback& get_content_callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!resource_id.empty());
-  DCHECK(!get_file_callback.is_null());
-
-  download_operation_->EnsureFileDownloadedByResourceId(
-      resource_id,
-      context,
-      GetFileContentInitializedCallback(),
-      get_content_callback,
-      get_file_callback);
-}
-
 void FileSystem::GetFileContentByPath(
     const base::FilePath& file_path,
     const GetFileContentInitializedCallback& initialized_callback,
@@ -681,57 +648,6 @@
   callback.Run(FILE_ERROR_OK, filtered.Pass());
 }
 
-void FileSystem::RefreshDirectory(
-    const base::FilePath& directory_path,
-    const FileOperationCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  // Make sure the destination directory exists.
-  resource_metadata_->GetResourceEntryByPathOnUIThread(
-      directory_path,
-      base::Bind(&FileSystem::RefreshDirectoryAfterGetResourceEntry,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 directory_path,
-                 callback));
-}
-
-void FileSystem::RefreshDirectoryAfterGetResourceEntry(
-    const base::FilePath& directory_path,
-    const FileOperationCallback& callback,
-    FileError error,
-    scoped_ptr<ResourceEntry> entry) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  if (error != FILE_ERROR_OK) {
-    callback.Run(error);
-    return;
-  }
-  if (!entry->file_info().is_directory()) {
-    callback.Run(FILE_ERROR_NOT_A_DIRECTORY);
-    return;
-  }
-  if (util::IsSpecialResourceId(entry->resource_id())) {
-    // Do not load special directories. Just return.
-    callback.Run(FILE_ERROR_OK);
-    return;
-  }
-
-  change_list_loader_->LoadDirectoryFromServer(
-      entry->resource_id(),
-      callback);
-}
-
-void FileSystem::UpdateFileByResourceId(
-    const std::string& resource_id,
-    const ClientContext& context,
-    const FileOperationCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-  update_operation_->UpdateFileByResourceId(resource_id, context, callback);
-}
-
 void FileSystem::GetAvailableSpace(
     const GetAvailableSpaceCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -891,9 +807,8 @@
 
 void FileSystem::OnDisableDriveHostedFilesChanged() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  PrefService* pref_service = profile_->GetPrefs();
   SetHideHostedDocuments(
-      pref_service->GetBoolean(prefs::kDisableDriveHostedFiles));
+      pref_service_->GetBoolean(prefs::kDisableDriveHostedFiles));
 }
 
 void FileSystem::SetHideHostedDocuments(bool hide) {
@@ -915,7 +830,7 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   pref_registrar_.reset(new PrefChangeRegistrar());
-  pref_registrar_->Init(profile_->GetPrefs());
+  pref_registrar_->Init(pref_service_);
   pref_registrar_->Add(
       prefs::kDisableDriveHostedFiles,
       base::Bind(&FileSystem::OnDisableDriveHostedFilesChanged,
@@ -923,99 +838,12 @@
 }
 
 void FileSystem::OpenFile(const base::FilePath& file_path,
+                          OpenMode open_mode,
                           const OpenFileCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
-  // If the file is already opened, it cannot be opened again before closed.
-  // This is for avoiding simultaneous modification to the file, and moreover
-  // to avoid an inconsistent cache state (suppose an operation sequence like
-  // Open->Open->modify->Close->modify->Close; the second modify may not be
-  // synchronized to the server since it is already Closed on the cache).
-  if (open_files_.find(file_path) != open_files_.end()) {
-    base::MessageLoopProxy::current()->PostTask(
-        FROM_HERE,
-        base::Bind(callback, FILE_ERROR_IN_USE, base::FilePath()));
-    return;
-  }
-  open_files_.insert(file_path);
-
-  download_operation_->EnsureFileDownloadedByPath(
-      file_path,
-      ClientContext(USER_INITIATED),
-      GetFileContentInitializedCallback(),
-      google_apis::GetContentCallback(),
-      base::Bind(&FileSystem::OpenFileAfterFileDownloaded,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 file_path,
-                 base::Bind(&FileSystem::OnOpenFileFinished,
-                            weak_ptr_factory_.GetWeakPtr(),
-                            file_path,
-                            callback)));
-}
-
-void FileSystem::OpenFileAfterFileDownloaded(
-    const base::FilePath& file_path,
-    const OpenFileCallback& callback,
-    FileError error,
-    const base::FilePath& local_file_path,
-    scoped_ptr<ResourceEntry> entry) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  if (error == FILE_ERROR_OK) {
-    DCHECK(entry);
-    DCHECK(entry->has_file_specific_info());
-    if (entry->file_specific_info().is_hosted_document())
-      // No support for opening a hosted document.
-      error = FILE_ERROR_INVALID_OPERATION;
-  }
-
-  if (error != FILE_ERROR_OK) {
-    callback.Run(error, base::FilePath());
-    return;
-  }
-
-  cache_->MarkDirtyOnUIThread(entry->resource_id(),
-                              entry->file_specific_info().md5(),
-                              base::Bind(&FileSystem::OpenFileAfterMarkDirty,
-                                         weak_ptr_factory_.GetWeakPtr(),
-                                         entry->resource_id(),
-                                         entry->file_specific_info().md5(),
-                                         callback));
-}
-
-void FileSystem::OpenFileAfterMarkDirty(
-    const std::string& resource_id,
-    const std::string& md5,
-    const OpenFileCallback& callback,
-    FileError error) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  if (error != FILE_ERROR_OK) {
-    callback.Run(error, base::FilePath());
-    return;
-  }
-
-  cache_->GetFileOnUIThread(resource_id, md5, callback);
-}
-
-void FileSystem::OnOpenFileFinished(
-    const base::FilePath& file_path,
-    const OpenFileCallback& callback,
-    FileError result,
-    const base::FilePath& cache_file_path) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  // All the invocation of |callback| from operations initiated from OpenFile
-  // must go through here. Removes the |file_path| from the remembered set when
-  // the file was not successfully opened.
-  if (result != FILE_ERROR_OK)
-    open_files_.erase(file_path);
-
-  callback.Run(result, cache_file_path);
+  open_file_operation_->OpenFile(file_path, open_mode, callback);
 }
 
 void FileSystem::CloseFile(const base::FilePath& file_path,
@@ -1023,49 +851,7 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
-  if (open_files_.find(file_path) == open_files_.end()) {
-    // The file is not being opened.
-    base::MessageLoopProxy::current()->PostTask(
-        FROM_HERE,
-        base::Bind(callback, FILE_ERROR_NOT_FOUND));
-    return;
-  }
-
-  // Step 1 of CloseFile: Get resource_id and md5 for |file_path|.
-  resource_metadata_->GetResourceEntryByPathOnUIThread(
-      file_path,
-      base::Bind(&FileSystem::CloseFileAfterGetResourceEntry,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 file_path,
-                 callback));
-}
-
-void FileSystem::CloseFileAfterGetResourceEntry(
-    const base::FilePath& file_path,
-    const FileOperationCallback& callback,
-    FileError error,
-    scoped_ptr<ResourceEntry> entry) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  if (entry.get() && !entry->has_file_specific_info())
-    error = FILE_ERROR_NOT_FOUND;
-
-  // Step 2 of CloseFile: Trigger upload.
-  // TODO(benchan,kinaba): Call ClearDirtyInCache if the file has not been
-  // modified. Come up with a way to detect the intactness effectively, or
-  // provide a method for user to declare it when calling CloseFile().
-  if (error == FILE_ERROR_OK)
-    sync_client_->AddUploadTask(entry->resource_id());
-
-  // Step 3 of CloseFile.
-  // All the invocation of |callback| from operations initiated from CloseFile
-  // must go through here. Removes the |file_path| from the remembered set so
-  // that subsequent operations can open the file again.
-  open_files_.erase(file_path);
-
-  // Then invokes the user-supplied callback function.
-  callback.Run(error);
+  close_file_operation_->CloseFile(file_path, callback);
 }
 
 void FileSystem::CheckLocalModificationAndRun(
diff --git a/chrome/browser/chromeos/drive/file_system.h b/chrome/browser/chromeos/drive/file_system.h
index 6ed4e52..2b469cc 100644
--- a/chrome/browser/chromeos/drive/file_system.h
+++ b/chrome/browser/chromeos/drive/file_system.h
@@ -17,7 +17,7 @@
 #include "chrome/browser/google_apis/gdata_errorcode.h"
 
 class PrefChangeRegistrar;
-class Profile;
+class PrefService;
 
 namespace base {
 struct PlatformFileInfo;
@@ -43,11 +43,13 @@
 }  // namespace internal
 
 namespace file_system {
+class CloseFileOperation;
 class CopyOperation;
 class CreateDirectoryOperation;
 class CreateFileOperation;
 class DownloadOperation;
 class MoveOperation;
+class OpenFileOperation;
 class OperationObserver;
 class RemoveOperation;
 class SearchOperation;
@@ -61,7 +63,7 @@
                    public internal::ChangeListLoaderObserver,
                    public file_system::OperationObserver {
  public:
-  FileSystem(Profile* profile,
+  FileSystem(PrefService* pref_service,
              internal::FileCache* cache,
              DriveServiceInterface* drive_service,
              JobScheduler* scheduler,
@@ -75,9 +77,6 @@
   virtual void AddObserver(FileSystemObserver* observer) OVERRIDE;
   virtual void RemoveObserver(FileSystemObserver* observer) OVERRIDE;
   virtual void CheckForUpdates() OVERRIDE;
-  virtual void GetResourceEntryById(
-      const std::string& resource_id,
-      const GetResourceEntryCallback& callback) OVERRIDE;
   virtual void Search(const std::string& search_query,
                       const GURL& next_url,
                       const SearchCallback& callback) OVERRIDE;
@@ -94,6 +93,7 @@
       const base::FilePath& remote_dest_file_path,
       const FileOperationCallback& callback) OVERRIDE;
   virtual void OpenFile(const base::FilePath& file_path,
+                        OpenMode open_mode,
                         const OpenFileCallback& callback) OVERRIDE;
   virtual void CloseFile(const base::FilePath& file_path,
                          const FileOperationCallback& callback) OVERRIDE;
@@ -126,29 +126,17 @@
                      const FileOperationCallback& callback) OVERRIDE;
   virtual void GetFileByPath(const base::FilePath& file_path,
                              const GetFileCallback& callback) OVERRIDE;
-  virtual void GetFileByResourceId(
-      const std::string& resource_id,
-      const ClientContext& context,
-      const GetFileCallback& get_file_callback,
-      const google_apis::GetContentCallback& get_content_callback) OVERRIDE;
   virtual void GetFileContentByPath(
       const base::FilePath& file_path,
       const GetFileContentInitializedCallback& initialized_callback,
       const google_apis::GetContentCallback& get_content_callback,
       const FileOperationCallback& completion_callback) OVERRIDE;
-  virtual void UpdateFileByResourceId(
-      const std::string& resource_id,
-      const ClientContext& context,
-      const FileOperationCallback& callback) OVERRIDE;
   virtual void GetResourceEntryByPath(
       const base::FilePath& file_path,
       const GetResourceEntryCallback& callback) OVERRIDE;
   virtual void ReadDirectoryByPath(
       const base::FilePath& directory_path,
       const ReadDirectoryCallback& callback) OVERRIDE;
-  virtual void RefreshDirectory(
-      const base::FilePath& directory_path,
-      const FileOperationCallback& callback) OVERRIDE;
   virtual void GetAvailableSpace(
       const GetAvailableSpaceCallback& callback) OVERRIDE;
   virtual void GetMetadata(
@@ -220,40 +208,6 @@
                    const std::string& resource_id,
                    FileError error);
 
-  // Part of OpenFile(). Called after the file downloading is completed.
-  void OpenFileAfterFileDownloaded(
-      const base::FilePath& file_path,
-      const OpenFileCallback& callback,
-      FileError error,
-      const base::FilePath& local_file_path,
-      scoped_ptr<ResourceEntry> entry);
-
-  // Part of OpenFile(). Called after the cache file is marked dirty.
-  void OpenFileAfterMarkDirty(
-      const std::string& resource_id,
-      const std::string& md5,
-      const OpenFileCallback& callback,
-      FileError error);
-
-  // Invoked at the last step of OpenFile. It removes |file_path| from the
-  // current set of opened files if |result| is an error, and then invokes the
-  // |callback| function.
-  void OnOpenFileFinished(const base::FilePath& file_path,
-                          const OpenFileCallback& callback,
-                          FileError result,
-                          const base::FilePath& cache_file_path);
-
-  // Invoked during the process of CloseFile. What is done here is as follows:
-  // 1) Gets resource_id and md5 of the entry at |file_path|.
-  // 2) Commits the modification to the cache system.
-  // 3) Removes the |file_path| from the remembered set of opened files.
-  // 4) Invokes the user-supplied |callback|.
-  // |callback| must not be null.
-  void CloseFileAfterGetResourceEntry(const base::FilePath& file_path,
-                                      const FileOperationCallback& callback,
-                                      FileError error,
-                                      scoped_ptr<ResourceEntry> entry);
-
   // Callback for handling about resource fetch.
   void OnGetAboutResource(
       const GetAvailableSpaceCallback& callback,
@@ -312,22 +266,6 @@
       FileError error,
       scoped_ptr<ResourceEntryVector> entries);
 
-  // Part of GetResourceEntryById(). Called after
-  // ResourceMetadata::GetResourceEntryById() is complete.
-  // |callback| must not be null.
-  void GetResourceEntryByIdAfterGetEntry(
-      const GetResourceEntryCallback& callback,
-      FileError error,
-      scoped_ptr<ResourceEntry> entry);
-
-  // Part of RefreshDirectory(). Called after
-  // GetResourceEntryByPath() is complete.
-  void RefreshDirectoryAfterGetResourceEntry(
-      const base::FilePath& directory_path,
-      const FileOperationCallback& callback,
-      FileError error,
-      scoped_ptr<ResourceEntry> entry);
-
   // Part of GetEntryByResourceId and GetEntryByPath. Checks whether there is a
   // local dirty cache for the entry, and if there is, replace the
   // PlatformFileInfo part of the |entry| with the locally modified info.
@@ -357,8 +295,8 @@
       FileError error,
       scoped_ptr<ResourceEntry> entry);
 
-  // The profile hosts the FileSystem via DriveIntegrationService.
-  Profile* profile_;
+  // Used to get Drive related preferences.
+  PrefService* pref_service_;
 
   // Sub components owned by DriveIntegrationService.
   internal::FileCache* cache_;
@@ -375,8 +313,9 @@
   // True if hosted documents should be hidden.
   bool hide_hosted_docs_;
 
-  // The set of paths opened by OpenFile but not yet closed by CloseFile.
-  std::set<base::FilePath> open_files_;
+  // Map from opened file paths to the number how many the file is opened.
+  // The value should be incremented by OpenFile, and decremented by CloseFile.
+  std::map<base::FilePath, int> open_files_;
 
   scoped_ptr<PrefChangeRegistrar> pref_registrar_;
 
@@ -392,10 +331,12 @@
   base::FilePath temporary_file_directory_;
 
   // Implementation of each file system operation.
+  scoped_ptr<file_system::CloseFileOperation> close_file_operation_;
   scoped_ptr<file_system::CopyOperation> copy_operation_;
   scoped_ptr<file_system::CreateDirectoryOperation> create_directory_operation_;
   scoped_ptr<file_system::CreateFileOperation> create_file_operation_;
   scoped_ptr<file_system::MoveOperation> move_operation_;
+  scoped_ptr<file_system::OpenFileOperation> open_file_operation_;
   scoped_ptr<file_system::RemoveOperation> remove_operation_;
   scoped_ptr<file_system::TouchOperation> touch_operation_;
   scoped_ptr<file_system::TruncateOperation> truncate_operation_;
diff --git a/chrome/browser/chromeos/drive/file_system/close_file_operation.cc b/chrome/browser/chromeos/drive/file_system/close_file_operation.cc
new file mode 100644
index 0000000..dfd2a55
--- /dev/null
+++ b/chrome/browser/chromeos/drive/file_system/close_file_operation.cc
@@ -0,0 +1,83 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/drive/file_system/close_file_operation.h"
+
+#include "base/logging.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/sequenced_task_runner.h"
+#include "chrome/browser/chromeos/drive/drive.pb.h"
+#include "chrome/browser/chromeos/drive/file_errors.h"
+#include "chrome/browser/chromeos/drive/file_system/operation_observer.h"
+#include "chrome/browser/chromeos/drive/resource_metadata.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+namespace drive {
+namespace file_system {
+
+CloseFileOperation::CloseFileOperation(
+    base::SequencedTaskRunner* blocking_task_runner,
+    OperationObserver* observer,
+    internal::ResourceMetadata* metadata,
+    std::map<base::FilePath, int>* open_files)
+    : blocking_task_runner_(blocking_task_runner),
+      observer_(observer),
+      metadata_(metadata),
+      open_files_(open_files),
+      weak_ptr_factory_(this) {
+}
+
+CloseFileOperation::~CloseFileOperation() {
+}
+
+void CloseFileOperation::CloseFile(const base::FilePath& file_path,
+                                   const FileOperationCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+
+  if (open_files_->find(file_path) == open_files_->end()) {
+    // The file is not being opened.
+    base::MessageLoopProxy::current()->PostTask(
+        FROM_HERE, base::Bind(callback, FILE_ERROR_NOT_FOUND));
+    return;
+  }
+
+  ResourceEntry* entry = new ResourceEntry;
+  base::PostTaskAndReplyWithResult(
+      blocking_task_runner_.get(),
+      FROM_HERE,
+      base::Bind(&internal::ResourceMetadata::GetResourceEntryByPath,
+                 base::Unretained(metadata_), file_path, entry),
+      base::Bind(&CloseFileOperation::CloseFileAfterGetResourceEntry,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 file_path, callback, base::Owned(entry)));
+}
+
+void CloseFileOperation::CloseFileAfterGetResourceEntry(
+    const base::FilePath& file_path,
+    const FileOperationCallback& callback,
+    const ResourceEntry* entry,
+    FileError error) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+  DCHECK(entry);
+
+  if (error == FILE_ERROR_OK && entry->file_info().is_directory())
+    error = FILE_ERROR_NOT_FOUND;
+
+  DCHECK_GT((*open_files_)[file_path], 0);
+  if (--(*open_files_)[file_path] == 0) {
+    // All clients closes this file, so notify to upload the file.
+    open_files_->erase(file_path);
+    observer_->OnCacheFileUploadNeededByOperation(entry->resource_id());
+  }
+
+  // Then invokes the user-supplied callback function.
+  callback.Run(error);
+}
+
+}  // namespace file_system
+}  // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system/close_file_operation.h b/chrome/browser/chromeos/drive/file_system/close_file_operation.h
new file mode 100644
index 0000000..005c9cf
--- /dev/null
+++ b/chrome/browser/chromeos/drive/file_system/close_file_operation.h
@@ -0,0 +1,70 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_CLOSE_FILE_OPERATION_H_
+#define CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_CLOSE_FILE_OPERATION_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/chromeos/drive/file_errors.h"
+
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}  // namespace base
+
+namespace drive {
+
+class ResourceEntry;
+
+namespace internal {
+class ResourceMetadata;
+}  // namespace internal
+
+namespace file_system {
+
+class OperationObserver;
+
+class CloseFileOperation {
+ public:
+  CloseFileOperation(base::SequencedTaskRunner* blocking_task_runner,
+                     OperationObserver* observer,
+                     internal::ResourceMetadata* metadata,
+                     std::map<base::FilePath, int>* open_files);
+  ~CloseFileOperation();
+
+  // Closes the currently opened file |file_path|.
+  // |callback| must not be null.
+  void CloseFile(const base::FilePath& file_path,
+                 const FileOperationCallback& callback);
+
+ private:
+  // Part of CloseFile(). Called after ResourceMetadata::GetResourceEntry().
+  void CloseFileAfterGetResourceEntry(const base::FilePath& file_path,
+                                      const FileOperationCallback& callback,
+                                      const ResourceEntry* entry,
+                                      FileError error);
+
+  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
+  OperationObserver* observer_;
+  internal::ResourceMetadata* metadata_;
+
+  // The map from paths for opened file to the number how many the file is
+  // opened. The instance is owned by FileSystem and shared with
+  // OpenFileOperation.
+  std::map<base::FilePath, int>* open_files_;
+
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate its weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<CloseFileOperation> weak_ptr_factory_;
+  DISALLOW_COPY_AND_ASSIGN(CloseFileOperation);
+};
+
+}  // namespace file_system
+}  // namespace drive
+
+#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_CLOSE_FILE_OPERATION_H_
diff --git a/chrome/browser/chromeos/drive/file_system/close_file_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/close_file_operation_unittest.cc
new file mode 100644
index 0000000..2fe4d88
--- /dev/null
+++ b/chrome/browser/chromeos/drive/file_system/close_file_operation_unittest.cc
@@ -0,0 +1,105 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/drive/file_system/close_file_operation.h"
+
+#include <set>
+
+#include "base/files/file_path.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/drive/drive.pb.h"
+#include "chrome/browser/chromeos/drive/file_errors.h"
+#include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
+#include "chrome/browser/google_apis/test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace drive {
+namespace file_system {
+
+class CloseFileOperationTest : public OperationTestBase {
+ protected:
+  virtual void SetUp() {
+    OperationTestBase::SetUp();
+
+    operation_.reset(new CloseFileOperation(
+        blocking_task_runner(), observer(), metadata(), &open_files_));
+  }
+
+  std::map<base::FilePath, int> open_files_;
+  scoped_ptr<CloseFileOperation> operation_;
+};
+
+TEST_F(CloseFileOperationTest, CloseFile) {
+  base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  ResourceEntry src_entry;
+  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
+
+  open_files_[file_in_root] = 1;
+  FileError error = FILE_ERROR_FAILED;
+  operation_->CloseFile(
+      file_in_root,
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  test_util::RunBlockingPoolTask();
+
+  EXPECT_EQ(FILE_ERROR_OK, error);
+  EXPECT_TRUE(open_files_.empty());
+  EXPECT_EQ(
+      1U,
+      observer()->upload_needed_resource_ids().count(src_entry.resource_id()));
+}
+
+TEST_F(CloseFileOperationTest, NotOpenedFile) {
+  base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  ResourceEntry src_entry;
+  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
+
+  FileError error = FILE_ERROR_FAILED;
+  operation_->CloseFile(
+      file_in_root,
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  test_util::RunBlockingPoolTask();
+
+  // Even if the file is actually exists, NOT_FOUND should be returned if the
+  // file is not opened.
+  EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
+}
+
+TEST_F(CloseFileOperationTest, CloseFileTwice) {
+  base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  ResourceEntry src_entry;
+  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
+
+  // Set the number of opening clients is two.
+  open_files_[file_in_root] = 2;
+
+  // The first CloseFile.
+  FileError error = FILE_ERROR_FAILED;
+  operation_->CloseFile(
+      file_in_root,
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  test_util::RunBlockingPoolTask();
+
+  EXPECT_EQ(FILE_ERROR_OK, error);
+  EXPECT_EQ(1, open_files_[file_in_root]);
+
+  // There still remains a client opening the file, so it shouldn't be
+  // uploaded yet.
+  EXPECT_TRUE(observer()->upload_needed_resource_ids().empty());
+
+  // The second CloseFile.
+  operation_->CloseFile(
+      file_in_root,
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  test_util::RunBlockingPoolTask();
+
+  EXPECT_EQ(FILE_ERROR_OK, error);
+  EXPECT_TRUE(open_files_.empty());
+  // Here, all the clients close the file, so it should be uploaded then.
+  EXPECT_EQ(
+      1U,
+      observer()->upload_needed_resource_ids().count(src_entry.resource_id()));
+}
+
+}  // namespace file_system
+}  // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system/copy_operation.cc b/chrome/browser/chromeos/drive/file_system/copy_operation.cc
index 72d6e07..3b10008 100644
--- a/chrome/browser/chromeos/drive/file_system/copy_operation.cc
+++ b/chrome/browser/chromeos/drive/file_system/copy_operation.cc
@@ -28,12 +28,12 @@
 namespace {
 
 // Copies a file from |src_file_path| to |dest_file_path| on the local
-// file system using file_util::CopyFile.
+// file system using base::CopyFile.
 // Returns FILE_ERROR_OK on success or FILE_ERROR_FAILED otherwise.
 FileError CopyLocalFileOnBlockingPool(
     const base::FilePath& src_file_path,
     const base::FilePath& dest_file_path) {
-  return file_util::CopyFile(src_file_path, dest_file_path) ?
+  return base::CopyFile(src_file_path, dest_file_path) ?
       FILE_ERROR_OK : FILE_ERROR_FAILED;
 }
 
@@ -328,17 +328,17 @@
 
   // If Drive API v2 is enabled, we can copy resources on server side.
   if (util::IsDriveV2ApiEnabled()) {
-    base::FilePath new_name = dest_file_path.BaseName();
+    base::FilePath new_title = dest_file_path.BaseName();
     if (src_file_proto->file_specific_info().is_hosted_document()) {
       // Drop the document extension, which should not be in the title.
       // TODO(yoshiki): Remove this code with crbug.com/223304.
-      new_name = new_name.RemoveExtension();
+      new_title = new_title.RemoveExtension();
     }
 
     scheduler_->CopyResource(
         src_file_proto->resource_id(),
         dest_parent_proto->resource_id(),
-        new_name.value(),
+        new_title.value(),
         base::Bind(&CopyOperation::OnCopyResourceCompleted,
                    weak_ptr_factory_.GetWeakPtr(), callback));
     return;
diff --git a/chrome/browser/chromeos/drive/file_system/copy_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/copy_operation_unittest.cc
index 0bf9e6d..d9643e5 100644
--- a/chrome/browser/chromeos/drive/file_system/copy_operation_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system/copy_operation_unittest.cc
@@ -49,7 +49,7 @@
       local_src_path,
       remote_dest_path,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // TransferFileFromLocalToRemote stores a copy of the local file in the cache,
@@ -62,7 +62,7 @@
   cache()->GetCacheEntryOnUIThread(
       entry.resource_id(), std::string(),
       google_apis::test_util::CreateCopyResultCallback(&found, &cache_entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_TRUE(found);
   EXPECT_TRUE(cache_entry.is_present());
   EXPECT_TRUE(cache_entry.is_dirty());
@@ -94,7 +94,7 @@
       local_src_path,
       remote_dest_path,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry));
@@ -119,7 +119,7 @@
       remote_src_path,
       local_dest_path,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // The content is "x"s of the file size.
@@ -128,7 +128,7 @@
                              entry.file_specific_info().md5(),
                              google_apis::test_util::CreateCopyResultCallback(
                                  &error, &cache_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   const std::string kExpectedContent = "This is some test content.";
@@ -157,7 +157,7 @@
       remote_src_path,
       local_dest_path,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   ResourceEntry entry;
@@ -180,7 +180,7 @@
   operation_->Copy(src_path,
                    dest_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
 
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &entry));
@@ -201,7 +201,7 @@
   operation_->Copy(src_path,
                    dest_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
 
   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
@@ -226,7 +226,7 @@
   operation_->Copy(src_path,
                    dest_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error);
 
   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
diff --git a/chrome/browser/chromeos/drive/file_system/create_directory_operation.cc b/chrome/browser/chromeos/drive/file_system/create_directory_operation.cc
index 89a7d60..56df421 100644
--- a/chrome/browser/chromeos/drive/file_system/create_directory_operation.cc
+++ b/chrome/browser/chromeos/drive/file_system/create_directory_operation.cc
@@ -167,15 +167,13 @@
   std::vector<base::FilePath::StringType> components;
   relative_file_path.GetComponents(&components);
   DCHECK(!components.empty());
-  // TODO(hidehiko): Rename this variable to "title" with other variable names.
-  // crbug.com/242794.
-  base::FilePath name(components[0]);
+  base::FilePath title(components[0]);
   base::FilePath remaining_path;
-  name.AppendRelativePath(relative_file_path, &remaining_path);
+  title.AppendRelativePath(relative_file_path, &remaining_path);
 
   scheduler_->AddNewDirectory(
       parent_resource_id,
-      name.AsUTF8Unsafe(),
+      title.AsUTF8Unsafe(),
       base::Bind(&CreateDirectoryOperation
                      ::CreateDirectoryRecursivelyAfterAddNewDirectory,
                  weak_ptr_factory_.GetWeakPtr(), remaining_path, callback));
diff --git a/chrome/browser/chromeos/drive/file_system/create_directory_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/create_directory_operation_unittest.cc
index 2ee63e5..e79692b 100644
--- a/chrome/browser/chromeos/drive/file_system/create_directory_operation_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system/create_directory_operation_unittest.cc
@@ -47,7 +47,7 @@
       true, // is_exclusive
       false,  // is_recursive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(FILE_ERROR_OK, FindDirectory(kNewDirectory1));
   EXPECT_EQ(1U, observer()->get_changed_paths().size());
@@ -61,7 +61,7 @@
       true, // is_exclusive
       false,  // is_recursive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, FindDirectory(kNewDirectory2));
 
@@ -70,7 +70,7 @@
       true, // is_exclusive
       true,  // is_recursive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(FILE_ERROR_OK, FindDirectory(kNewDirectory2));
 
@@ -80,7 +80,7 @@
       true, // is_exclusive
       false,  // is_recursive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_EXISTS, error);
 
   operation.CreateDirectory(
@@ -88,7 +88,7 @@
       false, // is_exclusive
       false,  // is_recursive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Try to create a directory with a path for an existing file.
@@ -97,7 +97,7 @@
       false, // is_exclusive
       true,  // is_recursive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
 
   // Try to create a directory under a file.
@@ -106,7 +106,7 @@
       false, // is_exclusive
       true,  // is_recursive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
 }
 
diff --git a/chrome/browser/chromeos/drive/file_system/create_file_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/create_file_operation_unittest.cc
index fe21079..791a106 100644
--- a/chrome/browser/chromeos/drive/file_system/create_file_operation_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system/create_file_operation_unittest.cc
@@ -35,7 +35,7 @@
       kExistingFile,
       true,  // is_exclusive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_EXISTS, error);
 
   // Create succeeds if is_exclusive = false and a file exists.
@@ -43,7 +43,7 @@
       kExistingFile,
       false,  // is_exclusive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Create fails if a directory existed even when is_exclusive = false.
@@ -51,7 +51,7 @@
       kExistingDirectory,
       false,  // is_exclusive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_EXISTS, error);
 
   // Create succeeds if no entry exists.
@@ -59,7 +59,7 @@
       kNonExistingFile,
       true,   // is_exclusive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Create fails if the parent directory does not exist.
@@ -67,7 +67,7 @@
       kFileInNonExistingDirectory,
       false,  // is_exclusive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error);
 }
 
diff --git a/chrome/browser/chromeos/drive/file_system/download_operation.cc b/chrome/browser/chromeos/drive/file_system/download_operation.cc
index 754bb46..a391986 100644
--- a/chrome/browser/chromeos/drive/file_system/download_operation.cc
+++ b/chrome/browser/chromeos/drive/file_system/download_operation.cc
@@ -182,7 +182,7 @@
 
   FileError error = util::GDataToFileError(gdata_error);
   if (error != FILE_ERROR_OK) {
-    base::Delete(downloaded_file_path, false /* recursive */);
+    base::DeleteFile(downloaded_file_path, false /* recursive */);
     return error;
   }
 
@@ -190,7 +190,7 @@
   error = cache->Store(resource_id, md5, downloaded_file_path,
                        internal::FileCache::FILE_OPERATION_MOVE);
   if (error != FILE_ERROR_OK) {
-    base::Delete(downloaded_file_path, false /* recursive */);
+    base::DeleteFile(downloaded_file_path, false /* recursive */);
     return error;
   }
 
diff --git a/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc
index 40a2648..5d0f298 100644
--- a/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc
@@ -50,7 +50,7 @@
       google_apis::GetContentCallback(),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &file_path, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   ASSERT_TRUE(entry);
@@ -87,7 +87,7 @@
       google_apis::GetContentCallback(),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &file_path, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_NO_SPACE, error);
 }
@@ -121,7 +121,7 @@
       "<resource_id>", "<md5>", tmp_file,
       internal::FileCache::FILE_OPERATION_COPY,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   base::FilePath file_path;
@@ -133,7 +133,7 @@
       google_apis::GetContentCallback(),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &file_path, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   ASSERT_TRUE(entry);
@@ -151,7 +151,7 @@
       "<resource_id>", "<md5>",
       google_apis::test_util::CreateCopyResultCallback(&result,
                                                        &cache_entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   ASSERT_FALSE(result);
 }
 
@@ -181,7 +181,7 @@
       google_apis::GetContentCallback(),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &file_path, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_NO_SPACE, error);
 }
@@ -202,7 +202,7 @@
       temp_file,
       internal::FileCache::FILE_OPERATION_COPY,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   base::FilePath file_path;
@@ -214,7 +214,7 @@
       google_apis::GetContentCallback(),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &file_path, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   ASSERT_TRUE(entry);
@@ -235,7 +235,7 @@
       google_apis::GetContentCallback(),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &file_path, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   ASSERT_TRUE(entry);
@@ -263,7 +263,7 @@
       google_apis::GetContentCallback(),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &file_path, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   ASSERT_TRUE(entry);
@@ -296,7 +296,7 @@
         get_content_callback.callback(),
         google_apis::test_util::CreateCopyResultCallback(
             &completion_error, &local_path_dontcare, &entry_dontcare));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
 
     // For the first time, file is downloaded from the remote server.
     // In this case, |local_path| is empty while |cancel_download| is not.
@@ -333,7 +333,7 @@
         get_content_callback.callback(),
         google_apis::test_util::CreateCopyResultCallback(
             &completion_error, &local_path_dontcare, &entry_dontcare));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
 
     // Try second download. In this case, the file should be cached, so
     // |local_path| should not be empty while |cancel_download| is empty.
@@ -366,7 +366,7 @@
       temp_file,
       internal::FileCache::FILE_OPERATION_COPY,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // The file is obtained from the cache.
@@ -383,7 +383,7 @@
       google_apis::GetContentCallback(),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &file_path, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   ASSERT_TRUE(entry);
@@ -410,13 +410,13 @@
       dirty_file,
       internal::FileCache::FILE_OPERATION_COPY,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   cache()->MarkDirtyOnUIThread(
       src_entry.resource_id(),
       src_entry.file_specific_info().md5(),
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Record values passed to GetFileContentInitializedCallback().
@@ -435,7 +435,7 @@
       google_apis::GetContentCallback(),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &file_path, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   // Check that the result of local modification is propagated.
diff --git a/chrome/browser/chromeos/drive/file_system/move_operation.cc b/chrome/browser/chromeos/drive/file_system/move_operation.cc
index fea40b6..c7700d0 100644
--- a/chrome/browser/chromeos/drive/file_system/move_operation.cc
+++ b/chrome/browser/chromeos/drive/file_system/move_operation.cc
@@ -148,21 +148,22 @@
   // Drop the .g<something> extension from |new_name| if the file being
   // renamed is a hosted document and |new_name| has the same .g<something>
   // extension as the file.
-  const base::FilePath& new_name_arg(
-      new_name_has_hosted_extension ? new_name.RemoveExtension() : new_name);
+  const std::string new_title = new_name_has_hosted_extension ?
+      new_name.RemoveExtension().AsUTF8Unsafe() :
+      new_name.AsUTF8Unsafe();
 
   // Rename on the server.
   scheduler_->RenameResource(src_id,
-                             new_name_arg.AsUTF8Unsafe(),
+                             new_title,
                              base::Bind(&MoveOperation::RenameLocally,
                                         weak_ptr_factory_.GetWeakPtr(),
                                         src_path,
-                                        new_name_arg,
+                                        new_title,
                                         callback));
 }
 
 void MoveOperation::RenameLocally(const base::FilePath& src_path,
-                                  const base::FilePath& new_name,
+                                  const std::string& new_title,
                                   const FileMoveCallback& callback,
                                   google_apis::GDataErrorCode status) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -172,10 +173,9 @@
     callback.Run(error, base::FilePath());
     return;
   }
-  metadata_->RenameEntryOnUIThread(src_path, new_name.AsUTF8Unsafe(), callback);
+  metadata_->RenameEntryOnUIThread(src_path, new_title, callback);
 }
 
-
 void MoveOperation::AddToDirectory(const std::string& src_id,
                                    const std::string& dest_dir_id,
                                    const base::FilePath& src_path,
diff --git a/chrome/browser/chromeos/drive/file_system/move_operation.h b/chrome/browser/chromeos/drive/file_system/move_operation.h
index ec18427..792aca8 100644
--- a/chrome/browser/chromeos/drive/file_system/move_operation.h
+++ b/chrome/browser/chromeos/drive/file_system/move_operation.h
@@ -13,7 +13,7 @@
 
 namespace base {
 class FilePath;
-}  // namespace base;
+}  // namespace base
 
 namespace drive {
 
@@ -86,7 +86,7 @@
 
   // Called in Rename() to reflect the rename on the local metadata.
   void RenameLocally(const base::FilePath& src_path,
-                     const base::FilePath& new_name,
+                     const std::string& new_title,
                      const FileMoveCallback& callback,
                      google_apis::GDataErrorCode status);
 
diff --git a/chrome/browser/chromeos/drive/file_system/move_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/move_operation_unittest.cc
index 22b6b62..4f9430e 100644
--- a/chrome/browser/chromeos/drive/file_system/move_operation_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system/move_operation_unittest.cc
@@ -36,7 +36,7 @@
   operation_->Move(src_path,
                    dest_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
@@ -61,7 +61,7 @@
   operation_->Move(src_path,
                    dest_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
@@ -87,7 +87,7 @@
   operation_->Move(src_path,
                    dest_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
@@ -114,7 +114,7 @@
   operation_->Move(src_path,
                    dest_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
@@ -141,7 +141,7 @@
   operation_->Move(src_path,
                    dest_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
@@ -161,7 +161,7 @@
   operation_->Move(src_path,
                    dest_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
 
   ResourceEntry entry;
@@ -177,7 +177,7 @@
   operation_->Move(src_path,
                    dest_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
 
   ResourceEntry entry;
@@ -196,7 +196,7 @@
   operation_->Move(src_path,
                    dest_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error);
 
   ResourceEntry entry;
diff --git a/chrome/browser/chromeos/drive/file_system/open_file_operation.cc b/chrome/browser/chromeos/drive/file_system/open_file_operation.cc
new file mode 100644
index 0000000..e5a1bfa
--- /dev/null
+++ b/chrome/browser/chromeos/drive/file_system/open_file_operation.cc
@@ -0,0 +1,168 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/drive/file_system/open_file_operation.h"
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/task_runner_util.h"
+#include "chrome/browser/chromeos/drive/drive.pb.h"
+#include "chrome/browser/chromeos/drive/file_cache.h"
+#include "chrome/browser/chromeos/drive/file_errors.h"
+#include "chrome/browser/chromeos/drive/file_system/create_file_operation.h"
+#include "chrome/browser/chromeos/drive/file_system/download_operation.h"
+#include "chrome/browser/chromeos/drive/file_system_interface.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+namespace drive {
+namespace file_system {
+namespace {
+
+FileError UpdateFileLocalState(internal::FileCache* cache,
+                               const std::string& resource_id,
+                               const std::string& md5,
+                               base::FilePath* local_file_path) {
+  FileError error = cache->MarkDirty(resource_id, md5);
+  if (error != FILE_ERROR_OK)
+    return error;
+
+  return cache->GetFile(resource_id, md5, local_file_path);
+}
+
+}  // namespace
+
+OpenFileOperation::OpenFileOperation(
+    base::SequencedTaskRunner* blocking_task_runner,
+    OperationObserver* observer,
+    JobScheduler* scheduler,
+    internal::ResourceMetadata* metadata,
+    internal::FileCache* cache,
+    const base::FilePath& temporary_file_directory,
+    std::map<base::FilePath, int>* open_files)
+    : blocking_task_runner_(blocking_task_runner),
+      cache_(cache),
+      create_file_operation_(new CreateFileOperation(
+          blocking_task_runner, observer, scheduler, metadata, cache)),
+      download_operation_(new DownloadOperation(
+          blocking_task_runner, observer, scheduler,
+          metadata, cache, temporary_file_directory)),
+      open_files_(open_files),
+      weak_ptr_factory_(this) {
+  DCHECK(open_files);
+}
+
+OpenFileOperation::~OpenFileOperation() {
+}
+
+void OpenFileOperation::OpenFile(const base::FilePath& file_path,
+                                 OpenMode open_mode,
+                                 const OpenFileCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+
+  switch (open_mode) {
+    case OPEN_FILE:
+      // It is not necessary to create a new file even if not exists.
+      // So call OpenFileAfterCreateFile directly with FILE_ERROR_OK
+      // to skip file creation.
+      OpenFileAfterCreateFile(file_path, callback, FILE_ERROR_OK);
+      break;
+    case CREATE_FILE:
+      create_file_operation_->CreateFile(
+          file_path,
+          true /* exclusive */,
+          base::Bind(&OpenFileOperation::OpenFileAfterCreateFile,
+                     weak_ptr_factory_.GetWeakPtr(), file_path, callback));
+      break;
+    case OPEN_OR_CREATE_FILE:
+      create_file_operation_->CreateFile(
+          file_path,
+          false /* not-exclusive */,
+          base::Bind(&OpenFileOperation::OpenFileAfterCreateFile,
+                     weak_ptr_factory_.GetWeakPtr(), file_path, callback));
+      break;
+  }
+}
+
+void OpenFileOperation::OpenFileAfterCreateFile(
+    const base::FilePath& file_path,
+    const OpenFileCallback& callback,
+    FileError error) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+
+  if (error != FILE_ERROR_OK) {
+    callback.Run(error, base::FilePath());
+    return;
+  }
+
+  download_operation_->EnsureFileDownloadedByPath(
+      file_path,
+      ClientContext(USER_INITIATED),
+      GetFileContentInitializedCallback(),
+      google_apis::GetContentCallback(),
+      base::Bind(
+          &OpenFileOperation::OpenFileAfterFileDownloaded,
+          weak_ptr_factory_.GetWeakPtr(), file_path, callback));
+}
+
+void OpenFileOperation::OpenFileAfterFileDownloaded(
+    const base::FilePath& file_path,
+    const OpenFileCallback& callback,
+    FileError error,
+    const base::FilePath& local_file_path,
+    scoped_ptr<ResourceEntry> entry) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+
+  if (error == FILE_ERROR_OK) {
+    DCHECK(entry);
+    DCHECK(entry->has_file_specific_info());
+    if (entry->file_specific_info().is_hosted_document())
+      // No support for opening a hosted document.
+      error = FILE_ERROR_INVALID_OPERATION;
+  }
+
+  if (error != FILE_ERROR_OK) {
+    callback.Run(error, base::FilePath());
+    return;
+  }
+
+  // Note: after marking the file dirty, the local file path may be changed.
+  // So, it is necessary to take the path again.
+  base::FilePath* new_local_file_path = new base::FilePath;
+  base::PostTaskAndReplyWithResult(
+      blocking_task_runner_.get(),
+      FROM_HERE,
+      base::Bind(&UpdateFileLocalState,
+                 cache_,
+                 entry->resource_id(),
+                 entry->file_specific_info().md5(),
+                 new_local_file_path),
+      base::Bind(&OpenFileOperation::OpenFileAfterUpdateLocalState,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 file_path,
+                 callback,
+                 base::Owned(new_local_file_path)));
+}
+
+void OpenFileOperation::OpenFileAfterUpdateLocalState(
+    const base::FilePath& file_path,
+    const OpenFileCallback& callback,
+    const base::FilePath* local_file_path,
+    FileError error) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+
+  if (error == FILE_ERROR_OK)
+    ++(*open_files_)[file_path];
+  callback.Run(error, *local_file_path);
+}
+
+}  // namespace file_system
+}  // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system/open_file_operation.h b/chrome/browser/chromeos/drive/file_system/open_file_operation.h
new file mode 100644
index 0000000..8aea8ad
--- /dev/null
+++ b/chrome/browser/chromeos/drive/file_system/open_file_operation.h
@@ -0,0 +1,98 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_OPEN_FILE_OPERATION_H_
+#define CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_OPEN_FILE_OPERATION_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/chromeos/drive/file_errors.h"
+#include "chrome/browser/chromeos/drive/file_system_interface.h"
+
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}  // namespace base
+
+namespace drive {
+
+class JobScheduler;
+class ResourceEntry;
+
+namespace internal {
+class ResourceMetadata;
+class FileCache;
+}  // namespace internal
+
+namespace file_system {
+
+class CreateFileOperation;
+class DownloadOperation;
+class OperationObserver;
+
+class OpenFileOperation {
+ public:
+  OpenFileOperation(base::SequencedTaskRunner* blocking_task_runner,
+                    OperationObserver* observer,
+                    JobScheduler* scheduler,
+                    internal::ResourceMetadata* metadata,
+                    internal::FileCache* cache,
+                    const base::FilePath& temporary_file_directory,
+                    std::map<base::FilePath, int>* open_files);
+  ~OpenFileOperation();
+
+  // Opens the file at |file_path|.
+  // If the file is not actually downloaded, this method starts
+  // to download it to the cache, and then runs |callback| upon the
+  // completation with the path to the local cache file.
+  // See also the definition of OpenMode for its meaning.
+  // |callback| must not be null.
+  void OpenFile(const base::FilePath& file_path,
+                OpenMode open_mode,
+                const OpenFileCallback& callback);
+
+ private:
+  // Part of OpenFile(). Called after file creation is completed.
+  void OpenFileAfterCreateFile(const base::FilePath& file_path,
+                               const OpenFileCallback& callback,
+                               FileError error);
+
+  // Part of OpenFile(). Called after file downloading is completed.
+  void OpenFileAfterFileDownloaded(const base::FilePath& file_path,
+                                   const OpenFileCallback& callback,
+                                   FileError error,
+                                   const base::FilePath& local_file_path,
+                                   scoped_ptr<ResourceEntry> entry);
+
+  // Part of OpenFile(). Called after the updating of the local state.
+  void OpenFileAfterUpdateLocalState(const base::FilePath& file_path,
+                                     const OpenFileCallback& callback,
+                                     const base::FilePath* local_file_path,
+                                     FileError error);
+
+  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
+  internal::FileCache* cache_;
+
+  scoped_ptr<CreateFileOperation> create_file_operation_;
+  scoped_ptr<DownloadOperation> download_operation_;
+
+  // The map from paths for opened file to the number how many the file is
+  // opened. The instance is owned by FileSystem and shared with
+  // CloseFileOperation.
+  std::map<base::FilePath, int>* open_files_;
+
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate its weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<OpenFileOperation> weak_ptr_factory_;
+  DISALLOW_COPY_AND_ASSIGN(OpenFileOperation);
+};
+
+}  // namespace file_system
+}  // namespace drive
+
+#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_OPEN_FILE_OPERATION_H_
diff --git a/chrome/browser/chromeos/drive/file_system/open_file_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/open_file_operation_unittest.cc
new file mode 100644
index 0000000..4e22efe
--- /dev/null
+++ b/chrome/browser/chromeos/drive/file_system/open_file_operation_unittest.cc
@@ -0,0 +1,208 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/drive/file_system/open_file_operation.h"
+
+#include <map>
+
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/drive/drive.pb.h"
+#include "chrome/browser/chromeos/drive/file_errors.h"
+#include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
+#include "chrome/browser/google_apis/test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace drive {
+namespace file_system {
+
+class OpenFileOperationTest : public OperationTestBase {
+ protected:
+  virtual void SetUp() {
+    OperationTestBase::SetUp();
+
+    operation_.reset(new OpenFileOperation(
+        blocking_task_runner(), observer(), scheduler(), metadata(), cache(),
+        temp_dir(), &open_files_));
+  }
+
+  std::map<base::FilePath, int> open_files_;
+  scoped_ptr<OpenFileOperation> operation_;
+};
+
+TEST_F(OpenFileOperationTest, OpenExistingFile) {
+  const base::FilePath file_in_root(
+      FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  ResourceEntry src_entry;
+  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
+  const int64 file_size = src_entry.file_info().size();
+
+  FileError error = FILE_ERROR_FAILED;
+  base::FilePath file_path;
+  operation_->OpenFile(
+      file_in_root,
+      OPEN_FILE,
+      google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
+  test_util::RunBlockingPoolTask();
+
+  EXPECT_EQ(FILE_ERROR_OK, error);
+  ASSERT_TRUE(base::PathExists(file_path));
+  int64 local_file_size;
+  ASSERT_TRUE(file_util::GetFileSize(file_path, &local_file_size));
+  EXPECT_EQ(file_size, local_file_size);
+
+  // The file_path should be added into the set.
+  EXPECT_EQ(1, open_files_[file_in_root]);
+}
+
+TEST_F(OpenFileOperationTest, OpenNonExistingFile) {
+  const base::FilePath file_in_root(
+      FILE_PATH_LITERAL("drive/root/not-exist.txt"));
+
+  FileError error = FILE_ERROR_FAILED;
+  base::FilePath file_path;
+  operation_->OpenFile(
+      file_in_root,
+      OPEN_FILE,
+      google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
+  test_util::RunBlockingPoolTask();
+  EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
+
+  // The file shouldn't be in the set of opened files.
+  EXPECT_EQ(0U, open_files_.count(file_in_root));
+}
+
+TEST_F(OpenFileOperationTest, CreateExistingFile) {
+  const base::FilePath file_in_root(
+      FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  ResourceEntry src_entry;
+  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
+
+  FileError error = FILE_ERROR_FAILED;
+  base::FilePath file_path;
+  operation_->OpenFile(
+      file_in_root,
+      CREATE_FILE,
+      google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
+  test_util::RunBlockingPoolTask();
+
+  EXPECT_EQ(FILE_ERROR_EXISTS, error);
+
+  // The file shouldn't be in the set of opened files.
+  EXPECT_EQ(0U, open_files_.count(file_in_root));
+}
+
+TEST_F(OpenFileOperationTest, CreateNonExistingFile) {
+  const base::FilePath file_in_root(
+      FILE_PATH_LITERAL("drive/root/not-exist.txt"));
+
+  FileError error = FILE_ERROR_FAILED;
+  base::FilePath file_path;
+  operation_->OpenFile(
+      file_in_root,
+      CREATE_FILE,
+      google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
+  test_util::RunBlockingPoolTask();
+
+  EXPECT_EQ(FILE_ERROR_OK, error);
+  ASSERT_TRUE(base::PathExists(file_path));
+  int64 local_file_size;
+  ASSERT_TRUE(file_util::GetFileSize(file_path, &local_file_size));
+  EXPECT_EQ(0, local_file_size);  // Should be an empty file.
+
+  // The file_path should be added into the set.
+  EXPECT_EQ(1, open_files_[file_in_root]);
+}
+
+TEST_F(OpenFileOperationTest, OpenOrCreateExistingFile) {
+  const base::FilePath file_in_root(
+      FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  ResourceEntry src_entry;
+  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
+  const int64 file_size = src_entry.file_info().size();
+
+  FileError error = FILE_ERROR_FAILED;
+  base::FilePath file_path;
+  operation_->OpenFile(
+      file_in_root,
+      OPEN_OR_CREATE_FILE,
+      google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
+  test_util::RunBlockingPoolTask();
+
+  EXPECT_EQ(FILE_ERROR_OK, error);
+  ASSERT_TRUE(base::PathExists(file_path));
+  int64 local_file_size;
+  ASSERT_TRUE(file_util::GetFileSize(file_path, &local_file_size));
+  EXPECT_EQ(file_size, local_file_size);
+
+  // The file_path should be added into the set.
+  EXPECT_EQ(1, open_files_[file_in_root]);
+}
+
+TEST_F(OpenFileOperationTest, OpenOrCreateNonExistingFile) {
+  const base::FilePath file_in_root(
+      FILE_PATH_LITERAL("drive/root/not-exist.txt"));
+
+  FileError error = FILE_ERROR_FAILED;
+  base::FilePath file_path;
+  operation_->OpenFile(
+      file_in_root,
+      OPEN_OR_CREATE_FILE,
+      google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
+  test_util::RunBlockingPoolTask();
+
+  EXPECT_EQ(FILE_ERROR_OK, error);
+  ASSERT_TRUE(base::PathExists(file_path));
+  int64 local_file_size;
+  ASSERT_TRUE(file_util::GetFileSize(file_path, &local_file_size));
+  EXPECT_EQ(0, local_file_size);  // Should be an empty file.
+
+  // The file_path should be added into the set.
+  EXPECT_EQ(1, open_files_[file_in_root]);
+}
+
+TEST_F(OpenFileOperationTest, OpenFileTwice) {
+  const base::FilePath file_in_root(
+      FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  ResourceEntry src_entry;
+  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
+  const int64 file_size = src_entry.file_info().size();
+
+  FileError error = FILE_ERROR_FAILED;
+  base::FilePath file_path;
+  operation_->OpenFile(
+      file_in_root,
+      OPEN_FILE,
+      google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
+  test_util::RunBlockingPoolTask();
+
+  EXPECT_EQ(FILE_ERROR_OK, error);
+  ASSERT_TRUE(base::PathExists(file_path));
+  int64 local_file_size;
+  ASSERT_TRUE(file_util::GetFileSize(file_path, &local_file_size));
+  EXPECT_EQ(file_size, local_file_size);
+
+  // The file_path should be added into the set.
+  EXPECT_EQ(1, open_files_[file_in_root]);
+
+  // Open again.
+  error = FILE_ERROR_FAILED;
+  operation_->OpenFile(
+      file_in_root,
+      OPEN_FILE,
+      google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
+  test_util::RunBlockingPoolTask();
+
+  EXPECT_EQ(FILE_ERROR_OK, error);
+  ASSERT_TRUE(base::PathExists(file_path));
+  ASSERT_TRUE(file_util::GetFileSize(file_path, &local_file_size));
+  EXPECT_EQ(file_size, local_file_size);
+
+  // The file_path should be added into the set.
+  EXPECT_EQ(2, open_files_[file_in_root]);
+}
+
+}  // namespace file_system
+}  // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system/operation_test_base.cc b/chrome/browser/chromeos/drive/file_system/operation_test_base.cc
index 91879c2..ad1fb09 100644
--- a/chrome/browser/chromeos/drive/file_system/operation_test_base.cc
+++ b/chrome/browser/chromeos/drive/file_system/operation_test_base.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
 
+#include "base/prefs/testing_pref_service.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/chromeos/drive/change_list_loader.h"
 #include "chrome/browser/chromeos/drive/fake_free_disk_space_getter.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/chromeos/drive/test_util.h"
 #include "chrome/browser/drive/fake_drive_service.h"
 #include "chrome/browser/google_apis/test_util.h"
-#include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/browser_thread.h"
 
 namespace drive {
@@ -48,7 +48,9 @@
   blocking_task_runner_ =
       pool->GetSequencedTaskRunner(pool->GetSequenceToken());
 
-  profile_.reset(new TestingProfile);
+  pref_service_.reset(new TestingPrefServiceSimple);
+  test_util::RegisterDrivePrefs(pref_service_->registry());
+
   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
 
   fake_drive_service_.reset(new FakeDriveService);
@@ -57,19 +59,21 @@
   fake_drive_service_->LoadAccountMetadataForWapi(
       "gdata/account_metadata.json");
 
-  scheduler_.reset(new JobScheduler(profile_.get(), fake_drive_service_.get(),
-                                    blocking_task_runner_));
+  scheduler_.reset(new JobScheduler(
+      pref_service_.get(),
+      fake_drive_service_.get(),
+      blocking_task_runner_.get()));
 
   metadata_storage_.reset(new internal::ResourceMetadataStorage(
-      temp_dir_.path(), blocking_task_runner_));
+      temp_dir_.path(), blocking_task_runner_.get()));
   bool success = false;
   base::PostTaskAndReplyWithResult(
-      blocking_task_runner_,
+      blocking_task_runner_.get(),
       FROM_HERE,
       base::Bind(&internal::ResourceMetadataStorage::Initialize,
                  base::Unretained(metadata_storage_.get())),
       google_apis::test_util::CreateCopyResultCallback(&success));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   ASSERT_TRUE(success);
 
   metadata_.reset(new internal::ResourceMetadata(metadata_storage_.get(),
@@ -77,12 +81,12 @@
 
   FileError error = FILE_ERROR_FAILED;
   base::PostTaskAndReplyWithResult(
-      blocking_task_runner_,
+      blocking_task_runner_.get(),
       FROM_HERE,
       base::Bind(&internal::ResourceMetadata::Initialize,
                  base::Unretained(metadata_.get())),
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   ASSERT_EQ(FILE_ERROR_OK, error);
 
   fake_free_disk_space_getter_.reset(new FakeFreeDiskSpaceGetter);
@@ -92,12 +96,12 @@
                                        fake_free_disk_space_getter_.get()));
   success = false;
   base::PostTaskAndReplyWithResult(
-      blocking_task_runner_,
+      blocking_task_runner_.get(),
       FROM_HERE,
       base::Bind(&internal::FileCache::Initialize,
                  base::Unretained(cache_.get())),
       google_apis::test_util::CreateCopyResultCallback(&success));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   ASSERT_TRUE(success);
 
   // Makes sure the FakeDriveService's content is loaded to the metadata_.
@@ -107,7 +111,7 @@
   change_list_loader.LoadIfNeeded(
       DirectoryFetchInfo(),
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   ASSERT_EQ(FILE_ERROR_OK, error);
 }
 
@@ -120,7 +124,7 @@
       base::Bind(&internal::ResourceMetadata::GetResourceEntryByPath,
                  base::Unretained(metadata()), path, entry),
       base::Bind(google_apis::test_util::CreateCopyResultCallback(&error)));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   return error;
 }
 
diff --git a/chrome/browser/chromeos/drive/file_system/operation_test_base.h b/chrome/browser/chromeos/drive/file_system/operation_test_base.h
index fd44a80..b8b26cc 100644
--- a/chrome/browser/chromeos/drive/file_system/operation_test_base.h
+++ b/chrome/browser/chromeos/drive/file_system/operation_test_base.h
@@ -14,7 +14,7 @@
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-class TestingProfile;
+class TestingPrefServiceSimple;
 
 namespace base {
 class SequencedTaskRunner;
@@ -98,7 +98,7 @@
  private:
   content::TestBrowserThreadBundle thread_bundle_;
   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
-  scoped_ptr<TestingProfile> profile_;
+  scoped_ptr<TestingPrefServiceSimple> pref_service_;
   base::ScopedTempDir temp_dir_;
 
   LoggingObserver observer_;
diff --git a/chrome/browser/chromeos/drive/file_system/remove_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/remove_operation_unittest.cc
index fdbbb78..84ab831 100644
--- a/chrome/browser/chromeos/drive/file_system/remove_operation_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system/remove_operation_unittest.cc
@@ -33,7 +33,7 @@
   operation.Remove(file_in_root,
                    false,  // is_recursive
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(file_in_root, &entry));
 
@@ -43,7 +43,7 @@
   operation.Remove(file_in_subdir,
                    false,  // is_recursive
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(FILE_ERROR_NOT_FOUND,
             GetLocalResourceEntry(file_in_subdir, &entry));
@@ -55,7 +55,7 @@
   operation.Remove(base::FilePath::FromUTF8Unsafe("drive/root/Dummy file.txt"),
                    false,  // is_recursive
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
 
   // Verify observer notifications.
@@ -81,7 +81,7 @@
   operation.Remove(empty_dir,
                    false,  // is_recursive
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(FILE_ERROR_NOT_FOUND,
             GetLocalResourceEntry(empty_dir, &entry));
@@ -92,7 +92,7 @@
   operation.Remove(non_empty_dir,
                    false,  // is_recursive
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_EMPTY, error);
   EXPECT_EQ(FILE_ERROR_OK,
             GetLocalResourceEntry(non_empty_dir, &entry));
@@ -105,7 +105,7 @@
   operation.Remove(non_empty_dir,
                    true,  // is_recursive
                    google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(FILE_ERROR_NOT_FOUND,
             GetLocalResourceEntry(non_empty_dir, &entry));
diff --git a/chrome/browser/chromeos/drive/file_system/search_operation.cc b/chrome/browser/chromeos/drive/file_system/search_operation.cc
index ea4a63a..2bf067a 100644
--- a/chrome/browser/chromeos/drive/file_system/search_operation.cc
+++ b/chrome/browser/chromeos/drive/file_system/search_operation.cc
@@ -17,7 +17,7 @@
 #include "chrome/browser/chromeos/drive/resource_metadata.h"
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
diff --git a/chrome/browser/chromeos/drive/file_system/search_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/search_operation_unittest.cc
index 4ea9f33..e8426d0 100644
--- a/chrome/browser/chromeos/drive/file_system/search_operation_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system/search_operation_unittest.cc
@@ -44,7 +44,7 @@
   operation.Search("Directory", GURL(),
                    google_apis::test_util::CreateCopyResultCallback(
                        &error, &next_url, &results));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(GURL(), next_url);
@@ -67,7 +67,7 @@
       "New Directory 1!",
       google_apis::test_util::CreateCopyResultCallback(
           &gdata_error, &resource_entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   ASSERT_EQ(google_apis::HTTP_CREATED, gdata_error);
 
   // As the result of the first Search(), only entries in the current file
@@ -85,7 +85,7 @@
   operation.Search("\"Directory 1\"", GURL(),
                    google_apis::test_util::CreateCopyResultCallback(
                        &error, &next_url, &results));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(GURL(), next_url);
@@ -102,7 +102,7 @@
       blocking_task_runner(), metadata(), scheduler());
   change_list_loader.CheckForUpdates(
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // Now the new entry must be reported to be in the right directory.
   const SearchResultPair kExpectedResultsAfterLoad[] = {
@@ -113,7 +113,7 @@
   operation.Search("\"Directory 1\"", GURL(),
                    google_apis::test_util::CreateCopyResultCallback(
                        &error, &next_url, &results));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(GURL(), next_url);
@@ -136,7 +136,7 @@
   operation.Search("\"no-match query\"", GURL(),
                    google_apis::test_util::CreateCopyResultCallback(
                        &error, &next_url, &results));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(GURL(), next_url);
diff --git a/chrome/browser/chromeos/drive/file_system/touch_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/touch_operation_unittest.cc
index ff4380a..7b684b9 100644
--- a/chrome/browser/chromeos/drive/file_system/touch_operation_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system/touch_operation_unittest.cc
@@ -38,7 +38,7 @@
       base::Time::FromUTCExploded(kLastAccessTime),
       base::Time::FromUTCExploded(kLastModifiedTime),
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   ResourceEntry entry;
diff --git a/chrome/browser/chromeos/drive/file_system/truncate_operation.cc b/chrome/browser/chromeos/drive/file_system/truncate_operation.cc
index 018d9a5..df3918c 100644
--- a/chrome/browser/chromeos/drive/file_system/truncate_operation.cc
+++ b/chrome/browser/chromeos/drive/file_system/truncate_operation.cc
@@ -53,6 +53,10 @@
                                  int64 length) {
   DCHECK(cache);
 
+  FileError error = cache->MarkDirty(resource_id, md5);
+  if (error != FILE_ERROR_OK)
+    return error;
+
   base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED;
   base::PlatformFile file = base::CreatePlatformFile(
       local_cache_path,
@@ -68,7 +72,7 @@
   if (!base::TruncatePlatformFile(file, length))
     return FILE_ERROR_FAILED;
 
-  return cache->MarkDirty(resource_id, md5);
+  return FILE_ERROR_OK;
 }
 
 }  // namespace
@@ -159,8 +163,7 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
-  if (error == FILE_ERROR_OK)
-    observer_->OnCacheFileUploadNeededByOperation(resource_id);
+  observer_->OnCacheFileUploadNeededByOperation(resource_id);
 
   callback.Run(error);
 }
diff --git a/chrome/browser/chromeos/drive/file_system/truncate_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/truncate_operation_unittest.cc
index 47a7205..32ff259 100644
--- a/chrome/browser/chromeos/drive/file_system/truncate_operation_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system/truncate_operation_unittest.cc
@@ -42,7 +42,7 @@
       file_in_root,
       1,  // Truncate to 1 byte.
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   base::FilePath local_path;
@@ -50,7 +50,7 @@
   cache()->GetFileOnUIThread(
       src_entry.resource_id(), src_entry.file_specific_info().md5(),
       google_apis::test_util::CreateCopyResultCallback(&error, &local_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   ASSERT_EQ(FILE_ERROR_OK, error);
 
   // The local file should be truncated.
@@ -73,7 +73,7 @@
       file_in_root,
       -1,  // Truncate to "-1" byte.
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_INVALID_OPERATION, error);
 }
 
@@ -86,7 +86,7 @@
       file_in_root,
       1,  // Truncate to 1 byte.
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_INVALID_OPERATION, error);
 }
 
@@ -101,7 +101,7 @@
       file_in_root,
       file_size + 10,  // Extend to 10 bytes.
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   base::FilePath local_path;
@@ -109,7 +109,7 @@
   cache()->GetFileOnUIThread(
       src_entry.resource_id(), src_entry.file_specific_info().md5(),
       google_apis::test_util::CreateCopyResultCallback(&error, &local_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   ASSERT_EQ(FILE_ERROR_OK, error);
 
   // The local file should be truncated.
diff --git a/chrome/browser/chromeos/drive/file_system/update_operation.cc b/chrome/browser/chromeos/drive/file_system/update_operation.cc
index af789ad..7bc4255 100644
--- a/chrome/browser/chromeos/drive/file_system/update_operation.cc
+++ b/chrome/browser/chromeos/drive/file_system/update_operation.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/chromeos/drive/file_system/update_operation.h"
 
+#include "base/platform_file.h"
 #include "chrome/browser/chromeos/drive/drive.pb.h"
 #include "chrome/browser/chromeos/drive/file_cache.h"
 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h"
@@ -26,7 +27,8 @@
                             const std::string& resource_id,
                             ResourceEntry* entry,
                             base::FilePath* drive_file_path,
-                            base::FilePath* cache_file_path) {
+                            base::FilePath* cache_file_path,
+                            bool* content_is_same) {
   FileError error = metadata->GetResourceEntryById(resource_id, entry);
   if (error != FILE_ERROR_OK)
     return error;
@@ -38,9 +40,17 @@
   if (drive_file_path->empty())
     return FILE_ERROR_NOT_FOUND;
 
-  return cache->GetFile(resource_id,
-                        entry->file_specific_info().md5(),
-                        cache_file_path);
+  error = cache->GetFile(
+      resource_id, entry->file_specific_info().md5(), cache_file_path);
+  if (error != FILE_ERROR_OK)
+    return error;
+
+  const std::string& md5 = util::GetMd5Digest(*cache_file_path);
+  *content_is_same = (md5 == entry->file_specific_info().md5());
+  if (*content_is_same)
+    cache->ClearDirty(resource_id, md5);
+
+  return FILE_ERROR_OK;
 }
 
 // Updates locally stored information about the specified file.
@@ -68,6 +78,16 @@
 
 }  // namespace
 
+struct UpdateOperation::LocalState {
+  LocalState() : content_is_same(false) {
+  }
+
+  ResourceEntry entry;
+  base::FilePath drive_file_path;
+  base::FilePath cache_file_path;
+  bool content_is_same;
+};
+
 UpdateOperation::UpdateOperation(
     base::SequencedTaskRunner* blocking_task_runner,
     OperationObserver* observer,
@@ -94,9 +114,7 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
-  ResourceEntry* entry = new ResourceEntry;
-  base::FilePath* drive_file_path = new base::FilePath;
-  base::FilePath* cache_file_path = new base::FilePath;
+  LocalState* local_state = new LocalState;
   base::PostTaskAndReplyWithResult(
       blocking_task_runner_.get(),
       FROM_HERE,
@@ -104,38 +122,35 @@
                  metadata_,
                  cache_,
                  resource_id,
-                 entry,
-                 drive_file_path,
-                 cache_file_path),
+                 &local_state->entry,
+                 &local_state->drive_file_path,
+                 &local_state->cache_file_path,
+                 &local_state->content_is_same),
       base::Bind(&UpdateOperation::UpdateFileAfterGetLocalState,
                  weak_ptr_factory_.GetWeakPtr(),
                  context,
                  callback,
-                 base::Owned(entry),
-                 base::Owned(drive_file_path),
-                 base::Owned(cache_file_path)));
+                 base::Owned(local_state)));
 }
 
 void UpdateOperation::UpdateFileAfterGetLocalState(
     const ClientContext& context,
     const FileOperationCallback& callback,
-    const ResourceEntry* entry,
-    const base::FilePath* drive_file_path,
-    const base::FilePath* cache_file_path,
+    const LocalState* local_state,
     FileError error) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
-  if (error != FILE_ERROR_OK) {
+  if (error != FILE_ERROR_OK || local_state->content_is_same) {
     callback.Run(error);
     return;
   }
 
   scheduler_->UploadExistingFile(
-      entry->resource_id(),
-      *drive_file_path,
-      *cache_file_path,
-      entry->file_specific_info().content_mime_type(),
+      local_state->entry.resource_id(),
+      local_state->drive_file_path,
+      local_state->cache_file_path,
+      local_state->entry.file_specific_info().content_mime_type(),
       "",  // etag
       context,
       base::Bind(&UpdateOperation::UpdateFileAfterUpload,
diff --git a/chrome/browser/chromeos/drive/file_system/update_operation.h b/chrome/browser/chromeos/drive/file_system/update_operation.h
index 0088e50..9e321c6 100644
--- a/chrome/browser/chromeos/drive/file_system/update_operation.h
+++ b/chrome/browser/chromeos/drive/file_system/update_operation.h
@@ -58,11 +58,11 @@
                               const FileOperationCallback& callback);
 
  private:
+  struct LocalState;
+
   void UpdateFileAfterGetLocalState(const ClientContext& context,
                                     const FileOperationCallback& callback,
-                                    const ResourceEntry* entry,
-                                    const base::FilePath* drive_file_path,
-                                    const base::FilePath* cache_file_path,
+                                    const LocalState* local_state,
                                     FileError error);
 
   void UpdateFileAfterUpload(
diff --git a/chrome/browser/chromeos/drive/file_system/update_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/update_operation_unittest.cc
index 58ba355..b9aa729 100644
--- a/chrome/browser/chromeos/drive/file_system/update_operation_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system/update_operation_unittest.cc
@@ -42,7 +42,7 @@
   cache()->PinOnUIThread(
       kResourceId,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // First store a file to cache.
@@ -51,7 +51,7 @@
       kResourceId, kMd5, kTestFile,
       internal::FileCache::FILE_OPERATION_COPY,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Add the dirty bit.
@@ -59,7 +59,7 @@
   cache()->MarkDirtyOnUIThread(
       kResourceId, kMd5,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   int64 original_changestamp = fake_service()->largest_changestamp();
@@ -71,7 +71,7 @@
       kResourceId,
       ClientContext(USER_INITIATED),
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Check that the server has received an update.
@@ -84,10 +84,21 @@
       kResourceId,
       google_apis::test_util::CreateCopyResultCallback(&gdata_error,
                                                        &server_entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
   EXPECT_EQ(static_cast<int64>(kTestFileContent.size()),
             server_entry->file_size());
+
+  // Make sure that the cache is no longer dirty.
+  bool success = false;
+  FileCacheEntry cache_entry;
+  cache()->GetCacheEntryOnUIThread(
+      server_entry->resource_id(),
+      server_entry->file_md5(),
+      google_apis::test_util::CreateCopyResultCallback(&success, &cache_entry));
+  test_util::RunBlockingPoolTask();
+  ASSERT_TRUE(success);
+  EXPECT_FALSE(cache_entry.is_dirty());
 }
 
 TEST_F(UpdateOperationTest, UpdateFileByResourceId_NonexistentFile) {
@@ -96,9 +107,106 @@
       "file:nonexistent_resource_id",
       ClientContext(USER_INITIATED),
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
 }
 
+TEST_F(UpdateOperationTest, UpdateFileByResourceId_Md5) {
+  const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  const std::string kResourceId("file:2_file_resource_id");
+  const std::string kMd5("3b4382ebefec6e743578c76bbd0575ce");
+
+  const base::FilePath kTestFile = temp_dir().Append(FILE_PATH_LITERAL("foo"));
+  const std::string kTestFileContent = "I'm being uploaded! Yay!";
+  google_apis::test_util::WriteStringToFile(kTestFile, kTestFileContent);
+
+  // First store a file to cache.
+  FileError error = FILE_ERROR_FAILED;
+  cache()->StoreOnUIThread(
+      kResourceId, kMd5, kTestFile,
+      internal::FileCache::FILE_OPERATION_COPY,
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  test_util::RunBlockingPoolTask();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  // Add the dirty bit.
+  error = FILE_ERROR_FAILED;
+  cache()->MarkDirtyOnUIThread(
+      kResourceId, kMd5,
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  test_util::RunBlockingPoolTask();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  int64 original_changestamp = fake_service()->largest_changestamp();
+
+  // The callback will be called upon completion of
+  // UpdateFileByResourceId().
+  error = FILE_ERROR_FAILED;
+  operation_->UpdateFileByResourceId(
+      kResourceId,
+      ClientContext(USER_INITIATED),
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  test_util::RunBlockingPoolTask();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  // Check that the server has received an update.
+  EXPECT_LT(original_changestamp, fake_service()->largest_changestamp());
+
+  // Check that the file size is updated to that of the updated content.
+  google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR;
+  scoped_ptr<google_apis::ResourceEntry> server_entry;
+  fake_service()->GetResourceEntry(
+      kResourceId,
+      google_apis::test_util::CreateCopyResultCallback(&gdata_error,
+                                                       &server_entry));
+  test_util::RunBlockingPoolTask();
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
+  EXPECT_EQ(static_cast<int64>(kTestFileContent.size()),
+            server_entry->file_size());
+
+  // Make sure that the cache is no longer dirty.
+  bool success = false;
+  FileCacheEntry cache_entry;
+  cache()->GetCacheEntryOnUIThread(
+      server_entry->resource_id(),
+      server_entry->file_md5(),
+      google_apis::test_util::CreateCopyResultCallback(&success, &cache_entry));
+  test_util::RunBlockingPoolTask();
+  ASSERT_TRUE(success);
+  EXPECT_FALSE(cache_entry.is_dirty());
+
+  // Again mark the cache file dirty.
+  error = FILE_ERROR_FAILED;
+  cache()->MarkDirtyOnUIThread(
+      kResourceId, server_entry->file_md5(),
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  test_util::RunBlockingPoolTask();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  // And call UpdateFileByResourceId again.
+  // In this case, although the file is marked as dirty, but the content
+  // hasn't been changed. Thus, the actual uploading should be skipped.
+  original_changestamp = fake_service()->largest_changestamp();
+  error = FILE_ERROR_FAILED;
+  operation_->UpdateFileByResourceId(
+      kResourceId,
+      ClientContext(USER_INITIATED),
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  test_util::RunBlockingPoolTask();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  EXPECT_EQ(original_changestamp, fake_service()->largest_changestamp());
+
+  // Make sure that the cache is no longer dirty.
+  success = false;
+  cache()->GetCacheEntryOnUIThread(
+      server_entry->resource_id(),
+      server_entry->file_md5(),
+      google_apis::test_util::CreateCopyResultCallback(&success, &cache_entry));
+  test_util::RunBlockingPoolTask();
+  ASSERT_TRUE(success);
+  EXPECT_FALSE(cache_entry.is_dirty());
+}
+
 }  // namespace file_system
 }  // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system_backend_delegate.cc b/chrome/browser/chromeos/drive/file_system_backend_delegate.cc
new file mode 100644
index 0000000..9745d66
--- /dev/null
+++ b/chrome/browser/chromeos/drive/file_system_backend_delegate.cc
@@ -0,0 +1,102 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/drive/file_system_backend_delegate.h"
+
+#include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/drive/async_file_util.h"
+#include "chrome/browser/chromeos/drive/file_system_util.h"
+#include "chrome/browser/chromeos/drive/webkit_file_stream_reader_impl.h"
+#include "chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.h"
+#include "chrome/browser/chromeos/fileapi/remote_file_system_operation.h"
+#include "chrome/browser/profiles/profile.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "webkit/browser/blob/file_stream_reader.h"
+#include "webkit/browser/fileapi/async_file_util.h"
+#include "webkit/browser/fileapi/external_mount_points.h"
+#include "webkit/browser/fileapi/file_system_task_runners.h"
+#include "webkit/browser/fileapi/remote_file_system_proxy.h"
+
+using content::BrowserThread;
+
+namespace drive {
+
+FileSystemBackendDelegate::FileSystemBackendDelegate(
+    content::BrowserContext* browser_context)
+    : mount_points_(content::BrowserContext::GetMountPoints(browser_context)),
+      profile_id_(Profile::FromBrowserContext(browser_context)),
+      async_file_util_(new internal::AsyncFileUtil(
+          base::Bind(&util::GetFileSystemByProfileId, profile_id_))) {
+  DCHECK(profile_id_);
+}
+
+FileSystemBackendDelegate::~FileSystemBackendDelegate() {
+}
+
+fileapi::AsyncFileUtil* FileSystemBackendDelegate::GetAsyncFileUtil(
+    fileapi::FileSystemType type) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_EQ(fileapi::kFileSystemTypeDrive, type);
+  return async_file_util_.get();
+}
+
+scoped_ptr<webkit_blob::FileStreamReader>
+FileSystemBackendDelegate::CreateFileStreamReader(
+    const fileapi::FileSystemURL& url,
+    int64 offset,
+    const base::Time& expected_modification_time,
+    fileapi::FileSystemContext* context) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_EQ(fileapi::kFileSystemTypeDrive, url.type());
+
+  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+  if (file_path.empty())
+    return scoped_ptr<webkit_blob::FileStreamReader>();
+
+  return scoped_ptr<webkit_blob::FileStreamReader>(
+      new internal::WebkitFileStreamReaderImpl(
+          base::Bind(&util::GetFileSystemByProfileId, profile_id_),
+          context->task_runners()->file_task_runner(),
+          file_path, offset, expected_modification_time));
+}
+
+scoped_ptr<fileapi::FileStreamWriter>
+FileSystemBackendDelegate::CreateFileStreamWriter(
+    const fileapi::FileSystemURL& url,
+    int64 offset,
+    fileapi::FileSystemContext* context) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_EQ(fileapi::kFileSystemTypeDrive, url.type());
+
+  fileapi::RemoteFileSystemProxyInterface* proxy =
+      mount_points_->GetRemoteFileSystemProxy(url.filesystem_id());
+  if (!proxy)
+    return scoped_ptr<fileapi::FileStreamWriter>();
+
+  return scoped_ptr<fileapi::FileStreamWriter>(
+      new internal::WebkitFileStreamWriterImpl(
+          proxy, url, offset, context->task_runners()->file_task_runner()));
+}
+
+fileapi::FileSystemOperation*
+FileSystemBackendDelegate::CreateFileSystemOperation(
+    const fileapi::FileSystemURL& url,
+    fileapi::FileSystemContext* context,
+    base::PlatformFileError* error_code) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_EQ(fileapi::kFileSystemTypeDrive, url.type());
+
+  fileapi::RemoteFileSystemProxyInterface* proxy =
+      mount_points_->GetRemoteFileSystemProxy(url.filesystem_id());
+  if (!proxy) {
+    *error_code = base::PLATFORM_FILE_ERROR_NOT_FOUND;
+    return NULL;
+  }
+
+  return new chromeos::RemoteFileSystemOperation(proxy);
+}
+
+}  // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system_backend_delegate.h b/chrome/browser/chromeos/drive/file_system_backend_delegate.h
new file mode 100644
index 0000000..6eec8f0
--- /dev/null
+++ b/chrome/browser/chromeos/drive/file_system_backend_delegate.h
@@ -0,0 +1,62 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_BACKEND_DELEGATE_H_
+#define CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_BACKEND_DELEGATE_H_
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/fileapi/file_system_backend_delegate.h"
+
+namespace content {
+class BrowserContext;
+}  // namespace content
+
+namespace fileapi {
+class AsyncFileUtil;
+class ExternalMountPoints;
+}  // namespace fileapi
+
+namespace drive {
+
+// Delegate implementation of the some methods in chromeos::FileSystemBackend
+// for Drive file system.
+class FileSystemBackendDelegate : public chromeos::FileSystemBackendDelegate {
+ public:
+  // |browser_context| is currently used to take the ExternalMountPoints.
+  explicit FileSystemBackendDelegate(
+      content::BrowserContext* browser_context);
+  virtual ~FileSystemBackendDelegate();
+
+  // FileSystemBackend::Delegate overrides.
+  virtual fileapi::AsyncFileUtil* GetAsyncFileUtil(
+      fileapi::FileSystemType type) OVERRIDE;
+  virtual scoped_ptr<webkit_blob::FileStreamReader> CreateFileStreamReader(
+      const fileapi::FileSystemURL& url,
+      int64 offset,
+      const base::Time& expected_modification_time,
+      fileapi::FileSystemContext* context) OVERRIDE;
+  virtual scoped_ptr<fileapi::FileStreamWriter> CreateFileStreamWriter(
+      const fileapi::FileSystemURL& url,
+      int64 offset,
+      fileapi::FileSystemContext* context) OVERRIDE;
+  virtual fileapi::FileSystemOperation* CreateFileSystemOperation(
+      const fileapi::FileSystemURL& url,
+      fileapi::FileSystemContext* context,
+      base::PlatformFileError* error_code) OVERRIDE;
+
+ private:
+  scoped_refptr<fileapi::ExternalMountPoints> mount_points_;
+
+  // The profile for processing Drive accesses. Should not be NULL.
+  void* profile_id_;
+  scoped_ptr<fileapi::AsyncFileUtil> async_file_util_;
+
+  DISALLOW_COPY_AND_ASSIGN(FileSystemBackendDelegate);
+};
+
+}  // namespace drive
+
+#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_BACKEND_DELEGATE_H_
diff --git a/chrome/browser/chromeos/drive/file_system_interface.h b/chrome/browser/chromeos/drive/file_system_interface.h
index b7d61f8..bf3b3be 100644
--- a/chrome/browser/chromeos/drive/file_system_interface.h
+++ b/chrome/browser/chromeos/drive/file_system_interface.h
@@ -108,6 +108,18 @@
 typedef base::Callback<void(const FileSystemMetadata&)>
     GetFilesystemMetadataCallback;
 
+// The mode of opening a file.
+enum OpenMode {
+  // Open the file if exists. If not, failed.
+  OPEN_FILE,
+
+  // Create a new file if not exists, and then open it. If exists, failed.
+  CREATE_FILE,
+
+  // Open the file if exists. If not, create a new file and then open it.
+  OPEN_OR_CREATE_FILE,
+};
+
 // Priority of a job.  Higher values are lower priority.
 enum ContextType {
   USER_INITIATED,
@@ -153,14 +165,6 @@
   // Checks for updates on the server.
   virtual void CheckForUpdates() = 0;
 
-  // Finds an entry (file or directory) by using |resource_id|. This call
-  // does not initiate content refreshing.
-  //
-  // |callback| must not be null.
-  virtual void GetResourceEntryById(
-      const std::string& resource_id,
-      const GetResourceEntryCallback& callback) = 0;
-
   // Initiates transfer of |remote_src_file_path| to |local_dest_file_path|.
   // |remote_src_file_path| is the virtual source path on the Drive file system.
   // |local_dest_file_path| is the destination path on the local file system.
@@ -192,6 +196,7 @@
   //
   // |callback| must not be null.
   virtual void OpenFile(const base::FilePath& file_path,
+                        OpenMode open_mode,
                         const OpenFileCallback& callback) = 0;
 
   // Closes a file at the virtual path |file_path| on the Drive file system,
@@ -315,17 +320,6 @@
   virtual void GetFileByPath(const base::FilePath& file_path,
                              const GetFileCallback& callback) = 0;
 
-  // Gets a file by the given |resource_id| from the Drive server. Used for
-  // fetching pinned-but-not-fetched files.
-  //
-  // |get_file_callback| must not be null.
-  // |get_content_callback| may be null.
-  virtual void GetFileByResourceId(
-      const std::string& resource_id,
-      const ClientContext& context,
-      const GetFileCallback& get_file_callback,
-      const google_apis::GetContentCallback& get_content_callback) = 0;
-
   // Gets a file by the given |file_path|.
   // Calls |initialized_callback| when either:
   //   1) The cached file (or JSON file for hosted file) is found, or
@@ -343,19 +337,6 @@
       const google_apis::GetContentCallback& get_content_callback,
       const FileOperationCallback& completion_callback) = 0;
 
-  // Updates a file by the given |resource_id| on the Drive server by
-  // uploading an updated version. Used for uploading dirty files. The file
-  // should already be present in the cache.
-  //
-  // TODO(satorux): As of now, the function only handles files with the dirty
-  // bit committed. We should eliminate the restriction. crbug.com/134558.
-  //
-  // |callback| must not be null.
-  virtual void UpdateFileByResourceId(
-      const std::string& resource_id,
-      const ClientContext& context,
-      const FileOperationCallback& callback) = 0;
-
   // Finds an entry (a file or a directory) by |file_path|. This call will also
   // retrieve and refresh file system content from server and disk cache.
   //
@@ -372,25 +353,6 @@
       const base::FilePath& file_path,
       const ReadDirectoryCallback& callback) = 0;
 
-  // Refreshes the directory pointed by |file_path| (i.e. fetches the latest
-  // metadata of files in the target directory).
-  //
-  // In particular, this function is used to get the latest thumbnail
-  // URLs. Thumbnail URLs change periodically even if contents of files are
-  // not changed, hence we should get the new thumbnail URLs manually if we
-  // detect that the existing thumbnail URLs are stale.
-  //
-  // Upon success, the metadata of files in the target directory is updated
-  // and the change is notified via Observer::OnDirectoryChanged().
-  // |callback| is called with an error code regardless of whether the
-  // refresh was success or not. Note that this function ignores changes in
-  // directories in the target directory. Changes in directories are handled
-  // via the change lists.
-  //
-  // |callback| must not be null.
-  virtual void RefreshDirectory(const base::FilePath& file_path,
-                                const FileOperationCallback& callback) = 0;
-
   // Does server side content search for |search_query|.
   // If |next_url| is set, this is the search result url that will be fetched.
   // Search results will be returned as a list of results' |SearchResultInfo|
diff --git a/chrome/browser/chromeos/drive/file_system_proxy.cc b/chrome/browser/chromeos/drive/file_system_proxy.cc
index 37845ab..25214f5 100644
--- a/chrome/browser/chromeos/drive/file_system_proxy.cc
+++ b/chrome/browser/chromeos/drive/file_system_proxy.cc
@@ -61,11 +61,11 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
   scoped_refptr<webkit_blob::ShareableFileReference> file_reference =
-      webkit_blob::ShareableFileReference::GetOrCreate(
-          webkit_blob::ScopedFile(
-              local_path, scope_out_policy,
-              BrowserThread::GetMessageLoopProxyForThread(
-                  BrowserThread::FILE)));
+      webkit_blob::ShareableFileReference::GetOrCreate(webkit_blob::ScopedFile(
+          local_path,
+          scope_out_policy,
+          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)
+              .get()));
   callback.Run(error, file_info, local_path, file_reference);
 }
 
@@ -73,15 +73,13 @@
 
 FileSystemProxy::FileSystemProxy(
     FileSystemInterface* file_system)
-    : file_system_(file_system),
-      worker_(new internal::FileApiWorker(file_system)) {
+    : file_system_(file_system) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
 
 void FileSystemProxy::DetachFromFileSystem() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   file_system_ = NULL;
-  worker_.reset();
 }
 
 void FileSystemProxy::GetFileInfo(
@@ -98,9 +96,8 @@
     return;
   }
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::GetFileInfo,
-                 base::Unretained(worker_.get()),
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::GetFileInfo,
                  file_path, google_apis::CreateRelayCallback(callback)));
 }
 
@@ -119,9 +116,8 @@
     return;
   }
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::Copy,
-                 base::Unretained(worker_.get()),
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::Copy,
                  src_file_path, dest_file_path,
                  google_apis::CreateRelayCallback(callback)));
 }
@@ -141,9 +137,8 @@
     return;
   }
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::Move,
-                 base::Unretained(worker_.get()),
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::Move,
                  src_file_path, dest_file_path,
                  google_apis::CreateRelayCallback(callback)));
 }
@@ -164,9 +159,8 @@
     return;
   }
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::ReadDirectory,
-                 base::Unretained(worker_.get()),
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::ReadDirectory,
                  file_path, google_apis::CreateRelayCallback(callback)));
 }
 
@@ -184,9 +178,8 @@
     return;
   }
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::Remove,
-                 base::Unretained(worker_.get()),
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::Remove,
                  file_path, recursive,
                  google_apis::CreateRelayCallback(callback)));
 }
@@ -206,9 +199,8 @@
     return;
   }
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::CreateDirectory,
-                 base::Unretained(worker_.get()),
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::CreateDirectory,
                  file_path, exclusive, recursive,
                  google_apis::CreateRelayCallback(callback)));
 }
@@ -227,9 +219,8 @@
     return;
   }
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::CreateFile,
-                 base::Unretained(worker_.get()),
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::CreateFile,
                  file_path, exclusive,
                  google_apis::CreateRelayCallback(callback)));
 }
@@ -248,9 +239,8 @@
     return;
   }
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::Truncate,
-                 base::Unretained(worker_.get()),
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::Truncate,
                  file_path, length,
                  google_apis::CreateRelayCallback(callback)));
 }
@@ -273,9 +263,8 @@
     return;
   }
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::OpenFile,
-                 base::Unretained(worker_.get()),
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::OpenFile,
                  file_path, file_flags,
                  google_apis::CreateRelayCallback(
                      base::Bind(&RunOpenFileCallback, peer_handle, callback))));
@@ -286,9 +275,8 @@
   if (!ValidateUrl(url, &file_path))
     return;
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::CloseFile,
-                 base::Unretained(worker_.get()), file_path));
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::CloseFile, file_path));
 }
 
 void FileSystemProxy::TouchFile(
@@ -302,9 +290,8 @@
   if (!ValidateUrl(url, &file_path))
     return;
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::TouchFile,
-                 base::Unretained(worker_.get()),
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::TouchFile,
                  file_path, last_access_time, last_modified_time,
                  google_apis::CreateRelayCallback(callback)));
 }
@@ -326,9 +313,9 @@
     return;
   }
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::CreateSnapshotFile,
-                 base::Unretained(worker_.get()), file_path,
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::CreateSnapshotFile,
+                 file_path,
                  google_apis::CreateRelayCallback(
                      base::Bind(&RunSnapshotFileCallback, callback))));
 }
@@ -353,6 +340,7 @@
       base::Bind(&FileSystemInterface::OpenFile,
                  base::Unretained(file_system_),
                  file_path,
+                 OPEN_FILE,
                  google_apis::CreateRelayCallback(
                      base::Bind(
                          &FileSystemProxy::OnCreateWritableSnapshotFile,
@@ -369,21 +357,12 @@
     const base::Time& expected_modification_time) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
-  base::FilePath drive_file_path;
-  if (!ValidateUrl(url, &drive_file_path))
-    return scoped_ptr<webkit_blob::FileStreamReader>();
-
-  return scoped_ptr<webkit_blob::FileStreamReader>(
-      new internal::WebkitFileStreamReaderImpl(
-          base::Bind(&FileSystemProxy::GetFileSystemOnUIThread, this),
-          file_task_runner,
-          drive_file_path,
-          offset,
-          expected_modification_time));
+  NOTREACHED();
+  return scoped_ptr<webkit_blob::FileStreamReader>();
 }
 
 FileSystemProxy::~FileSystemProxy() {
-  // Should be deleted from the CrosMountPointProvider on UI thread.
+  // Should be deleted from the FileSystemBackend on UI thread.
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
 
@@ -414,6 +393,18 @@
     method_call.Run();
 }
 
+void FileSystemProxy::CallFileApiInternalFunctionOnUIThread(
+    const base::Callback<void(FileSystemInterface*)>& function) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  BrowserThread::PostTask(
+      BrowserThread::UI,
+      FROM_HERE,
+      base::Bind(
+          &fileapi_internal::RunFileSystemCallback,
+          base::Bind(&FileSystemProxy::GetFileSystemOnUIThread, this),
+          function, base::Closure()));
+}
+
 void FileSystemProxy::OnCreateWritableSnapshotFile(
     const base::FilePath& virtual_path,
     const fileapi::WritableSnapshotFile& callback,
@@ -427,7 +418,7 @@
     file_ref = ShareableFileReference::GetOrCreate(
         local_path,
         ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
-        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
+        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get());
     file_ref->AddFinalReleaseCallback(
         base::Bind(&FileSystemProxy::CloseWritableSnapshotFile,
                    this,
@@ -442,9 +433,8 @@
     const base::FilePath& local_path) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
-  CallFileSystemMethodOnUIThread(
-      base::Bind(&internal::FileApiWorker::CloseFile,
-                 base::Unretained(worker_.get()), virtual_path));
+  CallFileApiInternalFunctionOnUIThread(
+      base::Bind(&fileapi_internal::CloseFile, virtual_path));
 }
 
 FileSystemInterface* FileSystemProxy::GetFileSystemOnUIThread() {
diff --git a/chrome/browser/chromeos/drive/file_system_proxy.h b/chrome/browser/chromeos/drive/file_system_proxy.h
index f4dcaca..349c5c0 100644
--- a/chrome/browser/chromeos/drive/file_system_proxy.h
+++ b/chrome/browser/chromeos/drive/file_system_proxy.h
@@ -117,6 +117,11 @@
   void CallFileSystemMethodOnUIThreadInternal(
       const base::Closure& method_call);
 
+  // Helper method to call drive::filapi_internal functions. This method
+  // aborts calls in case DetachFromFileSystem() has been called.
+  void CallFileApiInternalFunctionOnUIThread(
+      const base::Callback<void(FileSystemInterface*)>& function);
+
   // Helper callback for relaying reply for CreateWritableSnapshotFile() to
   // the calling thread.
   void OnCreateWritableSnapshotFile(
@@ -135,10 +140,7 @@
   // Returns |file_system_| on UI thread.
   FileSystemInterface* GetFileSystemOnUIThread();
 
-  // TODO(hidehiko): Remove |file_system_| when all the core implementation
-  // is moved to FileApiWorker.
   FileSystemInterface* file_system_;
-  scoped_ptr<internal::FileApiWorker> worker_;
 };
 
 }  // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system_unittest.cc b/chrome/browser/chromeos/drive/file_system_unittest.cc
index 430539b..9a043c7 100644
--- a/chrome/browser/chromeos/drive/file_system_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop_proxy.h"
+#include "base/prefs/testing_pref_service.h"
 #include "base/run_loop.h"
 #include "chrome/browser/chromeos/drive/change_list_loader.h"
 #include "chrome/browser/chromeos/drive/drive.pb.h"
@@ -79,6 +80,8 @@
  protected:
   virtual void SetUp() OVERRIDE {
     profile_.reset(new TestingProfile);
+    pref_service_.reset(new TestingPrefServiceSimple);
+    test_util::RegisterDrivePrefs(pref_service_->registry());
 
     fake_network_change_notifier_.reset(
         new test_util::FakeNetworkChangeNotifier);
@@ -91,9 +94,9 @@
 
     fake_free_disk_space_getter_.reset(new FakeFreeDiskSpaceGetter);
 
-    scheduler_.reset(new JobScheduler(profile_.get(),
+    scheduler_.reset(new JobScheduler(pref_service_.get(),
                                       fake_drive_service_.get(),
-                                      base::MessageLoopProxy::current()));
+                                      base::MessageLoopProxy::current().get()));
 
     ASSERT_TRUE(file_util::CreateDirectory(util::GetCacheRootPath(
         profile_.get()).Append(util::kMetadataDirectory)));
@@ -110,14 +113,14 @@
   void SetUpResourceMetadataAndFileSystem() {
     metadata_storage_.reset(new internal::ResourceMetadataStorage(
         util::GetCacheRootPath(profile_.get()).Append(util::kMetadataDirectory),
-        base::MessageLoopProxy::current()));
+        base::MessageLoopProxy::current().get()));
     ASSERT_TRUE(metadata_storage_->Initialize());
 
     cache_.reset(new internal::FileCache(
         metadata_storage_.get(),
         util::GetCacheRootPath(profile_.get()).Append(
             util::kCacheFileDirectory),
-        base::MessageLoopProxy::current(),
+        base::MessageLoopProxy::current().get(),
         fake_free_disk_space_getter_.get()));
     ASSERT_TRUE(cache_->Initialize());
 
@@ -125,12 +128,12 @@
         metadata_storage_.get(), base::MessageLoopProxy::current()));
 
     file_system_.reset(new FileSystem(
-        profile_.get(),
+        pref_service_.get(),
         cache_.get(),
         fake_drive_service_.get(),
         scheduler_.get(),
         resource_metadata_.get(),
-        base::MessageLoopProxy::current(),
+        base::MessageLoopProxy::current().get(),
         util::GetCacheRootPath(profile_.get()).Append(
             util::kTemporaryFileDirectory)));
     file_system_->AddObserver(mock_directory_observer_.get());
@@ -149,7 +152,7 @@
     file_system_->change_list_loader()->LoadIfNeeded(
         DirectoryFetchInfo(),
         google_apis::test_util::CreateCopyResultCallback(&error));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     return error == FILE_ERROR_OK;
   }
 
@@ -161,7 +164,7 @@
     file_system_->GetResourceEntryByPath(
         file_path,
         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
 
     return entry.Pass();
   }
@@ -175,7 +178,7 @@
         file_path,
         google_apis::test_util::CreateCopyResultCallback(
             &error, &entries));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
 
     return entries.Pass();
   }
@@ -214,8 +217,8 @@
         util::GetCacheRootPath(profile_.get()).Append(util::kMetadataDirectory);
     scoped_ptr<internal::ResourceMetadataStorage,
                test_util::DestroyHelperForTests> metadata_storage(
-                   new internal::ResourceMetadataStorage(
-                       metadata_directory, base::MessageLoopProxy::current()));
+        new internal::ResourceMetadataStorage(
+            metadata_directory, base::MessageLoopProxy::current().get()));
 
     scoped_ptr<internal::ResourceMetadata, test_util::DestroyHelperForTests>
         resource_metadata(new internal::ResourceMetadata(
@@ -294,6 +297,9 @@
 
   content::TestBrowserThreadBundle thread_bundle_;
   scoped_ptr<TestingProfile> profile_;
+  // We don't use TestingProfile::GetPrefs() in favor of having less
+  // dependencies to Profile in general.
+  scoped_ptr<TestingPrefServiceSimple> pref_service_;
   scoped_ptr<test_util::FakeNetworkChangeNotifier>
       fake_network_change_notifier_;
 
@@ -536,7 +542,7 @@
   // it should change its state to "loaded", which admits periodic refresh.
   // To test it, call CheckForUpdates and verify it does try to check updates.
   file_system_->CheckForUpdates();
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(2, fake_drive_service_->about_resource_load_count());
 }
 
@@ -581,7 +587,7 @@
 
   file_system_->CheckForUpdates();
 
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(1, fake_drive_service_->about_resource_load_count());
   EXPECT_EQ(1, fake_drive_service_->change_list_load_count());
 
@@ -637,7 +643,7 @@
       true,  // is_exclusive
       false,  // is_recursive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // It should fail because is_exclusive is set to true.
   EXPECT_EQ(FILE_ERROR_EXISTS, error);
@@ -656,7 +662,7 @@
   FileError error = FILE_ERROR_FAILED;
   file_system_->Pin(file_path,
                     google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   FileCacheEntry cache_entry;
@@ -669,7 +675,7 @@
   error = FILE_ERROR_FAILED;
   file_system_->Unpin(file_path,
                       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   EXPECT_TRUE(cache_->GetCacheEntry(
@@ -702,7 +708,7 @@
       file_path,
       google_apis::test_util::CreateCopyResultCallback(&error_unpin));
 
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error_pin);
   EXPECT_EQ(FILE_ERROR_OK, error_unpin);
 
@@ -719,27 +725,11 @@
   file_system_->GetAvailableSpace(
       google_apis::test_util::CreateCopyResultCallback(
           &error, &bytes_total, &bytes_used));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(GG_LONGLONG(6789012345), bytes_used);
   EXPECT_EQ(GG_LONGLONG(9876543210), bytes_total);
 }
 
-TEST_F(FileSystemTest, RefreshDirectory) {
-  ASSERT_TRUE(LoadFullResourceList());
-
-  FileError error = FILE_ERROR_FAILED;
-  file_system_->RefreshDirectory(
-      util::GetDriveMyDriveRootPath(),
-      google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
-  EXPECT_EQ(FILE_ERROR_OK, error);
-
-  // We'll notify the directory change to the observer.
-  ASSERT_EQ(1u, mock_directory_observer_->changed_directories().size());
-  EXPECT_EQ(util::GetDriveMyDriveRootPath(),
-            mock_directory_observer_->changed_directories()[0]);
-}
-
 TEST_F(FileSystemTest, OpenAndCloseFile) {
   ASSERT_TRUE(LoadFullResourceList());
 
@@ -753,8 +743,9 @@
   base::FilePath file_path;
   file_system_->OpenFile(
       kFileInRoot,
+      OPEN_FILE,
       google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   const base::FilePath opened_file_path = file_path;
 
   // Verify that the file was properly opened.
@@ -767,15 +758,6 @@
   EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("drive/root")),
             mock_directory_observer_->changed_directories()[0]);
 
-  // Try to open the already opened file.
-  file_system_->OpenFile(
-      kFileInRoot,
-      google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
-  google_apis::test_util::RunBlockingPoolTask();
-
-  // It must fail.
-  EXPECT_EQ(FILE_ERROR_IN_USE, error);
-
   // Verify that the file contents match the expected contents.
   const std::string kExpectedContent = "This is some test content.";
   std::string cache_file_data;
@@ -801,7 +783,7 @@
   file_system_->CloseFile(
       kFileInRoot,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // Verify that the file was properly closed.
   EXPECT_EQ(FILE_ERROR_OK, error);
@@ -813,7 +795,7 @@
       file_resource_id,
       google_apis::test_util::CreateCopyResultCallback(
           &gdata_error, &gdata_entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(gdata_error, google_apis::HTTP_SUCCESS);
   ASSERT_TRUE(gdata_entry);
   EXPECT_EQ(static_cast<int>(kNewContent.size()), gdata_entry->file_size());
@@ -828,7 +810,7 @@
   file_system_->CloseFile(
       kFileInRoot,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   // It must fail.
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
@@ -856,7 +838,7 @@
   file_system_->MarkCacheFileAsMounted(
       file_in_root,
       google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Cannot remove a cache entry while it's being mounted.
@@ -867,7 +849,7 @@
   file_system_->MarkCacheFileAsUnmounted(
       file_path,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Now able to remove the cache entry.
diff --git a/chrome/browser/chromeos/drive/file_system_util.cc b/chrome/browser/chromeos/drive/file_system_util.cc
index 704450c..ab1862d 100644
--- a/chrome/browser/chromeos/drive/file_system_util.cc
+++ b/chrome/browser/chromeos/drive/file_system_util.cc
@@ -15,11 +15,13 @@
 #include "base/i18n/icu_string_conversions.h"
 #include "base/json/json_file_value_serializer.h"
 #include "base/logging.h"
+#include "base/md5.h"
 #include "base/message_loop/message_loop_proxy.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/sequenced_worker_pool.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/drive/drive.pb.h"
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
 #include "chrome/browser/chromeos/drive/file_system_interface.h"
@@ -27,6 +29,7 @@
 #include "chrome/browser/chromeos/drive/job_list.h"
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths_internal.h"
 #include "chrome/common/url_constants.h"
@@ -56,6 +59,12 @@
 const char kSlash[] = "/";
 const char kEscapedSlash[] = "\xE2\x88\x95";
 
+struct PlatformFileCloser {
+  void operator()(base::PlatformFile* file) const {
+    base::ClosePlatformFile(*file);
+  }
+};
+
 const base::FilePath& GetDriveMyDriveMountPointPath() {
   CR_DEFINE_STATIC_LOCAL(base::FilePath, drive_mydrive_mount_path,
       (kDriveMyDriveMountPointPath));
@@ -113,7 +122,7 @@
   for (base::FilePath file_from = enumerator.Next(); !file_from.empty();
        file_from = enumerator.Next()) {
     const base::FilePath file_to = directory_to.Append(file_from.BaseName());
-    if (!file_util::PathExists(file_to))  // Do not overwrite existing files.
+    if (!base::PathExists(file_to))  // Do not overwrite existing files.
       base::Move(file_from, file_to);
   }
 }
@@ -138,6 +147,17 @@
   return drive_mount_path;
 }
 
+FileSystemInterface* GetFileSystemByProfileId(void* profile_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  // |profile_id| needs to be checked with ProfileManager::IsValidProfile
+  // before using it.
+  Profile* profile = reinterpret_cast<Profile*>(profile_id);
+  if (!g_browser_process->profile_manager()->IsValidProfile(profile))
+    return NULL;
+  return GetFileSystem(profile);
+}
+
 bool IsSpecialResourceId(const std::string& resource_id) {
   return resource_id == kDriveGrandRootSpecialResourceId ||
       resource_id == kDriveOtherDirSpecialResourceId;
@@ -289,33 +309,13 @@
   return output;
 }
 
-void ParseCacheFilePath(const base::FilePath& path,
-                        std::string* resource_id,
-                        std::string* md5) {
-  DCHECK(resource_id);
-  DCHECK(md5);
-
-  // Extract up to one extension from the right.
-  base::FilePath base_name = path.BaseName();
-  base::FilePath::StringType extension = base_name.Extension();
-  if (!extension.empty()) {
-    // base::FilePath::Extension returns ".", so strip it.
-    extension = UnescapeCacheFileName(extension.substr(1));
-    base_name = base_name.RemoveExtension();
-  }
-
-  // The base_name here is already stripped of extensions in the loop above.
-  *resource_id = UnescapeCacheFileName(base_name.value());
-  *md5 = extension;
-}
-
 void MigrateCacheFilesFromOldDirectories(
     const base::FilePath& cache_root_directory) {
   const base::FilePath persistent_directory =
       cache_root_directory.AppendASCII("persistent");
   const base::FilePath tmp_directory =
       cache_root_directory.AppendASCII("tmp");
-  if (!file_util::PathExists(persistent_directory))
+  if (!base::PathExists(persistent_directory))
     return;
 
   const base::FilePath cache_file_directory =
@@ -323,7 +323,7 @@
 
   // Move all files inside "persistent" to "files".
   MoveAllFilesFromDirectory(persistent_directory, cache_file_directory);
-  base::Delete(persistent_directory,  true /* recursive */);
+  base::DeleteFile(persistent_directory,  true /* recursive */);
 
   // Move all files inside "tmp" to "files".
   MoveAllFilesFromDirectory(tmp_directory, cache_file_directory);
@@ -439,5 +439,41 @@
   return ReadStringFromGDocFile(file_path, "resource_id");
 }
 
+std::string GetMd5Digest(const base::FilePath& file_path) {
+  const int kBufferSize = 512 * 1024;  // 512kB.
+
+  base::PlatformFile file = base::CreatePlatformFile(
+      file_path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
+      NULL, NULL);
+  if (file == base::kInvalidPlatformFileValue)
+    return std::string();
+  scoped_ptr<base::PlatformFile, PlatformFileCloser> file_closer(&file);
+
+  base::MD5Context context;
+  base::MD5Init(&context);
+
+  scoped_ptr<char[]> buffer(new char[kBufferSize]);
+  while (true) {
+    int result = base::ReadPlatformFileCurPosNoBestEffort(
+        file, buffer.get(), kBufferSize);
+
+    if (result < 0) {
+      // Found an error.
+      return std::string();
+    }
+
+    if (result == 0) {
+      // End of file.
+      break;
+    }
+
+    base::MD5Update(&context, base::StringPiece(buffer.get(), result));
+  }
+
+  base::MD5Digest digest;
+  base::MD5Final(&digest, &context);
+  return MD5DigestToBase16(digest);
+}
+
 }  // namespace util
 }  // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system_util.h b/chrome/browser/chromeos/drive/file_system_util.h
index e57c695..066442a 100644
--- a/chrome/browser/chromeos/drive/file_system_util.h
+++ b/chrome/browser/chromeos/drive/file_system_util.h
@@ -10,7 +10,7 @@
 #include "base/callback_forward.h"
 #include "chrome/browser/chromeos/drive/file_errors.h"
 #include "chrome/browser/google_apis/gdata_errorcode.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Profile;
 
@@ -25,6 +25,7 @@
 
 namespace drive {
 
+class FileSystemInterface;
 class PlatformFileInfoProto;
 class ResourceEntry;
 
@@ -43,12 +44,6 @@
 const base::FilePath::CharType kTemporaryFileDirectory[] =
     FILE_PATH_LITERAL("tmp");
 
-// The extension for dirty files. The file names look like
-// "<resource-id>.local".
-const base::FilePath::CharType kLocallyModifiedFileExtension[] =
-    FILE_PATH_LITERAL("local");
-const base::FilePath::CharType kWildCard[] = FILE_PATH_LITERAL("*");
-
 // Special resource IDs introduced to manage pseudo directory tree locally.
 // These strings are supposed to be different from any resource ID used on the
 // server, and are never sent to the server. Practical resource IDs used so far
@@ -79,6 +74,16 @@
 // Returns the Drive mount point path, which looks like "/special/drive".
 const base::FilePath& GetDriveMountPointPath();
 
+// Returns a FileSystemInterface instance for the |profile_id|, or NULL
+// if the Profile for |profile_id| is destructed or Drive File System is
+// disabled for the profile.
+// Note: |profile_id| should be the pointer of the Profile instance if it is
+// alive. Considering timing issues due to task posting across threads,
+// this function can accept a dangling pointer as |profile_id| (and will return
+// NULL for such a case).
+// This function must be called on UI thread.
+FileSystemInterface* GetFileSystemByProfileId(void* profile_id);
+
 // Checks if the resource ID is a special one, which is effective only in our
 // implementation and is not supposed to be sent to the server.
 bool IsSpecialResourceId(const std::string& resource_id);
@@ -141,13 +146,6 @@
 // profile.
 base::FilePath GetCacheRootPath(Profile* profile);
 
-// Extracts resource_id and md5 from cache path.
-// Example: path="/user/GCache/v1/tmp/pdf:a1b2.01234567" =>
-//          resource_id="pdf:a1b2", md5="01234567"
-void ParseCacheFilePath(const base::FilePath& path,
-                        std::string* resource_id,
-                        std::string* md5);
-
 // Migrates cache files from old "persistent" and "tmp" directories to the new
 // "files" directory (see crbug.com/248905).
 // TODO(hashimoto): Remove this function at some point.
@@ -227,6 +225,10 @@
 // Reads resource ID from a GDoc file.
 std::string ReadResourceIdFromGDocFile(const base::FilePath& file_path);
 
+// Returns the (base-16 encoded) MD5 digest of the file content at |file_path|,
+// or an empty string if an error is found.
+std::string GetMd5Digest(const base::FilePath& file_path);
+
 }  // namespace util
 }  // namespace drive
 
diff --git a/chrome/browser/chromeos/drive/file_system_util_unittest.cc b/chrome/browser/chromeos/drive/file_system_util_unittest.cc
index 3ff445d..9355866 100644
--- a/chrome/browser/chromeos/drive/file_system_util_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system_util_unittest.cc
@@ -7,14 +7,15 @@
 #include "base/file_util.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/md5.h"
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/google_apis/test_util.h"
 #include "chrome/test/base/testing_profile.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "webkit/browser/fileapi/external_mount_points.h"
+#include "webkit/browser/fileapi/file_system_backend.h"
 #include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/browser/fileapi/file_system_mount_point_provider.h"
 #include "webkit/browser/fileapi/file_system_task_runners.h"
 #include "webkit/browser/fileapi/file_system_url.h"
 #include "webkit/browser/fileapi/isolated_context.h"
@@ -102,7 +103,7 @@
           mount_points.get(),
           NULL,  // special_storage_policy
           NULL,  // quota_manager_proxy,
-          ScopedVector<fileapi::FileSystemMountPointProvider>(),
+          ScopedVector<fileapi::FileSystemBackend>(),
           temp_dir_.path(),  // partition_path
           fileapi::CreateAllowFileAccessOptions()));
 
@@ -181,25 +182,6 @@
             util::GetCacheRootPath(&profile));
 }
 
-TEST(FileSystemUtilTest, ParseCacheFilePath) {
-  std::string resource_id, md5;
-
-  ParseCacheFilePath(
-      base::FilePath::FromUTF8Unsafe(
-          "/home/user/GCache/v1/files/pdf:a1b2.0123456789abcdef"),
-      &resource_id,
-      &md5);
-  EXPECT_EQ(resource_id, "pdf:a1b2");
-  EXPECT_EQ(md5, "0123456789abcdef");
-
-  ParseCacheFilePath(
-      base::FilePath::FromUTF8Unsafe("/home/user/GCache/v1/files/pdf:a1b2"),
-      &resource_id,
-      &md5);
-  EXPECT_EQ(resource_id, "pdf:a1b2");
-  EXPECT_EQ(md5, "");
-}
-
 TEST(FileSystemUtilTest, MigrateCacheFilesFromOldDirectories) {
   base::ScopedTempDir temp_dir;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
@@ -224,9 +206,9 @@
   // Migrate.
   MigrateCacheFilesFromOldDirectories(temp_dir.path());
 
-  EXPECT_FALSE(file_util::PathExists(persistent_directory));
-  EXPECT_TRUE(file_util::PathExists(files_directory.AppendASCII("foo.abc")));
-  EXPECT_TRUE(file_util::PathExists(files_directory.AppendASCII("bar.123")));
+  EXPECT_FALSE(base::PathExists(persistent_directory));
+  EXPECT_TRUE(base::PathExists(files_directory.AppendASCII("foo.abc")));
+  EXPECT_TRUE(base::PathExists(files_directory.AppendASCII("bar.123")));
 }
 
 TEST(FileSystemUtilTest, NeedsNamespaceMigration) {
@@ -337,12 +319,22 @@
   // Non GDoc file.
   file = temp_dir.path().AppendASCII("test.txt");
   std::string data = "Hello world!";
-  EXPECT_EQ(static_cast<int>(data.size()),
-            file_util::WriteFile(file, data.data(), data.size()));
+  EXPECT_TRUE(google_apis::test_util::WriteStringToFile(file, data));
   EXPECT_FALSE(HasGDocFileExtension(file));
   EXPECT_TRUE(ReadUrlFromGDocFile(file).is_empty());
   EXPECT_TRUE(ReadResourceIdFromGDocFile(file).empty());
 }
 
+TEST(FileSystemUtilTest, GetMd5Digest) {
+  base::ScopedTempDir temp_dir;
+  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+
+  base::FilePath path = temp_dir.path().AppendASCII("test.txt");
+  const char kTestData[] = "abcdefghijklmnopqrstuvwxyz0123456789";
+  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(path, kTestData));
+
+  EXPECT_EQ(base::MD5String(kTestData), GetMd5Digest(path));
+}
+
 }  // namespace util
 }  // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_write_helper.cc b/chrome/browser/chromeos/drive/file_write_helper.cc
index 6506458..c48262c 100644
--- a/chrome/browser/chromeos/drive/file_write_helper.cc
+++ b/chrome/browser/chromeos/drive/file_write_helper.cc
@@ -42,34 +42,10 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
-  file_system_->CreateFile(
-      file_path,
-      false,  // it is not an error, even if the path already exists.
-      base::Bind(&FileWriteHelper::PrepareWritableFileAndRunAfterCreateFile,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 file_path,
-                 callback));
-}
-
-void FileWriteHelper::PrepareWritableFileAndRunAfterCreateFile(
-    const base::FilePath& file_path,
-    const OpenFileCallback& callback,
-    FileError error) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  if (error != FILE_ERROR_OK) {
-    content::BrowserThread::GetBlockingPool()->PostTask(
-        FROM_HERE,
-        base::Bind(callback, error, base::FilePath()));
-    return;
-  }
   file_system_->OpenFile(
-      file_path,
+      file_path, OPEN_OR_CREATE_FILE,
       base::Bind(&FileWriteHelper::PrepareWritableFileAndRunAfterOpenFile,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 file_path,
-                 callback));
+                 weak_ptr_factory_.GetWeakPtr(), file_path, callback));
 }
 
 void FileWriteHelper::PrepareWritableFileAndRunAfterOpenFile(
diff --git a/chrome/browser/chromeos/drive/file_write_helper.h b/chrome/browser/chromeos/drive/file_write_helper.h
index 88b824f..6b60a69 100644
--- a/chrome/browser/chromeos/drive/file_write_helper.h
+++ b/chrome/browser/chromeos/drive/file_write_helper.h
@@ -35,10 +35,6 @@
   // Part of PrepareWritableFilePathAndRun(). It tries CreateFile for the case
   // file does not exist yet, does OpenFile to download and mark the file as
   // dirty, runs |callback|, and finally calls CloseFile.
-  void PrepareWritableFileAndRunAfterCreateFile(
-      const base::FilePath& file_path,
-      const OpenFileCallback& callback,
-      FileError result);
   void PrepareWritableFileAndRunAfterOpenFile(
       const base::FilePath& file_path,
       const OpenFileCallback& callback,
diff --git a/chrome/browser/chromeos/drive/file_write_helper_unittest.cc b/chrome/browser/chromeos/drive/file_write_helper_unittest.cc
index 936748d..af7bf9d 100644
--- a/chrome/browser/chromeos/drive/file_write_helper_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_write_helper_unittest.cc
@@ -23,45 +23,25 @@
 
 class TestFileSystem : public DummyFileSystem {
  public:
-  // Mimics CreateFile. It always succeeds unless kInvalidPath is passed.
-  virtual void CreateFile(const base::FilePath& file_path,
-                          bool is_exclusive,
-                          const FileOperationCallback& callback) OVERRIDE {
-   if (file_path == base::FilePath(kInvalidPath)) {
-     callback.Run(FILE_ERROR_ACCESS_DENIED);
-     return;
-   }
-   created.insert(file_path);
-   callback.Run(FILE_ERROR_OK);
-  }
-
-  // Mimics OpenFile. It fails if the |file_path| is a path that is not
-  // passed to CreateFile before. This tests that FileWriteHelper always
-  // ensures file existence before trying to open. It also fails if the
-  // path is already opened, to match the behavior of real FileSystem.
+  // Mimics OpenFile. It fails if the |file_path| points to a hosted document.
   virtual void OpenFile(const base::FilePath& file_path,
+                        OpenMode open_mode,
                         const OpenFileCallback& callback) OVERRIDE {
-    // Files failed to create should never be opened.
-    EXPECT_TRUE(created.count(file_path));
-    created.erase(file_path);
-    if (opened.count(file_path)) {
-      callback.Run(FILE_ERROR_IN_USE, base::FilePath());
-    } else {
-      opened.insert(file_path);
-      callback.Run(FILE_ERROR_OK, base::FilePath(kLocalPath));
+    EXPECT_EQ(OPEN_OR_CREATE_FILE, open_mode);
+
+    // Emulate a case of opening a hosted document.
+    if (file_path == base::FilePath(kInvalidPath)) {
+      callback.Run(FILE_ERROR_INVALID_OPERATION, base::FilePath());
+      return;
     }
+
+    callback.Run(FILE_ERROR_OK, base::FilePath(kLocalPath));
   }
 
-  // Mimics CloseFile. It fails if it is passed a path not OpenFile'd.
   virtual void CloseFile(const base::FilePath& file_path,
                          const FileOperationCallback& callback) OVERRIDE {
-    // Files failed to open should never be closed.
-    EXPECT_TRUE(opened.count(file_path));
-    opened.erase(file_path);
     callback.Run(FILE_ERROR_OK);
   }
-  std::set<base::FilePath> created;
-  std::set<base::FilePath> opened;
 };
 
 }  // namespace
@@ -85,7 +65,7 @@
   file_write_helper.PrepareWritableFileAndRun(
       base::FilePath(kDrivePath),
       google_apis::test_util::CreateCopyResultCallback(&error, &path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(kLocalPath, path.value());
@@ -100,36 +80,9 @@
   file_write_helper.PrepareWritableFileAndRun(
       base::FilePath(kInvalidPath),
       google_apis::test_util::CreateCopyResultCallback(&error, &path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
 
-  EXPECT_EQ(FILE_ERROR_ACCESS_DENIED, error);
-  EXPECT_TRUE(path.empty());
-}
-
-TEST_F(FileWriteHelperTest, PrepareFileForWritingOpenFail) {
-  // Externally open the path beforehand.
-  FileError error = FILE_ERROR_FAILED;
-  base::FilePath path;
-  test_file_system_->CreateFile(
-      base::FilePath(kDrivePath),
-      false,
-      google_apis::test_util::CreateCopyResultCallback(&error));
-  ASSERT_EQ(FILE_ERROR_OK, error);
-  error = FILE_ERROR_FAILED;
-  test_file_system_->OpenFile(
-      base::FilePath(kDrivePath),
-      google_apis::test_util::CreateCopyResultCallback(&error, &path));
-  ASSERT_EQ(FILE_ERROR_OK, error);
-
-  // Run FileWriteHelper on a file already opened in somewhere else.
-  // It should fail to open the file, and should not try to close it.
-  FileWriteHelper file_write_helper(test_file_system_.get());
-  file_write_helper.PrepareWritableFileAndRun(
-      base::FilePath(kDrivePath),
-      google_apis::test_util::CreateCopyResultCallback(&error, &path));
-  google_apis::test_util::RunBlockingPoolTask();
-
-  EXPECT_EQ(FILE_ERROR_IN_USE, error);
+  EXPECT_EQ(FILE_ERROR_INVALID_OPERATION, error);
   EXPECT_TRUE(path.empty());
 }
 
diff --git a/chrome/browser/chromeos/drive/fileapi_worker.cc b/chrome/browser/chromeos/drive/fileapi_worker.cc
index e69a386..825a19b 100644
--- a/chrome/browser/chromeos/drive/fileapi_worker.cc
+++ b/chrome/browser/chromeos/drive/fileapi_worker.cc
@@ -18,18 +18,39 @@
 using content::BrowserThread;
 
 namespace drive {
-namespace internal {
+namespace fileapi_internal {
 namespace {
 
+// The summary of opening mode is:
+// - PLATFORM_FILE_OPEN: Open the existing file. Fail if not exists.
+// - PLATFORM_FILE_CREATE: Create the file if not exists. Fail if exists.
+// - PLATFORM_FILE_OPEN_ALWAYS: Open the existing file. Create a new file
+//     if not exists.
+// - PLATFORM_FILE_CREATE_ALWAYS: Create a new file if not exists. If exists
+//     open it with truncate.
+// - PLATFORM_FILE_OPEN_TRUNCATE: Open the existing file with truncate.
+//     Fail if not exists.
+OpenMode GetOpenMode(int file_flag) {
+  if (file_flag & (base::PLATFORM_FILE_OPEN |
+                   base::PLATFORM_FILE_OPEN_TRUNCATED))
+    return OPEN_FILE;
+
+  if (file_flag & base::PLATFORM_FILE_CREATE)
+    return CREATE_FILE;
+
+  DCHECK(file_flag & (base::PLATFORM_FILE_OPEN_ALWAYS |
+                      base::PLATFORM_FILE_CREATE_ALWAYS));
+  return OPEN_OR_CREATE_FILE;
+}
+
 // Runs |callback| with the PlatformFileError converted from |error|.
-void RunStatusCallbackByFileError(
-    const FileApiWorker::StatusCallback& callback,
-    FileError error) {
+void RunStatusCallbackByFileError(const StatusCallback& callback,
+                                  FileError error) {
   callback.Run(FileErrorToPlatformError(error));
 }
 
 // Runs |callback| with arguments converted from |error| and |entry|.
-void RunGetFileInfoCallback(const FileApiWorker::GetFileInfoCallback& callback,
+void RunGetFileInfoCallback(const GetFileInfoCallback& callback,
                             FileError error,
                             scoped_ptr<ResourceEntry> entry) {
   if (error != FILE_ERROR_OK) {
@@ -45,7 +66,7 @@
 
 // Runs |callback| with arguments converted from |error| and |resource_entries|.
 void RunReadDirectoryCallback(
-    const FileApiWorker::ReadDirectoryCallback& callback,
+    const ReadDirectoryCallback& callback,
     FileError error,
     scoped_ptr<ResourceEntryVector> resource_entries) {
   if (error != FILE_ERROR_OK) {
@@ -76,11 +97,10 @@
 }
 
 // Runs |callback| with arguments based on |error|, |local_path| and |entry|.
-void RunCreateSnapshotFileCallback(
-    const FileApiWorker::CreateSnapshotFileCallback& callback,
-    FileError error,
-    const base::FilePath& local_path,
-    scoped_ptr<ResourceEntry> entry) {
+void RunCreateSnapshotFileCallback(const CreateSnapshotFileCallback& callback,
+                                   FileError error,
+                                   const base::FilePath& local_path,
+                                   scoped_ptr<ResourceEntry> entry) {
   if (error != FILE_ERROR_OK) {
     callback.Run(
         FileErrorToPlatformError(error),
@@ -113,19 +133,17 @@
 }
 
 // Runs |callback| with |error| and |platform_file|.
-void RunOpenFileCallback(
-    const FileApiWorker::OpenFileCallback& callback,
-    base::PlatformFileError* error,
-    base::PlatformFile platform_file) {
+void RunOpenFileCallback(const OpenFileCallback& callback,
+                         base::PlatformFileError* error,
+                         base::PlatformFile platform_file) {
   callback.Run(*error, platform_file);
 }
 
-// Part of FileApiWorker::OpenFile(). Called after FileSystem::OpenFile().
-void OpenFileAfterFileSystemOpenFile(
-    int file_flags,
-    const FileApiWorker::OpenFileCallback& callback,
-    FileError error,
-    const base::FilePath& local_path) {
+// Part of OpenFile(). Called after FileSystem::OpenFile().
+void OpenFileAfterFileSystemOpenFile(int file_flags,
+                                     const OpenFileCallback& callback,
+                                     FileError error,
+                                     const base::FilePath& local_path) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   if (error != FILE_ERROR_OK) {
@@ -134,6 +152,21 @@
     return;
   }
 
+  // Here, the file should be at |local_path|, but there may be timing issue.
+  // Because the file is managed by Drive file system, so, in order to avoid
+  // unexpected file creation, CREATE, OPEN_ALWAYS and CREATE_ALWAYS are
+  // translated into OPEN or OPEN_TRUNCATED, here. Keep OPEN and OPEN_TRUNCATED
+  // as is.
+  if (file_flags & (base::PLATFORM_FILE_CREATE |
+                    base::PLATFORM_FILE_OPEN_ALWAYS)) {
+    file_flags &= ~(base::PLATFORM_FILE_CREATE |
+                    base::PLATFORM_FILE_OPEN_ALWAYS);
+    file_flags |= base::PLATFORM_FILE_OPEN;
+  } else if (file_flags & base::PLATFORM_FILE_CREATE_ALWAYS) {
+    file_flags &= ~base::PLATFORM_FILE_CREATE_ALWAYS;
+    file_flags |= base::PLATFORM_FILE_OPEN_TRUNCATED;
+  }
+
   // Cache file prepared for modification is available. Open it locally.
   base::PlatformFileError* result =
       new base::PlatformFileError(base::PLATFORM_FILE_ERROR_FAILED);
@@ -145,18 +178,6 @@
   DCHECK(posted);
 }
 
-// Part of FileApiWorker::OpenFile(). Called after FileSystem::GetFileByPath().
-void OpenFileAfterGetFileByPath(int file_flags,
-                                const FileApiWorker::OpenFileCallback& callback,
-                                FileError error,
-                                const base::FilePath& local_path,
-                                scoped_ptr<ResourceEntry> entry) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  // Just redirect to OpenFileAfterFileSystemOpenFile() with ignoring |entry|.
-  OpenFileAfterFileSystemOpenFile(file_flags, callback, error, local_path);
-}
-
 // Emits debug log when FileSystem::CloseFile() is complete.
 void EmitDebugLogForCloseFile(const base::FilePath& local_path,
                               FileError file_error) {
@@ -165,182 +186,162 @@
 
 }  // namespace
 
-FileApiWorker::FileApiWorker(FileSystemInterface* file_system)
-    : file_system_(file_system),
-      weak_ptr_factory_(this) {
+void RunFileSystemCallback(
+    const FileSystemGetter& file_system_getter,
+    const base::Callback<void(FileSystemInterface*)>& callback,
+    const base::Closure& on_error_callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(file_system);
+  FileSystemInterface* file_system = file_system_getter.Run();
+
+  if (!file_system) {
+    if (!on_error_callback.is_null())
+      on_error_callback.Run();
+    return;
+  }
+
+  callback.Run(file_system);
 }
 
-FileApiWorker::~FileApiWorker() {
-}
-
-void FileApiWorker::GetFileInfo(const base::FilePath& file_path,
-                                const GetFileInfoCallback& callback) {
+void GetFileInfo(const base::FilePath& file_path,
+                 const GetFileInfoCallback& callback,
+                 FileSystemInterface* file_system) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  file_system_->GetResourceEntryByPath(
+  file_system->GetResourceEntryByPath(
       file_path,
       base::Bind(&RunGetFileInfoCallback, callback));
 }
 
-void FileApiWorker::Copy(const base::FilePath& src_file_path,
-                         const base::FilePath& dest_file_path,
-                         const StatusCallback& callback) {
+void Copy(const base::FilePath& src_file_path,
+          const base::FilePath& dest_file_path,
+          const StatusCallback& callback,
+          FileSystemInterface* file_system) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  file_system_->Copy(src_file_path, dest_file_path,
-                     base::Bind(&RunStatusCallbackByFileError, callback));
+  file_system->Copy(src_file_path, dest_file_path,
+                    base::Bind(&RunStatusCallbackByFileError, callback));
 }
 
-void FileApiWorker::Move(const base::FilePath& src_file_path,
-                         const base::FilePath& dest_file_path,
-                         const StatusCallback& callback) {
+void Move(const base::FilePath& src_file_path,
+          const base::FilePath& dest_file_path,
+          const StatusCallback& callback,
+          FileSystemInterface* file_system) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  file_system_->Move(src_file_path, dest_file_path,
-                     base::Bind(&RunStatusCallbackByFileError, callback));
+  file_system->Move(src_file_path, dest_file_path,
+                    base::Bind(&RunStatusCallbackByFileError, callback));
 }
 
-void FileApiWorker::ReadDirectory(const base::FilePath& file_path,
-                                  const ReadDirectoryCallback& callback) {
+void CopyInForeignFile(const base::FilePath& src_foreign_file_path,
+                       const base::FilePath& dest_file_path,
+                       const StatusCallback& callback,
+                       FileSystemInterface* file_system) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  file_system_->ReadDirectoryByPath(
+  file_system->TransferFileFromLocalToRemote(
+      src_foreign_file_path, dest_file_path,
+      base::Bind(&RunStatusCallbackByFileError, callback));
+}
+
+void ReadDirectory(const base::FilePath& file_path,
+                   const ReadDirectoryCallback& callback,
+                   FileSystemInterface* file_system) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  file_system->ReadDirectoryByPath(
       file_path,
       base::Bind(&RunReadDirectoryCallback, callback));
 }
 
-void FileApiWorker::Remove(const base::FilePath& file_path,
-                           bool is_recursive,
-                           const StatusCallback& callback) {
+void Remove(const base::FilePath& file_path,
+            bool is_recursive,
+            const StatusCallback& callback,
+            FileSystemInterface* file_system) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  file_system_->Remove(file_path, is_recursive,
-                       base::Bind(&RunStatusCallbackByFileError, callback));
+  file_system->Remove(file_path, is_recursive,
+                      base::Bind(&RunStatusCallbackByFileError, callback));
 }
 
-void FileApiWorker::CreateDirectory(const base::FilePath& file_path,
-                                    bool is_exclusive,
-                                    bool is_recursive,
-                                    const StatusCallback& callback) {
+void CreateDirectory(const base::FilePath& file_path,
+                     bool is_exclusive,
+                     bool is_recursive,
+                     const StatusCallback& callback,
+                     FileSystemInterface* file_system) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  file_system_->CreateDirectory(
+  file_system->CreateDirectory(
       file_path, is_exclusive, is_recursive,
       base::Bind(&RunStatusCallbackByFileError, callback));
 }
 
-void FileApiWorker::CreateFile(const base::FilePath& file_path,
-                               bool is_exclusive,
-                               const StatusCallback& callback) {
+void CreateFile(const base::FilePath& file_path,
+                bool is_exclusive,
+                const StatusCallback& callback,
+                FileSystemInterface* file_system) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  file_system_->CreateFile(file_path, is_exclusive,
-                           base::Bind(&RunStatusCallbackByFileError, callback));
+  file_system->CreateFile(file_path, is_exclusive,
+                          base::Bind(&RunStatusCallbackByFileError, callback));
 }
 
-void FileApiWorker::Truncate(const base::FilePath& file_path,
-                             int64 length,
-                             const StatusCallback& callback) {
+void Truncate(const base::FilePath& file_path,
+              int64 length,
+              const StatusCallback& callback,
+              FileSystemInterface* file_system) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  file_system_->TruncateFile(
+  file_system->TruncateFile(
       file_path, length,
       base::Bind(&RunStatusCallbackByFileError, callback));
 }
 
-void FileApiWorker::CreateSnapshotFile(
-    const base::FilePath& file_path,
-    const CreateSnapshotFileCallback& callback) {
+void CreateSnapshotFile(const base::FilePath& file_path,
+                        const CreateSnapshotFileCallback& callback,
+                        FileSystemInterface* file_system) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  file_system_->GetFileByPath(
+  file_system->GetFileByPath(
       file_path,
       base::Bind(&RunCreateSnapshotFileCallback, callback));
 }
 
-void FileApiWorker::OpenFile(const base::FilePath& file_path,
-                             int file_flags,
-                             const OpenFileCallback& callback) {
+void OpenFile(const base::FilePath& file_path,
+              int file_flags,
+              const OpenFileCallback& callback,
+              FileSystemInterface* file_system) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  // TODO(zelidrag): Wire all other file open operations.
-  if (file_flags & base::PLATFORM_FILE_DELETE_ON_CLOSE) {
-    NOTIMPLEMENTED() << "File create/write operations not yet supported "
-                     << file_path.value();
-    callback.Run(base::PLATFORM_FILE_ERROR_FAILED,
-                 base::kInvalidPlatformFileValue);
+  // Returns an error if any unsupported flag is found.
+  if (file_flags & ~(base::PLATFORM_FILE_OPEN |
+                     base::PLATFORM_FILE_CREATE |
+                     base::PLATFORM_FILE_OPEN_ALWAYS |
+                     base::PLATFORM_FILE_CREATE_ALWAYS |
+                     base::PLATFORM_FILE_OPEN_TRUNCATED |
+                     base::PLATFORM_FILE_READ |
+                     base::PLATFORM_FILE_WRITE |
+                     base::PLATFORM_FILE_WRITE_ATTRIBUTES |
+                     base::PLATFORM_FILE_APPEND)) {
+    base::MessageLoopProxy::current()->PostTask(
+        FROM_HERE,
+        base::Bind(callback,
+                   base::PLATFORM_FILE_ERROR_FAILED,
+                   base::kInvalidPlatformFileValue));
     return;
   }
 
-  // TODO(hidehiko): The opening logic should be moved to FileSystem.
-  //   crbug.com/256583.
-  if (file_flags & (base::PLATFORM_FILE_OPEN |
-                    base::PLATFORM_FILE_OPEN_ALWAYS |
-                    base::PLATFORM_FILE_OPEN_TRUNCATED)) {
-    if (file_flags & (base::PLATFORM_FILE_OPEN_TRUNCATED |
-                      base::PLATFORM_FILE_OPEN_ALWAYS |
-                      base::PLATFORM_FILE_WRITE |
-                      base::PLATFORM_FILE_EXCLUSIVE_WRITE)) {
-      // Open existing file for writing.
-      file_system_->OpenFile(
-          file_path,
-          base::Bind(&OpenFileAfterFileSystemOpenFile, file_flags, callback));
-    } else {
-      // Read-only file open.
-      file_system_->GetFileByPath(
-          file_path,
-          base::Bind(&OpenFileAfterGetFileByPath, file_flags, callback));
-    }
-  } else if (file_flags & (base::PLATFORM_FILE_CREATE |
-                           base::PLATFORM_FILE_CREATE_ALWAYS)) {
-    // Create a new file.
-    file_system_->CreateFile(
-        file_path,
-        file_flags & base::PLATFORM_FILE_EXCLUSIVE_WRITE,
-        base::Bind(&FileApiWorker::OpenFileAfterCreateFile,
-                   weak_ptr_factory_.GetWeakPtr(),
-                   file_path, file_flags, callback));
-  } else {
-    NOTREACHED() << "Unhandled file flags combination " << file_flags;
-    callback.Run(base::PLATFORM_FILE_ERROR_FAILED,
-                 base::kInvalidPlatformFileValue);
-    return;
-  }
-}
-
-void FileApiWorker::CloseFile(const base::FilePath& file_path) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  file_system_->CloseFile(file_path,
-                          base::Bind(&EmitDebugLogForCloseFile, file_path));
-}
-
-void FileApiWorker::TouchFile(const base::FilePath& file_path,
-                              const base::Time& last_access_time,
-                              const base::Time& last_modified_time,
-                              const StatusCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  file_system_->TouchFile(file_path, last_access_time, last_modified_time,
-                          base::Bind(&RunStatusCallbackByFileError, callback));
-
-}
-
-void FileApiWorker::OpenFileAfterCreateFile(const base::FilePath& file_path,
-                                            int file_flags,
-                                            const OpenFileCallback& callback,
-                                            FileError error) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  if (error != FILE_ERROR_OK &&
-      (error != FILE_ERROR_EXISTS ||
-       (file_flags & base::PLATFORM_FILE_CREATE))) {
-    callback.Run(FileErrorToPlatformError(error),
-                 base::kInvalidPlatformFileValue);
-    return;
-  }
-
-  // If we are trying to always create an existing file, then
-  // if it really exists open it as truncated.
-  file_flags &=
-      ~(base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_CREATE_ALWAYS);
-  file_flags |= base::PLATFORM_FILE_OPEN_TRUNCATED;
-
-  // Open created (or existing) file for writing.
-  file_system_->OpenFile(
-      file_path,
+  file_system->OpenFile(
+      file_path, GetOpenMode(file_flags),
       base::Bind(&OpenFileAfterFileSystemOpenFile, file_flags, callback));
 }
 
-}  // namespace internal
+void CloseFile(const base::FilePath& file_path,
+               FileSystemInterface* file_system) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  file_system->CloseFile(file_path,
+                         base::Bind(&EmitDebugLogForCloseFile, file_path));
+}
+
+void TouchFile(const base::FilePath& file_path,
+               const base::Time& last_access_time,
+               const base::Time& last_modified_time,
+               const StatusCallback& callback,
+               FileSystemInterface* file_system) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  file_system->TouchFile(file_path, last_access_time, last_modified_time,
+                         base::Bind(&RunStatusCallbackByFileError, callback));
+
+}
+
+}  // namespace fileapi_internal
 }  // namespace drive
diff --git a/chrome/browser/chromeos/drive/fileapi_worker.h b/chrome/browser/chromeos/drive/fileapi_worker.h
index caac16c..c97a511 100644
--- a/chrome/browser/chromeos/drive/fileapi_worker.h
+++ b/chrome/browser/chromeos/drive/fileapi_worker.h
@@ -1,6 +1,20 @@
 // Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
+//
+// This file provides the core implementation of fileapi methods.
+// The functions should be called on UI thread.
+// Note that most method invocation of fileapi is done on IO thread. The gap is
+// filled by FileSystemProxy.
+// Also, the order of arguments for the functions which take FileSystemInterface
+// at the last is intentional. The instance of FileSystemInterface should be
+// accessible only on UI thread, but arguments are passed on IO thread.
+// So, here is an intended use case:
+//   1) Bind arguments on IO thread. Then a callback instance whose type is
+//      Callback<void(FileSysstemInterface*)> is created.
+//   2) Post the task to the UI thread.
+//   3) On UI thread, check if the instance of FileSystemInterface is alive or
+//      not. If yes, Run the callback with it.
 
 #ifndef CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_WORKER_H_
 #define CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_WORKER_H_
@@ -26,124 +40,131 @@
 
 class FileSystemInterface;
 
-namespace internal {
+namespace fileapi_internal {
 
-// This provides the core implementation of the methods for fileapi.
-// This class lives on UI thread. Note that most method invocation of fileapi
-// is done on IO thread. The gap is filled by FileSystemProxy.
-class FileApiWorker {
- public:
-  typedef base::Callback<
-      void(base::PlatformFileError result)> StatusCallback;
-  typedef base::Callback<
-      void(base::PlatformFileError result,
-           const base::PlatformFileInfo& file_info)> GetFileInfoCallback;
-  typedef base::Callback<
-      void(base::PlatformFileError result,
-           const std::vector<fileapi::DirectoryEntry>& file_list,
-           bool has_more)> ReadDirectoryCallback;
-  typedef base::Callback<
-      void(base::PlatformFileError result,
-           const base::PlatformFileInfo& file_info,
-           const base::FilePath& snapshot_file_path,
-           webkit_blob::ScopedFile::ScopeOutPolicy scope_out_policy)>
-      CreateSnapshotFileCallback;
-  typedef base::Callback<
-      void(base::PlatformFileError result,
-           base::PlatformFile platform_file)> OpenFileCallback;
+typedef base::Callback<FileSystemInterface*()> FileSystemGetter;
 
-  // |file_system| must not be NULL.
-  explicit FileApiWorker(FileSystemInterface* file_system);
-  ~FileApiWorker();
+typedef base::Callback<
+    void(base::PlatformFileError result)> StatusCallback;
+typedef base::Callback<
+    void(base::PlatformFileError result,
+         const base::PlatformFileInfo& file_info)> GetFileInfoCallback;
+typedef base::Callback<
+    void(base::PlatformFileError result,
+         const std::vector<fileapi::DirectoryEntry>& file_list,
+         bool has_more)> ReadDirectoryCallback;
+typedef base::Callback<
+    void(base::PlatformFileError result,
+         const base::PlatformFileInfo& file_info,
+         const base::FilePath& snapshot_file_path,
+         webkit_blob::ScopedFile::ScopeOutPolicy scope_out_policy)>
+    CreateSnapshotFileCallback;
+typedef base::Callback<
+    void(base::PlatformFileError result,
+         base::PlatformFile platform_file)> OpenFileCallback;
 
-  FileSystemInterface* file_system() { return file_system_; }
+// Runs |file_system_getter| to obtain the instance of FileSystemInstance,
+// and then runs |callback| with it.
+// If |file_system_getter| returns NULL, runs |on_error_callback| instead.
+// This function must be called on UI thread.
+// |file_system_getter| and |callback| must not be null, but
+// |on_error_callback| can be null (if no operation is necessary for error
+// case).
+void RunFileSystemCallback(
+    const FileSystemGetter& file_system_getter,
+    const base::Callback<void(FileSystemInterface*)>& callback,
+    const base::Closure& on_error_callback);
 
-  // Returns the metadata info of the file at |file_path|.
-  // Called from FileSystemProxy::GetFileInfo().
-  void GetFileInfo(const base::FilePath& file_path,
-                   const GetFileInfoCallback& callback);
+// Returns the metadata info of the file at |file_path|.
+// Called from FileSystemProxy::GetFileInfo().
+void GetFileInfo(const base::FilePath& file_path,
+                 const GetFileInfoCallback& callback,
+                 FileSystemInterface* file_system);
 
-  // Copies a file from |src_file_path| to |dest_file_path|.
-  // Called from FileSystemProxy::Copy().
-  void Copy(const base::FilePath& src_file_path,
-            const base::FilePath& dest_file_path,
-            const StatusCallback& callback);
+// Copies a file from |src_file_path| to |dest_file_path|.
+// Called from FileSystemProxy::Copy().
+void Copy(const base::FilePath& src_file_path,
+          const base::FilePath& dest_file_path,
+          const StatusCallback& callback,
+          FileSystemInterface* file_system);
 
-  // Moves a file from |src_file_path| to |dest_file_path|.
-  // Called from FileSystemProxy::Move().
-  void Move(const base::FilePath& src_file_path,
-            const base::FilePath& dest_file_path,
-            const StatusCallback& callback);
+// Moves a file from |src_file_path| to |dest_file_path|.
+// Called from FileSystemProxy::Move().
+void Move(const base::FilePath& src_file_path,
+          const base::FilePath& dest_file_path,
+          const StatusCallback& callback,
+          FileSystemInterface* file_system);
 
-  // Reads the contents of the directory at |file_path|.
-  // Called from FileSystemProxy::ReadDirectory().
-  void ReadDirectory(const base::FilePath& file_path,
-                     const ReadDirectoryCallback& callback);
 
-  // Removes a file at |file_path|. Called from FileSystemProxy::Remove().
-  void Remove(const base::FilePath& file_path,
-              bool is_recursive,
-              const StatusCallback& callback);
+// Copies a file at |src_foreign_file_path|, which is not managed by Drive File
+// System, to |dest_file_path|.
+void CopyInForeignFile(const base::FilePath& src_foreign_file_path,
+                       const base::FilePath& dest_file_path,
+                       const StatusCallback& callback,
+                       FileSystemInterface* file_system);
 
-  // Creates a new directory at |file_path|.
-  // Called from FileSystemProxy::CreateDirectory().
-  void CreateDirectory(const base::FilePath& file_path,
-                       bool is_exclusive,
-                       bool is_recursive,
-                       const StatusCallback& callback);
+// Reads the contents of the directory at |file_path|.
+// Called from FileSystemProxy::ReadDirectory().
+void ReadDirectory(const base::FilePath& file_path,
+                   const ReadDirectoryCallback& callback,
+                   FileSystemInterface* file_system);
 
-  // Creates a new file at |file_path|.
-  // Called from FileSystemProxy::CreateFile().
-  void CreateFile(const base::FilePath& file_path,
-                  bool is_exclusive,
-                  const StatusCallback& callback);
+// Removes a file at |file_path|. Called from FileSystemProxy::Remove().
+void Remove(const base::FilePath& file_path,
+            bool is_recursive,
+            const StatusCallback& callback,
+            FileSystemInterface* file_system);
 
-  // Truncates the file at |file_path| to |length| bytes.
-  // Called from FileSystemProxy::Truncate().
-  void Truncate(const base::FilePath& file_path,
-                int64 length,
-                const StatusCallback& callback);
+// Creates a new directory at |file_path|.
+// Called from FileSystemProxy::CreateDirectory().
+void CreateDirectory(const base::FilePath& file_path,
+                     bool is_exclusive,
+                     bool is_recursive,
+                     const StatusCallback& callback,
+                     FileSystemInterface* file_system);
 
-  // Creates a snapshot for the file at |file_path|.
-  // Called from FileSystemProxy::CreateSnapshotFile().
-  void CreateSnapshotFile(const base::FilePath& file_path,
-                          const CreateSnapshotFileCallback& callback);
+// Creates a new file at |file_path|.
+// Called from FileSystemProxy::CreateFile().
+void CreateFile(const base::FilePath& file_path,
+                bool is_exclusive,
+                const StatusCallback& callback,
+                FileSystemInterface* file_system);
 
-  // Opens the file at |file_path| with options |file_flags|.
-  // Called from FileSystemProxy::OpenFile.
-  void OpenFile(const base::FilePath& file_path,
-                int file_flags,
-                const OpenFileCallback& callback);
+// Truncates the file at |file_path| to |length| bytes.
+// Called from FileSystemProxy::Truncate().
+void Truncate(const base::FilePath& file_path,
+              int64 length,
+              const StatusCallback& callback,
+              FileSystemInterface* file_system);
 
-  // Closes the file at |file_path|.
-  // Called from FileSystemProxy::NotifyCloseFile and
-  // FileSystemProxy::CloseWRitableSnapshotFile.
-  void CloseFile(const base::FilePath& file_path);
+// Creates a snapshot for the file at |file_path|.
+// Called from FileSystemProxy::CreateSnapshotFile().
+void CreateSnapshotFile(const base::FilePath& file_path,
+                        const CreateSnapshotFileCallback& callback,
+                        FileSystemInterface* file_system);
 
-  // Changes timestamp of the file at |file_path| to |last_access_time| and
-  // |last_modified_time|. Called from FileSystemProxy::TouchFile().
-  void TouchFile(const base::FilePath& file_path,
-                 const base::Time& last_access_time,
-                 const base::Time& last_modified_time,
-                 const StatusCallback& callback);
+// Opens the file at |file_path| with options |file_flags|.
+// Called from FileSystemProxy::OpenFile.
+void OpenFile(const base::FilePath& file_path,
+              int file_flags,
+              const OpenFileCallback& callback,
+              FileSystemInterface* file_system);
 
- private:
-  // Part of OpenFile(). Called after FileSystem::CreateFile().
-  void OpenFileAfterCreateFile(const base::FilePath& file_path,
-                               int file_flags,
-                               const OpenFileCallback& callback,
-                               FileError error);
+// Closes the file at |file_path|.
+// Called from FileSystemProxy::NotifyCloseFile and
+// FileSystemProxy::CloseWRitableSnapshotFile.
+void CloseFile(const base::FilePath& file_path,
+               FileSystemInterface* file_system);
 
-  FileSystemInterface* file_system_;
+// Changes timestamp of the file at |file_path| to |last_access_time| and
+// |last_modified_time|. Called from FileSystemProxy::TouchFile().
+void TouchFile(const base::FilePath& file_path,
+               const base::Time& last_access_time,
+               const base::Time& last_modified_time,
+               const StatusCallback& callback,
+               FileSystemInterface* file_system);
 
-  // Note: This should remain the last member so it'll be destroyed and
-  // invalidate the weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<FileApiWorker> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileApiWorker);
-};
-
-}  // namespace internal
+}  // namespace fileapi_internal
 }  // namespace drive
 
 #endif  // CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_WORKER_H_
diff --git a/chrome/browser/chromeos/drive/fileapi_worker_unittest.cc b/chrome/browser/chromeos/drive/fileapi_worker_unittest.cc
new file mode 100644
index 0000000..9e5299f
--- /dev/null
+++ b/chrome/browser/chromeos/drive/fileapi_worker_unittest.cc
@@ -0,0 +1,67 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/drive/fileapi_worker.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/drive/dummy_file_system.h"
+#include "chrome/browser/google_apis/test_util.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace drive {
+namespace fileapi_internal {
+namespace {
+
+// Increments |num_called| for checking how many times the closure is called.
+void Increment(int* num_called) {
+  ++*num_called;
+}
+
+// Returns the |instance| as is.
+FileSystemInterface* GetFileSystem(FileSystemInterface* instance) {
+  return instance;
+}
+
+}  // namespace
+
+class FileApiWorkerTest : public testing::Test {
+ private:
+  content::TestBrowserThreadBundle thread_bundle_;
+};
+
+TEST_F(FileApiWorkerTest, RunFileSystemCallbackSuccess) {
+  DummyFileSystem dummy_file_system;
+
+  FileSystemInterface* file_system = NULL;
+  RunFileSystemCallback(
+      base::Bind(&GetFileSystem, &dummy_file_system),
+      google_apis::test_util::CreateCopyResultCallback(&file_system),
+      base::Closure());
+
+  EXPECT_EQ(&dummy_file_system, file_system);
+}
+
+TEST_F(FileApiWorkerTest, RunFileSystemCallbackFail) {
+  FileSystemInterface* file_system = NULL;
+
+  // Make sure on_error_callback is called if file_system_getter returns NULL.
+  int num_called = 0;
+  RunFileSystemCallback(
+      base::Bind(&GetFileSystem, static_cast<FileSystemInterface*>(NULL)),
+      google_apis::test_util::CreateCopyResultCallback(&file_system),
+      base::Bind(&Increment, &num_called));
+  EXPECT_EQ(1, num_called);
+
+  // Just make sure this null |on_error_callback| doesn't cause a crash.
+  RunFileSystemCallback(
+      base::Bind(&GetFileSystem, static_cast<FileSystemInterface*>(NULL)),
+      google_apis::test_util::CreateCopyResultCallback(&file_system),
+      base::Closure());
+}
+
+}  // namespace fileapi_internal
+}  // namespace drive
diff --git a/chrome/browser/chromeos/drive/job_scheduler.cc b/chrome/browser/chromeos/drive/job_scheduler.cc
index 621021e..c43c9d9 100644
--- a/chrome/browser/chromeos/drive/job_scheduler.cc
+++ b/chrome/browser/chromeos/drive/job_scheduler.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/browser/chromeos/drive/logging.h"
 #include "chrome/browser/google_apis/drive_api_parser.h"
-#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/google_apis/task_util.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -89,34 +89,6 @@
                                     params.progress_callback);
 }
 
-// Helper for CreateErrorRunCallback.
-template<typename P1>
-struct CreateErrorRunCallbackHelper {
-  static void Run(
-      const base::Callback<void(google_apis::GDataErrorCode, P1)>& callback,
-      google_apis::GDataErrorCode error) {
-    callback.Run(error, P1());
-  }
-};
-
-template<typename P1>
-struct CreateErrorRunCallbackHelper<const P1&> {
-  static void Run(
-      const base::Callback<void(google_apis::GDataErrorCode,
-                                const P1&)>& callback,
-      google_apis::GDataErrorCode error) {
-    callback.Run(error, P1());
-  }
-};
-
-// Returns a callback with the tail parameter bound to its default value.
-// In other words, returned_callback.Run(error) runs callback.Run(error, T()).
-template<typename P1>
-base::Callback<void(google_apis::GDataErrorCode)> CreateErrorRunCallback(
-    const base::Callback<void(google_apis::GDataErrorCode, P1)>& callback) {
-  return base::Bind(&CreateErrorRunCallbackHelper<P1>::Run, callback);
-}
-
 }  // namespace
 
 const int JobScheduler::kMaxJobCount[] = {
@@ -142,14 +114,14 @@
 };
 
 JobScheduler::JobScheduler(
-    Profile* profile,
+    PrefService* pref_service,
     DriveServiceInterface* drive_service,
     base::SequencedTaskRunner* blocking_task_runner)
     : throttle_count_(0),
       disable_throttling_(false),
       drive_service_(drive_service),
       uploader_(new DriveUploader(drive_service, blocking_task_runner)),
-      profile_(profile),
+      pref_service_(pref_service),
       weak_ptr_factory_(this) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
@@ -226,7 +198,7 @@
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -243,7 +215,7 @@
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -260,7 +232,7 @@
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -280,7 +252,7 @@
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -299,7 +271,7 @@
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -318,7 +290,7 @@
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -337,7 +309,7 @@
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -358,7 +330,7 @@
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -385,7 +357,7 @@
 void JobScheduler::CopyResource(
     const std::string& resource_id,
     const std::string& parent_resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const google_apis::GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -396,18 +368,18 @@
       base::Unretained(drive_service_),
       resource_id,
       parent_resource_id,
-      new_name,
+      new_title,
       base::Bind(&JobScheduler::OnGetResourceEntryJobDone,
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
 void JobScheduler::CopyHostedDocument(
     const std::string& resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const google_apis::GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -417,18 +389,18 @@
       &DriveServiceInterface::CopyHostedDocument,
       base::Unretained(drive_service_),
       resource_id,
-      new_name,
+      new_title,
       base::Bind(&JobScheduler::OnGetResourceEntryJobDone,
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
 void JobScheduler::RenameResource(
     const std::string& resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const google_apis::EntryActionCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -438,7 +410,7 @@
       &DriveServiceInterface::RenameResource,
       base::Unretained(drive_service_),
       resource_id,
-      new_name,
+      new_title,
       base::Bind(&JobScheduler::OnEntryActionJobDone,
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
@@ -466,7 +438,7 @@
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -513,7 +485,7 @@
 
 void JobScheduler::AddNewDirectory(
     const std::string& parent_resource_id,
-    const std::string& directory_name,
+    const std::string& directory_title,
     const google_apis::GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
@@ -522,12 +494,12 @@
       &DriveServiceInterface::AddNewDirectory,
       base::Unretained(drive_service_),
       parent_resource_id,
-      directory_name,
+      directory_title,
       base::Bind(&JobScheduler::OnGetResourceEntryJobDone,
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id,
                  callback));
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -556,7 +528,8 @@
       base::Bind(&JobScheduler::UpdateProgress,
                  weak_ptr_factory_.GetWeakPtr(),
                  new_job->job_info.job_id));
-  new_job->abort_callback = CreateErrorRunCallback(download_action_callback);
+  new_job->abort_callback =
+      google_apis::CreateErrorRunCallback(download_action_callback);
   StartJob(new_job);
   return new_job->job_info.job_id;
 }
@@ -594,7 +567,7 @@
                                         weak_ptr_factory_.GetWeakPtr(),
                                         new_job->job_info.job_id);
   new_job->task = base::Bind(&RunUploadNewFile, uploader_.get(), params);
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -631,7 +604,7 @@
                                         weak_ptr_factory_.GetWeakPtr(),
                                         new_job->job_info.job_id);
   new_job->task = base::Bind(&RunUploadExistingFile, uploader_.get(), params);
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -668,7 +641,7 @@
   params.progress_callback = google_apis::ProgressCallback();
 
   new_job->task = base::Bind(&RunUploadNewFile, uploader_.get(), params);
-  new_job->abort_callback = CreateErrorRunCallback(callback);
+  new_job->abort_callback = google_apis::CreateErrorRunCallback(callback);
   StartJob(new_job);
 }
 
@@ -742,7 +715,7 @@
   const int kNoJobShouldRun = -1;
 
   // Should stop if Drive was disabled while running the fetch loop.
-  if (profile_->GetPrefs()->GetBoolean(prefs::kDisableDrive))
+  if (pref_service_->GetBoolean(prefs::kDisableDrive))
     return kNoJobShouldRun;
 
   // Should stop if the network is not online.
@@ -752,7 +725,7 @@
   // For the file queue, if it is on cellular network, only user initiated
   // operations are allowed to start.
   if (queue_type == FILE_QUEUE &&
-      profile_->GetPrefs()->GetBoolean(prefs::kDisableDriveOverCellular) &&
+      pref_service_->GetBoolean(prefs::kDisableDriveOverCellular) &&
       net::NetworkChangeNotifier::IsConnectionCellular(
           net::NetworkChangeNotifier::GetConnectionType()))
     return USER_INITIATED;
@@ -1014,6 +987,7 @@
   base::Callback<void(google_apis::GDataErrorCode)> callback =
       job->abort_callback;
   queue_[GetJobQueueType(job->job_info.job_type)]->Remove(job->job_info.job_id);
+  NotifyJobDone(job->job_info, error);
   job_map_.Remove(job->job_info.job_id);
   base::MessageLoopProxy::current()->PostTask(FROM_HERE,
                                               base::Bind(callback, error));
diff --git a/chrome/browser/chromeos/drive/job_scheduler.h b/chrome/browser/chromeos/drive/job_scheduler.h
index d0388fd..404ce7f 100644
--- a/chrome/browser/chromeos/drive/job_scheduler.h
+++ b/chrome/browser/chromeos/drive/job_scheduler.h
@@ -17,7 +17,7 @@
 #include "chrome/browser/drive/drive_uploader.h"
 #include "net/base/network_change_notifier.h"
 
-class Profile;
+class PrefService;
 
 namespace base {
 class SeqencedTaskRunner;
@@ -51,7 +51,7 @@
     : public net::NetworkChangeNotifier::ConnectionTypeObserver,
       public JobListInterface {
  public:
-  JobScheduler(Profile* profile,
+  JobScheduler(PrefService* pref_service,
                DriveServiceInterface* drive_service,
                base::SequencedTaskRunner* blocking_task_runner);
   virtual ~JobScheduler();
@@ -111,18 +111,18 @@
   void CopyResource(
       const std::string& resource_id,
       const std::string& parent_resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback);
 
   // Adds a CopyHostedDocument operation to the queue.
   void CopyHostedDocument(
       const std::string& resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback);
 
   // Adds a RenameResource operation to the queue.
   void RenameResource(const std::string& resource_id,
-                      const std::string& new_name,
+                      const std::string& new_title,
                       const google_apis::EntryActionCallback& callback);
 
   // Adds a TouchResource operation to the queue.
@@ -144,7 +144,7 @@
 
   // Adds a AddNewDirectory operation to the queue.
   void AddNewDirectory(const std::string& parent_resource_id,
-                       const std::string& directory_name,
+                       const std::string& directory_title,
                        const google_apis::GetResourceEntryCallback& callback);
 
   // Adds a DownloadFile operation to the queue.
@@ -347,7 +347,7 @@
   DriveServiceInterface* drive_service_;
   scoped_ptr<DriveUploaderInterface> uploader_;
 
-  Profile* profile_;
+  PrefService* pref_service_;
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
diff --git a/chrome/browser/chromeos/drive/job_scheduler_unittest.cc b/chrome/browser/chromeos/drive/job_scheduler_unittest.cc
index 57f3dbe..f734529 100644
--- a/chrome/browser/chromeos/drive/job_scheduler_unittest.cc
+++ b/chrome/browser/chromeos/drive/job_scheduler_unittest.cc
@@ -8,7 +8,8 @@
 
 #include "base/bind.h"
 #include "base/file_util.h"
-#include "base/prefs/pref_service.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/prefs/testing_pref_service.h"
 #include "base/run_loop.h"
 #include "base/stl_util.h"
 #include "chrome/browser/chromeos/drive/test_util.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
 #include "chrome/browser/google_apis/test_util.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -88,7 +88,8 @@
 class JobSchedulerTest : public testing::Test {
  public:
   JobSchedulerTest()
-      : profile_(new TestingProfile) {
+      : pref_service_(new TestingPrefServiceSimple) {
+    test_util::RegisterDrivePrefs(pref_service_->registry());
   }
 
   virtual void SetUp() OVERRIDE {
@@ -103,9 +104,9 @@
     fake_drive_service_->LoadAppListForDriveApi(
         "drive/applist.json");
 
-    scheduler_.reset(new JobScheduler(profile_.get(),
+    scheduler_.reset(new JobScheduler(pref_service_.get(),
                                       fake_drive_service_.get(),
-                                      base::MessageLoopProxy::current()));
+                                      base::MessageLoopProxy::current().get()));
     scheduler_->SetDisableThrottling(true);
   }
 
@@ -141,7 +142,7 @@
   }
 
   content::TestBrowserThreadBundle thread_bundle_;
-  scoped_ptr<TestingProfile> profile_;
+  scoped_ptr<TestingPrefServiceSimple> pref_service_;
   scoped_ptr<test_util::FakeNetworkChangeNotifier>
       fake_network_change_notifier_;
   scoped_ptr<FakeDriveService> fake_drive_service_;
@@ -325,7 +326,7 @@
   scheduler_->CopyResource(
       "file:2_file_resource_id",  // resource ID
       "folder:1_folder_resource_id",  // parent resource ID
-      "New Document",  // new name
+      "New Document",  // new title
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
   base::RunLoop().RunUntilIdle();
 
@@ -341,7 +342,7 @@
 
   scheduler_->CopyHostedDocument(
       "document:5_document_resource_id",  // resource ID
-      "New Document",  // new name
+      "New Document",  // new title
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
   base::RunLoop().RunUntilIdle();
 
@@ -356,7 +357,7 @@
 
   scheduler_->RenameResource(
       "file:2_file_resource_id",
-      "New Name",
+      "New Title",
       google_apis::test_util::CreateCopyResultCallback(&error));
   base::RunLoop().RunUntilIdle();
 
@@ -506,7 +507,7 @@
   ConnectToCellular();
 
   // Disable fetching over cellular network.
-  profile_->GetPrefs()->SetBoolean(prefs::kDisableDriveOverCellular, true);
+  pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true);
 
   // Try to get a file in the background
   base::ScopedTempDir temp_dir;
@@ -558,7 +559,7 @@
   ConnectToWimax();
 
   // Disable fetching over cellular network.
-  profile_->GetPrefs()->SetBoolean(prefs::kDisableDriveOverCellular, true);
+  pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true);
 
   // Try to get a file in the background
   base::ScopedTempDir temp_dir;
@@ -610,7 +611,7 @@
   ConnectToCellular();
 
   // Enable fetching over cellular network.
-  profile_->GetPrefs()->SetBoolean(prefs::kDisableDriveOverCellular, false);
+  pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, false);
 
   // Try to get a file in the background
   base::ScopedTempDir temp_dir;
@@ -654,7 +655,7 @@
   ConnectToWimax();
 
   // Enable fetching over cellular network.
-  profile_->GetPrefs()->SetBoolean(prefs::kDisableDriveOverCellular, false);
+  pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, false);
 
   // Try to get a file in the background
   base::ScopedTempDir temp_dir;
@@ -700,7 +701,7 @@
 
   // Disable background upload/download.
   ConnectToWimax();
-  profile_->GetPrefs()->SetBoolean(prefs::kDisableDriveOverCellular, true);
+  pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true);
 
   base::ScopedTempDir temp_dir;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
@@ -725,7 +726,7 @@
   expected_types.insert(TYPE_RENAME_RESOURCE);
   scheduler_->RenameResource(
       "file:2_file_resource_id",
-      "New Name",
+      "New Title",
       google_apis::test_util::CreateCopyResultCallback(&error));
   expected_types.insert(TYPE_DOWNLOAD_FILE);
   scheduler_->DownloadFile(
diff --git a/chrome/browser/chromeos/drive/local_file_reader_unittest.cc b/chrome/browser/chromeos/drive/local_file_reader_unittest.cc
index 0af9c0a..e89e5b6 100644
--- a/chrome/browser/chromeos/drive/local_file_reader_unittest.cc
+++ b/chrome/browser/chromeos/drive/local_file_reader_unittest.cc
@@ -49,7 +49,7 @@
     worker_thread_.reset(new base::Thread("LocalFileReaderTest"));
     ASSERT_TRUE(worker_thread_->Start());
     file_reader_.reset(
-        new LocalFileReader(worker_thread_->message_loop_proxy()));
+        new LocalFileReader(worker_thread_->message_loop_proxy().get()));
   }
 
   base::MessageLoop message_loop_;
diff --git a/chrome/browser/chromeos/drive/remove_stale_cache_files.cc b/chrome/browser/chromeos/drive/remove_stale_cache_files.cc
index 798a559..56296ca 100644
--- a/chrome/browser/chromeos/drive/remove_stale_cache_files.cc
+++ b/chrome/browser/chromeos/drive/remove_stale_cache_files.cc
@@ -25,9 +25,10 @@
     ResourceEntry entry;
     FileError error = resource_metadata->GetResourceEntryById(it->GetID(),
                                                               &entry);
-    // The entry is not found or the MD5 does not match.
+    // Stale = the entry is not found, or not dirty but the MD5 does not match.
     if (error != FILE_ERROR_OK ||
-        it->GetValue().md5() != entry.file_specific_info().md5()) {
+        (!it->GetValue().is_dirty() &&
+         it->GetValue().md5() != entry.file_specific_info().md5())) {
       FileError error = cache->Remove(it->GetID());
       LOG_IF(WARNING, error != FILE_ERROR_OK)
           << "Failed to remove a stale cache file. resource_id: "
diff --git a/chrome/browser/chromeos/drive/remove_stale_cache_files_unittest.cc b/chrome/browser/chromeos/drive/remove_stale_cache_files_unittest.cc
index f99c6f1..751b6a8 100644
--- a/chrome/browser/chromeos/drive/remove_stale_cache_files_unittest.cc
+++ b/chrome/browser/chromeos/drive/remove_stale_cache_files_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/run_loop.h"
 #include "chrome/browser/chromeos/drive/drive.pb.h"
 #include "chrome/browser/chromeos/drive/fake_free_disk_space_getter.h"
+#include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/browser/chromeos/drive/remove_stale_cache_files.h"
 #include "chrome/browser/chromeos/drive/resource_metadata.h"
 #include "chrome/browser/chromeos/drive/test_util.h"
@@ -29,11 +30,11 @@
     fake_free_disk_space_getter_.reset(new FakeFreeDiskSpaceGetter);
 
     metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.path(), base::MessageLoopProxy::current()));
+        temp_dir_.path(), base::MessageLoopProxy::current().get()));
 
     cache_.reset(new FileCache(metadata_storage_.get(),
                                temp_dir_.path(),
-                               base::MessageLoopProxy::current(),
+                               base::MessageLoopProxy::current().get(),
                                fake_free_disk_space_getter_.get()));
 
     resource_metadata_.reset(new ResourceMetadata(
@@ -82,5 +83,43 @@
   EXPECT_FALSE(cache_->GetCacheEntry(resource_id, md5, &cache_entry));
 }
 
+TEST_F(RemoveStaleCacheFilesTest, DirtyCacheFiles) {
+  base::FilePath dummy_file;
+  ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(),
+                                                  &dummy_file));
+
+  // Dirty and deleted (= absent in resource_metada) cache entry.
+  std::string resource_id_1("file:1");
+  std::string md5_1("abcdef0123456789");
+  EXPECT_EQ(FILE_ERROR_OK,
+            cache_->Store(resource_id_1, md5_1, dummy_file,
+                          FileCache::FILE_OPERATION_COPY));
+  EXPECT_EQ(FILE_ERROR_OK, cache_->MarkDirty(resource_id_1, md5_1));
+
+  // Dirty and mismatching-MD5 entry.
+  std::string resource_id_2("file:2");
+  std::string md5_2_cache("0123456789abcdef");
+  std::string md5_2_metadata("abcdef0123456789");
+  EXPECT_EQ(FILE_ERROR_OK,
+            cache_->Store(resource_id_2, md5_2_cache, dummy_file,
+                          FileCache::FILE_OPERATION_COPY));
+  EXPECT_EQ(FILE_ERROR_OK, cache_->MarkDirty(resource_id_2, md5_2_cache));
+
+  ResourceEntry entry;
+  entry.set_resource_id(resource_id_2);
+  entry.mutable_file_specific_info()->set_md5(md5_2_metadata);
+  entry.set_parent_resource_id(util::kDriveGrandRootSpecialResourceId);
+  resource_metadata_->AddEntry(entry);
+
+  // Remove stale cache files.
+  RemoveStaleCacheFiles(cache_.get(), resource_metadata_.get());
+
+  // Dirty cache should be removed if and only if the entry does not exist in
+  // resource_metadata.
+  FileCacheEntry cache_entry;
+  EXPECT_FALSE(cache_->GetCacheEntry(resource_id_1, md5_1, &cache_entry));
+  EXPECT_TRUE(cache_->GetCacheEntry(resource_id_2, md5_2_cache, &cache_entry));
+}
+
 }  // namespace internal
 }  // namespace drive
diff --git a/chrome/browser/chromeos/drive/resource_entry_conversion.cc b/chrome/browser/chromeos/drive/resource_entry_conversion.cc
index 9ba85ad..d37f9a6 100644
--- a/chrome/browser/chromeos/drive/resource_entry_conversion.cc
+++ b/chrome/browser/chromeos/drive/resource_entry_conversion.cc
@@ -14,8 +14,8 @@
 #include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/browser/drive/drive_api_util.h"
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/escape.h"
+#include "url/gurl.h"
 
 namespace drive {
 
diff --git a/chrome/browser/chromeos/drive/resource_entry_conversion_unittest.cc b/chrome/browser/chromeos/drive/resource_entry_conversion_unittest.cc
index 619d5d1..08ba2e5 100644
--- a/chrome/browser/chromeos/drive/resource_entry_conversion_unittest.cc
+++ b/chrome/browser/chromeos/drive/resource_entry_conversion_unittest.cc
@@ -10,8 +10,8 @@
 #include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/browser/chromeos/drive/test_util.h"
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace drive {
 
diff --git a/chrome/browser/chromeos/drive/resource_metadata.cc b/chrome/browser/chromeos/drive/resource_metadata.cc
index 4e79a57..b0ad6a1 100644
--- a/chrome/browser/chromeos/drive/resource_metadata.cc
+++ b/chrome/browser/chromeos/drive/resource_metadata.cc
@@ -544,14 +544,14 @@
 
 FileError ResourceMetadata::RenameEntry(
     const base::FilePath& file_path,
-    const std::string& new_name,
+    const std::string& new_title,
     base::FilePath* out_file_path) {
   DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
   DCHECK(!file_path.empty());
-  DCHECK(!new_name.empty());
+  DCHECK(!new_title.empty());
   DCHECK(out_file_path);
 
-  DVLOG(1) << "RenameEntry " << file_path.value() << " to " << new_name;
+  DVLOG(1) << "RenameEntry " << file_path.value() << " to " << new_title;
 
   if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
     return FILE_ERROR_NO_SPACE;
@@ -560,10 +560,10 @@
   if (!FindEntryByPathSync(file_path, &entry))
     return FILE_ERROR_NOT_FOUND;
 
-  if (base::FilePath::FromUTF8Unsafe(new_name) == file_path.BaseName())
+  if (base::FilePath::FromUTF8Unsafe(new_title) == file_path.BaseName())
     return FILE_ERROR_EXISTS;
 
-  entry.set_title(new_name);
+  entry.set_title(new_title);
 
   FileError error = RefreshEntry(entry);
   if (error == FILE_ERROR_OK)
diff --git a/chrome/browser/chromeos/drive/resource_metadata_storage.cc b/chrome/browser/chromeos/drive/resource_metadata_storage.cc
index b7a6264..6f7c74d 100644
--- a/chrome/browser/chromeos/drive/resource_metadata_storage.cc
+++ b/chrome/browser/chromeos/drive/resource_metadata_storage.cc
@@ -217,7 +217,7 @@
 
   // Remove unused child map DB.
   const base::FilePath child_map_path = directory_path_.Append(kChildMapDBName);
-  base::Delete(child_map_path, true /* recursive */);
+  base::DeleteFile(child_map_path, true /* recursive */);
 
   resource_map_.reset();
 
@@ -227,10 +227,11 @@
   // Try to open the existing DB.
   leveldb::DB* db = NULL;
   leveldb::Options options;
+  options.max_open_files = 0;  // Use minimum.
   options.create_if_missing = false;
 
   DBInitStatus open_existing_result = DB_INIT_NOT_FOUND;
-  if (file_util::PathExists(resource_map_path)) {
+  if (base::PathExists(resource_map_path)) {
     leveldb::Status status =
         leveldb::DB::Open(options, resource_map_path.AsUTF8Unsafe(), &db);
     open_existing_result = LevelDBStatusToDBInitStatus(status);
@@ -267,9 +268,10 @@
 
     // Clean up the destination.
     const bool kRecursive = true;
-    base::Delete(resource_map_path, kRecursive);
+    base::DeleteFile(resource_map_path, kRecursive);
 
     // Create DB.
+    options.max_open_files = 0;  // Use minimum.
     options.create_if_missing = true;
 
     leveldb::Status status =
diff --git a/chrome/browser/chromeos/drive/resource_metadata_storage_unittest.cc b/chrome/browser/chromeos/drive/resource_metadata_storage_unittest.cc
index 4ab0acf..a1f31ad 100644
--- a/chrome/browser/chromeos/drive/resource_metadata_storage_unittest.cc
+++ b/chrome/browser/chromeos/drive/resource_metadata_storage_unittest.cc
@@ -23,7 +23,7 @@
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
 
     storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.path(), base::MessageLoopProxy::current()));
+        temp_dir_.path(), base::MessageLoopProxy::current().get()));
     ASSERT_TRUE(storage_->Initialize());
   }
 
@@ -312,7 +312,7 @@
 
   // Close DB and reopen.
   storage_.reset(new ResourceMetadataStorage(
-      temp_dir_.path(), base::MessageLoopProxy::current()));
+      temp_dir_.path(), base::MessageLoopProxy::current().get()));
   ASSERT_TRUE(storage_->Initialize());
 
   // Can read data.
@@ -344,7 +344,7 @@
   // Set incompatible version and reopen DB.
   SetDBVersion(ResourceMetadataStorage::kDBVersion - 1);
   storage_.reset(new ResourceMetadataStorage(
-      temp_dir_.path(), base::MessageLoopProxy::current()));
+      temp_dir_.path(), base::MessageLoopProxy::current().get()));
   ASSERT_TRUE(storage_->Initialize());
 
   // Data is erased because of the incompatible version.
@@ -358,7 +358,7 @@
   ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &path));
 
   storage_.reset(new ResourceMetadataStorage(
-      path, base::MessageLoopProxy::current()));
+      path, base::MessageLoopProxy::current().get()));
   // Cannot initialize DB beacause the path does not point a directory.
   ASSERT_FALSE(storage_->Initialize());
 }
diff --git a/chrome/browser/chromeos/drive/resource_metadata_unittest.cc b/chrome/browser/chromeos/drive/resource_metadata_unittest.cc
index 27608c6..68eb589 100644
--- a/chrome/browser/chromeos/drive/resource_metadata_unittest.cc
+++ b/chrome/browser/chromeos/drive/resource_metadata_unittest.cc
@@ -125,15 +125,15 @@
         pool->GetSequencedTaskRunner(pool->GetSequenceToken());
 
     metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.path(), blocking_task_runner_));
+        temp_dir_.path(), blocking_task_runner_.get()));
     bool success = false;
     base::PostTaskAndReplyWithResult(
-        blocking_task_runner_,
+        blocking_task_runner_.get(),
         FROM_HERE,
         base::Bind(&ResourceMetadataStorage::Initialize,
                    base::Unretained(metadata_storage_.get())),
         google_apis::test_util::CreateCopyResultCallback(&success));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     ASSERT_TRUE(success);
 
     resource_metadata_.reset(new ResourceMetadata(metadata_storage_.get(),
@@ -141,19 +141,19 @@
 
     FileError error = FILE_ERROR_FAILED;
     base::PostTaskAndReplyWithResult(
-        blocking_task_runner_,
+        blocking_task_runner_.get(),
         FROM_HERE,
         base::Bind(&ResourceMetadata::Initialize,
                    base::Unretained(resource_metadata_.get())),
         google_apis::test_util::CreateCopyResultCallback(&error));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     ASSERT_EQ(FILE_ERROR_OK, error);
 
     blocking_task_runner_->PostTask(
         FROM_HERE,
         base::Bind(&SetUpEntries,
                    base::Unretained(resource_metadata_.get())));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
   }
 
   virtual void TearDown() OVERRIDE {
@@ -170,7 +170,7 @@
     resource_metadata_->GetResourceEntryByPathOnUIThread(
         file_path,
         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     EXPECT_TRUE(error == FILE_ERROR_OK || !entry);
     return entry.Pass();
   }
@@ -184,7 +184,7 @@
     resource_metadata_->ReadDirectoryByPathOnUIThread(
         directory_path,
         google_apis::test_util::CreateCopyResultCallback(&error, &entries));
-    google_apis::test_util::RunBlockingPoolTask();
+    test_util::RunBlockingPoolTask();
     EXPECT_TRUE(error == FILE_ERROR_OK || !entries);
     return entries.Pass();
   }
@@ -204,13 +204,13 @@
   resource_metadata_->SetLargestChangestampOnUIThread(
       in_changestamp,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   int64 out_changestamp = 0;
   resource_metadata_->GetLargestChangestampOnUIThread(
       google_apis::test_util::CreateCopyResultCallback(&out_changestamp));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   DCHECK_EQ(in_changestamp, out_changestamp);
 }
 
@@ -221,7 +221,7 @@
   resource_metadata_->GetResourceEntryByIdOnUIThread(
       util::kDriveGrandRootSpecialResourceId,
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   ASSERT_TRUE(entry.get());
   EXPECT_EQ("drive", entry->base_name());
@@ -234,7 +234,7 @@
   resource_metadata_->GetResourceEntryByIdOnUIThread(
       "resource_id:file4",
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   ASSERT_TRUE(entry.get());
   EXPECT_EQ("file4", entry->base_name());
@@ -245,7 +245,7 @@
   resource_metadata_->GetResourceEntryByIdOnUIThread(
       "file:non_existing",
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
   EXPECT_FALSE(entry.get());
 }
@@ -257,7 +257,7 @@
   resource_metadata_->GetResourceEntryByPathOnUIThread(
       base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"),
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   ASSERT_TRUE(entry.get());
   EXPECT_EQ("file4", entry->base_name());
@@ -268,7 +268,7 @@
   resource_metadata_->GetResourceEntryByPathOnUIThread(
       base::FilePath::FromUTF8Unsafe("drive/root/dir1/non_existing"),
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
   EXPECT_FALSE(entry.get());
 
@@ -278,7 +278,7 @@
   resource_metadata_->GetResourceEntryByPathOnUIThread(
       base::FilePath::FromUTF8Unsafe("drive"),
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_TRUE(entry.get());
 
@@ -288,7 +288,7 @@
   resource_metadata_->GetResourceEntryByPathOnUIThread(
       base::FilePath::FromUTF8Unsafe("non_existing"),
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
   EXPECT_FALSE(entry.get());
 
@@ -298,7 +298,7 @@
   resource_metadata_->GetResourceEntryByPathOnUIThread(
       base::FilePath::FromUTF8Unsafe("non_existing/root"),
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
   EXPECT_FALSE(entry.get());
 }
@@ -310,7 +310,7 @@
   resource_metadata_->ReadDirectoryByPathOnUIThread(
       base::FilePath::FromUTF8Unsafe("drive/root/dir1"),
       google_apis::test_util::CreateCopyResultCallback(&error, &entries));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   ASSERT_TRUE(entries.get());
   ASSERT_EQ(3U, entries->size());
@@ -326,7 +326,7 @@
   resource_metadata_->ReadDirectoryByPathOnUIThread(
       base::FilePath::FromUTF8Unsafe("drive/root/non_existing"),
       google_apis::test_util::CreateCopyResultCallback(&error, &entries));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
   EXPECT_FALSE(entries.get());
 
@@ -336,7 +336,7 @@
   resource_metadata_->ReadDirectoryByPathOnUIThread(
       base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"),
       google_apis::test_util::CreateCopyResultCallback(&error, &entries));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error);
   EXPECT_FALSE(entries.get());
 }
@@ -348,7 +348,7 @@
       base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"),
       base::FilePath::FromUTF8Unsafe("drive/root/dir1/file5"),
       google_apis::test_util::CreateCopyResultCallback(&pair_result));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   // The first entry should be found.
   EXPECT_EQ(FILE_ERROR_OK, pair_result->first.error);
   EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"),
@@ -368,7 +368,7 @@
       base::FilePath::FromUTF8Unsafe("drive/root/dir1/non_existent"),
       base::FilePath::FromUTF8Unsafe("drive/root/dir1/file5"),
       google_apis::test_util::CreateCopyResultCallback(&pair_result));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   // The first entry should not be found.
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, pair_result->first.error);
   EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/root/dir1/non_existent"),
@@ -385,7 +385,7 @@
       base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"),
       base::FilePath::FromUTF8Unsafe("drive/root/dir1/non_existent"),
       google_apis::test_util::CreateCopyResultCallback(&pair_result));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   // The first entry should be found.
   EXPECT_EQ(FILE_ERROR_OK, pair_result->first.error);
   EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"),
@@ -410,7 +410,7 @@
       base::FilePath::FromUTF8Unsafe("drive/root/dir1"),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/root/dir1/file8"),
             drive_file_path);
@@ -419,7 +419,7 @@
   resource_metadata_->GetResourceEntryByIdOnUIThread(
       "resource_id:file8",
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Move non-existent file to drive/dir1. This should fail.
@@ -428,7 +428,7 @@
       base::FilePath::FromUTF8Unsafe("drive/root/dir1"),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
   EXPECT_EQ(base::FilePath(), drive_file_path);
 
@@ -438,7 +438,7 @@
       base::FilePath::FromUTF8Unsafe("drive/root/dir4"),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
   EXPECT_EQ(base::FilePath(), drive_file_path);
 
@@ -448,7 +448,7 @@
       base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error);
   EXPECT_EQ(base::FilePath(), drive_file_path);
 
@@ -458,7 +458,7 @@
       base::FilePath::FromUTF8Unsafe("drive/root"),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/root/file8"),
             drive_file_path);
@@ -469,7 +469,7 @@
       base::FilePath::FromUTF8Unsafe("drive/root/dir2"),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/root/dir2/file8"),
             drive_file_path);
@@ -478,7 +478,7 @@
   resource_metadata_->GetResourceEntryByIdOnUIThread(
       "resource_id:file8",
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 }
 
@@ -493,7 +493,7 @@
       "file11",
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/root/dir2/file11"),
             drive_file_path);
@@ -502,7 +502,7 @@
   resource_metadata_->GetResourceEntryByIdOnUIThread(
       "resource_id:file8",
       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Rename to file7 to force a duplicate name.
@@ -511,7 +511,7 @@
       "file7",
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/root/dir2/file7 (1)"),
             drive_file_path);
@@ -522,7 +522,7 @@
       "file7 (1)",
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_EXISTS, error);
   EXPECT_EQ(base::FilePath(), drive_file_path);
 
@@ -532,7 +532,7 @@
       "file11",
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
   EXPECT_EQ(base::FilePath(), drive_file_path);
 }
@@ -568,7 +568,7 @@
       DirectoryFetchInfo(dir1_proto->resource_id(), kNewChangestamp),
       entry_map,
       google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(kDirectoryPath, file_path);
 
@@ -659,7 +659,7 @@
       DirectoryFetchInfo(dir1_proto->resource_id(), kNewChangestamp),
       entry_map,
       google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(kDirectoryPath, file_path);
 
@@ -754,7 +754,7 @@
       DirectoryFetchInfo(dir1_proto->resource_id(), kNewChangestamp),
       entry_map,
       google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(kDirectoryPath, file_path);
 
@@ -775,7 +775,7 @@
       file_entry,
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file100"),
             drive_file_path);
@@ -786,7 +786,7 @@
       dir_entry,
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
   EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir101"),
             drive_file_path);
@@ -797,7 +797,7 @@
       file_entry3,
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
 
   // Add an existing file.
@@ -805,7 +805,7 @@
       file_entry,
       google_apis::test_util::CreateCopyResultCallback(
           &error, &drive_file_path));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_EXISTS, error);
 }
 
@@ -821,7 +821,7 @@
   FileError error = FILE_ERROR_FAILED;
   resource_metadata_->ResetOnUIThread(
       google_apis::test_util::CreateCopyResultCallback(&error));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   base::FilePath drive_file_path;
@@ -831,7 +831,7 @@
   int64 changestamp = -1;
   resource_metadata_->GetLargestChangestampOnUIThread(
       google_apis::test_util::CreateCopyResultCallback(&changestamp));
-  google_apis::test_util::RunBlockingPoolTask();
+  test_util::RunBlockingPoolTask();
   EXPECT_EQ(0, changestamp);
 
   // root should continue to exist.
@@ -859,7 +859,7 @@
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
 
     metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.path(), base::MessageLoopProxy::current()));
+        temp_dir_.path(), base::MessageLoopProxy::current().get()));
     ASSERT_TRUE(metadata_storage_->Initialize());
 
     resource_metadata_.reset(new ResourceMetadata(
diff --git a/chrome/browser/chromeos/drive/search_metadata.cc b/chrome/browser/chromeos/drive/search_metadata.cc
index b0824f9..6623d2e 100644
--- a/chrome/browser/chromeos/drive/search_metadata.cc
+++ b/chrome/browser/chromeos/drive/search_metadata.cc
@@ -8,7 +8,8 @@
 #include <queue>
 
 #include "base/bind.h"
-#include "base/strings/string_util.h"
+#include "base/i18n/string_search.h"
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/drive/file_cache.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "content/public/browser/browser_thread.h"
@@ -116,10 +117,12 @@
 
 // Used to implement SearchMetadata.
 // Adds entry to the result when appropriate.
+// In particular, if |query| is non-null, only adds files with the name matching
+// the query.
 void MaybeAddEntryToResult(
     ResourceMetadata* resource_metadata,
     FileCache* cache,
-    const std::string& query,
+    base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents* query,
     int options,
     size_t at_most_num_matches,
     ScopedPriorityQueue<MetadataSearchResult,
@@ -139,7 +142,7 @@
   // contain |query| to match the query.
   std::string highlighted;
   if (!IsEligibleEntry(entry, cache, options) ||
-      !FindAndHighlight(entry.base_name(), query, &highlighted))
+      (query && !FindAndHighlight(entry.base_name(), query, &highlighted)))
     return;
 
   base::FilePath path = resource_metadata->GetFilePath(entry.resource_id());
@@ -156,16 +159,22 @@
 scoped_ptr<MetadataSearchResultVector> SearchMetadataOnBlockingPool(
     ResourceMetadata* resource_metadata,
     FileCache* cache,
-    const std::string& query,
+    const std::string& query_text,
     int options,
     int at_most_num_matches) {
   ScopedPriorityQueue<MetadataSearchResult,
                       MetadataSearchResultComparator> result_candidates;
 
+  // Prepare data structure for searching.
+  base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents query(
+      base::UTF8ToUTF16(query_text));
+
   // Iterate over entries.
   scoped_ptr<ResourceMetadata::Iterator> it = resource_metadata->GetIterator();
   for (; !it->IsAtEnd(); it->Advance()) {
-    MaybeAddEntryToResult(resource_metadata, cache, query, options,
+    MaybeAddEntryToResult(resource_metadata, cache,
+                          query_text.empty() ? NULL : &query,
+                          options,
                           at_most_num_matches, &result_candidates, it->Get());
   }
 
@@ -208,31 +217,28 @@
                                    base::Bind(callback, FILE_ERROR_OK));
 }
 
-bool FindAndHighlight(const std::string& text,
-                      const std::string& query,
-                      std::string* highlighted_text) {
+bool FindAndHighlight(
+    const std::string& text,
+    base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents* query,
+    std::string* highlighted_text) {
+  DCHECK(query);
   DCHECK(highlighted_text);
   highlighted_text->clear();
 
-  // For empty query, any filename matches with no highlighted text.
-  if (query.empty())
-    return true;
-
-  // TODO(kinaba): Should support non-ASCII characters.
-  std::string lower_text = StringToLowerASCII(text);
-  std::string lower_query = StringToLowerASCII(query);
-  std::string::size_type match_start = lower_text.find(lower_query);
-  if (match_start == std::string::npos)
+  string16 text16 = base::UTF8ToUTF16(text);
+  size_t match_start = 0;
+  size_t match_length = 0;
+  if (!query->Search(text16, &match_start, &match_length))
     return false;
 
-  std::string pre = text.substr(0, match_start);
-  std::string match = text.substr(match_start, query.size());
-  std::string post = text.substr(match_start + query.size());
-  highlighted_text->append(net::EscapeForHTML(pre));
+  string16 pre = text16.substr(0, match_start);
+  string16 match = text16.substr(match_start, match_length);
+  string16 post = text16.substr(match_start + match_length);
+  highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(pre)));
   highlighted_text->append("<b>");
-  highlighted_text->append(net::EscapeForHTML(match));
+  highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(match)));
   highlighted_text->append("</b>");
-  highlighted_text->append(net::EscapeForHTML(post));
+  highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(post)));
   return true;
 }
 
diff --git a/chrome/browser/chromeos/drive/search_metadata.h b/chrome/browser/chromeos/drive/search_metadata.h
index e250a09..d4e0e6f 100644
--- a/chrome/browser/chromeos/drive/search_metadata.h
+++ b/chrome/browser/chromeos/drive/search_metadata.h
@@ -9,6 +9,12 @@
 
 #include "chrome/browser/chromeos/drive/file_system_interface.h"
 
+namespace base {
+namespace i18n {
+class FixedPatternStringSearchIgnoringCaseAndAccents;
+}  // namespace i18n
+}  // namespace base
+
 namespace drive {
 namespace internal {
 
@@ -38,9 +44,10 @@
 // text with matched portions highlighted with <b> tag (only the first match
 // is highlighted). Meta characters are escaped like &lt;. The original
 // contents of |highlighted_text| will be lost.
-bool FindAndHighlight(const std::string& text,
-                      const std::string& query,
-                      std::string* highlighted_text);
+bool FindAndHighlight(
+    const std::string& text,
+    base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents* query,
+    std::string* highlighted_text);
 
 }  // namespace internal
 }  // namespace drive
diff --git a/chrome/browser/chromeos/drive/search_metadata_unittest.cc b/chrome/browser/chromeos/drive/search_metadata_unittest.cc
index 645ccb5..1c9c3d4 100644
--- a/chrome/browser/chromeos/drive/search_metadata_unittest.cc
+++ b/chrome/browser/chromeos/drive/search_metadata_unittest.cc
@@ -5,9 +5,11 @@
 #include "chrome/browser/chromeos/drive/search_metadata.h"
 
 #include "base/files/scoped_temp_dir.h"
+#include "base/i18n/string_search.h"
 #include "base/message_loop/message_loop_proxy.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/drive/fake_free_disk_space_getter.h"
 #include "chrome/browser/chromeos/drive/file_cache.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
@@ -23,6 +25,17 @@
 const int kDefaultAtMostNumMatches = 10;
 const int64 kCacheEntriesLastAccessedTimeBase = 100;
 
+// A simple wrapper for testing FindAndHighlightWrapper(). It just converts the
+// query text parameter to FixedPatternStringSearchIgnoringCaseAndAccents.
+bool FindAndHighlightWrapper(
+    const std::string& text,
+    const std::string& query_text,
+    std::string* highlighted_text) {
+  base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents query(
+      base::UTF8ToUTF16(query_text));
+  return FindAndHighlight(text, &query, highlighted_text);
+}
+
 // Generator of sequential fake data for ResourceEntry.
 class MetadataInfoGenerator {
  public:
@@ -68,12 +81,12 @@
     fake_free_disk_space_getter_.reset(new FakeFreeDiskSpaceGetter);
 
     metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.path(), base::MessageLoopProxy::current()));
+        temp_dir_.path(), base::MessageLoopProxy::current().get()));
     ASSERT_TRUE(metadata_storage_->Initialize());
 
     cache_.reset(new FileCache(metadata_storage_.get(),
                                temp_dir_.path(),
-                               base::MessageLoopProxy::current(),
+                               base::MessageLoopProxy::current().get(),
                                fake_free_disk_space_getter_.get()));
     ASSERT_TRUE(cache_->Initialize());
 
@@ -237,8 +250,8 @@
             result->at(0).path.AsUTF8Unsafe());
 }
 
-// This test checks if |FindAndHighlight| does case-insensitive search.
-// Tricker test cases for |FindAndHighlight| can be found below.
+// This test checks if |FindAndHighlightWrapper| does case-insensitive search.
+// Tricker test cases for |FindAndHighlightWrapper| can be found below.
 TEST_F(SearchMetadataTest, SearchMetadata_CaseInsensitiveSearch) {
   FileError error = FILE_ERROR_FAILED;
   scoped_ptr<MetadataSearchResultVector> result;
@@ -501,72 +514,97 @@
 
 TEST(SearchMetadataSimpleTest, FindAndHighlight_ZeroMatches) {
   std::string highlighted_text;
-  EXPECT_FALSE(FindAndHighlight("text", "query", &highlighted_text));
-}
-
-TEST(SearchMetadataSimpleTest, FindAndHighlight_EmptyQuery) {
-  std::string highlighted_text;
-  EXPECT_TRUE(FindAndHighlight("text", "", &highlighted_text));
-  EXPECT_EQ("", highlighted_text);
+  EXPECT_FALSE(FindAndHighlightWrapper("text", "query", &highlighted_text));
 }
 
 TEST(SearchMetadataSimpleTest, FindAndHighlight_EmptyText) {
   std::string highlighted_text;
-  EXPECT_FALSE(FindAndHighlight("", "query", &highlighted_text));
-}
-
-TEST(SearchMetadataSimpleTest, FindAndHighlight_EmptyTextAndQuery) {
-  std::string highlighted_text;
-  EXPECT_TRUE(FindAndHighlight("", "", &highlighted_text));
-  EXPECT_EQ("", highlighted_text);
+  EXPECT_FALSE(FindAndHighlightWrapper("", "query", &highlighted_text));
 }
 
 TEST(SearchMetadataSimpleTest, FindAndHighlight_FullMatch) {
   std::string highlighted_text;
-  EXPECT_TRUE(FindAndHighlight("hello", "hello", &highlighted_text));
+  EXPECT_TRUE(FindAndHighlightWrapper("hello", "hello", &highlighted_text));
   EXPECT_EQ("<b>hello</b>", highlighted_text);
 }
 
 TEST(SearchMetadataSimpleTest, FindAndHighlight_StartWith) {
   std::string highlighted_text;
-  EXPECT_TRUE(FindAndHighlight("hello, world", "hello", &highlighted_text));
+  EXPECT_TRUE(FindAndHighlightWrapper("hello, world", "hello",
+                                     &highlighted_text));
   EXPECT_EQ("<b>hello</b>, world", highlighted_text);
 }
 
 TEST(SearchMetadataSimpleTest, FindAndHighlight_EndWith) {
   std::string highlighted_text;
-  EXPECT_TRUE(FindAndHighlight("hello, world", "world", &highlighted_text));
+  EXPECT_TRUE(FindAndHighlightWrapper("hello, world", "world",
+                                     &highlighted_text));
   EXPECT_EQ("hello, <b>world</b>", highlighted_text);
 }
 
 TEST(SearchMetadataSimpleTest, FindAndHighlight_InTheMiddle) {
   std::string highlighted_text;
-  EXPECT_TRUE(FindAndHighlight("yo hello, world", "hello", &highlighted_text));
+  EXPECT_TRUE(FindAndHighlightWrapper("yo hello, world", "hello",
+                                     &highlighted_text));
   EXPECT_EQ("yo <b>hello</b>, world", highlighted_text);
 }
 
 TEST(SearchMetadataSimpleTest, FindAndHighlight_MultipeMatches) {
   std::string highlighted_text;
-  EXPECT_TRUE(FindAndHighlight("yoyoyoyoy", "yoy", &highlighted_text));
+  EXPECT_TRUE(FindAndHighlightWrapper("yoyoyoyoy", "yoy", &highlighted_text));
   // Only the first match is highlighted.
   EXPECT_EQ("<b>yoy</b>oyoyoy", highlighted_text);
 }
 
 TEST(SearchMetadataSimpleTest, FindAndHighlight_IgnoreCase) {
   std::string highlighted_text;
-  EXPECT_TRUE(FindAndHighlight("HeLLo", "hello", &highlighted_text));
+  EXPECT_TRUE(FindAndHighlightWrapper("HeLLo", "hello", &highlighted_text));
   EXPECT_EQ("<b>HeLLo</b>", highlighted_text);
 }
 
+TEST(SearchMetadataSimpleTest, FindAndHighlight_IgnoreCaseNonASCII) {
+  std::string highlighted_text;
+
+  // Case and accent ignorance in Greek. Find "socra" in "Socra'tes".
+  EXPECT_TRUE(FindAndHighlightWrapper(
+      "\xCE\xA3\xCF\x89\xCE\xBA\xCF\x81\xCE\xAC\xCF\x84\xCE\xB7\xCF\x82",
+      "\xCF\x83\xCF\x89\xCE\xBA\xCF\x81\xCE\xB1", &highlighted_text));
+  EXPECT_EQ(
+      "<b>\xCE\xA3\xCF\x89\xCE\xBA\xCF\x81\xCE\xAC</b>\xCF\x84\xCE\xB7\xCF\x82",
+      highlighted_text);
+
+  // In Japanese characters.
+  // Find Hiragana "pi" + "(small)ya" in Katakana "hi" + semi-voiced-mark + "ya"
+  EXPECT_TRUE(FindAndHighlightWrapper(
+      "\xE3\x81\xB2\xE3\x82\x9A\xE3\x82\x83\xE3\x83\xBC",
+      "\xE3\x83\x94\xE3\x83\xA4",
+      &highlighted_text));
+  EXPECT_EQ(
+      "<b>\xE3\x81\xB2\xE3\x82\x9A\xE3\x82\x83</b>\xE3\x83\xBC",
+      highlighted_text);
+}
+
+TEST(SearchMetadataSimpleTest, MultiTextBySingleQuery) {
+  base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents query(
+      base::UTF8ToUTF16("hello"));
+
+  std::string highlighted_text;
+  EXPECT_TRUE(FindAndHighlight("hello", &query, &highlighted_text));
+  EXPECT_EQ("<b>hello</b>", highlighted_text);
+  EXPECT_FALSE(FindAndHighlight("goodbye", &query, &highlighted_text));
+  EXPECT_TRUE(FindAndHighlight("1hello2", &query, &highlighted_text));
+  EXPECT_EQ("1<b>hello</b>2", highlighted_text);
+}
+
 TEST(SearchMetadataSimpleTest, FindAndHighlight_MetaChars) {
   std::string highlighted_text;
-  EXPECT_TRUE(FindAndHighlight("<hello>", "hello", &highlighted_text));
+  EXPECT_TRUE(FindAndHighlightWrapper("<hello>", "hello", &highlighted_text));
   EXPECT_EQ("&lt;<b>hello</b>&gt;", highlighted_text);
 }
 
 TEST(SearchMetadataSimpleTest, FindAndHighlight_MoreMetaChars) {
   std::string highlighted_text;
-  EXPECT_TRUE(FindAndHighlight("a&b&c&d", "b&c", &highlighted_text));
+  EXPECT_TRUE(FindAndHighlightWrapper("a&b&c&d", "b&c", &highlighted_text));
   EXPECT_EQ("a&amp;<b>b&amp;c</b>&amp;d", highlighted_text);
 }
 
diff --git a/chrome/browser/chromeos/drive/sync_client_unittest.cc b/chrome/browser/chromeos/drive/sync_client_unittest.cc
index ec76076..de42956 100644
--- a/chrome/browser/chromeos/drive/sync_client_unittest.cc
+++ b/chrome/browser/chromeos/drive/sync_client_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/prefs/testing_pref_service.h"
 #include "base/run_loop.h"
 #include "base/test/test_timeouts.h"
 #include "chrome/browser/chromeos/drive/change_list_loader.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/chromeos/drive/test_util.h"
 #include "chrome/browser/drive/fake_drive_service.h"
 #include "chrome/browser/google_apis/test_util.h"
-#include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -85,7 +85,8 @@
   virtual void SetUp() OVERRIDE {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
 
-    profile_.reset(new TestingProfile);
+    pref_service_.reset(new TestingPrefServiceSimple);
+    test_util::RegisterDrivePrefs(pref_service_->registry());
 
     fake_network_change_notifier_.reset(
         new test_util::FakeNetworkChangeNotifier);
@@ -95,11 +96,12 @@
     drive_service_->LoadAccountMetadataForWapi(
         "gdata/account_metadata.json");
 
-    scheduler_.reset(new JobScheduler(profile_.get(), drive_service_.get(),
-                                      base::MessageLoopProxy::current()));
+    scheduler_.reset(new JobScheduler(pref_service_.get(),
+                                      drive_service_.get(),
+                                      base::MessageLoopProxy::current().get()));
 
     metadata_storage_.reset(new ResourceMetadataStorage(
-        temp_dir_.path(), base::MessageLoopProxy::current()));
+        temp_dir_.path(), base::MessageLoopProxy::current().get()));
     ASSERT_TRUE(metadata_storage_->Initialize());
 
     metadata_.reset(new internal::ResourceMetadata(
@@ -108,13 +110,13 @@
 
     cache_.reset(new FileCache(metadata_storage_.get(),
                                temp_dir_.path(),
-                               base::MessageLoopProxy::current(),
+                               base::MessageLoopProxy::current().get(),
                                NULL /* free_disk_space_getter */));
     ASSERT_TRUE(cache_->Initialize());
 
     ASSERT_NO_FATAL_FAILURE(SetUpTestData());
 
-    sync_client_.reset(new SyncClient(base::MessageLoopProxy::current(),
+    sync_client_.reset(new SyncClient(base::MessageLoopProxy::current().get(),
                                       &observer_,
                                       scheduler_.get(),
                                       metadata_.get(),
@@ -182,7 +184,9 @@
     // Load data from the service to the metadata.
     FileError error = FILE_ERROR_FAILED;
     internal::ChangeListLoader change_list_loader(
-        base::MessageLoopProxy::current(), metadata_.get(), scheduler_.get());
+        base::MessageLoopProxy::current().get(),
+        metadata_.get(),
+        scheduler_.get());
     change_list_loader.LoadIfNeeded(
         DirectoryFetchInfo(),
         google_apis::test_util::CreateCopyResultCallback(&error));
@@ -193,7 +197,7 @@
  protected:
   content::TestBrowserThreadBundle thread_bundle_;
   base::ScopedTempDir temp_dir_;
-  scoped_ptr<TestingProfile> profile_;
+  scoped_ptr<TestingPrefServiceSimple> pref_service_;
   scoped_ptr<test_util::FakeNetworkChangeNotifier>
       fake_network_change_notifier_;
   scoped_ptr<SyncClientTestDriveService> drive_service_;
diff --git a/chrome/browser/chromeos/drive/test_util.cc b/chrome/browser/chromeos/drive/test_util.cc
index 8caaa31..947150b 100644
--- a/chrome/browser/chromeos/drive/test_util.cc
+++ b/chrome/browser/chromeos/drive/test_util.cc
@@ -9,12 +9,57 @@
 #include "base/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/message_loop.h"
+#include "base/pending_task.h"
+#include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/testing_pref_service.h"
+#include "base/run_loop.h"
+#include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/chromeos/drive/drive.pb.h"
+#include "chrome/common/pref_names.h"
+#include "content/public/browser/browser_thread.h"
 
 namespace drive {
 
 namespace test_util {
 
+namespace {
+
+// This class is used to monitor if any task is posted to a message loop.
+class TaskObserver : public base::MessageLoop::TaskObserver {
+ public:
+  TaskObserver() : posted_(false) {}
+  virtual ~TaskObserver() {}
+
+  // MessageLoop::TaskObserver overrides.
+  virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE {
+  }
+  virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {
+    posted_ = true;
+  }
+
+  // Returns true if any task was posted.
+  bool posted() const { return posted_; }
+
+ private:
+  bool posted_;
+  DISALLOW_COPY_AND_ASSIGN(TaskObserver);
+};
+
+}  // namespace
+
+void RunBlockingPoolTask() {
+  while (true) {
+    content::BrowserThread::GetBlockingPool()->FlushForTesting();
+
+    TaskObserver task_observer;
+    base::MessageLoop::current()->AddTaskObserver(&task_observer);
+    base::RunLoop().RunUntilIdle();
+    base::MessageLoop::current()->RemoveTaskObserver(&task_observer);
+    if (!task_observer.posted())
+      break;
+  }
+}
+
 TestCacheResource::TestCacheResource(const std::string& source_file,
                                      const std::string& resource_id,
                                      const std::string& md5,
@@ -94,7 +139,7 @@
           source_path,
           internal::FileCache::FILE_OPERATION_COPY,
           google_apis::test_util::CreateCopyResultCallback(&error));
-      google_apis::test_util::RunBlockingPoolTask();
+      test_util::RunBlockingPoolTask();
       if (error != FILE_ERROR_OK)
         return false;
     }
@@ -104,7 +149,7 @@
       cache->PinOnUIThread(
           resources[i].resource_id,
           google_apis::test_util::CreateCopyResultCallback(&error));
-      google_apis::test_util::RunBlockingPoolTask();
+      test_util::RunBlockingPoolTask();
       if (error != FILE_ERROR_OK)
         return false;
     }
@@ -115,7 +160,7 @@
           resources[i].resource_id,
           resources[i].md5,
           google_apis::test_util::CreateCopyResultCallback(&error));
-      google_apis::test_util::RunBlockingPoolTask();
+      test_util::RunBlockingPoolTask();
       if (error != FILE_ERROR_OK)
         return false;
     }
@@ -123,6 +168,18 @@
   return true;
 }
 
+void RegisterDrivePrefs(PrefRegistrySimple* pref_registry) {
+  pref_registry->RegisterBooleanPref(
+      prefs::kDisableDrive,
+      false);
+  pref_registry->RegisterBooleanPref(
+      prefs::kDisableDriveOverCellular,
+      true);
+  pref_registry->RegisterBooleanPref(
+      prefs::kDisableDriveHostedFiles,
+      false);
+}
+
 FakeNetworkChangeNotifier::FakeNetworkChangeNotifier()
     : type_(CONNECTION_WIFI) {
 }
diff --git a/chrome/browser/chromeos/drive/test_util.h b/chrome/browser/chromeos/drive/test_util.h
index 823ffd7..99fe567 100644
--- a/chrome/browser/chromeos/drive/test_util.h
+++ b/chrome/browser/chromeos/drive/test_util.h
@@ -15,6 +15,8 @@
 #include "net/base/network_change_notifier.h"
 #include "net/base/test_completion_callback.h"
 
+class PrefRegistrySimple;
+
 namespace net {
 class IOBuffer;
 }  // namespace net
@@ -26,6 +28,15 @@
 // Disk space size used by FakeFreeDiskSpaceGetter.
 const int64 kLotsOfSpace = internal::kMinFreeSpace * 10;
 
+// Runs a task posted to the blocking pool, including subsequent tasks posted
+// to the UI message loop and the blocking pool.
+//
+// A task is often posted to the blocking pool with PostTaskAndReply(). In
+// that case, a task is posted back to the UI message loop, which can again
+// post a task to the blocking pool. This function processes these tasks
+// repeatedly.
+void RunBlockingPoolTask();
+
 // Test data type of file cache
 struct TestCacheResource {
   TestCacheResource(const std::string& source_file,
@@ -53,7 +64,7 @@
   void operator()(T* object) const {
     if (object) {
       object->Destroy();
-      google_apis::test_util::RunBlockingPoolTask();  // Finish destruction.
+      test_util::RunBlockingPoolTask();  // Finish destruction.
     }
   }
 };
@@ -82,6 +93,11 @@
     internal::FileCache* cache,
     const std::vector<TestCacheResource>& resources);
 
+// Registers Drive related preferences in |pref_registry|. Drive related
+// preferences should be registered as TestingPrefServiceSimple will crash if
+// unregistered prefrence is referenced.
+void RegisterDrivePrefs(PrefRegistrySimple* pref_registry);
+
 // Fake NetworkChangeNotifier implementation.
 class FakeNetworkChangeNotifier : public net::NetworkChangeNotifier {
  public:
diff --git a/chrome/browser/chromeos/drive/webkit_file_stream_reader_impl_unittest.cc b/chrome/browser/chromeos/drive/webkit_file_stream_reader_impl_unittest.cc
index 1392ac5..e453b35 100644
--- a/chrome/browser/chromeos/drive/webkit_file_stream_reader_impl_unittest.cc
+++ b/chrome/browser/chromeos/drive/webkit_file_stream_reader_impl_unittest.cc
@@ -73,13 +73,12 @@
   const base::FilePath kDriveFile =
       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
 
-  scoped_ptr<WebkitFileStreamReaderImpl> reader(
-      new WebkitFileStreamReaderImpl(
-          GetFileSystemGetter(),
-          worker_thread_->message_loop_proxy(),
-          kDriveFile,
-          0,  // offset
-          base::Time()));  // expected modification time
+  scoped_ptr<WebkitFileStreamReaderImpl> reader(new WebkitFileStreamReaderImpl(
+      GetFileSystemGetter(),
+      worker_thread_->message_loop_proxy().get(),
+      kDriveFile,
+      0,               // offset
+      base::Time()));  // expected modification time
 
   std::string content;
   ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &content));
@@ -94,13 +93,12 @@
   const base::FilePath kDriveFile =
       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
 
-  scoped_ptr<WebkitFileStreamReaderImpl> reader(
-      new WebkitFileStreamReaderImpl(
-          GetFileSystemGetter(),
-          worker_thread_->message_loop_proxy(),
-          kDriveFile,
-          0,  // offset
-          base::Time()));  // expected modification time
+  scoped_ptr<WebkitFileStreamReaderImpl> reader(new WebkitFileStreamReaderImpl(
+      GetFileSystemGetter(),
+      worker_thread_->message_loop_proxy().get(),
+      kDriveFile,
+      0,               // offset
+      base::Time()));  // expected modification time
 
   net::TestInt64CompletionCallback callback;
   int64 length = reader->GetLength(callback.callback());
@@ -116,13 +114,12 @@
       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
   const int kOffset = 5;
 
-  scoped_ptr<WebkitFileStreamReaderImpl> reader(
-      new WebkitFileStreamReaderImpl(
-          GetFileSystemGetter(),
-          worker_thread_->message_loop_proxy(),
-          kDriveFile,
-          kOffset,
-          base::Time()));  // expected modification time
+  scoped_ptr<WebkitFileStreamReaderImpl> reader(new WebkitFileStreamReaderImpl(
+      GetFileSystemGetter(),
+      worker_thread_->message_loop_proxy().get(),
+      kDriveFile,
+      kOffset,
+      base::Time()));  // expected modification time
 
   std::string content;
   ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &content));
@@ -137,13 +134,12 @@
   const base::FilePath kDriveFile =
       util::GetDriveMyDriveRootPath().AppendASCII("non-existing.txt");
 
-  scoped_ptr<WebkitFileStreamReaderImpl> reader(
-      new WebkitFileStreamReaderImpl(
-          GetFileSystemGetter(),
-          worker_thread_->message_loop_proxy(),
-          kDriveFile,
-          0,  // offset
-          base::Time()));  // expected modification time
+  scoped_ptr<WebkitFileStreamReaderImpl> reader(new WebkitFileStreamReaderImpl(
+      GetFileSystemGetter(),
+      worker_thread_->message_loop_proxy().get(),
+      kDriveFile,
+      0,               // offset
+      base::Time()));  // expected modification time
 
   const int kBufferSize = 10;
   scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(kBufferSize));
@@ -157,13 +153,12 @@
   const base::FilePath kDriveFile =
       util::GetDriveMyDriveRootPath().AppendASCII("non-existing.txt");
 
-  scoped_ptr<WebkitFileStreamReaderImpl> reader(
-      new WebkitFileStreamReaderImpl(
-          GetFileSystemGetter(),
-          worker_thread_->message_loop_proxy(),
-          kDriveFile,
-          0,  // offset
-          base::Time()));  // expected modification time
+  scoped_ptr<WebkitFileStreamReaderImpl> reader(new WebkitFileStreamReaderImpl(
+      GetFileSystemGetter(),
+      worker_thread_->message_loop_proxy().get(),
+      kDriveFile,
+      0,               // offset
+      base::Time()));  // expected modification time
 
   net::TestInt64CompletionCallback callback;
   int64 result = reader->GetLength(callback.callback());
@@ -179,12 +174,11 @@
   ASSERT_TRUE(google_apis::util::GetTimeFromString(
       "2011-12-14T00:40:47.330Z", &expected_modification_time));
   scoped_ptr<WebkitFileStreamReaderImpl> reader(
-      new WebkitFileStreamReaderImpl(
-          GetFileSystemGetter(),
-          worker_thread_->message_loop_proxy(),
-          kDriveFile,
-          0,  // offset
-          expected_modification_time));
+      new WebkitFileStreamReaderImpl(GetFileSystemGetter(),
+                                     worker_thread_->message_loop_proxy().get(),
+                                     kDriveFile,
+                                     0,  // offset
+                                     expected_modification_time));
 
   net::TestInt64CompletionCallback callback;
   int64 result = reader->GetLength(callback.callback());
@@ -200,12 +194,11 @@
       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
 
   scoped_ptr<WebkitFileStreamReaderImpl> reader(
-      new WebkitFileStreamReaderImpl(
-          GetFileSystemGetter(),
-          worker_thread_->message_loop_proxy(),
-          kDriveFile,
-          0,  // offset
-          base::Time::FromInternalValue(1)));
+      new WebkitFileStreamReaderImpl(GetFileSystemGetter(),
+                                     worker_thread_->message_loop_proxy().get(),
+                                     kDriveFile,
+                                     0,  // offset
+                                     base::Time::FromInternalValue(1)));
 
   net::TestInt64CompletionCallback callback;
   int64 result = reader->GetLength(callback.callback());
diff --git a/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.cc b/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.cc
new file mode 100644
index 0000000..87a54fd
--- /dev/null
+++ b/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.cc
@@ -0,0 +1,132 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.h"
+
+#include "base/callback_helpers.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "webkit/browser/blob/local_file_stream_reader.h"
+#include "webkit/browser/fileapi/local_file_stream_writer.h"
+#include "webkit/browser/fileapi/remote_file_system_proxy.h"
+#include "webkit/common/blob/shareable_file_reference.h"
+
+namespace drive {
+namespace internal {
+
+WebkitFileStreamWriterImpl::WebkitFileStreamWriterImpl(
+    const scoped_refptr<fileapi::RemoteFileSystemProxyInterface>&
+        remote_filesystem,
+    const fileapi::FileSystemURL& url,
+    int64 offset,
+    base::TaskRunner* local_task_runner)
+    : remote_filesystem_(remote_filesystem),
+      local_task_runner_(local_task_runner),
+      url_(url),
+      initial_offset_(offset),
+      has_pending_create_snapshot_(false),
+      weak_ptr_factory_(this) {
+}
+
+WebkitFileStreamWriterImpl::~WebkitFileStreamWriterImpl() {
+}
+
+int WebkitFileStreamWriterImpl::Write(net::IOBuffer* buf,
+                                      int buf_len,
+                                      const net::CompletionCallback& callback) {
+  DCHECK(!has_pending_create_snapshot_);
+  DCHECK(pending_cancel_callback_.is_null());
+
+  // If the local file is already available, just delegate to it.
+  if (local_file_writer_)
+    return local_file_writer_->Write(buf, buf_len, callback);
+
+  // In this WebkitFileStreamWriterImpl, we only create snapshot file and don't
+  // have explicit close operation. This is ok, because close is automatically
+  // triggered by a refcounted |file_ref_| passed to
+  // WriteAfterCreateWritableSnapshotFile, from the destructor of
+  // WebkitFileStreamWriterImpl.
+  has_pending_create_snapshot_ = true;
+  remote_filesystem_->CreateWritableSnapshotFile(
+      url_,
+      base::Bind(
+          &WebkitFileStreamWriterImpl::WriteAfterCreateWritableSnapshotFile,
+          weak_ptr_factory_.GetWeakPtr(),
+          make_scoped_refptr(buf),
+          buf_len,
+          callback));
+  return net::ERR_IO_PENDING;
+}
+
+int WebkitFileStreamWriterImpl::Cancel(
+    const net::CompletionCallback& callback) {
+  DCHECK(!callback.is_null());
+  DCHECK(pending_cancel_callback_.is_null());
+
+  // If LocalFileWriter is already created, just delegate the cancel to it.
+  if (local_file_writer_)
+    return local_file_writer_->Cancel(callback);
+
+  // If file open operation is in-flight, wait for its completion and cancel
+  // further write operation in WriteAfterCreateWritableSnapshotFile.
+  if (has_pending_create_snapshot_) {
+    pending_cancel_callback_ = callback;
+    return net::ERR_IO_PENDING;
+  }
+
+  // Write() is not called yet.
+  return net::ERR_UNEXPECTED;
+}
+
+int WebkitFileStreamWriterImpl::Flush(const net::CompletionCallback& callback) {
+  DCHECK(!callback.is_null());
+  DCHECK(pending_cancel_callback_.is_null());
+
+  // If LocalFileWriter is already created, just delegate to it.
+  if (local_file_writer_)
+    return local_file_writer_->Flush(callback);
+
+  // There shouldn't be in-flight Write operation.
+  DCHECK(!has_pending_create_snapshot_);
+
+  // Here is the case Flush() is called before any Write() invocation.
+  // Do nothing.
+  // Synchronization to the remote server is not done until the file is closed.
+  return net::OK;
+}
+
+void WebkitFileStreamWriterImpl::WriteAfterCreateWritableSnapshotFile(
+    net::IOBuffer* buf,
+    int buf_len,
+    const net::CompletionCallback& callback,
+    base::PlatformFileError open_result,
+    const base::FilePath& local_path,
+    const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
+  has_pending_create_snapshot_ = false;
+  if (!pending_cancel_callback_.is_null()) {
+    // Cancel() is called during the creation of the snapshot file.
+    // Don't write to the file.
+    base::ResetAndReturn(&pending_cancel_callback_).Run(net::OK);
+    return;
+  }
+
+  if (open_result != base::PLATFORM_FILE_OK) {
+    callback.Run(net::PlatformFileErrorToNetError(open_result));
+    return;
+  }
+
+  // Hold the reference to the file. Releasing the reference notifies the file
+  // system about to close file.
+  file_ref_ = file_ref;
+
+  DCHECK(!local_file_writer_);
+  local_file_writer_.reset(new fileapi::LocalFileStreamWriter(
+      local_task_runner_.get(), local_path, initial_offset_));
+  int result = local_file_writer_->Write(buf, buf_len, callback);
+  if (result != net::ERR_IO_PENDING)
+    callback.Run(result);
+}
+
+}  // namespace internal
+}  // namespace drive
diff --git a/chrome/browser/chromeos/fileapi/remote_file_stream_writer.h b/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.h
similarity index 72%
rename from chrome/browser/chromeos/fileapi/remote_file_stream_writer.h
rename to chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.h
index c1f3aff..38bfa54 100644
--- a/chrome/browser/chromeos/fileapi/remote_file_stream_writer.h
+++ b/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_CHROMEOS_FILEAPI_REMOTE_FILE_STREAM_WRITER_H_
-#define CHROME_BROWSER_CHROMEOS_FILEAPI_REMOTE_FILE_STREAM_WRITER_H_
+#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_WEBKIT_FILE_STREAM_WRITER_IMPL_H_
+#define CHROME_BROWSER_CHROMEOS_DRIVE_WEBKIT_FILE_STREAM_WRITER_IMPL_H_
 
 #include "base/basictypes.h"
 #include "base/files/file_path.h"
@@ -26,23 +26,24 @@
 class ShareableFileReference;
 }
 
-namespace chromeos {
+namespace drive {
+namespace internal {
 
-// FileStreamWriter interface for writing to a file on remote file system.
-class RemoteFileStreamWriter : public fileapi::FileStreamWriter {
+// The implementation of fileapi::FileStreamWriter for the Drive File System.
+class WebkitFileStreamWriterImpl : public fileapi::FileStreamWriter {
  public:
   // Creates a writer for a file on |remote_filesystem| with path url |url|
   // (like "filesystem:chrome-extension://id/external/drive/...") that
   // starts writing from |offset|. When invalid parameters are set, the first
   // call to Write() method fails.
   // Uses |local_task_runner| for local file operations.
-  RemoteFileStreamWriter(
+  WebkitFileStreamWriterImpl(
       const scoped_refptr<fileapi::RemoteFileSystemProxyInterface>&
           remote_filesystem,
       const fileapi::FileSystemURL& url,
       int64 offset,
       base::TaskRunner* local_task_runner);
-  virtual ~RemoteFileStreamWriter();
+  virtual ~WebkitFileStreamWriterImpl();
 
   // FileWriter override.
   virtual int Write(net::IOBuffer* buf, int buf_len,
@@ -53,15 +54,13 @@
  private:
   // Callback function to do the continuation of the work of the first Write()
   // call, which tries to open the local copy of the file before writing.
-  void OnFileOpened(
+  void WriteAfterCreateWritableSnapshotFile(
       net::IOBuffer* buf,
       int buf_len,
       const net::CompletionCallback& callback,
       base::PlatformFileError open_result,
       const base::FilePath& local_path,
       const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref);
-  // Calls |pending_cancel_callback_|, assuming it is non-null.
-  void InvokePendingCancelCallback(int result);
 
   scoped_refptr<fileapi::RemoteFileSystemProxyInterface> remote_filesystem_;
   scoped_refptr<base::TaskRunner> local_task_runner_;
@@ -72,11 +71,14 @@
   bool has_pending_create_snapshot_;
   net::CompletionCallback pending_cancel_callback_;
 
-  base::WeakPtrFactory<RemoteFileStreamWriter> weak_factory_;
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate the weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<WebkitFileStreamWriterImpl> weak_ptr_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(RemoteFileStreamWriter);
+  DISALLOW_COPY_AND_ASSIGN(WebkitFileStreamWriterImpl);
 };
 
-}  // namespace chromeos
+}  // namespace internal
+}  // namespace drive
 
-#endif  // CHROME_BROWSER_CHROMEOS_FILEAPI_REMOTE_FILE_STREAM_WRITER_H_
+#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_WEBKIT_FILE_STREAM_WRITER_IMPL_H_
diff --git a/chrome/browser/chromeos/enterprise_extension_observer.cc b/chrome/browser/chromeos/enterprise_extension_observer.cc
index f34632e..5ae21c5 100644
--- a/chrome/browser/chromeos/enterprise_extension_observer.cc
+++ b/chrome/browser/chromeos/enterprise_extension_observer.cc
@@ -6,9 +6,8 @@
 
 #include "base/bind.h"
 #include "base/file_util.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager_client.h"
 #include "content/public/browser/browser_thread.h"
@@ -53,7 +52,7 @@
 void EnterpriseExtensionObserver::CheckExtensionAndNotifyEntd(
     const base::FilePath& path) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-  if (file_util::PathExists(
+  if (base::PathExists(
       path.Append(FILE_PATH_LITERAL("isa-cros-policy")))) {
     BrowserThread::PostTask(
         BrowserThread::UI,
diff --git a/chrome/browser/chromeos/extensions/OWNERS b/chrome/browser/chromeos/extensions/OWNERS
index d85d766..6a5847e 100644
--- a/chrome/browser/chromeos/extensions/OWNERS
+++ b/chrome/browser/chromeos/extensions/OWNERS
@@ -1,7 +1,6 @@
 # This should match chrome/browser/extensions/OWNERS
 asargent@chromium.org
 benwells@chromium.org
-erikkay@chromium.org
 finnur@chromium.org
 jyasskin@chromium.org
 kalman@chromium.org
diff --git a/chrome/browser/chromeos/extensions/default_app_order.cc b/chrome/browser/chromeos/extensions/default_app_order.cc
index 4ffc078..ac88f72 100644
--- a/chrome/browser/chromeos/extensions/default_app_order.cc
+++ b/chrome/browser/chromeos/extensions/default_app_order.cc
@@ -27,7 +27,7 @@
 // if the file does not exist or could not be parsed properly. Caller takes
 // ownership of the returned value.
 base::ListValue* ReadExternalOrdinalFile(const base::FilePath& path) {
-  if (!file_util::PathExists(path))
+  if (!base::PathExists(path))
     return NULL;
 
   JSONFileValueSerializer serializer(path);
diff --git a/chrome/browser/chromeos/extensions/default_app_order_unittest.cc b/chrome/browser/chromeos/extensions/default_app_order_unittest.cc
index 7f92499..e89af59 100644
--- a/chrome/browser/chromeos/extensions/default_app_order_unittest.cc
+++ b/chrome/browser/chromeos/extensions/default_app_order_unittest.cc
@@ -100,7 +100,7 @@
 
   base::FilePath none_existent_file =
       scoped_tmp_dir.path().AppendASCII("none_existent_file");
-  ASSERT_FALSE(file_util::PathExists(none_existent_file));
+  ASSERT_FALSE(base::PathExists(none_existent_file));
   SetExternalFile(none_existent_file);
 
   scoped_ptr<default_app_order::ExternalLoader> loader(
diff --git a/chrome/browser/chromeos/extensions/file_manager/external_filesystem_apitest.cc b/chrome/browser/chromeos/extensions/file_manager/external_filesystem_apitest.cc
index ba56fda..1f2a945 100644
--- a/chrome/browser/chromeos/extensions/file_manager/external_filesystem_apitest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/external_filesystem_apitest.cc
@@ -6,6 +6,7 @@
 #include "base/file_util.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
 #include "chrome/browser/chromeos/extensions/file_manager/drive_test_util.h"
 #include "chrome/browser/drive/fake_drive_service.h"
@@ -13,7 +14,6 @@
 #include "chrome/browser/google_apis/test_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/test/test_utils.h"
@@ -290,10 +290,9 @@
 
   // FileSystemExtensionApiTestBase OVERRIDE.
   virtual void InitTestFileSystem() OVERRIDE {
-    // Set up cache root and documents service to be used when creating gdata
-    // system service. This has to be done early on (before the browser is
-    // created) because the system service instance is initialized very early
-    // by FileManagerEventRouter.
+    // Set up cache root to be used by DriveIntegrationService. This has to be
+    // done before the browser is created because the service instance is
+    // initialized by FileManagerEventRouter.
     ASSERT_TRUE(test_cache_root_.CreateUniqueTempDir());
 
     drive::DriveIntegrationServiceFactory::SetFactoryForTest(
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler.cc b/chrome/browser/chromeos/extensions/file_manager/file_browser_handler.cc
deleted file mode 100644
index ed894d3..0000000
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler.cc
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/extensions/file_manager/file_browser_handler.h"
-
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/extension_manifest_constants.h"
-#include "chrome/common/extensions/manifest.h"
-#include "content/public/common/url_constants.h"
-#include "extensions/common/error_utils.h"
-#include "extensions/common/url_pattern.h"
-
-namespace keys = extension_manifest_keys;
-namespace errors = extension_manifest_errors;
-
-namespace {
-
-const char kReadAccessString[] = "read";
-const char kReadWriteAccessString[] = "read-write";
-const char kCreateAccessString[] = "create";
-
-unsigned int kPermissionsNotDefined = 0;
-unsigned int kReadPermission = 1;
-unsigned int kWritePermission = 1 << 1;
-unsigned int kCreatePermission = 1 << 2;
-unsigned int kInvalidPermission = 1 << 3;
-
-unsigned int GetAccessPermissionFlagFromString(const std::string& access_str) {
-  if (access_str == kReadAccessString)
-    return kReadPermission;
-  if (access_str == kReadWriteAccessString)
-    return kReadPermission | kWritePermission;
-  if (access_str == kCreateAccessString)
-    return kCreatePermission;
-  return kInvalidPermission;
-}
-
-// Stored on the Extension.
-struct FileBrowserHandlerInfo : public extensions::Extension::ManifestData {
-  FileBrowserHandler::List file_browser_handlers;
-
-  FileBrowserHandlerInfo();
-  virtual ~FileBrowserHandlerInfo();
-};
-
-FileBrowserHandlerInfo::FileBrowserHandlerInfo() {
-}
-
-FileBrowserHandlerInfo::~FileBrowserHandlerInfo() {
-}
-
-}  // namespace
-
-FileBrowserHandler::FileBrowserHandler()
-    : file_access_permission_flags_(kPermissionsNotDefined) {
-}
-
-FileBrowserHandler::~FileBrowserHandler() {
-}
-
-void FileBrowserHandler::AddPattern(const URLPattern& pattern) {
-  url_set_.AddPattern(pattern);
-}
-
-void FileBrowserHandler::ClearPatterns() {
-  url_set_.ClearPatterns();
-}
-
-bool FileBrowserHandler::MatchesURL(const GURL& url) const {
-  return url_set_.MatchesURL(url);
-}
-
-bool FileBrowserHandler::AddFileAccessPermission(
-    const std::string& access) {
-  file_access_permission_flags_ |= GetAccessPermissionFlagFromString(access);
-  return (file_access_permission_flags_ & kInvalidPermission) != 0U;
-}
-
-bool FileBrowserHandler::ValidateFileAccessPermissions() {
-  bool is_invalid = (file_access_permission_flags_ & kInvalidPermission) != 0U;
-  bool can_create = (file_access_permission_flags_ & kCreatePermission) != 0U;
-  bool can_read_or_write = (file_access_permission_flags_ &
-      (kReadPermission | kWritePermission)) != 0U;
-  if (is_invalid || (can_create && can_read_or_write)) {
-    file_access_permission_flags_ = kInvalidPermission;
-    return false;
-  }
-
-  if (file_access_permission_flags_ == kPermissionsNotDefined)
-    file_access_permission_flags_ = kReadPermission | kWritePermission;
-  return true;
-}
-
-bool FileBrowserHandler::CanRead() const {
-  DCHECK(!(file_access_permission_flags_ & kInvalidPermission));
-  return (file_access_permission_flags_ & kReadPermission) != 0;
-}
-
-bool FileBrowserHandler::CanWrite() const {
-  DCHECK(!(file_access_permission_flags_ & kInvalidPermission));
-  return (file_access_permission_flags_ & kWritePermission) != 0;
-}
-
-bool FileBrowserHandler::HasCreateAccessPermission() const {
-  DCHECK(!(file_access_permission_flags_ & kInvalidPermission));
-  return (file_access_permission_flags_ & kCreatePermission) != 0;
-}
-
-// static
-FileBrowserHandler::List*
-FileBrowserHandler::GetHandlers(const extensions::Extension* extension) {
-  FileBrowserHandlerInfo* info = static_cast<FileBrowserHandlerInfo*>(
-      extension->GetManifestData(keys::kFileBrowserHandlers));
-  if (info)
-    return &info->file_browser_handlers;
-  return NULL;
-}
-
-FileBrowserHandlerParser::FileBrowserHandlerParser() {
-}
-
-FileBrowserHandlerParser::~FileBrowserHandlerParser() {
-}
-
-namespace {
-
-FileBrowserHandler* LoadFileBrowserHandler(
-    const std::string& extension_id,
-    const DictionaryValue* file_browser_handler,
-    string16* error) {
-  scoped_ptr<FileBrowserHandler> result(new FileBrowserHandler());
-  result->set_extension_id(extension_id);
-
-  std::string handler_id;
-  // Read the file action |id| (mandatory).
-  if (!file_browser_handler->HasKey(keys::kPageActionId) ||
-      !file_browser_handler->GetString(keys::kPageActionId, &handler_id)) {
-    *error = ASCIIToUTF16(errors::kInvalidPageActionId);
-    return NULL;
-  }
-  result->set_id(handler_id);
-
-  // Read the page action title from |default_title| (mandatory).
-  std::string title;
-  if (!file_browser_handler->HasKey(keys::kPageActionDefaultTitle) ||
-      !file_browser_handler->GetString(keys::kPageActionDefaultTitle, &title)) {
-    *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle);
-    return NULL;
-  }
-  result->set_title(title);
-
-  // Initialize access permissions (optional).
-  const ListValue* access_list_value = NULL;
-  if (file_browser_handler->HasKey(keys::kFileAccessList)) {
-    if (!file_browser_handler->GetList(keys::kFileAccessList,
-                                       &access_list_value) ||
-        access_list_value->empty()) {
-      *error = ASCIIToUTF16(errors::kInvalidFileAccessList);
-      return NULL;
-    }
-    for (size_t i = 0; i < access_list_value->GetSize(); ++i) {
-      std::string access;
-      if (!access_list_value->GetString(i, &access) ||
-          result->AddFileAccessPermission(access)) {
-        *error = extensions::ErrorUtils::FormatErrorMessageUTF16(
-            errors::kInvalidFileAccessValue, base::IntToString(i));
-        return NULL;
-      }
-    }
-  }
-  if (!result->ValidateFileAccessPermissions()) {
-    *error = ASCIIToUTF16(errors::kInvalidFileAccessList);
-    return NULL;
-  }
-
-  // Initialize file filters (mandatory, unless "create" access is specified,
-  // in which case is ignored). The list can be empty.
-  if (!result->HasCreateAccessPermission()) {
-    const ListValue* file_filters = NULL;
-    if (!file_browser_handler->HasKey(keys::kFileFilters) ||
-        !file_browser_handler->GetList(keys::kFileFilters, &file_filters)) {
-      *error = ASCIIToUTF16(errors::kInvalidFileFiltersList);
-      return NULL;
-    }
-    for (size_t i = 0; i < file_filters->GetSize(); ++i) {
-      std::string filter;
-      if (!file_filters->GetString(i, &filter)) {
-        *error = extensions::ErrorUtils::FormatErrorMessageUTF16(
-            errors::kInvalidFileFilterValue, base::IntToString(i));
-        return NULL;
-      }
-      StringToLowerASCII(&filter);
-      if (!StartsWithASCII(filter,
-                           std::string(chrome::kFileSystemScheme) + ':',
-                           true)) {
-        *error = extensions::ErrorUtils::FormatErrorMessageUTF16(
-            errors::kInvalidURLPatternError, filter);
-        return NULL;
-      }
-      // The user inputs filesystem:*; we don't actually implement scheme
-      // wildcards in URLPattern, so transform to what will match correctly.
-      filter.replace(0, 11, "chrome-extension://*/");
-      URLPattern pattern(URLPattern::SCHEME_EXTENSION);
-      if (pattern.Parse(filter) != URLPattern::PARSE_SUCCESS) {
-        *error = extensions::ErrorUtils::FormatErrorMessageUTF16(
-            errors::kInvalidURLPatternError, filter);
-        return NULL;
-      }
-      std::string path = pattern.path();
-      bool allowed = path == "/*" || path == "/*.*" ||
-          (path.compare(0, 3, "/*.") == 0 &&
-           path.find_first_of('*', 3) == std::string::npos);
-      if (!allowed) {
-        *error = extensions::ErrorUtils::FormatErrorMessageUTF16(
-            errors::kInvalidURLPatternError, filter);
-        return NULL;
-      }
-      result->AddPattern(pattern);
-    }
-  }
-
-  std::string default_icon;
-  // Read the file browser action |default_icon| (optional).
-  if (file_browser_handler->HasKey(keys::kPageActionDefaultIcon)) {
-    if (!file_browser_handler->GetString(
-            keys::kPageActionDefaultIcon, &default_icon) ||
-        default_icon.empty()) {
-      *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath);
-      return NULL;
-    }
-    result->set_icon_path(default_icon);
-  }
-
-  return result.release();
-}
-
-// Loads FileBrowserHandlers from |extension_actions| into a list in |result|.
-bool LoadFileBrowserHandlers(
-    const std::string& extension_id,
-    const ListValue* extension_actions,
-    FileBrowserHandler::List* result,
-    string16* error) {
-  for (ListValue::const_iterator iter = extension_actions->begin();
-       iter != extension_actions->end();
-       ++iter) {
-    if (!(*iter)->IsType(Value::TYPE_DICTIONARY)) {
-      *error = ASCIIToUTF16(errors::kInvalidFileBrowserHandler);
-      return false;
-    }
-    scoped_ptr<FileBrowserHandler> action(
-        LoadFileBrowserHandler(
-            extension_id, reinterpret_cast<DictionaryValue*>(*iter), error));
-    if (!action.get())
-      return false;  // Failed to parse file browser action definition.
-    result->push_back(linked_ptr<FileBrowserHandler>(action.release()));
-  }
-  return true;
-}
-
-}  // namespace
-
-bool FileBrowserHandlerParser::Parse(extensions::Extension* extension,
-                                     string16* error) {
-  const ListValue* file_browser_handlers_value = NULL;
-  if (!extension->manifest()->GetList(keys::kFileBrowserHandlers,
-                                      &file_browser_handlers_value)) {
-    *error = ASCIIToUTF16(errors::kInvalidFileBrowserHandler);
-    return false;
-  }
-  scoped_ptr<FileBrowserHandlerInfo> info(new FileBrowserHandlerInfo);
-  if (!LoadFileBrowserHandlers(extension->id(),
-                               file_browser_handlers_value,
-                               &info->file_browser_handlers,
-                               error)) {
-    return false;  // Failed to parse file browser actions definition.
-  }
-
-  extension->SetManifestData(keys::kFileBrowserHandlers, info.release());
-  return true;
-}
-
-const std::vector<std::string> FileBrowserHandlerParser::Keys() const {
-  return SingleKey(keys::kFileBrowserHandlers);
-}
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler.h b/chrome/browser/chromeos/extensions/file_manager/file_browser_handler.h
deleted file mode 100644
index 7b9169c..0000000
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_BROWSER_HANDLER_H_
-#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_BROWSER_HANDLER_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/manifest_handler.h"
-#include "extensions/common/url_pattern.h"
-#include "extensions/common/url_pattern_set.h"
-
-class GURL;
-class URLPattern;
-
-// FileBrowserHandler encapsulates the state of a file browser action.
-class FileBrowserHandler {
- public:
-  typedef std::vector<linked_ptr<FileBrowserHandler> > List;
-
-  FileBrowserHandler();
-  ~FileBrowserHandler();
-
-  // extension id
-  std::string extension_id() const { return extension_id_; }
-  void set_extension_id(const std::string& extension_id) {
-    extension_id_ = extension_id;
-  }
-
-  // action id
-  const std::string& id() const { return id_; }
-  void set_id(const std::string& id) { id_ = id; }
-
-  // default title
-  const std::string& title() const { return title_; }
-  void set_title(const std::string& title) { title_ = title; }
-
-  // File schema URL patterns.
-  const extensions::URLPatternSet& file_url_patterns() const {
-    return url_set_;
-  }
-  void AddPattern(const URLPattern& pattern);
-  bool MatchesURL(const GURL& url) const;
-  void ClearPatterns();
-
-  // Action icon path.
-  const std::string icon_path() const { return default_icon_path_; }
-  void set_icon_path(const std::string& path) {
-    default_icon_path_ = path;
-  }
-
-  // File access permissions.
-  // Adjusts file_access_permission_flags_ to allow specified permission.
-  bool AddFileAccessPermission(const std::string& permission_str);
-  // Checks that specified file access permissions are valid (all set
-  // permissions are valid and there is no other permission specified with
-  // "create")
-  // If no access permissions were set, initialize them to default value.
-  bool ValidateFileAccessPermissions();
-  // Checks if handler has read access.
-  bool CanRead() const;
-  // Checks if handler has write access.
-  bool CanWrite() const;
-  // Checks if handler has "create" access specified.
-  bool HasCreateAccessPermission() const;
-
-  // Returns the file browser handlers associated with the |extension|.
-  static List* GetHandlers(const extensions::Extension* extension);
-
- private:
-  // The id for the extension this action belongs to (as defined in the
-  // extension manifest).
-  std::string extension_id_;
-  std::string title_;
-  std::string default_icon_path_;
-  // The id for the FileBrowserHandler, for example: "PdfFileAction".
-  std::string id_;
-  unsigned int file_access_permission_flags_;
-
-  // A list of file filters.
-  extensions::URLPatternSet url_set_;
-};
-
-// Parses the "file_browser_handlers" extension manifest key.
-class FileBrowserHandlerParser : public extensions::ManifestHandler {
- public:
-  FileBrowserHandlerParser();
-  virtual ~FileBrowserHandlerParser();
-
-  virtual bool Parse(extensions::Extension* extension,
-                     string16* error) OVERRIDE;
-
- private:
-  virtual const std::vector<std::string> Keys() const OVERRIDE;
-};
-
-#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_BROWSER_HANDLER_H_
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.cc b/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.cc
index cfe538b..09b55ea 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.cc
@@ -21,7 +21,7 @@
 //  - The function grants permissions needed to read/write/create file under the
 //    selected path. To grant permissions to the caller, caller's extension ID
 //    has to be allowed to access the files virtual path (e.g. /Downloads/foo)
-//    in ExternalFileSystemMountPointProvider. Additionally, the callers render
+//    in ExternalFileSystemBackend. Additionally, the callers render
 //    process ID has to be granted read, write and create permissions for the
 //    selected file's full filesystem path (e.g.
 //    /home/chronos/user/Downloads/foo) in ChildProcessSecurityPolicy.
@@ -48,8 +48,8 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/storage_partition.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
+#include "webkit/browser/fileapi/file_system_backend.h"
 #include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/browser/fileapi/file_system_mount_point_provider.h"
 
 using content::BrowserContext;
 using content::BrowserThread;
@@ -367,24 +367,22 @@
 
 void FileBrowserHandlerInternalSelectFileFunction::GrantPermissions() {
   content::SiteInstance* site_instance = render_view_host()->GetSiteInstance();
-  fileapi::ExternalFileSystemMountPointProvider* external_provider =
+  fileapi::ExternalFileSystemBackend* external_backend =
       BrowserContext::GetStoragePartition(profile_, site_instance)->
-      GetFileSystemContext()->external_provider();
-  DCHECK(external_provider);
+      GetFileSystemContext()->external_backend();
+  DCHECK(external_backend);
 
-  external_provider->GetVirtualPath(full_path_, &virtual_path_);
+  external_backend->GetVirtualPath(full_path_, &virtual_path_);
   DCHECK(!virtual_path_.empty());
 
   // Grant access to this particular file to target extension. This will
   // ensure that the target extension can access only this FS entry and
   // prevent from traversing FS hierarchy upward.
-  external_provider->GrantFileAccessToExtension(extension_id(), virtual_path_);
+  external_backend->GrantFileAccessToExtension(extension_id(), virtual_path_);
 
   // Grant access to the selected file to target extensions render view process.
-  content::ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile(
-      render_view_host()->GetProcess()->GetID(),
-      full_path_,
-      file_handler_util::GetReadWritePermissions());
+  content::ChildProcessSecurityPolicy::GetInstance()->GrantCreateReadWriteFile(
+      render_view_host()->GetProcess()->GetID(), full_path_);
 }
 
 void FileBrowserHandlerInternalSelectFileFunction::Respond(bool success) {
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api_test.cc b/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api_test.cc
index 6f827f7..c63e08e 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api_test.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api_test.cc
@@ -264,7 +264,7 @@
       FileBrowserHandlerExtensionTest::TestSelectFileFunctionFactory));
 
   // Selected path should still not exist.
-  ASSERT_FALSE(file_util::PathExists(selected_path));
+  ASSERT_FALSE(base::PathExists(selected_path));
 
   const Extension* extension = LoadExtension(
       test_data_dir_.AppendASCII("file_browser/filehandler_create"));
@@ -281,7 +281,7 @@
 
   // Selected path should have been created by the test extension after the
   // extension function call.
-  ASSERT_TRUE(file_util::PathExists(selected_path));
+  ASSERT_TRUE(base::PathExists(selected_path));
 
   // Let's check that the file has the expected content.
   const std::string expected_contents = "hello from test extension.";
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc b/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc
index fe15db1..c81be45 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc
@@ -29,13 +29,12 @@
 #include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/browser/chromeos/drive/job_list.h"
 #include "chrome/browser/chromeos/drive/logging.h"
-#include "chrome/browser/chromeos/extensions/file_manager/file_browser_handler.h"
 #include "chrome/browser/chromeos/extensions/file_manager/file_browser_private_api_factory.h"
 #include "chrome/browser/chromeos/extensions/file_manager/file_handler_util.h"
 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.h"
 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h"
 #include "chrome/browser/chromeos/extensions/file_manager/zip_file_creator.h"
-#include "chrome/browser/chromeos/fileapi/cros_mount_point_provider.h"
+#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/system/statistics_provider.h"
 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
@@ -50,6 +49,7 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/views/select_file_dialog_extension.h"
 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
+#include "chrome/common/extensions/api/file_browser_handlers/file_browser_handler.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/extension_icon_set.h"
@@ -61,7 +61,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/common/page_zoom.h"
-#include "googleurl/src/gurl.h"
 #include "grit/app_locale_settings.h"
 #include "grit/generated_resources.h"
 #include "net/base/escape.h"
@@ -69,6 +68,7 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/shell_dialogs/selected_file_info.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/gurl.h"
 #include "webkit/browser/fileapi/file_system_context.h"
 #include "webkit/browser/fileapi/file_system_file_util.h"
 #include "webkit/browser/fileapi/file_system_operation_context.h"
@@ -201,14 +201,6 @@
   return mount_info;
 }
 
-// Gives the extension renderer |host| file |permissions| for the given |path|.
-void GrantFilePermissionsToHost(content::RenderViewHost* host,
-                                const base::FilePath& path,
-                                int permissions) {
-  ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile(
-      host->GetProcess()->GetID(), path, permissions);
-}
-
 void SetDriveMountPointPermissions(
     Profile* profile,
     const std::string& extension_id,
@@ -219,22 +211,21 @@
   }
 
   content::SiteInstance* site_instance = render_view_host->GetSiteInstance();
-  fileapi::ExternalFileSystemMountPointProvider* provider =
+  fileapi::ExternalFileSystemBackend* backend =
       BrowserContext::GetStoragePartition(profile, site_instance)->
-      GetFileSystemContext()->external_provider();
-  if (!provider)
+      GetFileSystemContext()->external_backend();
+  if (!backend)
     return;
 
   const base::FilePath mount_point = drive::util::GetDriveMountPointPath();
   // Grant R/W permissions to drive 'folder'. File API layer still
   // expects this to be satisfied.
-  GrantFilePermissionsToHost(render_view_host,
-                             mount_point,
-                             file_handler_util::GetReadWritePermissions());
+  ChildProcessSecurityPolicy::GetInstance()->GrantCreateReadWriteFile(
+      render_view_host->GetProcess()->GetID(), mount_point);
 
   base::FilePath mount_point_virtual;
-  if (provider->GetVirtualPath(mount_point, &mount_point_virtual))
-    provider->GrantFileAccessToExtension(extension_id, mount_point_virtual);
+  if (backend->GetVirtualPath(mount_point, &mount_point_virtual))
+    backend->GrantFileAccessToExtension(extension_id, mount_point_virtual);
 }
 
 // Finds an icon in the list of icons. If unable to find an icon of the exact
@@ -414,8 +405,6 @@
 
 FileBrowserPrivateAPI::FileBrowserPrivateAPI(Profile* profile)
     : event_router_(new FileManagerEventRouter(profile)) {
-  (new FileBrowserHandlerParser)->Register();
-
   ExtensionFunctionRegistry* registry =
       ExtensionFunctionRegistry::GetInstance();
   registry->RegisterFunction<LogoutUserFunction>();
@@ -446,13 +435,12 @@
   registry->RegisterFunction<SearchDriveFunction>();
   registry->RegisterFunction<SearchDriveMetadataFunction>();
   registry->RegisterFunction<ClearDriveCacheFunction>();
-  registry->RegisterFunction<ReloadDriveFunction>();
   registry->RegisterFunction<GetDriveConnectionStateFunction>();
-  registry->RegisterFunction<RequestDirectoryRefreshFunction>();
   registry->RegisterFunction<SetLastModifiedFunction>();
   registry->RegisterFunction<ZipSelectionFunction>();
   registry->RegisterFunction<ValidatePathNameLengthFunction>();
   registry->RegisterFunction<ZoomFunction>();
+  registry->RegisterFunction<RequestAccessTokenFunction>();
   event_router_->ObserveFileSystemEvents();
 }
 
@@ -540,21 +528,20 @@
     return false;
   }
 
-  fileapi::ExternalFileSystemMountPointProvider* provider =
-      file_system_context->external_provider();
-  if (!provider)
+  fileapi::ExternalFileSystemBackend* backend =
+      file_system_context->external_backend();
+  if (!backend)
     return false;
 
   // Grant full access to File API from this component extension.
-  provider->GrantFullAccessToExtension(extension_->id());
+  backend->GrantFullAccessToExtension(extension_->id());
 
   // Grant R/W file permissions to the renderer hosting component
-  // extension for all paths exposed by our local file system provider.
-  std::vector<base::FilePath> root_dirs = provider->GetRootDirectories();
+  // extension for all paths exposed by our local file system backend.
+  std::vector<base::FilePath> root_dirs = backend->GetRootDirectories();
   for (size_t i = 0; i < root_dirs.size(); ++i) {
-    ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile(
-        child_id, root_dirs[i],
-        file_handler_util::GetReadWritePermissions());
+    ChildProcessSecurityPolicy::GetInstance()->GrantCreateReadWriteFile(
+        child_id, root_dirs[i]);
   }
   return true;
 }
@@ -815,7 +802,7 @@
   for (ExtensionSet::const_iterator iter = service->extensions()->begin();
        iter != service->extensions()->end();
        ++iter) {
-    const Extension* extension = *iter;
+    const Extension* extension = iter->get();
 
     // We don't support using hosted apps to open files.
     if (!extension->is_platform_app())
@@ -906,7 +893,7 @@
     GURL file_url(file_url_str);
     fileapi::FileSystemURL file_system_url(
         file_system_context->CrackURL(file_url));
-    if (!chromeos::CrosMountPointProvider::CanHandleURL(file_system_url))
+    if (!chromeos::FileSystemBackend::CanHandleURL(file_system_url))
       continue;
 
     file_urls.push_back(file_url);
@@ -1045,7 +1032,7 @@
       return false;
     }
     FileSystemURL url = file_system_context->CrackURL(GURL(file_url_str));
-    if (!chromeos::CrosMountPointProvider::CanHandleURL(url)) {
+    if (!chromeos::FileSystemBackend::CanHandleURL(url)) {
       error_ = kInvalidFileUrl;
       return false;
     }
@@ -1163,7 +1150,7 @@
   const fileapi::FileSystemURL filesystem_url(
       file_system_context->CrackURL(url));
   base::FilePath path;
-  if (!chromeos::CrosMountPointProvider::CanHandleURL(filesystem_url))
+  if (!chromeos::FileSystemBackend::CanHandleURL(filesystem_url))
     return base::FilePath();
   return filesystem_url.path();
 }
@@ -1431,15 +1418,16 @@
       break;
     }
     case chromeos::MOUNT_TYPE_GOOGLE_DRIVE: {
-      const bool success = true;
+      // Dispatch fake 'mounted' event because JS code depends on it.
+      // TODO(hashimoto): Remove this redanduncy.
+      FileBrowserPrivateAPI::Get(profile_)->event_router()->
+          OnFileSystemMounted();
+
       // Pass back the drive mount point path as source path.
       const std::string& drive_path =
           drive::util::GetDriveMountPointPathAsString();
       SetResult(new base::StringValue(drive_path));
-      FileBrowserPrivateAPI::Get(profile_)->event_router()->
-          MountDrive(base::Bind(&AddMountFunction::SendResponse,
-                                this,
-                                success));
+      SendResponse(true);
       break;
     }
     default: {
@@ -1997,6 +1985,10 @@
   SET_STRING("CUT_BUTTON_LABEL", IDS_FILE_BROWSER_CUT_BUTTON_LABEL);
   SET_STRING("ZIP_SELECTION_BUTTON_LABEL",
              IDS_FILE_BROWSER_ZIP_SELECTION_BUTTON_LABEL);
+  SET_STRING("PIN_FOLDER_BUTTON_LABEL",
+             IDS_FILE_BROWSER_PIN_FOLDER_BUTTON_LABEL);
+  SET_STRING("UNPIN_FOLDER_BUTTON_LABEL",
+             IDS_FILE_BROWSER_UNPIN_FOLDER_BUTTON_LABEL);
   SET_STRING("SHARE_BUTTON_LABEL",
              IDS_FILE_BROWSER_SHARE_BUTTON_LABEL);
 
@@ -2064,7 +2056,6 @@
              IDS_FILE_BROWSER_DRIVE_MOBILE_CONNECTION_OPTION);
   SET_STRING("DRIVE_CLEAR_LOCAL_CACHE",
              IDS_FILE_BROWSER_DRIVE_CLEAR_LOCAL_CACHE);
-  SET_STRING("DRIVE_RELOAD", IDS_FILE_BROWSER_DRIVE_RELOAD);
   SET_STRING("DRIVE_SPACE_AVAILABLE_LONG",
              IDS_FILE_BROWSER_DRIVE_SPACE_AVAILABLE_LONG);
   SET_STRING("DRIVE_BUY_MORE_SPACE", IDS_FILE_BROWSER_DRIVE_BUY_MORE_SPACE);
@@ -2250,16 +2241,6 @@
 
   webui::SetFontAndTextDirection(dict);
 
-  drive::DriveIntegrationService* integration_service =
-      drive::DriveIntegrationServiceFactory::GetForProfile(profile_);
-  dict->SetBoolean("ENABLE_GDATA", integration_service != NULL);
-
-#if defined(USE_ASH)
-  dict->SetBoolean("ASH", true);
-#else
-  dict->SetBoolean("ASH", false);
-#endif
-
   std::string board;
   chromeos::system::StatisticsProvider* provider =
       chromeos::system::StatisticsProvider::GetInstance();
@@ -2612,7 +2593,7 @@
       drive::util::IsUnderDriveMountPoint(destination_file);
 
   if (source_file_under_drive && !destination_file_under_drive) {
-    // Transfer a file from gdata to local file system.
+    // Transfer a file from drive to local file system.
     source_file = drive::util::ExtractDrivePath(source_file);
     integration_service->file_system()->TransferFileFromRemoteToLocal(
         source_file,
@@ -2884,19 +2865,6 @@
   return true;
 }
 
-bool ReloadDriveFunction::RunImpl() {
-  // |integration_service| is NULL if Drive is disabled.
-  drive::DriveIntegrationService* integration_service =
-      drive::DriveIntegrationServiceFactory::GetForProfile(profile_);
-  if (!integration_service)
-    return false;
-
-  integration_service->ReloadAndRemountFileSystem();
-
-  SendResponse(true);
-  return true;
-}
-
 bool GetDriveConnectionStateFunction::RunImpl() {
   scoped_ptr<DictionaryValue> value(new DictionaryValue());
   scoped_ptr<ListValue> reasons(new ListValue());
@@ -2935,34 +2903,6 @@
   return true;
 }
 
-bool RequestDirectoryRefreshFunction::RunImpl() {
-  std::string file_url_as_string;
-  if (!args_->GetString(0, &file_url_as_string))
-    return false;
-
-  drive::DriveIntegrationService* integration_service =
-      drive::DriveIntegrationServiceFactory::GetForProfile(profile_);
-  // |integration_service| is NULL if Drive is disabled.
-  if (!integration_service || !integration_service->file_system())
-    return false;
-
-  content::SiteInstance* site_instance = render_view_host()->GetSiteInstance();
-  scoped_refptr<fileapi::FileSystemContext> file_system_context =
-      BrowserContext::GetStoragePartition(profile(), site_instance)->
-          GetFileSystemContext();
-
-  base::FilePath directory_path =
-      drive::util::ExtractDrivePathFromFileSystemUrl(
-          file_system_context->CrackURL(GURL(file_url_as_string)));
-  if (directory_path.empty())
-    return false;
-
-  integration_service->file_system()->RefreshDirectory(
-      directory_path,
-      base::Bind(&drive::util::EmptyFileOperationCallback));
-  return true;
-}
-
 ZipSelectionFunction::ZipSelectionFunction() {
 }
 
@@ -3056,7 +2996,7 @@
           GetFileSystemContext();
   fileapi::FileSystemURL filesystem_url(
       file_system_context->CrackURL(GURL(parent_url)));
-  if (!chromeos::CrosMountPointProvider::CanHandleURL(filesystem_url))
+  if (!chromeos::FileSystemBackend::CanHandleURL(filesystem_url))
     return false;
 
   // No explicit limit on the length of Drive file names.
@@ -3101,3 +3041,38 @@
   view_host->Zoom(zoom_type);
   return true;
 }
+
+RequestAccessTokenFunction::RequestAccessTokenFunction() {
+}
+
+RequestAccessTokenFunction::~RequestAccessTokenFunction() {
+}
+
+bool RequestAccessTokenFunction::RunImpl() {
+  drive::DriveIntegrationService* integration_service =
+      drive::DriveIntegrationServiceFactory::GetForProfile(profile_);
+  bool refresh;
+  args_->GetBoolean(0, &refresh);
+
+  if (!integration_service) {
+    SetResult(new base::StringValue(""));
+    SendResponse(true);
+    return true;
+  }
+
+  // If refreshing is requested, then clear the token to refetch it.
+  if (refresh)
+    integration_service->drive_service()->ClearAccessToken();
+
+  // Retrieve the cached auth token (if available), otherwise the AuthService
+  // instance will try to refetch it.
+  integration_service->drive_service()->RequestAccessToken(
+      base::Bind(&RequestAccessTokenFunction::OnAccessTokenFetched, this));
+  return true;
+}
+
+void RequestAccessTokenFunction::OnAccessTokenFetched(
+    google_apis::GDataErrorCode code, const std::string& access_token) {
+  SetResult(new base::StringValue(access_token));
+  SendResponse(true);
+}
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h b/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h
index c408946..bf5ff1e 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h
+++ b/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h
@@ -81,7 +81,7 @@
   int32 GetTabId() const;
 
   // Returns the local FilePath associated with |url|. If the file isn't of the
-  // type CrosMountPointProvider handles, returns an empty FilePath.
+  // type FileSystemBackend handles, returns an empty FilePath.
   //
   // Local paths will look like "/home/chronos/user/Downloads/foo/bar.txt" or
   // "/special/drive/foo/bar.txt".
@@ -560,14 +560,14 @@
   void OnPinStateSet(drive::FileError error);
 };
 
-// Get gdata files for the given list of file URLs. Initiate downloading of
-// gdata files if these are not cached. Return a list of local file names.
+// Get drive files for the given list of file URLs. Initiate downloading of
+// drive files if these are not cached. Return a list of local file names.
 // This function puts empty strings instead of local paths for files could
 // not be obtained. For instance, this can happen if the user specifies a new
-// file name to save a file on gdata. There may be other reasons to fail. The
+// file name to save a file on drive. There may be other reasons to fail. The
 // file manager should check if the local paths returned from getDriveFiles()
 // contain empty paths.
-// TODO(satorux): Should we propagate error types to the JavasScript layer?
+// TODO(satorux): Should we propagate error types to the JavaScript layer?
 class GetDriveFilesFunction : public FileBrowserFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.getDriveFiles",
@@ -704,19 +704,6 @@
   virtual bool RunImpl() OVERRIDE;
 };
 
-// Implements the chrome.fileBrowserPrivate.reloadDrive method,
-// which is used to reload the file system metadata from the server.
-class ReloadDriveFunction: public AsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.reloadDrive",
-                             FILEBROWSERPRIVATE_RELOADDRIVE)
-
- protected:
-  virtual ~ReloadDriveFunction() {}
-
-  virtual bool RunImpl() OVERRIDE;
-};
-
 // Implements the chrome.fileBrowserPrivate.getDriveConnectionState method.
 class GetDriveConnectionStateFunction : public SyncExtensionFunction {
  public:
@@ -730,19 +717,6 @@
   virtual bool RunImpl() OVERRIDE;
 };
 
-// Implements the chrome.fileBrowserPrivate.requestDirectoryRefresh method.
-class RequestDirectoryRefreshFunction : public SyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION(
-      "fileBrowserPrivate.requestDirectoryRefresh",
-      FILEBROWSERPRIVATE_REQUESTDIRECTORYREFRESH);
-
- protected:
-  virtual ~RequestDirectoryRefreshFunction() {}
-
-  virtual bool RunImpl() OVERRIDE;
-};
-
 // Create a zip file for the selected files.
 class ZipSelectionFunction : public FileBrowserFunction,
                              public extensions::ZipFileCreator::Observer {
@@ -792,4 +766,23 @@
   virtual bool RunImpl() OVERRIDE;
 };
 
+// Implements the chrome.fileBrowserPrivate.requestAccessToken method.
+class RequestAccessTokenFunction : public AsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.requestAccessToken",
+                             FILEBROWSERPRIVATE_REQUESTACCESSTOKEN)
+
+  RequestAccessTokenFunction();
+
+ protected:
+  virtual ~RequestAccessTokenFunction();
+
+  // AsyncExtensionFunction overrides.
+  virtual bool RunImpl() OVERRIDE;
+
+  // Received the cached auth token (if available) or the fetched one.
+  void OnAccessTokenFetched(google_apis::GDataErrorCode code,
+                            const std::string& access_token);
+};
+
 #endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_BROWSER_PRIVATE_API_H_
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_handler_util.cc b/chrome/browser/chromeos/extensions/file_manager/file_handler_util.cc
index 53815ab..ca94b06 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_handler_util.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_handler_util.cc
@@ -12,9 +12,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/browser/chromeos/drive/file_task_executor.h"
-#include "chrome/browser/chromeos/extensions/file_manager/file_browser_handler.h"
 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h"
-#include "chrome/browser/chromeos/fileapi/cros_mount_point_provider.h"
+#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -27,6 +26,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/host_desktop.h"
+#include "chrome/common/extensions/api/file_browser_handlers/file_browser_handler.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
@@ -62,23 +62,6 @@
 const size_t kDriveTaskExtensionPrefixLength =
     arraysize(kDriveTaskExtensionPrefix) - 1;
 
-const int kReadWriteFilePermissions = base::PLATFORM_FILE_OPEN |
-                                      base::PLATFORM_FILE_CREATE |
-                                      base::PLATFORM_FILE_OPEN_ALWAYS |
-                                      base::PLATFORM_FILE_CREATE_ALWAYS |
-                                      base::PLATFORM_FILE_OPEN_TRUNCATED |
-                                      base::PLATFORM_FILE_READ |
-                                      base::PLATFORM_FILE_WRITE |
-                                      base::PLATFORM_FILE_EXCLUSIVE_READ |
-                                      base::PLATFORM_FILE_EXCLUSIVE_WRITE |
-                                      base::PLATFORM_FILE_ASYNC |
-                                      base::PLATFORM_FILE_WRITE_ATTRIBUTES;
-
-const int kReadOnlyFilePermissions = base::PLATFORM_FILE_OPEN |
-                                     base::PLATFORM_FILE_READ |
-                                     base::PLATFORM_FILE_EXCLUSIVE_READ |
-                                     base::PLATFORM_FILE_ASYNC;
-
 // Returns process id of the process the extension is running in.
 int ExtractProcessFromExtensionId(Profile* profile,
                                   const std::string& extension_id) {
@@ -109,22 +92,6 @@
   return NULL;
 }
 
-unsigned int GetAccessPermissionsForFileBrowserHandler(
-    const Extension* extension,
-    const std::string& action_id) {
-  const FileBrowserHandler* action =
-      FindFileBrowserHandler(extension, action_id);
-  if (!action)
-    return 0;
-  unsigned int result = 0;
-  if (action->CanRead())
-    result |= kReadOnlyFilePermissions;
-  if (action->CanWrite())
-    result |= kReadWriteFilePermissions;
-  // TODO(tbarzic): We don't handle Create yet.
-  return result;
-}
-
 std::string EscapedUtf8ToLower(const std::string& str) {
   string16 utf16 = UTF8ToUTF16(
       net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL));
@@ -148,7 +115,7 @@
   for (ExtensionSet::const_iterator iter = service->extensions()->begin();
        iter != service->extensions()->end();
        ++iter) {
-    const Extension* extension = *iter;
+    const Extension* extension = iter->get();
     if (profile->IsOffTheRecord() &&
         !service->IsIncognitoEnabled(extension->id()))
       continue;
@@ -187,10 +154,10 @@
     const GURL& source_url,
     const std::string& file_browser_id,
     const std::vector<FileSystemURL>& files) {
-  fileapi::ExternalFileSystemMountPointProvider* external_provider =
+  fileapi::ExternalFileSystemBackend* backend =
       GetFileSystemContextForExtension(profile, file_browser_id)->
-      external_provider();
-  if (!external_provider)
+      external_backend();
+  if (!backend)
     return false;
 
   for (size_t i = 0; i < files.size(); ++i) {
@@ -198,8 +165,8 @@
     if (source_url.GetOrigin() != files[i].origin())
       return false;
 
-    if (!chromeos::CrosMountPointProvider::CanHandleURL(files[i]) ||
-        !external_provider->IsAccessAllowed(files[i])) {
+    if (!chromeos::FileSystemBackend::CanHandleURL(files[i]) ||
+        !backend->IsAccessAllowed(files[i])) {
       return false;
     }
   }
@@ -276,14 +243,6 @@
   return task_id;
 }
 
-int GetReadWritePermissions() {
-  return kReadWriteFilePermissions;
-}
-
-int GetReadOnlyPermissions() {
-  return kReadOnlyFilePermissions;
-}
-
 std::string MakeTaskID(const std::string& extension_id,
                        const std::string& task_type,
                        const std::string& action_id) {
@@ -629,8 +588,8 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
   DCHECK(handler_extension.get());
 
-  fileapi::ExternalFileSystemMountPointProvider* external_provider_handler =
-      file_system_context_handler->external_provider();
+  fileapi::ExternalFileSystemBackend* backend =
+      file_system_context_handler->external_backend();
 
   FileDefinitionList file_list;
   for (size_t i = 0; i < file_urls.size(); ++i) {
@@ -648,7 +607,7 @@
     // If the file is under drive mount point, there is no actual file to be
     // found on the url.path().
     if (!is_drive_file) {
-      if (!file_util::PathExists(local_path) ||
+      if (!base::PathExists(local_path) ||
           file_util::IsLink(local_path) ||
           !file_util::GetFileInfo(local_path, &file_info)) {
         continue;
@@ -658,7 +617,7 @@
     // Grant access to this particular file to target extension. This will
     // ensure that the target extension can access only this FS entry and
     // prevent from traversing FS hierarchy upward.
-    external_provider_handler->GrantFileAccessToExtension(
+    backend->GrantFileAccessToExtension(
         handler_extension->id(), virtual_path);
 
     // Output values.
@@ -746,7 +705,7 @@
 
   int handler_pid = ExtractProcessFromExtensionId(profile_, extension_->id());
   if (handler_pid <= 0 &&
-      !extensions::BackgroundInfo::HasLazyBackgroundPage(extension_)) {
+      !extensions::BackgroundInfo::HasLazyBackgroundPage(extension_.get())) {
     ExecuteDoneOnUIThread(false);
     return;
   }
@@ -759,7 +718,7 @@
     extensions::LazyBackgroundTaskQueue* queue =
         extensions::ExtensionSystem::Get(profile_)->
         lazy_background_task_queue();
-    if (!queue->ShouldEnqueueTask(profile_, extension_)) {
+    if (!queue->ShouldEnqueueTask(profile_, extension_.get())) {
       ExecuteDoneOnUIThread(false);
       return;
     }
@@ -795,7 +754,8 @@
     return;
   }
 
-  SetupHandlerHostFileAccessPermissions(file_list, extension_, handler_pid);
+  SetupHandlerHostFileAccessPermissions(
+      file_list, extension_.get(), handler_pid);
 
   scoped_ptr<ListValue> event_args(new ListValue());
   event_args->Append(new base::StringValue(action_id_));
@@ -832,13 +792,21 @@
     const FileDefinitionList& file_list,
     const Extension* extension,
     int handler_pid) {
+  const FileBrowserHandler* action = FindFileBrowserHandler(extension_,
+                                                            action_id_);
   for (FileDefinitionList::const_iterator iter = file_list.begin();
        iter != file_list.end();
        ++iter) {
-    content::ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile(
-        handler_pid,
-        iter->absolute_path,
-        GetAccessPermissionsForFileBrowserHandler(extension_, action_id_));
+    if (!action)
+      continue;
+    if (action->CanRead()) {
+      content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(
+          handler_pid, iter->absolute_path);
+    }
+    if (action->CanWrite()) {
+      content::ChildProcessSecurityPolicy::GetInstance()->
+          GrantCreateReadWriteFile(handler_pid, iter->absolute_path);
+    }
   }
 }
 
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_handler_util.h b/chrome/browser/chromeos/extensions/file_manager/file_handler_util.h
index e994bfa..9cb5b67 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_handler_util.h
+++ b/chrome/browser/chromeos/extensions/file_manager/file_handler_util.h
@@ -53,11 +53,6 @@
                                       const std::string& mime_type,
                                       const std::string& suffix);
 
-// Gets read-write file access permission flags.
-int GetReadWritePermissions();
-// Gets read-only file access permission flags.
-int GetReadOnlyPermissions();
-
 // Generates task id for the action specified by the extension. The |task_type|
 // must be one of kTaskFile, kTaskDrive or kTaskApp.
 std::string MakeTaskID(const std::string& extension_id,
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_browsertest.cc
index 2072be6..0bc09e9 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_browsertest.cc
@@ -16,6 +16,7 @@
 #include "base/file_util.h"
 #include "base/files/file_path.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
 #include "chrome/browser/chromeos/drive/file_system_interface.h"
 #include "chrome/browser/chromeos/extensions/file_manager/drive_test_util.h"
@@ -27,7 +28,6 @@
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
 #include "chrome/browser/google_apis/test_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chromeos/chromeos_switches.h"
@@ -118,7 +118,7 @@
         base::FilePath source_path =
             google_apis::test_util::GetTestFilePath("chromeos/file_manager").
             AppendASCII(entry.source_file_name);
-        ASSERT_TRUE(file_util::CopyFile(source_path, target_path))
+        ASSERT_TRUE(base::CopyFile(source_path, target_path))
             << "Copy from " << source_path.value()
             << " to " << target_path.value() << " failed.";
         break;
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.cc
index c7499a7..be8d0ce 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.cc
@@ -12,11 +12,13 @@
 #include "base/stl_util.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
 #include "chrome/browser/chromeos/drive/file_system_interface.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_notifications.h"
 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h"
+#include "chrome/browser/chromeos/extensions/file_manager/mounted_disk_monitor.h"
 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
 #include "chrome/browser/chromeos/login/screen_locker.h"
 #include "chrome/browser/chromeos/net/connectivity_state_helper.h"
@@ -25,21 +27,14 @@
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/google_apis/task_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
-#include "chromeos/dbus/cros_disks_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/power_manager_client.h"
-#include "chromeos/dbus/session_manager_client.h"
 #include "chromeos/login/login_state.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_source.h"
 #include "webkit/common/fileapi/file_system_types.h"
 #include "webkit/common/fileapi/file_system_util.h"
 
-using chromeos::DBusThreadManager;
 using chromeos::disks::DiskMountManager;
 using content::BrowserThread;
 using drive::DriveIntegrationService;
@@ -50,19 +45,6 @@
 const char kPathChanged[] = "changed";
 const char kPathWatchError[] = "error";
 
-DictionaryValue* DiskToDictionaryValue(
-    const DiskMountManager::Disk* disk) {
-  DictionaryValue* result = new DictionaryValue();
-  result->SetString("mountPath", disk->mount_path());
-  result->SetString("devicePath", disk->device_path());
-  result->SetString("label", disk->device_label());
-  result->SetString("deviceType",
-                    DiskMountManager::DeviceTypeToString(disk->device_type()));
-  result->SetInteger("totalSizeKB", disk->total_size_in_bytes() / 1024);
-  result->SetBoolean("readOnly", disk->is_read_only());
-  return result;
-}
-
 // Used as a callback for FileSystem::MarkCacheFileAsUnmounted().
 void OnMarkAsUnmounted(drive::FileError error) {
   // Do nothing.
@@ -113,91 +95,12 @@
   return "";
 }
 
-// Observes PowerManager and updates its state when the system suspends and
-// resumes. After the system resumes it will stay in "is_resuming" state for 5
-// seconds. This is to give DiskManager time to process device removed/added
-// events (events for the devices that were present before suspend should not
-// trigger any new notifications or file manager windows).
-// The delegate will go into the same state after screen is unlocked. Cros-disks
-// will not send events while the screen is locked. The events will be postponed
-// until the screen is unlocked. These have to be handled too.
-class SuspendStateDelegateImpl
-    : public chromeos::PowerManagerClient::Observer,
-      public chromeos::SessionManagerClient::Observer,
-      public FileManagerEventRouter::SuspendStateDelegate {
- public:
-  SuspendStateDelegateImpl()
-      : is_resuming_(false),
-        weak_factory_(this) {
-    DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
-    DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
-  }
-
-  virtual ~SuspendStateDelegateImpl() {
-    DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
-    DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
-  }
-
-  // chromeos::PowerManagerClient::Observer implementation.
-  virtual void SuspendImminent() OVERRIDE {
-    is_resuming_ = false;
-    weak_factory_.InvalidateWeakPtrs();
-  }
-
-  // chromeos::PowerManagerClient::Observer implementation.
-  virtual void SystemResumed(const base::TimeDelta& sleep_duration) OVERRIDE {
-    is_resuming_ = true;
-    // Undo any previous resets.
-    weak_factory_.InvalidateWeakPtrs();
-    base::MessageLoopProxy::current()->PostDelayedTask(
-        FROM_HERE,
-        base::Bind(&SuspendStateDelegateImpl::Reset,
-                   weak_factory_.GetWeakPtr()),
-        base::TimeDelta::FromSeconds(5));
-  }
-
-  // chromeos::SessionManagerClient::Observer implementation.
-  virtual void ScreenIsUnlocked() OVERRIDE {
-    is_resuming_ = true;
-    // Undo any previous resets.
-    weak_factory_.InvalidateWeakPtrs();
-    base::MessageLoopProxy::current()->PostDelayedTask(
-        FROM_HERE,
-        base::Bind(&SuspendStateDelegateImpl::Reset,
-                   weak_factory_.GetWeakPtr()),
-        base::TimeDelta::FromSeconds(5));
-  }
-
-  // FileManagerEventRouter::SuspendStateDelegate implementation.
-  virtual bool SystemIsResuming() const OVERRIDE {
-    return is_resuming_;
-  }
-
-  // FileManagerEventRouter::SuspendStateDelegate implementation.
-  virtual bool DiskWasPresentBeforeSuspend(
-      const DiskMountManager::Disk& disk) const OVERRIDE {
-    // TODO(tbarzic): Implement this. Blocked on http://crbug.com/153338.
-    return false;
-  }
-
- private:
-  void Reset() {
-    is_resuming_ = false;
-  }
-
-  bool is_resuming_;
-
-  base::WeakPtrFactory<SuspendStateDelegateImpl> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(SuspendStateDelegateImpl);
-};
-
 void DirectoryExistsOnBlockingPool(const base::FilePath& directory_path,
                                    const base::Closure& success_callback,
                                    const base::Closure& failure_callback) {
   DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
 
-  if (file_util::DirectoryExists(directory_path))
+  if (base::DirectoryExists(directory_path))
     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, success_callback);
   else
     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, failure_callback);
@@ -364,7 +267,8 @@
     chromeos::ConnectivityStateHelper::Get()->
         AddNetworkManagerObserver(this);
   }
-  suspend_state_delegate_.reset(new SuspendStateDelegateImpl());
+
+  mounted_disk_monitor_.reset(new MountedDiskMonitor());
 
   pref_change_registrar_->Init(profile_->GetPrefs());
 
@@ -435,35 +339,12 @@
     return;
   // Remove the renderer process for this watch.
   iter->second->RemoveExtension(extension_id);
-  if (iter->second->GetRefCount() == 0) {
+  if (iter->second->ref_count() == 0) {
     delete iter->second;
     file_watchers_.erase(iter);
   }
 }
 
-void FileManagerEventRouter::MountDrive(
-    const base::Closure& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  // Pass back the gdata mount point path as source path.
-  const std::string& gdata_path = drive::util::GetDriveMountPointPathAsString();
-  DiskMountManager::MountPointInfo mount_info(
-      gdata_path,
-      gdata_path,
-      chromeos::MOUNT_TYPE_GOOGLE_DRIVE,
-      chromeos::disks::MOUNT_CONDITION_NONE);
-
-  // Raise mount event.
-  // We can pass chromeos::MOUNT_ERROR_NONE even when authentication is failed
-  // or network is unreachable. These two errors will be handled later.
-  OnMountEvent(DiskMountManager::MOUNTING,
-               chromeos::MOUNT_ERROR_NONE,
-               mount_info);
-
-  if (!callback.is_null())
-    callback.Run();
-}
-
 void FileManagerEventRouter::OnDiskEvent(
     DiskMountManager::DiskEvent event,
     const DiskMountManager::Disk* disk) {
@@ -512,9 +393,7 @@
     DiskMountManager* disk_mount_manager = DiskMountManager::GetInstance();
     const DiskMountManager::Disk* disk =
         disk_mount_manager->FindDiskBySourcePath(mount_info.source_path);
-    // TODO(tbarzic): DiskWasPresentBeforeSuspend is not yet functional. It
-    // always returns false.
-    if (!disk || suspend_state_delegate_->DiskWasPresentBeforeSuspend(*disk))
+    if (!disk || mounted_disk_monitor_->DiskIsRemounting(*disk))
       return;
 
     notifications_->ManageNotificationsOnMountCompleted(
@@ -529,7 +408,7 @@
           *disk,
           base::FilePath::FromUTF8Unsafe(mount_info.mount_path));
   } else if (mount_info.mount_type == chromeos::MOUNT_TYPE_ARCHIVE) {
-    // Clear the "mounted" state for archive files in gdata cache
+    // Clear the "mounted" state for archive files in drive cache
     // when mounting failed or unmounting succeeded.
     if ((event == DiskMountManager::MOUNTING) !=
         (error_code == chromeos::MOUNT_ERROR_NONE)) {
@@ -694,17 +573,28 @@
 void FileManagerEventRouter::OnFileSystemMounted() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  MountDrive(base::Bind(&base::DoNothing));  // Callback does nothing.
+  const std::string& drive_path = drive::util::GetDriveMountPointPathAsString();
+  DiskMountManager::MountPointInfo mount_info(
+      drive_path,
+      drive_path,
+      chromeos::MOUNT_TYPE_GOOGLE_DRIVE,
+      chromeos::disks::MOUNT_CONDITION_NONE);
+
+  // Raise mount event.
+  // We can pass chromeos::MOUNT_ERROR_NONE even when authentication is failed
+  // or network is unreachable. These two errors will be handled later.
+  OnMountEvent(DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE,
+               mount_info);
 }
 
 void FileManagerEventRouter::OnFileSystemBeingUnmounted() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   // Raise a mount event to notify the File Manager.
-  const std::string& gdata_path = drive::util::GetDriveMountPointPathAsString();
+  const std::string& drive_path = drive::util::GetDriveMountPointPathAsString();
   DiskMountManager::MountPointInfo mount_info(
-      gdata_path,
-      gdata_path,
+      drive_path,
+      drive_path,
       chromeos::MOUNT_TYPE_GOOGLE_DRIVE,
       chromeos::disks::MOUNT_CONDITION_NONE);
   OnMountEvent(DiskMountManager::UNMOUNTING, chromeos::MOUNT_ERROR_NONE,
@@ -730,21 +620,21 @@
   if (iter == file_watchers_.end()) {
     return;
   }
-  DispatchDirectoryChangeEvent(iter->second->GetVirtualPath(), got_error,
-                               iter->second->GetExtensions());
+  DispatchDirectoryChangeEvent(iter->second->virtual_path(), got_error,
+                               iter->second->extensions());
 }
 
 void FileManagerEventRouter::DispatchDirectoryChangeEvent(
     const base::FilePath& virtual_path,
     bool got_error,
-    const FileManagerEventRouter::ExtensionUsageRegistry& extensions) {
+    const FileWatcherExtensions::ExtensionUsageRegistry& extensions) {
   if (!profile_) {
     NOTREACHED();
     return;
   }
 
-  for (ExtensionUsageRegistry::const_iterator iter = extensions.begin();
-       iter != extensions.end(); ++iter) {
+  for (FileWatcherExtensions::ExtensionUsageRegistry::const_iterator iter =
+           extensions.begin(); iter != extensions.end(); ++iter) {
     GURL target_origin_url(extensions::Extension::GetBaseURLFromExtensionId(
         iter->first));
     GURL base_url = fileapi::GetFileSystemRootURI(target_origin_url,
@@ -969,119 +859,3 @@
                                      device_path);
   }
 }
-
-FileManagerEventRouter::FileWatcherExtensions::FileWatcherExtensions(
-    const base::FilePath& virtual_path,
-    const std::string& extension_id,
-    bool is_remote_file_system)
-    : file_watcher_(NULL),
-      virtual_path_(virtual_path),
-      ref_count_(0),
-      is_remote_file_system_(is_remote_file_system),
-      weak_ptr_factory_(this) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  AddExtension(extension_id);
-}
-
-FileManagerEventRouter::FileWatcherExtensions::~FileWatcherExtensions() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, file_watcher_);
-}
-
-void FileManagerEventRouter::FileWatcherExtensions::AddExtension(
-    const std::string& extension_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  ExtensionUsageRegistry::iterator it = extensions_.find(extension_id);
-  if (it != extensions_.end()) {
-    it->second++;
-  } else {
-    extensions_.insert(ExtensionUsageRegistry::value_type(extension_id, 1));
-  }
-
-  ref_count_++;
-}
-
-void FileManagerEventRouter::FileWatcherExtensions::RemoveExtension(
-    const std::string& extension_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  ExtensionUsageRegistry::iterator it = extensions_.find(extension_id);
-
-  if (it != extensions_.end()) {
-    // If entry found - decrease it's count and remove if necessary
-    if (0 == it->second--) {
-      extensions_.erase(it);
-    }
-
-    ref_count_--;
-  } else {
-    // Might be reference counting problem - e.g. if some component of
-    // extension subscribes/unsubscribes correctly, but other component
-    // only unsubscribes, developer of first one might receive this message
-    LOG(FATAL) << " Extension [" << extension_id
-        << "] tries to unsubscribe from folder [" << local_path_.value()
-        << "] it isn't subscribed";
-  }
-}
-
-const FileManagerEventRouter::ExtensionUsageRegistry&
-FileManagerEventRouter::FileWatcherExtensions::GetExtensions() const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  return extensions_;
-}
-
-unsigned int
-FileManagerEventRouter::FileWatcherExtensions::GetRefCount() const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  return ref_count_;
-}
-
-const base::FilePath&
-FileManagerEventRouter::FileWatcherExtensions::GetVirtualPath() const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  return virtual_path_;
-}
-
-void FileManagerEventRouter::FileWatcherExtensions::Watch(
-    const base::FilePath& local_path,
-    const base::FilePathWatcher::Callback& file_watcher_callback,
-    const BoolCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-  DCHECK(!file_watcher_);
-
-  local_path_ = local_path;  // For error message in RemoveExtension().
-
-  if (is_remote_file_system_) {
-    base::MessageLoopProxy::current()->PostTask(FROM_HERE,
-                                                base::Bind(callback, true));
-    return;
-  }
-
-  BrowserThread::PostTaskAndReplyWithResult(
-      BrowserThread::FILE,
-      FROM_HERE,
-      base::Bind(&CreateAndStartFilePathWatcher,
-                 local_path,
-                 google_apis::CreateRelayCallback(file_watcher_callback)),
-      base::Bind(
-          &FileManagerEventRouter::FileWatcherExtensions::OnWatcherStarted,
-          weak_ptr_factory_.GetWeakPtr(),
-          callback));
-}
-
-void FileManagerEventRouter::FileWatcherExtensions::OnWatcherStarted(
-    const BoolCallback& callback,
-    base::FilePathWatcher* file_watcher) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  if (file_watcher) {
-    file_watcher_ = file_watcher;
-    callback.Run(true);
-  } else {
-    callback.Run(false);
-  }
-}
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.h b/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.h
index db63487..7fff315 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.h
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.h
@@ -13,11 +13,13 @@
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
 #include "chrome/browser/chromeos/drive/file_system_observer.h"
 #include "chrome/browser/chromeos/drive/job_list.h"
+#include "chrome/browser/chromeos/extensions/file_manager/file_watcher_extensions.h"
 #include "chrome/browser/chromeos/net/connectivity_state_helper_observer.h"
 #include "chrome/browser/drive/drive_service_interface.h"
 #include "chromeos/disks/disk_mount_manager.h"
 
 class FileManagerNotifications;
+class MountedDiskMonitor;
 class PrefChangeRegistrar;
 class Profile;
 
@@ -31,22 +33,6 @@
       public drive::JobListObserver,
       public drive::DriveServiceObserver {
  public:
-  // Interface that should keep track of the system state in regards to system
-  // suspend and resume events.
-  // When the |IsResuming()| returns true, it should be able to check if a
-  // removable device was present before the was system suspended.
-  class SuspendStateDelegate {
-   public:
-    virtual ~SuspendStateDelegate() {}
-
-    // Returns true if the system has recently woken up.
-    virtual bool SystemIsResuming() const = 0;
-    // If system is resuming, returns true if the disk was present before the
-    // system suspend. Should return false if the system is not resuming.
-    virtual bool DiskWasPresentBeforeSuspend(
-        const chromeos::disks::DiskMountManager::Disk& disk) const = 0;
-  };
-
   explicit FileManagerEventRouter(Profile* profile);
   virtual ~FileManagerEventRouter();
 
@@ -71,10 +57,6 @@
   void RemoveFileWatch(const base::FilePath& local_path,
                        const std::string& extension_id);
 
-  // Mounts Drive on File browser. |callback| will be called after raising a
-  // mount request event to file manager on JS-side.
-  void MountDrive(const base::Closure& callback);
-
   // CrosDisksClient::Observer overrides.
   virtual void OnDiskEvent(
       chromeos::disks::DiskMountManager::DiskEvent event,
@@ -114,54 +96,6 @@
   virtual void OnFileSystemBeingUnmounted() OVERRIDE;
 
  private:
-  typedef std::map<std::string, int> ExtensionUsageRegistry;
-
-  // This class is used to remember what extensions are watching |virtual_path|.
-  class FileWatcherExtensions {
-   public:
-    FileWatcherExtensions(const base::FilePath& virtual_path,
-        const std::string& extension_id,
-        bool is_remote_file_system);
-
-    ~FileWatcherExtensions();
-
-    void AddExtension(const std::string& extension_id);
-
-    void RemoveExtension(const std::string& extension_id);
-
-    const ExtensionUsageRegistry& GetExtensions() const;
-
-    unsigned int GetRefCount() const;
-
-    const base::FilePath& GetVirtualPath() const;
-
-    // Starts a file watch at |local_path|. |file_watcher_callback| will be
-    // called when changes are notified.
-    //
-    // |callback| will be called with true, if the file watch is started
-    // successfully, or false if failed. |callback| must not be null.
-    void Watch(const base::FilePath& local_path,
-               const base::FilePathWatcher::Callback& file_watcher_callback,
-               const BoolCallback& callback);
-
-   private:
-    // Called when a FilePathWatcher is created and started.
-    // |file_path_watcher| is NULL, if the watcher wasn't started successfully.
-    void OnWatcherStarted(const BoolCallback& callback,
-                          base::FilePathWatcher* file_path_watcher);
-
-    base::FilePathWatcher* file_watcher_;
-    base::FilePath local_path_;
-    base::FilePath virtual_path_;
-    ExtensionUsageRegistry extensions_;
-    unsigned int ref_count_;
-    bool is_remote_file_system_;
-
-    // Note: This should remain the last member so it'll be destroyed and
-    // invalidate the weak pointers before any other members are destroyed.
-    base::WeakPtrFactory<FileWatcherExtensions> weak_ptr_factory_;
-  };
-
   typedef std::map<base::FilePath, FileWatcherExtensions*> WatcherMap;
 
   // USB mount event handlers.
@@ -186,8 +120,10 @@
                                    bool got_error);
 
   // Sends directory change event.
-  void DispatchDirectoryChangeEvent(const base::FilePath& path, bool error,
-                                    const ExtensionUsageRegistry& extensions);
+  void DispatchDirectoryChangeEvent(
+      const base::FilePath& path,
+      bool error,
+      const FileWatcherExtensions::ExtensionUsageRegistry& extensions);
 
   void DispatchMountEvent(
       chromeos::disks::DiskMountManager::MountEvent event,
@@ -221,7 +157,7 @@
   WatcherMap file_watchers_;
   scoped_ptr<FileManagerNotifications> notifications_;
   scoped_ptr<PrefChangeRegistrar> pref_change_registrar_;
-  scoped_ptr<SuspendStateDelegate> suspend_state_delegate_;
+  scoped_ptr<MountedDiskMonitor> mounted_disk_monitor_;
   Profile* profile_;
 
   // Note: This should remain the last member so it'll be destroyed and
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_manifest_unittest.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_manifest_unittest.cc
deleted file mode 100644
index acc676e..0000000
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_manifest_unittest.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/strings/string_number_conversions.h"
-#include "chrome/browser/chromeos/extensions/file_manager/file_browser_handler.h"
-#include "chrome/common/extensions/extension_builder.h"
-#include "chrome/common/extensions/extension_manifest_constants.h"
-#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
-#include "chrome/common/extensions/value_builder.h"
-#include "extensions/common/error_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace errors = extension_manifest_errors;
-
-using extensions::DictionaryBuilder;
-using extensions::Extension;
-using extensions::ExtensionBuilder;
-using extensions::ListBuilder;
-
-namespace {
-
-class FileBrowserHandlerManifestTest : public ExtensionManifestTest {
- protected:
-  virtual void SetUp() OVERRIDE {
-    ExtensionManifestTest::SetUp();
-    (new FileBrowserHandlerParser)->Register();
-  }
-};
-
-TEST_F(FileBrowserHandlerManifestTest, InvalidFileBrowserHandlers) {
-  Testcase testcases[] = {
-    Testcase("filebrowser_invalid_access_permission.json",
-             extensions::ErrorUtils::FormatErrorMessage(
-                 errors::kInvalidFileAccessValue, base::IntToString(1))),
-    Testcase("filebrowser_invalid_access_permission_list.json",
-             errors::kInvalidFileAccessList),
-    Testcase("filebrowser_invalid_empty_access_permission_list.json",
-             errors::kInvalidFileAccessList),
-    Testcase("filebrowser_invalid_actions_1.json",
-             errors::kInvalidFileBrowserHandler),
-    Testcase("filebrowser_invalid_actions_2.json",
-             errors::kInvalidFileBrowserHandler),
-    Testcase("filebrowser_invalid_action_id.json",
-             errors::kInvalidPageActionId),
-    Testcase("filebrowser_invalid_action_title.json",
-             errors::kInvalidPageActionDefaultTitle),
-    Testcase("filebrowser_invalid_file_filters_1.json",
-             errors::kInvalidFileFiltersList),
-    Testcase("filebrowser_invalid_file_filters_2.json",
-             extensions::ErrorUtils::FormatErrorMessage(
-                errors::kInvalidFileFilterValue, base::IntToString(0))),
-    Testcase("filebrowser_invalid_file_filters_url.json",
-             extensions::ErrorUtils::FormatErrorMessage(
-                errors::kInvalidURLPatternError, "http:*.html"))
-  };
-  RunTestcases(testcases, arraysize(testcases), EXPECT_TYPE_ERROR);
-}
-
-TEST_F(FileBrowserHandlerManifestTest, ValidFileBrowserHandler) {
-  scoped_refptr<const Extension> extension =
-      ExtensionBuilder()
-      .SetManifest(DictionaryBuilder()
-                   .Set("name", "file browser handler test")
-                   .Set("version", "1.0.0")
-                   .Set("manifest_version", 2)
-                   .Set("file_browser_handlers", ListBuilder()
-                       .Append(DictionaryBuilder()
-                           .Set("id", "ExtremelyCoolAction")
-                           .Set("default_title", "Be Amazed")
-                           .Set("default_icon", "icon.png")
-                           .Set("file_filters", ListBuilder()
-                               .Append("filesystem:*.txt")))))
-      .Build();
-
-  ASSERT_TRUE(extension.get());
-  FileBrowserHandler::List* handlers =
-      FileBrowserHandler::GetHandlers(extension.get());
-  ASSERT_TRUE(handlers != NULL);
-  ASSERT_EQ(1U, handlers->size());
-  const FileBrowserHandler* action = handlers->at(0).get();
-
-  EXPECT_EQ("ExtremelyCoolAction", action->id());
-  EXPECT_EQ("Be Amazed", action->title());
-  EXPECT_EQ("icon.png", action->icon_path());
-  const extensions::URLPatternSet& patterns = action->file_url_patterns();
-  ASSERT_EQ(1U, patterns.patterns().size());
-  EXPECT_TRUE(action->MatchesURL(
-      GURL("filesystem:chrome-extension://foo/local/test.txt")));
-  EXPECT_FALSE(action->HasCreateAccessPermission());
-  EXPECT_TRUE(action->CanRead());
-  EXPECT_TRUE(action->CanWrite());
-}
-
-TEST_F(FileBrowserHandlerManifestTest, ValidFileBrowserHandlerMIMETypes) {
-  scoped_refptr<const Extension> extension =
-      ExtensionBuilder()
-      .SetID(extension_misc::kQuickOfficeExtensionId)
-      .SetManifest(DictionaryBuilder()
-                   .Set("name", "file browser handler test")
-                   .Set("version", "1.0.0")
-                   .Set("manifest_version", 2)
-                   .Set("file_browser_handlers", ListBuilder()
-                       .Append(DictionaryBuilder()
-                           .Set("id", "ID")
-                           .Set("default_title", "Default title")
-                           .Set("default_icon", "icon.png")
-                           .Set("file_filters", ListBuilder()
-                               .Append("filesystem:*.txt")))))
-      .Build();
-
-  ASSERT_TRUE(extension.get());
-  FileBrowserHandler::List* handlers =
-      FileBrowserHandler::GetHandlers(extension.get());
-  ASSERT_TRUE(handlers != NULL);
-  ASSERT_EQ(1U, handlers->size());
-  const FileBrowserHandler* action = handlers->at(0).get();
-
-  const extensions::URLPatternSet& patterns = action->file_url_patterns();
-  ASSERT_EQ(1U, patterns.patterns().size());
-  EXPECT_TRUE(action->MatchesURL(
-      GURL("filesystem:chrome-extension://foo/local/test.txt")));
-}
-
-TEST_F(FileBrowserHandlerManifestTest, ValidFileBrowserHandlerWithCreate) {
-  scoped_refptr<const Extension> extension =
-      ExtensionBuilder()
-      .SetManifest(DictionaryBuilder()
-                   .Set("name", "file browser handler test create")
-                   .Set("version", "1.0.0")
-                   .Set("manifest_version", 2)
-                   .Set("file_browser_handlers", ListBuilder()
-                       .Append(DictionaryBuilder()
-                           .Set("id", "ID")
-                           .Set("default_title", "Default title")
-                           .Set("default_icon", "icon.png")
-                           .Set("file_filters", ListBuilder()
-                               .Append("filesystem:*.txt"))
-                           .Set("file_access", ListBuilder()
-                               .Append("create")))))
-      .Build();
-
-  ASSERT_TRUE(extension.get());
-  FileBrowserHandler::List* handlers =
-      FileBrowserHandler::GetHandlers(extension.get());
-  ASSERT_TRUE(handlers != NULL);
-  ASSERT_EQ(1U, handlers->size());
-  const FileBrowserHandler* action = handlers->at(0).get();
-  const extensions::URLPatternSet& patterns = action->file_url_patterns();
-
-  EXPECT_EQ(0U, patterns.patterns().size());
-  EXPECT_TRUE(action->HasCreateAccessPermission());
-  EXPECT_FALSE(action->CanRead());
-  EXPECT_FALSE(action->CanWrite());
-}
-
-TEST_F(FileBrowserHandlerManifestTest, FileManagerURLOverride) {
-  scoped_ptr<DictionaryValue> manifest_value =
-      DictionaryBuilder()
-          .Set("name", "override_files")
-          .Set("version", "1.0.0")
-          .Set("manifest_version", 2)
-          .Set("chrome_url_overrides", DictionaryBuilder()
-              .Set("files", "main.html"))
-      .Build();
-
-  // Non component extensions can't override chrome://files/ URL.
-  LoadAndExpectError(Manifest(manifest_value.get(), "override_files"),
-                     errors::kInvalidChromeURLOverrides);
-
-  // A component extension can override chrome://files/ URL.
-  std::string error;
-  LoadExtension(Manifest(manifest_value.get(), "override_files"),
-                &error, extensions::Manifest::COMPONENT, Extension::NO_FLAGS);
-#if defined(FILE_MANAGER_EXTENSION)
-  EXPECT_EQ("", error);
-#else
-  EXPECT_EQ(std::string(errors::kInvalidChromeURLOverrides), error);
-#endif
-}
-
-}  // namespace
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_notifications.h b/chrome/browser/chromeos/extensions/file_manager/file_manager_notifications.h
index 5325b50..559e9cc 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_notifications.h
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_notifications.h
@@ -47,9 +47,6 @@
                                            bool success,
                                            bool is_unsupported);
 
-  void ManageNotificationOnGDataSyncProgress(int count);
-  void ManageNotificationOnGDataSyncFinish(bool success);
-
   // Primary method for showing a notification.
   void ShowNotification(NotificationType type, const std::string& path);
   void ShowNotificationDelayed(NotificationType type,
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc
index 81b8198..4ce88d2 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
 #include "chrome/browser/chromeos/drive/file_system.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
-#include "chrome/browser/chromeos/extensions/file_manager/file_browser_handler.h"
 #include "chrome/browser/chromeos/extensions/file_manager/file_handler_util.h"
 #include "chrome/browser/chromeos/media/media_player.h"
 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
@@ -41,6 +40,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/common/extensions/api/file_browser_handlers/file_browser_handler.h"
 #include "chrome/common/url_constants.h"
 #include "chromeos/chromeos_switches.h"
 #include "content/public/browser/browser_thread.h"
@@ -55,8 +55,8 @@
 #include "net/base/net_util.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/screen.h"
+#include "webkit/browser/fileapi/file_system_backend.h"
 #include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/browser/fileapi/file_system_mount_point_provider.h"
 #include "webkit/browser/fileapi/file_system_operation_runner.h"
 #include "webkit/browser/fileapi/file_system_url.h"
 #include "webkit/common/fileapi/file_system_util.h"
@@ -131,8 +131,8 @@
   if (!pepper_info)
     return false;
 
-  PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile);
-  if (!plugin_prefs)
+  scoped_refptr<PluginPrefs> plugin_prefs = PluginPrefs::GetForProfile(profile);
+  if (!plugin_prefs.get())
     return false;
 
   return plugin_prefs->IsPluginEnabled(pepper_info->ToWebPluginInfo());
@@ -256,12 +256,12 @@
   // site for which file access permissions should be granted.
   GURL site = extensions::ExtensionSystem::Get(profile)->extension_service()->
       GetSiteForExtensionId(kFileBrowserDomain);
-  fileapi::ExternalFileSystemMountPointProvider* external_provider =
+  fileapi::ExternalFileSystemBackend* backend =
       BrowserContext::GetStoragePartitionForSite(profile, site)->
-          GetFileSystemContext()->external_provider();
-  if (!external_provider)
+          GetFileSystemContext()->external_backend();
+  if (!backend)
     return false;
-  external_provider->GrantFullAccessToExtension(GetFileBrowserUrl().host());
+  backend->GrantFullAccessToExtension(GetFileBrowserUrl().host());
   return true;
 }
 
@@ -348,7 +348,7 @@
   for (ExtensionSet::const_iterator iter = service->extensions()->begin();
        iter != service->extensions()->end();
        ++iter) {
-    const Extension* extension = *iter;
+    const Extension* extension = iter->get();
 
     // We don't support using hosted apps to open files.
     if (!extension->is_platform_app())
@@ -570,14 +570,14 @@
   // extension's site is the one in whose file system context the virtual path
   // should be found.
   GURL site = service->GetSiteForExtensionId(extension_id);
-  fileapi::ExternalFileSystemMountPointProvider* provider =
+  fileapi::ExternalFileSystemBackend* backend =
       BrowserContext::GetStoragePartitionForSite(profile, site)->
-          GetFileSystemContext()->external_provider();
-  if (!provider)
+          GetFileSystemContext()->external_backend();
+  if (!backend)
     return false;
 
-  // Find if this file path is managed by the external provider.
-  if (!provider->GetVirtualPath(full_file_path, virtual_path))
+  // Find if this file path is managed by the external backend.
+  if (!backend->GetVirtualPath(full_file_path, virtual_path))
     return false;
 
   return true;
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_watcher_extensions.cc b/chrome/browser/chromeos/extensions/file_manager/file_watcher_extensions.cc
new file mode 100644
index 0000000..7dfd98e
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/file_manager/file_watcher_extensions.cc
@@ -0,0 +1,117 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/extensions/file_manager/file_watcher_extensions.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "chrome/browser/google_apis/task_util.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+namespace {
+
+// Creates a base::FilePathWatcher and starts watching at |watch_path| with
+// |callback|. Returns NULL on failure.
+base::FilePathWatcher* CreateAndStartFilePathWatcher(
+    const base::FilePath& watch_path,
+    const base::FilePathWatcher::Callback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+  DCHECK(!callback.is_null());
+
+  scoped_ptr<base::FilePathWatcher> watcher(new base::FilePathWatcher);
+  if (!watcher->Watch(watch_path, false /* recursive */, callback))
+    return NULL;
+
+  return watcher.release();
+}
+
+}  // namespace
+
+FileWatcherExtensions::FileWatcherExtensions(const base::FilePath& virtual_path,
+                                             const std::string& extension_id,
+                                             bool is_remote_file_system)
+    : file_watcher_(NULL),
+      virtual_path_(virtual_path),
+      ref_count_(0),
+      is_remote_file_system_(is_remote_file_system),
+      weak_ptr_factory_(this) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  AddExtension(extension_id);
+}
+
+FileWatcherExtensions::~FileWatcherExtensions() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, file_watcher_);
+}
+
+void FileWatcherExtensions::AddExtension(const std::string& extension_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  extensions_[extension_id]++;
+  ref_count_++;
+}
+
+void FileWatcherExtensions::RemoveExtension(const std::string& extension_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  ExtensionUsageRegistry::iterator it = extensions_.find(extension_id);
+  if (it == extensions_.end()) {
+    LOG(ERROR) << " Extension [" << extension_id
+               << "] tries to unsubscribe from folder [" << local_path_.value()
+               << "] it isn't subscribed";
+    return;
+  }
+
+  // If entry found - decrease it's count and remove if necessary
+  if (it->second-- == 0)
+    extensions_.erase(it);
+
+  ref_count_--;
+}
+
+void FileWatcherExtensions::Watch(
+    const base::FilePath& local_path,
+    const base::FilePathWatcher::Callback& file_watcher_callback,
+    const BoolCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+  DCHECK(!file_watcher_);
+
+  local_path_ = local_path;  // For error message in RemoveExtension().
+
+  if (is_remote_file_system_) {
+    base::MessageLoopProxy::current()->PostTask(FROM_HERE,
+                                                base::Bind(callback, true));
+    return;
+  }
+
+  BrowserThread::PostTaskAndReplyWithResult(
+      BrowserThread::FILE,
+      FROM_HERE,
+      base::Bind(&CreateAndStartFilePathWatcher,
+                 local_path,
+                 google_apis::CreateRelayCallback(file_watcher_callback)),
+      base::Bind(&FileWatcherExtensions::OnWatcherStarted,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 callback));
+}
+
+void FileWatcherExtensions::OnWatcherStarted(
+    const BoolCallback& callback,
+    base::FilePathWatcher* file_watcher) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+  DCHECK(!file_watcher_);
+
+  if (file_watcher) {
+    file_watcher_ = file_watcher;
+    callback.Run(true);
+  } else {
+    callback.Run(false);
+  }
+}
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_watcher_extensions.h b/chrome/browser/chromeos/extensions/file_manager/file_watcher_extensions.h
new file mode 100644
index 0000000..69774af
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/file_manager/file_watcher_extensions.h
@@ -0,0 +1,65 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_WATCHER_EXTENSIONS_H_
+#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_WATCHER_EXTENSIONS_H_
+
+#include <map>
+#include <string>
+
+#include "base/callback_forward.h"
+#include "base/files/file_path.h"
+#include "base/files/file_path_watcher.h"
+#include "base/memory/weak_ptr.h"
+
+// This class is used to remember what extensions are watching |virtual_path|.
+class FileWatcherExtensions {
+ public:
+  typedef std::map<std::string, int> ExtensionUsageRegistry;
+  typedef base::Callback<void(bool success)> BoolCallback;
+
+  FileWatcherExtensions(const base::FilePath& virtual_path,
+                        const std::string& extension_id,
+                        bool is_remote_file_system);
+
+  ~FileWatcherExtensions();
+
+  void AddExtension(const std::string& extension_id);
+
+  void RemoveExtension(const std::string& extension_id);
+
+  const ExtensionUsageRegistry& extensions() const { return extensions_; }
+
+  int ref_count() const { return ref_count_; }
+
+  const base::FilePath& virtual_path() const { return virtual_path_; }
+
+  // Starts a file watch at |local_path|. |file_watcher_callback| will be
+  // called when changes are notified.
+  //
+  // |callback| will be called with true, if the file watch is started
+  // successfully, or false if failed. |callback| must not be null.
+  void Watch(const base::FilePath& local_path,
+             const base::FilePathWatcher::Callback& file_watcher_callback,
+             const BoolCallback& callback);
+
+ private:
+  // Called when a FilePathWatcher is created and started.
+  // |file_path_watcher| is NULL, if the watcher wasn't started successfully.
+  void OnWatcherStarted(const BoolCallback& callback,
+                        base::FilePathWatcher* file_path_watcher);
+
+  base::FilePathWatcher* file_watcher_;
+  base::FilePath local_path_;
+  base::FilePath virtual_path_;
+  ExtensionUsageRegistry extensions_;
+  int ref_count_;
+  bool is_remote_file_system_;
+
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate the weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<FileWatcherExtensions> weak_ptr_factory_;
+};
+
+#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_WATCHER_EXTENSIONS_H_
diff --git a/chrome/browser/chromeos/extensions/file_manager/mounted_disk_monitor.cc b/chrome/browser/chromeos/extensions/file_manager/mounted_disk_monitor.cc
new file mode 100644
index 0000000..4628179
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/file_manager/mounted_disk_monitor.cc
@@ -0,0 +1,114 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/extensions/file_manager/mounted_disk_monitor.h"
+
+#include "base/bind.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/power_manager_client.h"
+#include "content/public/browser/browser_thread.h"
+
+using chromeos::DBusThreadManager;
+using chromeos::disks::DiskMountManager;
+
+namespace {
+
+// Time span of the resuming process. All unmount events sent during this
+// time are considered as being part of remounting process, since remounting
+// is done just after resuming.
+const base::TimeDelta kResumingTimeSpan = base::TimeDelta::FromSeconds(5);
+
+}  // namespace
+
+MountedDiskMonitor::MountedDiskMonitor()
+    : is_resuming_(false),
+      weak_factory_(this) {
+  DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
+  DiskMountManager* disk_mount_manager = DiskMountManager::GetInstance();
+  if (disk_mount_manager) {
+    disk_mount_manager->AddObserver(this);
+    disk_mount_manager->RequestMountInfoRefresh();
+  }
+}
+
+MountedDiskMonitor::~MountedDiskMonitor() {
+  DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
+  DiskMountManager* disk_mount_manager = DiskMountManager::GetInstance();
+  if (disk_mount_manager)
+    disk_mount_manager->RemoveObserver(this);
+}
+
+void MountedDiskMonitor::SuspendImminent() {
+  is_resuming_ = false;
+  weak_factory_.InvalidateWeakPtrs();
+}
+
+void MountedDiskMonitor::SystemResumed(
+    const base::TimeDelta& sleep_duration) {
+  is_resuming_ = true;
+  // Undo any previous resets.
+  weak_factory_.InvalidateWeakPtrs();
+  base::MessageLoopProxy::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&MountedDiskMonitor::Reset,
+                 weak_factory_.GetWeakPtr()),
+      kResumingTimeSpan);
+}
+
+bool MountedDiskMonitor::DiskIsRemounting(
+    const DiskMountManager::Disk& disk) const {
+  return unmounted_while_resuming_.count(disk.fs_uuid()) > 0;
+}
+
+void MountedDiskMonitor::OnMountEvent(
+    chromeos::disks::DiskMountManager::MountEvent event,
+    chromeos::MountError error_code,
+    const chromeos::disks::DiskMountManager::MountPointInfo& mount_info) {
+  if (mount_info.mount_type != chromeos::MOUNT_TYPE_DEVICE)
+    return;
+
+  switch (event) {
+    case DiskMountManager::MOUNTING: {
+      DiskMountManager* disk_mount_manager = DiskMountManager::GetInstance();
+      const DiskMountManager::Disk* disk =
+          disk_mount_manager->FindDiskBySourcePath(mount_info.source_path);
+      if (!disk || error_code != chromeos::MOUNT_ERROR_NONE)
+        return;
+      mounted_disks_[mount_info.source_path] = disk->fs_uuid();
+      break;
+    }
+
+    case DiskMountManager::UNMOUNTING: {
+      DiskMap::iterator it = mounted_disks_.find(mount_info.source_path);
+      if (it == mounted_disks_.end())
+        return;
+      const std::string& fs_uuid = it->second;
+      if (is_resuming_)
+        unmounted_while_resuming_.insert(fs_uuid);
+      mounted_disks_.erase(it);
+      break;
+    }
+  }
+}
+
+void MountedDiskMonitor::OnDiskEvent(
+    chromeos::disks::DiskMountManager::DiskEvent event,
+    const chromeos::disks::DiskMountManager::Disk* disk) {
+}
+
+void MountedDiskMonitor::OnDeviceEvent(
+    chromeos::disks::DiskMountManager::DeviceEvent event,
+    const std::string& device_path) {
+}
+
+void MountedDiskMonitor::OnFormatEvent(
+    chromeos::disks::DiskMountManager::FormatEvent event,
+    chromeos::FormatError error_code,
+    const std::string& device_path) {
+}
+
+void MountedDiskMonitor::Reset() {
+  unmounted_while_resuming_.clear();
+  is_resuming_ = false;
+}
diff --git a/chrome/browser/chromeos/extensions/file_manager/mounted_disk_monitor.h b/chrome/browser/chromeos/extensions/file_manager/mounted_disk_monitor.h
new file mode 100644
index 0000000..98d7658
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/file_manager/mounted_disk_monitor.h
@@ -0,0 +1,71 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_MOUNTED_DISK_MONITOR_H_
+#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_MOUNTED_DISK_MONITOR_H_
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chromeos/dbus/power_manager_client.h"
+#include "chromeos/disks/disk_mount_manager.h"
+
+// Observes PowerManager and updates its state when the system suspends and
+// resumes. After the system resumes it will stay in "is_resuming" state for
+// couple of seconds. This is to give DiskManager time to process device
+// removed/added events (events for the devices that were present before suspend
+// should not trigger any new notifications or file manager windows).
+class MountedDiskMonitor
+    : public chromeos::PowerManagerClient::Observer,
+      public chromeos::disks::DiskMountManager::Observer {
+ public:
+  MountedDiskMonitor();
+  virtual ~MountedDiskMonitor();
+
+  // PowerManagerClient::Observer overrides:
+  virtual void SuspendImminent() OVERRIDE;
+  virtual void SystemResumed(const base::TimeDelta& sleep_duration) OVERRIDE;
+
+  // DiskMountManager::Observer overrides.
+  virtual void OnDiskEvent(
+      chromeos::disks::DiskMountManager::DiskEvent event,
+      const chromeos::disks::DiskMountManager::Disk* disk) OVERRIDE;
+  virtual void OnDeviceEvent(
+      chromeos::disks::DiskMountManager::DeviceEvent event,
+      const std::string& device_path) OVERRIDE;
+  virtual void OnMountEvent(
+      chromeos::disks::DiskMountManager::MountEvent event,
+      chromeos::MountError error_code,
+      const chromeos::disks::DiskMountManager::MountPointInfo& mount_info)
+      OVERRIDE;
+  virtual void OnFormatEvent(
+      chromeos::disks::DiskMountManager::FormatEvent event,
+      chromeos::FormatError error_code,
+      const std::string& device_path) OVERRIDE;
+
+  // Checks if the disk is being remounted. The disk is remounting if it has
+  // been unmounted during the resuming time span.
+  bool DiskIsRemounting(
+      const chromeos::disks::DiskMountManager::Disk& disk) const;
+ private:
+  // Maps source paths with corresponding uuids.
+  typedef std::map<std::string, std::string> DiskMap;
+
+  // Set of uuids.
+  typedef std::set<std::string> DiskSet;
+
+  void Reset();
+
+  bool is_resuming_;
+  DiskMap mounted_disks_;
+  DiskSet unmounted_while_resuming_;
+  base::WeakPtrFactory<MountedDiskMonitor> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(MountedDiskMonitor);
+};
+
+#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_MOUNTED_DISK_MONITOR_H_
diff --git a/chrome/browser/chromeos/extensions/file_manager/zip_file_creator.cc b/chrome/browser/chromeos/extensions/file_manager/zip_file_creator.cc
index facfe90..22cda01 100644
--- a/chrome/browser/chromeos/extensions/file_manager/zip_file_creator.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/zip_file_creator.cc
@@ -96,7 +96,8 @@
   dest_fd.auto_close = true;
 
   UtilityProcessHost* host = UtilityProcessHost::Create(
-      this, BrowserThread::GetMessageLoopProxyForThread(thread_identifier_));
+      this,
+      BrowserThread::GetMessageLoopProxyForThread(thread_identifier_).get());
   host->Send(new ChromeUtilityMsg_CreateZipFile(src_dir_, src_relative_paths_,
                                                 dest_fd));
 }
diff --git a/chrome/browser/chromeos/extensions/info_private_api.cc b/chrome/browser/chromeos/extensions/info_private_api.cc
index 8bd78aa..44db705 100644
--- a/chrome/browser/chromeos/extensions/info_private_api.cc
+++ b/chrome/browser/chromeos/extensions/info_private_api.cc
@@ -5,13 +5,11 @@
 #include "chrome/browser/chromeos/extensions/info_private_api.h"
 
 #include "base/values.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/system/statistics_provider.h"
 
-using chromeos::CrosLibrary;
 using chromeos::NetworkLibrary;
 
 namespace extensions {
@@ -66,7 +64,7 @@
     provider->GetMachineStatistic(chromeos::system::kHardwareClass, &hwid);
     return new base::StringValue(hwid);
   } else if (property_name == kPropertyHomeProvider) {
-    NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary();
+    NetworkLibrary* netlib = NetworkLibrary::Get();
     return new base::StringValue(netlib->GetCellularHomeCarrierId());
   } else if (property_name == kPropertyInitialLocale) {
     return new base::StringValue(
diff --git a/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc b/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc
index 8f0b432..128cd7f 100644
--- a/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc
+++ b/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc
@@ -6,9 +6,9 @@
 
 #include "base/command_line.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/extensions/input_method_event_router.h"
 #include "chrome/browser/extensions/api/test/test_api.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chromeos/ime/input_method_manager.h"
 #include "content/public/browser/notification_observer.h"
diff --git a/chrome/browser/chromeos/extensions/install_limiter.cc b/chrome/browser/chromeos/extensions/install_limiter.cc
index b25d820..2798af0 100644
--- a/chrome/browser/chromeos/extensions/install_limiter.cc
+++ b/chrome/browser/chromeos/extensions/install_limiter.cc
@@ -9,8 +9,8 @@
 #include "base/bind.h"
 #include "base/file_util.h"
 #include "base/threading/sequenced_worker_pool.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/extensions/install_limiter_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/chromeos/extensions/networking_private_apitest.cc b/chrome/browser/chromeos/extensions/networking_private_apitest.cc
index 0cb874a..fe7093c 100644
--- a/chrome/browser/chromeos/extensions/networking_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/networking_private_apitest.cc
@@ -2,12 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/callback.h"
 #include "base/command_line.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/login/user.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_types.h"
@@ -292,7 +294,8 @@
   policy.Set(policy::key::kOpenNetworkConfiguration,
              policy::POLICY_LEVEL_MANDATORY,
              policy::POLICY_SCOPE_USER,
-             Value::CreateStringValue(user_policy_blob));
+             Value::CreateStringValue(user_policy_blob),
+             NULL);
   provider_.UpdateChromePolicy(policy);
 
   content::RunAllPendingInMessageLoop();
diff --git a/chrome/browser/chromeos/extensions/networking_private_event_router.cc b/chrome/browser/chromeos/extensions/networking_private_event_router.cc
index 44ce9a4..97b3b60 100644
--- a/chrome/browser/chromeos/extensions/networking_private_event_router.cc
+++ b/chrome/browser/chromeos/extensions/networking_private_event_router.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/extensions/extension_system_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/extensions/api/networking_private.h"
+#include "chromeos/network/network_event_log.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
 #include "chromeos/network/onc/onc_constants.h"
@@ -96,8 +97,14 @@
   EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router();
   NetworkStateHandler::NetworkStateList networks;
   NetworkHandler::Get()->network_state_handler()->GetNetworkList(&networks);
-  if (!event_router->HasEventListener(kOnNetworkListChanged))
+  if (!event_router->HasEventListener(kOnNetworkListChanged)) {
+    // TODO(stevenjb): Remove logging once crbug.com/256881 is fixed
+    // (or at least reduce to LOG_DEBUG). Same with NET_LOG events below.
+    NET_LOG_EVENT("NetworkingPrivate.NetworkListChanged: No Listeners", "");
     return;
+  }
+
+  NET_LOG_EVENT("NetworkingPrivate.NetworkListChanged", "");
 
   std::vector<std::string> changes;
   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
@@ -117,9 +124,13 @@
 void NetworkingPrivateEventRouter::NetworkPropertiesUpdated(
     const NetworkState* network) {
   EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router();
-  if (!event_router->HasEventListener(kOnNetworksChanged))
+  if (!event_router->HasEventListener(kOnNetworksChanged)) {
+    NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated: No Listeners",
+                  network->path());
     return;
-
+  }
+  NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated",
+                network->path());
   scoped_ptr<base::ListValue> args(api::OnNetworksChanged::Create(
       std::vector<std::string>(1, network->path())));
   scoped_ptr<extensions::Event> extension_event(
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
index 228207e..1d79a69 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -29,7 +29,6 @@
 #include "chrome/common/chrome_paths.h"
 #include "chromeos/login/login_state.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
 #include "grit/app_locale_settings.h"
 #include "grit/generated_resources.h"
 #include "grit/platform_locale_settings.h"
@@ -39,6 +38,7 @@
 #include "ui/aura/window_observer.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/gurl.h"
 
 using base::BinaryValue;
 using content::BrowserThread;
@@ -77,13 +77,13 @@
 bool SaveData(int key, const std::string& file_name, const std::string& data) {
   base::FilePath data_dir;
   CHECK(PathService::Get(key, &data_dir));
-  if (!file_util::DirectoryExists(data_dir) &&
+  if (!base::DirectoryExists(data_dir) &&
       !file_util::CreateDirectory(data_dir)) {
     return false;
   }
   base::FilePath file_path = data_dir.Append(file_name);
 
-  return file_util::PathExists(file_path) ||
+  return base::PathExists(file_path) ||
          (file_util::WriteFile(file_path, data.c_str(),
                                data.size()) != -1);
 }
@@ -94,11 +94,11 @@
 // expected that we may try to access file which did not saved yet.
 bool GetData(const base::FilePath& path, std::string* data) {
   base::FilePath data_dir = path.DirName();
-  if (!file_util::DirectoryExists(data_dir) &&
+  if (!base::DirectoryExists(data_dir) &&
       !file_util::CreateDirectory(data_dir))
     return false;
 
-  return !file_util::PathExists(path) ||
+  return !base::PathExists(path) ||
          file_util::ReadFileToString(path, data);
 }
 
@@ -382,10 +382,10 @@
   std::string data;
   base::FilePath path = file_path;
 
-  if (!file_util::PathExists(file_path))
+  if (!base::PathExists(file_path))
     path = fallback_path;
 
-  if (file_util::PathExists(path) &&
+  if (base::PathExists(path) &&
       file_util::ReadFileToString(path, &data)) {
     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
         base::Bind(&WallpaperPrivateSetWallpaperIfExistsFunction::StartDecode,
@@ -492,7 +492,7 @@
     CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS, &wallpaper_dir));
     base::FilePath file_path = wallpaper_dir.Append(
         file_name).InsertBeforeExtension(chromeos::kSmallWallpaperSuffix);
-    if (file_util::PathExists(file_path))
+    if (base::PathExists(file_path))
       return;
     // Generates and saves small resolution wallpaper. Uses CENTER_CROPPED to
     // maintain the aspect ratio after resize.
@@ -628,7 +628,7 @@
   DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
       sequence_token_));
   chromeos::UserImage wallpaper(*image.get());
-  if (!file_util::PathExists(thumbnail_path.DirName()))
+  if (!base::PathExists(thumbnail_path.DirName()))
     file_util::CreateDirectory(thumbnail_path.DirName());
 
   scoped_refptr<base::RefCountedBytes> data;
@@ -893,7 +893,7 @@
   if (source == kOnlineSource) {
     base::FilePath wallpaper_dir;
     CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS, &wallpaper_dir));
-    if (file_util::DirectoryExists(wallpaper_dir)) {
+    if (base::DirectoryExists(wallpaper_dir)) {
       base::FileEnumerator files(wallpaper_dir, false,
                                  base::FileEnumerator::FILES);
       for (base::FilePath current = files.Next(); !current.empty();
diff --git a/chrome/browser/chromeos/external_protocol_dialog.cc b/chrome/browser/chromeos/external_protocol_dialog.cc
index c44ce44..724cd54 100644
--- a/chrome/browser/chromeos/external_protocol_dialog.cc
+++ b/chrome/browser/chromeos/external_protocol_dialog.cc
@@ -11,13 +11,13 @@
 #include "chrome/browser/tab_contents/tab_util.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_view.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/text/text_elider.h"
 #include "ui/views/controls/message_box_view.h"
 #include "ui/views/widget/widget.h"
+#include "url/gurl.h"
 
 using content::WebContents;
 
diff --git a/chrome/browser/chromeos/fileapi/cros_mount_point_provider.cc b/chrome/browser/chromeos/fileapi/file_system_backend.cc
similarity index 74%
rename from chrome/browser/chromeos/fileapi/cros_mount_point_provider.cc
rename to chrome/browser/chromeos/fileapi/file_system_backend.cc
index 82da083..1cc7457 100644
--- a/chrome/browser/chromeos/fileapi/cros_mount_point_provider.cc
+++ b/chrome/browser/chromeos/fileapi/file_system_backend.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/chromeos/fileapi/cros_mount_point_provider.h"
+#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
 
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
@@ -12,9 +12,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/lock.h"
 #include "chrome/browser/chromeos/fileapi/file_access_permissions.h"
-#include "chrome/browser/chromeos/fileapi/remote_file_stream_writer.h"
-#include "chrome/browser/chromeos/fileapi/remote_file_system_operation.h"
+#include "chrome/browser/chromeos/fileapi/file_system_backend_delegate.h"
 #include "chromeos/dbus/cros_disks_client.h"
+#include "webkit/browser/blob/file_stream_reader.h"
 #include "webkit/browser/fileapi/async_file_util_adapter.h"
 #include "webkit/browser/fileapi/copy_or_move_file_validator.h"
 #include "webkit/browser/fileapi/external_mount_points.h"
@@ -37,7 +37,7 @@
 namespace chromeos {
 
 // static
-bool CrosMountPointProvider::CanHandleURL(const fileapi::FileSystemURL& url) {
+bool FileSystemBackend::CanHandleURL(const fileapi::FileSystemURL& url) {
   if (!url.is_valid())
     return false;
   return url.type() == fileapi::kFileSystemTypeNativeLocal ||
@@ -45,7 +45,8 @@
          url.type() == fileapi::kFileSystemTypeDrive;
 }
 
-CrosMountPointProvider::CrosMountPointProvider(
+FileSystemBackend::FileSystemBackend(
+    FileSystemBackendDelegate* drive_delegate,
     scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy,
     scoped_refptr<fileapi::ExternalMountPoints> mount_points,
     fileapi::ExternalMountPoints* system_mount_points)
@@ -53,14 +54,15 @@
       file_access_permissions_(new FileAccessPermissions()),
       local_file_util_(new fileapi::AsyncFileUtilAdapter(
           new fileapi::IsolatedFileUtil())),
+      drive_delegate_(drive_delegate),
       mount_points_(mount_points),
       system_mount_points_(system_mount_points) {
 }
 
-CrosMountPointProvider::~CrosMountPointProvider() {
+FileSystemBackend::~FileSystemBackend() {
 }
 
-void CrosMountPointProvider::AddSystemMountPoints() {
+void FileSystemBackend::AddSystemMountPoints() {
   // RegisterFileSystem() is no-op if the mount point with the same name
   // already exists, hence it's safe to call without checking if a mount
   // point already exists or not.
@@ -91,7 +93,7 @@
       base::FilePath(FILE_PATH_LITERAL("/usr/share/oem")));
 }
 
-bool CrosMountPointProvider::CanHandleType(fileapi::FileSystemType type) const {
+bool FileSystemBackend::CanHandleType(fileapi::FileSystemType type) const {
   switch (type) {
     case fileapi::kFileSystemTypeExternal:
     case fileapi::kFileSystemTypeDrive:
@@ -104,31 +106,25 @@
   }
 }
 
-void CrosMountPointProvider::OpenFileSystem(
+void FileSystemBackend::InitializeFileSystem(
     const GURL& origin_url,
     fileapi::FileSystemType type,
     fileapi::OpenFileSystemMode mode,
-    const OpenFileSystemCallback& callback) {
+    fileapi::FileSystemContext* context,
+    const InitializeFileSystemCallback& callback) {
   DCHECK(fileapi::IsolatedContext::IsIsolatedType(type));
   // Nothing to validate for external filesystem.
-  callback.Run(base::PLATFORM_FILE_OK);
+  callback.Run(GetFileSystemRootURI(origin_url, type),
+               GetFileSystemName(origin_url, type),
+               base::PLATFORM_FILE_OK);
 }
 
-fileapi::FileSystemQuotaUtil* CrosMountPointProvider::GetQuotaUtil() {
+fileapi::FileSystemQuotaUtil* FileSystemBackend::GetQuotaUtil() {
   // No quota support.
   return NULL;
 }
 
-void CrosMountPointProvider::DeleteFileSystem(
-    const GURL& origin_url,
-    fileapi::FileSystemType type,
-    fileapi::FileSystemContext* context,
-    const DeleteFileSystemCallback& callback) {
-  NOTREACHED();
-  callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
-}
-
-bool CrosMountPointProvider::IsAccessAllowed(
+bool FileSystemBackend::IsAccessAllowed(
     const fileapi::FileSystemURL& url) const {
   if (!url.is_valid())
     return false;
@@ -154,7 +150,7 @@
                                                        url.virtual_path());
 }
 
-void CrosMountPointProvider::GrantFullAccessToExtension(
+void FileSystemBackend::GrantFullAccessToExtension(
     const std::string& extension_id) {
   DCHECK(special_storage_policy_->IsFileHandler(extension_id));
   if (!special_storage_policy_->IsFileHandler(extension_id))
@@ -171,7 +167,7 @@
   }
 }
 
-void CrosMountPointProvider::GrantFileAccessToExtension(
+void FileSystemBackend::GrantFileAccessToExtension(
     const std::string& extension_id, const base::FilePath& virtual_path) {
   // All we care about here is access from extensions for now.
   DCHECK(special_storage_policy_->IsFileHandler(extension_id));
@@ -195,12 +191,12 @@
   file_access_permissions_->GrantAccessPermission(extension_id, virtual_path);
 }
 
-void CrosMountPointProvider::RevokeAccessForExtension(
+void FileSystemBackend::RevokeAccessForExtension(
       const std::string& extension_id) {
   file_access_permissions_->RevokePermissions(extension_id);
 }
 
-std::vector<base::FilePath> CrosMountPointProvider::GetRootDirectories() const {
+std::vector<base::FilePath> FileSystemBackend::GetRootDirectories() const {
   std::vector<fileapi::MountPoints::MountPointInfo> mount_points;
   mount_points_->AddMountPointInfosTo(&mount_points);
   system_mount_points_->AddMountPointInfosTo(&mount_points);
@@ -211,29 +207,32 @@
   return root_dirs;
 }
 
-fileapi::FileSystemFileUtil* CrosMountPointProvider::GetFileUtil(
+fileapi::FileSystemFileUtil* FileSystemBackend::GetFileUtil(
     fileapi::FileSystemType type) {
   DCHECK(type == fileapi::kFileSystemTypeNativeLocal ||
          type == fileapi::kFileSystemTypeRestrictedNativeLocal);
   return local_file_util_->sync_file_util();
 }
 
-fileapi::AsyncFileUtil* CrosMountPointProvider::GetAsyncFileUtil(
+fileapi::AsyncFileUtil* FileSystemBackend::GetAsyncFileUtil(
     fileapi::FileSystemType type) {
+  if (type == fileapi::kFileSystemTypeDrive)
+    return drive_delegate_->GetAsyncFileUtil(type);
+
   DCHECK(type == fileapi::kFileSystemTypeNativeLocal ||
          type == fileapi::kFileSystemTypeRestrictedNativeLocal);
   return local_file_util_.get();
 }
 
 fileapi::CopyOrMoveFileValidatorFactory*
-CrosMountPointProvider::GetCopyOrMoveFileValidatorFactory(
+FileSystemBackend::GetCopyOrMoveFileValidatorFactory(
     fileapi::FileSystemType type, base::PlatformFileError* error_code) {
   DCHECK(error_code);
   *error_code = base::PLATFORM_FILE_OK;
   return NULL;
 }
 
-fileapi::FileSystemOperation* CrosMountPointProvider::CreateFileSystemOperation(
+fileapi::FileSystemOperation* FileSystemBackend::CreateFileSystemOperation(
     const fileapi::FileSystemURL& url,
     fileapi::FileSystemContext* context,
     base::PlatformFileError* error_code) const {
@@ -244,15 +243,8 @@
     return NULL;
   }
 
-  if (url.type() == fileapi::kFileSystemTypeDrive) {
-    fileapi::RemoteFileSystemProxyInterface* remote_proxy =
-        GetRemoteProxy(url.filesystem_id());
-    if (!remote_proxy) {
-      *error_code = base::PLATFORM_FILE_ERROR_NOT_FOUND;
-      return NULL;
-    }
-    return new RemoteFileSystemOperation(remote_proxy);
-  }
+  if (url.type() == fileapi::kFileSystemTypeDrive)
+    return drive_delegate_->CreateFileSystemOperation(url, context, error_code);
 
   DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal ||
          url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal);
@@ -264,7 +256,7 @@
 }
 
 scoped_ptr<webkit_blob::FileStreamReader>
-CrosMountPointProvider::CreateFileStreamReader(
+FileSystemBackend::CreateFileStreamReader(
     const fileapi::FileSystemURL& url,
     int64 offset,
     const base::Time& expected_modification_time,
@@ -275,13 +267,8 @@
     return scoped_ptr<webkit_blob::FileStreamReader>();
 
   if (url.type() == fileapi::kFileSystemTypeDrive) {
-    fileapi::RemoteFileSystemProxyInterface* remote_proxy =
-        GetRemoteProxy(url.filesystem_id());
-    if (!remote_proxy)
-      return scoped_ptr<webkit_blob::FileStreamReader>();
-    return remote_proxy->CreateFileStreamReader(
-        context->task_runners()->file_task_runner(),
-        url, offset, expected_modification_time);
+    return drive_delegate_->CreateFileStreamReader(
+        url, offset, expected_modification_time, context);
   }
 
   return scoped_ptr<webkit_blob::FileStreamReader>(
@@ -290,7 +277,7 @@
 }
 
 scoped_ptr<fileapi::FileStreamWriter>
-CrosMountPointProvider::CreateFileStreamWriter(
+FileSystemBackend::CreateFileStreamWriter(
     const fileapi::FileSystemURL& url,
     int64 offset,
     fileapi::FileSystemContext* context) const {
@@ -299,16 +286,8 @@
   if (!IsAccessAllowed(url))
     return scoped_ptr<fileapi::FileStreamWriter>();
 
-  if (url.type() == fileapi::kFileSystemTypeDrive) {
-    fileapi::RemoteFileSystemProxyInterface* remote_proxy =
-        GetRemoteProxy(url.filesystem_id());
-    if (!remote_proxy)
-      return scoped_ptr<fileapi::FileStreamWriter>();
-    return scoped_ptr<fileapi::FileStreamWriter>(
-        new RemoteFileStreamWriter(
-            remote_proxy, url, offset,
-            context->task_runners()->file_task_runner()));
-  }
+  if (url.type() == fileapi::kFileSystemTypeDrive)
+    return drive_delegate_->CreateFileStreamWriter(url, offset, context);
 
   if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal)
     return scoped_ptr<fileapi::FileStreamWriter>();
@@ -319,23 +298,14 @@
           context->task_runners()->file_task_runner(), url.path(), offset));
 }
 
-bool CrosMountPointProvider::GetVirtualPath(
+bool FileSystemBackend::GetVirtualPath(
     const base::FilePath& filesystem_path,
     base::FilePath* virtual_path) {
   return mount_points_->GetVirtualPath(filesystem_path, virtual_path) ||
          system_mount_points_->GetVirtualPath(filesystem_path, virtual_path);
 }
 
-fileapi::RemoteFileSystemProxyInterface* CrosMountPointProvider::GetRemoteProxy(
-    const std::string& mount_name) const {
-  fileapi::RemoteFileSystemProxyInterface* proxy =
-      mount_points_->GetRemoteFileSystemProxy(mount_name);
-  if (proxy)
-    return proxy;
-  return system_mount_points_->GetRemoteFileSystemProxy(mount_name);
-}
-
-base::FilePath CrosMountPointProvider::GetFileSystemRootPath(
+base::FilePath FileSystemBackend::GetFileSystemRootPath(
     const fileapi::FileSystemURL& url) const {
   DCHECK(fileapi::IsolatedContext::IsIsolatedType(url.mount_type()));
   if (!url.is_valid())
diff --git a/chrome/browser/chromeos/fileapi/cros_mount_point_provider.h b/chrome/browser/chromeos/fileapi/file_system_backend.h
similarity index 79%
rename from chrome/browser/chromeos/fileapi/cros_mount_point_provider.h
rename to chrome/browser/chromeos/fileapi/file_system_backend.h
index c68589d..d08c34a 100644
--- a/chrome/browser/chromeos/fileapi/cros_mount_point_provider.h
+++ b/chrome/browser/chromeos/fileapi/file_system_backend.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_CHROMEOS_FILEAPI_CROS_MOUNT_POINT_PROVIDER_H_
-#define CHROME_BROWSER_CHROMEOS_FILEAPI_CROS_MOUNT_POINT_PROVIDER_H_
+#ifndef CHROME_BROWSER_CHROMEOS_FILEAPI_FILE_SYSTEM_BACKEND_H_
+#define CHROME_BROWSER_CHROMEOS_FILEAPI_FILE_SYSTEM_BACKEND_H_
 
 #include <map>
 #include <string>
@@ -13,7 +13,7 @@
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/synchronization/lock.h"
-#include "webkit/browser/fileapi/file_system_mount_point_provider.h"
+#include "webkit/browser/fileapi/file_system_backend.h"
 #include "webkit/browser/quota/special_storage_policy.h"
 #include "webkit/browser/webkit_storage_browser_export.h"
 #include "webkit/common/fileapi/file_system_types.h"
@@ -29,10 +29,11 @@
 
 namespace chromeos {
 
+class FileSystemBackendDelegate;
 class FileAccessPermissions;
 
-// CrosMountPointProvider is a Chrome OS specific implementation of
-// ExternalFileSystemMountPointProvider. This class is responsible for a
+// FileSystemBackend is a Chrome OS specific implementation of
+// ExternalFileSystemBackend. This class is responsible for a
 // number of things, including:
 //
 // - Add system mount points
@@ -63,20 +64,20 @@
 //
 //   filesystem:<origin>/external/<mount_name>/...
 //
-class CrosMountPointProvider
-    : public fileapi::ExternalFileSystemMountPointProvider {
+class FileSystemBackend : public fileapi::ExternalFileSystemBackend {
  public:
-  using fileapi::FileSystemMountPointProvider::OpenFileSystemCallback;
-  using fileapi::FileSystemMountPointProvider::DeleteFileSystemCallback;
+  using fileapi::FileSystemBackend::InitializeFileSystemCallback;
 
-  // CrosMountPointProvider will take an ownership of a |mount_points|
+  // FileSystemBackend will take an ownership of a |mount_points|
   // reference. On the other hand, |system_mount_points| will be kept as a raw
-  // pointer and it should outlive CrosMountPointProvider instance.
-  CrosMountPointProvider(
+  // pointer and it should outlive FileSystemBackend instance.
+  // The ownership of |drive_delegate| is also taken.
+  FileSystemBackend(
+      FileSystemBackendDelegate* drive_delegate,
       scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy,
       scoped_refptr<fileapi::ExternalMountPoints> mount_points,
       fileapi::ExternalMountPoints* system_mount_points);
-  virtual ~CrosMountPointProvider();
+  virtual ~FileSystemBackend();
 
   // Adds system mount points, such as "archive", and "removable". This
   // function is no-op if these mount points are already present.
@@ -87,13 +88,14 @@
   // This could be called on any threads.
   static bool CanHandleURL(const fileapi::FileSystemURL& url);
 
-  // fileapi::FileSystemMountPointProvider overrides.
+  // fileapi::FileSystemBackend overrides.
   virtual bool CanHandleType(fileapi::FileSystemType type) const OVERRIDE;
-  virtual void OpenFileSystem(
+  virtual void InitializeFileSystem(
       const GURL& origin_url,
       fileapi::FileSystemType type,
       fileapi::OpenFileSystemMode mode,
-      const OpenFileSystemCallback& callback) OVERRIDE;
+      fileapi::FileSystemContext* context,
+      const InitializeFileSystemCallback& callback) OVERRIDE;
   virtual fileapi::FileSystemFileUtil* GetFileUtil(
       fileapi::FileSystemType type) OVERRIDE;
   virtual fileapi::AsyncFileUtil* GetAsyncFileUtil(
@@ -116,13 +118,8 @@
       int64 offset,
       fileapi::FileSystemContext* context) const OVERRIDE;
   virtual fileapi::FileSystemQuotaUtil* GetQuotaUtil() OVERRIDE;
-  virtual void DeleteFileSystem(
-      const GURL& origin_url,
-      fileapi::FileSystemType type,
-      fileapi::FileSystemContext* context,
-      const DeleteFileSystemCallback& callback) OVERRIDE;
 
-  // fileapi::ExternalFileSystemMountPointProvider overrides.
+  // fileapi::ExternalFileSystemBackend overrides.
   virtual bool IsAccessAllowed(const fileapi::FileSystemURL& url)
       const OVERRIDE;
   virtual std::vector<base::FilePath> GetRootDirectories() const OVERRIDE;
@@ -137,14 +134,15 @@
                               base::FilePath* virtual_path) OVERRIDE;
 
  private:
-  fileapi::RemoteFileSystemProxyInterface* GetRemoteProxy(
-      const std::string& mount_name) const;
   base::FilePath GetFileSystemRootPath(const fileapi::FileSystemURL& url) const;
 
   scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
   scoped_ptr<FileAccessPermissions> file_access_permissions_;
   scoped_ptr<fileapi::AsyncFileUtilAdapter> local_file_util_;
 
+  // The Delegate instance for the drive file system related operation.
+  scoped_ptr<FileSystemBackendDelegate> drive_delegate_;
+
   // Mount points specific to the owning context (i.e. per-profile mount
   // points).
   //
@@ -159,12 +157,12 @@
   scoped_refptr<fileapi::ExternalMountPoints> mount_points_;
 
   // Globally visible mount points. System MountPonts instance should outlive
-  // all CrosMountPointProvider instances, so raw pointer is safe.
+  // all FileSystemBackend instances, so raw pointer is safe.
   fileapi::ExternalMountPoints* system_mount_points_;
 
-  DISALLOW_COPY_AND_ASSIGN(CrosMountPointProvider);
+  DISALLOW_COPY_AND_ASSIGN(FileSystemBackend);
 };
 
 }  // namespace chromeos
 
-#endif  // CHROME_BROWSER_CHROMEOS_FILEAPI_CROS_MOUNT_POINT_PROVIDER_H_
+#endif  // CHROME_BROWSER_CHROMEOS_FILEAPI_FILE_SYSTEM_BACKEND_H_
diff --git a/chrome/browser/chromeos/fileapi/file_system_backend_delegate.h b/chrome/browser/chromeos/fileapi/file_system_backend_delegate.h
new file mode 100644
index 0000000..4367d2e
--- /dev/null
+++ b/chrome/browser/chromeos/fileapi/file_system_backend_delegate.h
@@ -0,0 +1,65 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_FILEAPI_FILE_SYSTEM_BACKEND_DELEGATE_H_
+#define CHROME_BROWSER_CHROMEOS_FILEAPI_FILE_SYSTEM_BACKEND_DELEGATE_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/platform_file.h"
+#include "webkit/common/fileapi/file_system_types.h"
+
+namespace base {
+class Time;
+}  // namespace base
+
+namespace fileapi {
+class AsyncFileUtil;
+class FileSystemContext;
+class FileSystemOperation;
+class FileSystemURL;
+class FileStreamWriter;
+}  // namespace fileapi
+
+namespace webkit_blob {
+class FileStreamReader;
+}  // namespace webkit_blob
+
+namespace chromeos {
+
+// This is delegate interface to inject the implementation of the some methods
+// of FileSystemBackend. The main goal is to inject Drive File System.
+class FileSystemBackendDelegate {
+ public:
+  virtual ~FileSystemBackendDelegate() {}
+
+  // Called from FileSystemBackend::GetAsyncFileUtil().
+  virtual fileapi::AsyncFileUtil* GetAsyncFileUtil(
+      fileapi::FileSystemType type) = 0;
+
+  // Called from FileSystemBackend::CreateFileStreamReader().
+  virtual scoped_ptr<webkit_blob::FileStreamReader> CreateFileStreamReader(
+      const fileapi::FileSystemURL& url,
+      int64 offset,
+      const base::Time& expected_modification_time,
+      fileapi::FileSystemContext* context) = 0;
+
+  // Called from FileSystemBackend::CreateFileStreamWriter().
+  virtual scoped_ptr<fileapi::FileStreamWriter> CreateFileStreamWriter(
+      const fileapi::FileSystemURL& url,
+      int64 offset,
+      fileapi::FileSystemContext* context) = 0;
+
+  // Called from FileSystemBackend::CreateFileSystemOperation().
+  // TODO(hidehiko): Get rid of this method when we merge the
+  // {Remote,Local}FileSystemOperation.
+  virtual fileapi::FileSystemOperation* CreateFileSystemOperation(
+      const fileapi::FileSystemURL& url,
+      fileapi::FileSystemContext* context,
+      base::PlatformFileError* error_code) = 0;
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_FILEAPI_FILE_SYSTEM_BACKEND_DELEGATE_H_
diff --git a/chrome/browser/chromeos/fileapi/cros_mount_point_provider_unittest.cc b/chrome/browser/chromeos/fileapi/file_system_backend_unittest.cc
similarity index 83%
rename from chrome/browser/chromeos/fileapi/cros_mount_point_provider_unittest.cc
rename to chrome/browser/chromeos/fileapi/file_system_backend_unittest.cc
index b74bdf8..0bef727 100644
--- a/chrome/browser/chromeos/fileapi/cros_mount_point_provider_unittest.cc
+++ b/chrome/browser/chromeos/fileapi/file_system_backend_unittest.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/chromeos/fileapi/cros_mount_point_provider.h"
+#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
 
 #include <set>
 
 #include "base/files/file_path.h"
 #include "base/path_service.h"
 #include "chromeos/dbus/cros_disks_client.h"
-#include "googleurl/src/url_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/url_util.h"
 #include "webkit/browser/fileapi/external_mount_points.h"
 #include "webkit/browser/fileapi/file_permission_policy.h"
 #include "webkit/browser/fileapi/file_system_url.h"
@@ -33,17 +33,18 @@
       base::FilePath::FromUTF8Unsafe(path));
 }
 
-TEST(CrosMountPointProviderTest, DefaultMountPoints) {
+TEST(ChromeOSFileSystemBackendTest, DefaultMountPoints) {
   scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
       new quota::MockSpecialStoragePolicy();
   scoped_refptr<fileapi::ExternalMountPoints> mount_points(
       fileapi::ExternalMountPoints::CreateRefCounted());
-  chromeos::CrosMountPointProvider provider(
+  chromeos::FileSystemBackend backend(
+      NULL,  // drive_delegate
       storage_policy,
       mount_points.get(),
       fileapi::ExternalMountPoints::GetSystemInstance());
-  provider.AddSystemMountPoints();
-  std::vector<base::FilePath> root_dirs = provider.GetRootDirectories();
+  backend.AddSystemMountPoints();
+  std::vector<base::FilePath> root_dirs = backend.GetRootDirectories();
   std::set<base::FilePath> root_dirs_set(root_dirs.begin(), root_dirs.end());
 
   // By default there should be 4 mount points (in system mount points):
@@ -59,7 +60,7 @@
   EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/usr/share/oem"))));
 }
 
-TEST(CrosMountPointProviderTest, GetRootDirectories) {
+TEST(ChromeOSFileSystemBackendTest, GetRootDirectories) {
   scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
       new quota::MockSpecialStoragePolicy();
   scoped_refptr<fileapi::ExternalMountPoints> mount_points(
@@ -68,12 +69,13 @@
   scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
       fileapi::ExternalMountPoints::CreateRefCounted());
 
-  chromeos::CrosMountPointProvider provider(
+  chromeos::FileSystemBackend backend(
+      NULL,  // drive_delegate
       storage_policy,
       mount_points.get(),
       system_mount_points.get());
 
-  const size_t initial_root_dirs_size = provider.GetRootDirectories().size();
+  const size_t initial_root_dirs_size = backend.GetRootDirectories().size();
 
   // Register 'local' test mount points.
   mount_points->RegisterFileSystem("c",
@@ -91,7 +93,7 @@
                                           fileapi::kFileSystemTypeNativeLocal,
                                           base::FilePath(FPL("/g/d/e")));
 
-  std::vector<base::FilePath> root_dirs = provider.GetRootDirectories();
+  std::vector<base::FilePath> root_dirs = backend.GetRootDirectories();
   std::set<base::FilePath> root_dirs_set(root_dirs.begin(), root_dirs.end());
   EXPECT_EQ(initial_root_dirs_size + 4, root_dirs.size());
   EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/a/b/c"))));
@@ -100,7 +102,7 @@
   EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/g/d/e"))));
 }
 
-TEST(CrosMountPointProviderTest, AccessPermissions) {
+TEST(ChromeOSFileSystemBackendTest, AccessPermissions) {
   url_util::AddStandardScheme("chrome-extension");
 
   scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy =
@@ -109,7 +111,8 @@
       fileapi::ExternalMountPoints::CreateRefCounted());
   scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
       fileapi::ExternalMountPoints::CreateRefCounted());
-  chromeos::CrosMountPointProvider provider(
+  chromeos::FileSystemBackend backend(
+      NULL,  // drive_delegate
       storage_policy,
       mount_points.get(),
       system_mount_points.get());
@@ -132,47 +135,47 @@
       fileapi::kFileSystemTypeRestrictedNativeLocal,
       base::FilePath(FPL("/usr/share/oem"))));
 
-  // Provider specific mount point access.
-  EXPECT_FALSE(provider.IsAccessAllowed(
+  // Backend specific mount point access.
+  EXPECT_FALSE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "removable/foo", mount_points.get())));
 
-  provider.GrantFileAccessToExtension(extension,
+  backend.GrantFileAccessToExtension(extension,
                                       base::FilePath(FPL("removable/foo")));
-  EXPECT_TRUE(provider.IsAccessAllowed(
+  EXPECT_TRUE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "removable/foo", mount_points.get())));
-  EXPECT_FALSE(provider.IsAccessAllowed(
+  EXPECT_FALSE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "removable/foo1", mount_points.get())));
 
   // System mount point access.
-  EXPECT_FALSE(provider.IsAccessAllowed(
+  EXPECT_FALSE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "system/foo", system_mount_points.get())));
 
-  provider.GrantFileAccessToExtension(extension,
+  backend.GrantFileAccessToExtension(extension,
                                       base::FilePath(FPL("system/foo")));
-  EXPECT_TRUE(provider.IsAccessAllowed(
+  EXPECT_TRUE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "system/foo", system_mount_points.get())));
-  EXPECT_FALSE(provider.IsAccessAllowed(
+  EXPECT_FALSE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "system/foo1",
                           system_mount_points.get())));
 
   // oem is restricted file system.
-  provider.GrantFileAccessToExtension(
+  backend.GrantFileAccessToExtension(
       extension, base::FilePath(FPL("oem/foo")));
   // The extension should not be able to access the file even if
   // GrantFileAccessToExtension was called.
-  EXPECT_FALSE(provider.IsAccessAllowed(
+  EXPECT_FALSE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "oem/foo", mount_points.get())));
 
-  provider.GrantFullAccessToExtension(extension);
+  backend.GrantFullAccessToExtension(extension);
   // The extension should be able to access restricted file system after it was
   // granted full access.
-  EXPECT_TRUE(provider.IsAccessAllowed(
+  EXPECT_TRUE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "oem/foo", mount_points.get())));
   // The extension which was granted full access should be able to access any
   // path on current file systems.
-  EXPECT_TRUE(provider.IsAccessAllowed(
+  EXPECT_TRUE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "removable/foo1", mount_points.get())));
-  EXPECT_TRUE(provider.IsAccessAllowed(
+  EXPECT_TRUE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "system/foo1",
                           system_mount_points.get())));
 
@@ -182,11 +185,11 @@
       "test",
       fileapi::kFileSystemTypeNativeLocal,
       base::FilePath(FPL("/foo/test"))));
-  EXPECT_FALSE(provider.IsAccessAllowed(
+  EXPECT_FALSE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "test_/foo", mount_points.get())));
 
-  provider.RevokeAccessForExtension(extension);
-  EXPECT_FALSE(provider.IsAccessAllowed(
+  backend.RevokeAccessForExtension(extension);
+  EXPECT_FALSE(backend.IsAccessAllowed(
       CreateFileSystemURL(extension, "removable/foo", mount_points.get())));
 
   fileapi::FileSystemURL internal_url = FileSystemURL::CreateForTest(
@@ -194,23 +197,25 @@
       fileapi::kFileSystemTypeExternal,
       base::FilePath(FPL("removable/")));
   // Internal WebUI should have full access.
-  EXPECT_TRUE(provider.IsAccessAllowed(internal_url));
+  EXPECT_TRUE(backend.IsAccessAllowed(internal_url));
 }
 
-TEST(CrosMountPointProvider, GetVirtualPathConflictWithSystemPoints) {
+TEST(ChromeOSFileSystemBackendTest, GetVirtualPathConflictWithSystemPoints) {
   scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy =
       new quota::MockSpecialStoragePolicy();
   scoped_refptr<fileapi::ExternalMountPoints> mount_points(
       fileapi::ExternalMountPoints::CreateRefCounted());
   scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
       fileapi::ExternalMountPoints::CreateRefCounted());
-  chromeos::CrosMountPointProvider provider(storage_policy,
+  chromeos::FileSystemBackend backend(
+      NULL,  // drive_delegate
+      storage_policy,
       mount_points.get(),
       system_mount_points.get());
 
   const fileapi::FileSystemType type = fileapi::kFileSystemTypeNativeLocal;
 
-  // Provider specific mount points.
+  // Backend specific mount points.
   ASSERT_TRUE(
       mount_points->RegisterFileSystem("b", type, base::FilePath(FPL("/a/b"))));
   ASSERT_TRUE(
@@ -251,7 +256,7 @@
     base::FilePath virtual_path(FPL("/mount"));
     base::FilePath local_path(kTestCases[i].local_path);
     EXPECT_EQ(kTestCases[i].success,
-              provider.GetVirtualPath(local_path, &virtual_path))
+              backend.GetVirtualPath(local_path, &virtual_path))
         << "Resolving " << kTestCases[i].local_path;
 
     // There are no guarantees for |virtual_path| value if |GetVirtualPath|
diff --git a/chrome/browser/chromeos/fileapi/remote_file_stream_writer.cc b/chrome/browser/chromeos/fileapi/remote_file_stream_writer.cc
deleted file mode 100644
index 5f2db47..0000000
--- a/chrome/browser/chromeos/fileapi/remote_file_stream_writer.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/fileapi/remote_file_stream_writer.h"
-
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "webkit/browser/blob/local_file_stream_reader.h"
-#include "webkit/browser/fileapi/local_file_stream_writer.h"
-#include "webkit/browser/fileapi/remote_file_system_proxy.h"
-#include "webkit/common/blob/shareable_file_reference.h"
-
-namespace chromeos {
-
-RemoteFileStreamWriter::RemoteFileStreamWriter(
-    const scoped_refptr<fileapi::RemoteFileSystemProxyInterface>&
-        remote_filesystem,
-    const fileapi::FileSystemURL& url,
-    int64 offset,
-    base::TaskRunner *local_task_runner)
-    : remote_filesystem_(remote_filesystem),
-      local_task_runner_(local_task_runner),
-      url_(url),
-      initial_offset_(offset),
-      has_pending_create_snapshot_(false),
-      weak_factory_(this) {
-}
-
-RemoteFileStreamWriter::~RemoteFileStreamWriter() {
-}
-
-int RemoteFileStreamWriter::Write(net::IOBuffer* buf,
-                                  int buf_len,
-                                  const net::CompletionCallback& callback) {
-  DCHECK(!has_pending_create_snapshot_);
-  DCHECK(pending_cancel_callback_.is_null());
-
-  if (!local_file_writer_) {
-    has_pending_create_snapshot_ = true;
-    // In this RemoteFileStreamWriter, we only create snapshot file and don't
-    // have explicit close operation. This is ok, because close is automatically
-    // triggered by a refcounted |file_ref_| passed to OnFileOpened, from the
-    // destructor of RemoteFileStreamWriter.
-    remote_filesystem_->CreateWritableSnapshotFile(
-        url_,
-        base::Bind(&RemoteFileStreamWriter::OnFileOpened,
-                   weak_factory_.GetWeakPtr(),
-                   make_scoped_refptr(buf),
-                   buf_len,
-                   callback));
-    return net::ERR_IO_PENDING;
-  }
-  return local_file_writer_->Write(buf, buf_len, callback);
-}
-
-void RemoteFileStreamWriter::OnFileOpened(
-    net::IOBuffer* buf,
-    int buf_len,
-    const net::CompletionCallback& callback,
-    base::PlatformFileError open_result,
-    const base::FilePath& local_path,
-    const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
-  has_pending_create_snapshot_ = false;
-  if (!pending_cancel_callback_.is_null()) {
-    InvokePendingCancelCallback(net::OK);
-    return;
-  }
-
-  if (open_result != base::PLATFORM_FILE_OK) {
-    callback.Run(net::PlatformFileErrorToNetError(open_result));
-    return;
-  }
-
-  // Hold the reference to the file. Releasing the reference notifies the file
-  // system about to close file.
-  file_ref_ = file_ref;
-
-  DCHECK(!local_file_writer_.get());
-  local_file_writer_.reset(new fileapi::LocalFileStreamWriter(
-      local_task_runner_, local_path, initial_offset_));
-  int result = local_file_writer_->Write(buf, buf_len, callback);
-  if (result != net::ERR_IO_PENDING)
-    callback.Run(result);
-}
-
-int RemoteFileStreamWriter::Cancel(const net::CompletionCallback& callback) {
-  DCHECK(!callback.is_null());
-  DCHECK(pending_cancel_callback_.is_null());
-
-  // If file open operation is in-flight, wait for its completion and cancel
-  // further write operation in OnFileOpened.
-  if (has_pending_create_snapshot_) {
-    pending_cancel_callback_ = callback;
-    return net::ERR_IO_PENDING;
-  }
-
-  // If LocalFileWriter is already created, just delegate the cancel to it.
-  if (local_file_writer_) {
-    pending_cancel_callback_ = callback;
-    return local_file_writer_->Cancel(
-        base::Bind(&RemoteFileStreamWriter::InvokePendingCancelCallback,
-                   weak_factory_.GetWeakPtr()));
-  }
-
-  // Write() is not called yet.
-  return net::ERR_UNEXPECTED;
-}
-
-int RemoteFileStreamWriter::Flush(const net::CompletionCallback& callback) {
-  // For remote file writer, Flush() is a no-op. Synchronization to the remote
-  // server is not done until the file is closed.
-  return net::OK;
-}
-
-void RemoteFileStreamWriter::InvokePendingCancelCallback(int result) {
-  net::CompletionCallback callback = pending_cancel_callback_;
-  pending_cancel_callback_.Reset();
-  callback.Run(result);
-}
-
-}  // namespace chromeos
diff --git a/chrome/browser/chromeos/fileapi/remote_file_system_operation.cc b/chrome/browser/chromeos/fileapi/remote_file_system_operation.cc
index 2a036d2..e51e568 100644
--- a/chrome/browser/chromeos/fileapi/remote_file_system_operation.cc
+++ b/chrome/browser/chromeos/fileapi/remote_file_system_operation.cc
@@ -8,9 +8,8 @@
 #include "base/platform_file.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/fileapi/remote_file_stream_writer.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_request.h"
+#include "url/gurl.h"
 #include "webkit/browser/fileapi/file_system_url.h"
 #include "webkit/browser/fileapi/file_writer_delegate.h"
 
diff --git a/chrome/browser/chromeos/fileapi/remote_file_system_operation.h b/chrome/browser/chromeos/fileapi/remote_file_system_operation.h
index 95f1142..a467368 100644
--- a/chrome/browser/chromeos/fileapi/remote_file_system_operation.h
+++ b/chrome/browser/chromeos/fileapi/remote_file_system_operation.h
@@ -28,6 +28,10 @@
       public base::SupportsWeakPtr<RemoteFileSystemOperation> {
  public:
   typedef fileapi::FileWriterDelegate FileWriterDelegate;
+
+  explicit RemoteFileSystemOperation(
+      scoped_refptr<fileapi::RemoteFileSystemProxyInterface> remote_proxy);
+
   virtual ~RemoteFileSystemOperation();
 
   // FileSystemOperation overrides.
@@ -77,11 +81,6 @@
       const SnapshotFileCallback& callback) OVERRIDE;
 
  private:
-  friend class CrosMountPointProvider;
-
-  RemoteFileSystemOperation(
-      scoped_refptr<fileapi::RemoteFileSystemProxyInterface> remote_proxy);
-
   // Used only for internal assertions.
   // Returns false if there's another inflight pending operation.
   bool SetPendingOperationType(OperationType type);
diff --git a/chrome/browser/chromeos/imageburner/burn_controller.cc b/chrome/browser/chromeos/imageburner/burn_controller.cc
index 7da990d..615d063 100644
--- a/chrome/browser/chromeos/imageburner/burn_controller.cc
+++ b/chrome/browser/chromeos/imageburner/burn_controller.cc
@@ -7,11 +7,10 @@
 #include "base/bind.h"
 #include "base/files/file_path.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/imageburner/burn_manager.h"
 #include "chromeos/network/network_state_handler.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 namespace imageburner {
diff --git a/chrome/browser/chromeos/imageburner/burn_manager.cc b/chrome/browser/chromeos/imageburner/burn_manager.cc
index 9d3ab26..51957c6 100644
--- a/chrome/browser/chromeos/imageburner/burn_manager.cc
+++ b/chrome/browser/chromeos/imageburner/burn_manager.cc
@@ -238,7 +238,7 @@
 
 BurnManager::~BurnManager() {
   if (image_dir_created_) {
-    base::Delete(image_dir_, true);
+    base::DeleteFile(image_dir_, true);
   }
   if (NetworkHandler::IsInitialized()) {
     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
diff --git a/chrome/browser/chromeos/imageburner/burn_manager.h b/chrome/browser/chromeos/imageburner/burn_manager.h
index b44a307..23cf662 100644
--- a/chrome/browser/chromeos/imageburner/burn_manager.h
+++ b/chrome/browser/chromeos/imageburner/burn_manager.h
@@ -19,8 +19,8 @@
 #include "chrome/browser/chromeos/imageburner/burn_device_handler.h"
 #include "chromeos/disks/disk_mount_manager.h"
 #include "chromeos/network/network_state_handler_observer.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_fetcher_delegate.h"
+#include "url/gurl.h"
 
 namespace net {
 class URLFetcher;
diff --git a/chrome/browser/chromeos/input_method/browser_state_monitor.cc b/chrome/browser/chromeos/input_method/browser_state_monitor.cc
index 4417b75..22b480b 100644
--- a/chrome/browser/chromeos/input_method/browser_state_monitor.cc
+++ b/chrome/browser/chromeos/input_method/browser_state_monitor.cc
@@ -5,8 +5,8 @@
 #include "chrome/browser/chromeos/input_method/browser_state_monitor.h"
 
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/input_method/input_method_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chromeos/ime/input_method_delegate.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/chromeos/input_method/browser_state_monitor_unittest.cc b/chrome/browser/chromeos/input_method/browser_state_monitor_unittest.cc
index 0a057ec..909c854 100644
--- a/chrome/browser/chromeos/input_method/browser_state_monitor_unittest.cc
+++ b/chrome/browser/chromeos/input_method/browser_state_monitor_unittest.cc
@@ -8,7 +8,7 @@
 
 #include "base/basictypes.h"
 #include "base/bind.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/chromeos/input_method/candidate_window_constants.h b/chrome/browser/chromeos/input_method/candidate_window_constants.h
index 96a597d..148ab65 100644
--- a/chrome/browser/chromeos/input_method/candidate_window_constants.h
+++ b/chrome/browser/chromeos/input_method/candidate_window_constants.h
@@ -8,22 +8,6 @@
 namespace chromeos {
 namespace input_method {
 
-// Colors used in the candidate window UI.
-const SkColor kFrameColor = SkColorSetRGB(0x96, 0x96, 0x96);
-const SkColor kShortcutBackgroundColor = SkColorSetARGB(0x10, 0x3, 0x4, 0xf);
-const SkColor kSelectedRowBackgroundColor = SkColorSetRGB(0xd1, 0xea, 0xff);
-const SkColor kDefaultBackgroundColor = SkColorSetRGB(0xff, 0xff, 0xff);
-const SkColor kSelectedRowFrameColor = SkColorSetRGB(0x7f, 0xac, 0xdd);
-const SkColor kFooterTopColor = SkColorSetRGB(0xff, 0xff, 0xff);
-const SkColor kFooterBottomColor = SkColorSetRGB(0xee, 0xee, 0xee);
-const SkColor kShortcutColor = SkColorSetRGB(0x61, 0x61, 0x61);
-const SkColor kDisabledShortcutColor = SkColorSetRGB(0xcc, 0xcc, 0xcc);
-const SkColor kAnnotationColor = SkColorSetRGB(0x88, 0x88, 0x88);
-const SkColor kSelectedInfolistRowBackgroundColor =
-    SkColorSetRGB(0xee, 0xee, 0xee);
-const SkColor kSelectedInfolistRowFrameColor = SkColorSetRGB(0xcc, 0xcc, 0xcc);
-const SkColor kInfolistTitleBackgroundColor = SkColorSetRGB(0xdd, 0xdd, 0xdd);
-
 // We'll use a bigger font size, so Chinese characters are more readable
 // in the candidate window.
 const int kFontSizeDelta = 2;
diff --git a/chrome/browser/chromeos/input_method/candidate_window_view.cc b/chrome/browser/chromeos/input_method/candidate_window_view.cc
index ff1b66e..b9b1138 100644
--- a/chrome/browser/chromeos/input_method/candidate_window_view.cc
+++ b/chrome/browser/chromeos/input_method/candidate_window_view.cc
@@ -11,6 +11,8 @@
 #include "chrome/browser/chromeos/input_method/candidate_window_constants.h"
 #include "chrome/browser/chromeos/input_method/hidable_area.h"
 #include "chromeos/dbus/ibus/ibus_lookup_table.h"
+#include "ui/gfx/color_utils.h"
+#include "ui/native_theme/native_theme.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/grid_layout.h"
 #include "ui/views/widget/widget.h"
@@ -81,7 +83,7 @@
 // Creates the shortcut label, and returns it (never returns NULL).
 // The label text is not set in this function.
 views::Label* CreateShortcutLabel(
-    IBusLookupTable::Orientation orientation) {
+    IBusLookupTable::Orientation orientation, const ui::NativeTheme& theme) {
   // Create the shortcut label. The label will be owned by
   // |wrapped_shortcut_label|, hence it's deleted when
   // |wrapped_shortcut_label| is deleted.
@@ -96,8 +98,10 @@
   }
   // TODO(satorux): Maybe we need to use language specific fonts for
   // candidate_label, like Chinese font for Chinese input method?
-  shortcut_label->SetEnabledColor(kShortcutColor);
-  shortcut_label->SetDisabledColor(kDisabledShortcutColor);
+  shortcut_label->SetEnabledColor(theme.GetSystemColor(
+      ui::NativeTheme::kColorId_LabelEnabledColor));
+  shortcut_label->SetDisabledColor(theme.GetSystemColor(
+      ui::NativeTheme::kColorId_LabelDisabledColor));
 
   return shortcut_label;
 }
@@ -107,7 +111,8 @@
 // The label text is not set in this function.
 views::View* CreateWrappedShortcutLabel(
     views::Label* shortcut_label,
-    IBusLookupTable::Orientation orientation) {
+    IBusLookupTable::Orientation orientation,
+    const ui::NativeTheme& theme) {
   // Wrap it with padding.
   const gfx::Insets kVerticalShortcutLabelInsets(1, 6, 1, 6);
   const gfx::Insets kHorizontalShortcutLabelInsets(1, 3, 1, 0);
@@ -121,9 +126,14 @@
   // Add decoration based on the orientation.
   if (orientation == IBusLookupTable::VERTICAL) {
     // Set the background color.
+    SkColor blackish = color_utils::AlphaBlend(
+        SK_ColorBLACK,
+        theme.GetSystemColor(ui::NativeTheme::kColorId_WindowBackground),
+        0x40);
+    SkColor transparent_blakish = color_utils::AlphaBlend(
+        SK_ColorTRANSPARENT, blackish, 0xE0);
     wrapped_shortcut_label->set_background(
-        views::Background::CreateSolidBackground(
-            kShortcutBackgroundColor));
+        views::Background::CreateSolidBackground(transparent_blakish));
     shortcut_label->SetBackgroundColor(
         wrapped_shortcut_label->background()->get_color());
   }
@@ -156,14 +166,15 @@
 // Creates the annotation label, and return it (never returns NULL).
 // The label text is not set in this function.
 views::Label* CreateAnnotationLabel(
-    IBusLookupTable::Orientation orientation) {
+    IBusLookupTable::Orientation orientation, const ui::NativeTheme& theme) {
   // Create the annotation label.
   views::Label* annotation_label = new views::Label;
 
   // Change the font size and color.
   annotation_label->SetFont(
       annotation_label->font().DeriveFont(kFontSizeDelta));
-  annotation_label->SetEnabledColor(kAnnotationColor);
+  annotation_label->SetEnabledColor(theme.GetSystemColor(
+      ui::NativeTheme::kColorId_LabelDisabledColor));
   annotation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
 
   return annotation_label;
@@ -171,16 +182,19 @@
 
 // Computes shortcut column size.
 gfx::Size ComputeShortcutColumnSize(
-    const IBusLookupTable& lookup_table) {
+    const IBusLookupTable& lookup_table,
+    const ui::NativeTheme& theme) {
   int shortcut_column_width = 0;
   int shortcut_column_height = 0;
   // Create the shortcut label. The label will be owned by
   // |wrapped_shortcut_label|, hence it's deleted when
   // |wrapped_shortcut_label| is deleted.
   views::Label* shortcut_label = CreateShortcutLabel(
-      lookup_table.orientation());
+      lookup_table.orientation(), theme);
   scoped_ptr<views::View> wrapped_shortcut_label(
-      CreateWrappedShortcutLabel(shortcut_label, lookup_table.orientation()));
+      CreateWrappedShortcutLabel(shortcut_label,
+                                 lookup_table.orientation(),
+                                 theme));
 
   // Compute the max width and height in shortcut labels.
   // We'll create temporary shortcut labels, and choose the largest width and
@@ -239,11 +253,11 @@
 
 // Computes annotation column size.
 gfx::Size ComputeAnnotationColumnSize(
-    const IBusLookupTable& lookup_table) {
+    const IBusLookupTable& lookup_table, const ui::NativeTheme& theme) {
   int annotation_column_width = 0;
   int annotation_column_height = 0;
   scoped_ptr<views::Label> annotation_label(
-      CreateAnnotationLabel(lookup_table.orientation()));
+      CreateAnnotationLabel(lookup_table.orientation(), theme));
 
   // Compute the start index of |lookup_table_|.
   const int current_page_index = ComputePageIndex(lookup_table);
@@ -283,12 +297,15 @@
     const gfx::Insets kInsets(2, 2, 2, 4);
     views::View* contents = WrapWithPadding(label_, kInsets);
     SetContents(contents);
-    contents->set_border(
-        views::Border::CreateSolidBorder(1, kFrameColor));
-    contents->set_background(
-        views::Background::CreateVerticalGradientBackground(
-            kFooterTopColor,
-            kFooterBottomColor));
+    contents->set_border(views::Border::CreateSolidBorder(
+        1,
+        GetNativeTheme()->GetSystemColor(
+            ui::NativeTheme::kColorId_MenuBorderColor)));
+    contents->set_background(views::Background::CreateSolidBackground(
+        color_utils::AlphaBlend(SK_ColorBLACK,
+                                GetNativeTheme()->GetSystemColor(
+                                    ui::NativeTheme::kColorId_WindowBackground),
+                                0x10)));
     label_->SetBackgroundColor(contents->background()->get_color());
   }
 
@@ -337,11 +354,12 @@
   SetLayoutManager(layout);  // |this| owns |layout|.
 
   // Create Labels.
-  shortcut_label_ = CreateShortcutLabel(orientation_);
+  const ui::NativeTheme& theme = *GetNativeTheme();
+  shortcut_label_ = CreateShortcutLabel(orientation_, theme);
   views::View* wrapped_shortcut_label =
-      CreateWrappedShortcutLabel(shortcut_label_, orientation_);
+      CreateWrappedShortcutLabel(shortcut_label_, orientation_, theme);
   candidate_label_ = CreateCandidateLabel(orientation_);
-  annotation_label_ = CreateAnnotationLabel(orientation_);
+  annotation_label_ = CreateAnnotationLabel(orientation_, theme);
 
   // Initialize the column set with three columns.
   views::ColumnSet* column_set = layout->AddColumnSet(0);
@@ -443,16 +461,22 @@
   if (!infolist_icon_ || (infolist_icon_enabled_ == enable))
     return;
   infolist_icon_enabled_ = enable;
-  infolist_icon_->set_background(enable ?
-      views::Background::CreateSolidBackground(kSelectedRowFrameColor) : NULL);
+  infolist_icon_->set_background(
+      enable ?
+      views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_FocusedBorderColor)) :
+      NULL);
   UpdateLabelBackgroundColors();
   SchedulePaint();
 }
 
 void CandidateView::Select() {
   set_background(
-      views::Background::CreateSolidBackground(kSelectedRowBackgroundColor));
-  set_border(views::Border::CreateSolidBorder(1, kSelectedRowFrameColor));
+      views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused)));
+  set_border(views::Border::CreateSolidBorder(
+      1, GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_FocusedBorderColor)));
   UpdateLabelBackgroundColors();
   // Need to call SchedulePaint() for background and border color changes.
   SchedulePaint();
@@ -503,7 +527,9 @@
 
 void CandidateView::UpdateLabelBackgroundColors() {
   SkColor color = background() ?
-      background()->get_color() : kDefaultBackgroundColor;
+      background()->get_color() :
+      GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_WindowBackground);
   if (orientation_ != IBusLookupTable::VERTICAL)
     shortcut_label_->SetBackgroundColor(color);
   candidate_label_->SetBackgroundColor(color);
@@ -531,8 +557,11 @@
 void CandidateWindowView::Init() {
   // Set the background and the border of the view.
   set_background(
-      views::Background::CreateSolidBackground(kDefaultBackgroundColor));
-  set_border(views::Border::CreateSolidBorder(1, kFrameColor));
+      views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_WindowBackground)));
+  set_border(views::Border::CreateSolidBorder(
+      1, GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_MenuBorderColor)));
 
   // Create areas.
   preedit_area_ = new InformationTextArea(gfx::ALIGN_LEFT,
@@ -758,9 +787,10 @@
   // If orientation is horizontal, don't need to compute width,
   // because each label is left aligned.
   if (orientation == IBusLookupTable::VERTICAL) {
-    shortcut_column_size = ComputeShortcutColumnSize(lookup_table);
+    const ui::NativeTheme& theme = *GetNativeTheme();
+    shortcut_column_size = ComputeShortcutColumnSize(lookup_table, theme);
     candidate_column_size = ComputeCandidateColumnSize(lookup_table);
-    annotation_column_size = ComputeAnnotationColumnSize(lookup_table);
+    annotation_column_size = ComputeAnnotationColumnSize(lookup_table, theme);
   }
 
   // If the requested number of views matches the number of current views, and
diff --git a/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc b/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc
index f2c0292..12c633f 100644
--- a/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc
+++ b/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc
@@ -240,8 +240,8 @@
     const base::FilePath manifest_path =
         component_ime.path.Append("manifest.json");
 
-    if (!file_util::PathExists(component_ime.path) ||
-        !file_util::PathExists(manifest_path))
+    if (!base::PathExists(component_ime.path) ||
+        !base::PathExists(manifest_path))
       continue;
 
     if (!file_util::ReadFileToString(manifest_path, &component_ime.manifest))
diff --git a/chrome/browser/chromeos/input_method/infolist_window_view.cc b/chrome/browser/chromeos/input_method/infolist_window_view.cc
index a18599c..491440f 100644
--- a/chrome/browser/chromeos/input_method/infolist_window_view.cc
+++ b/chrome/browser/chromeos/input_method/infolist_window_view.cc
@@ -15,7 +15,9 @@
 #include "chrome/browser/chromeos/input_method/hidable_area.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/color_utils.h"
 #include "ui/gfx/font.h"
+#include "ui/native_theme/native_theme.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/grid_layout.h"
@@ -124,10 +126,12 @@
   if (selected_)
     return;
   selected_ = true;
-  set_background(views::Background::CreateSolidBackground(
-      kSelectedInfolistRowBackgroundColor));
+  set_background(
+      views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused)));
   set_border(
-      views::Border::CreateSolidBorder(1, kSelectedInfolistRowFrameColor));
+      views::Border::CreateSolidBorder(1, GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_FocusedBorderColor)));
   UpdateLabelBackgroundColors();
 }
 
@@ -142,7 +146,9 @@
 
 void InfolistEntryView::UpdateLabelBackgroundColors() {
   SkColor color = background() ?
-      background()->get_color() : kDefaultBackgroundColor;
+      background()->get_color() :
+      GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_WindowBackground);
   title_label_->SetBackgroundColor(color);
   description_label_->SetBackgroundColor(color);
 }
@@ -162,8 +168,11 @@
 
 void InfolistWindowView::Init() {
   set_background(
-      views::Background::CreateSolidBackground(kDefaultBackgroundColor));
-  set_border(views::Border::CreateSolidBorder(1, kFrameColor));
+      views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_WindowBackground)));
+  set_border(
+      views::Border::CreateSolidBorder(1, GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_MenuBorderColor)));
 
   views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kVertical,
                                                   0, 0, 0);
@@ -174,9 +183,14 @@
   caption_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   caption_label->SetText(
       l10n_util::GetStringUTF16(IDS_INPUT_METHOD_INFOLIST_WINDOW_TITLE));
+  caption_label->SetEnabledColor(GetNativeTheme()->GetSystemColor(
+      ui::NativeTheme::kColorId_LabelEnabledColor));
   caption_label->set_border(views::Border::CreateEmptyBorder(2, 2, 2, 2));
-  caption_label->set_background(
-      views::Background::CreateSolidBackground(kInfolistTitleBackgroundColor));
+  caption_label->set_background(views::Background::CreateSolidBackground(
+      color_utils::AlphaBlend(SK_ColorBLACK,
+                              GetNativeTheme()->GetSystemColor(
+                                  ui::NativeTheme::kColorId_WindowBackground),
+                              0x10)));
   caption_label->SetBackgroundColor(caption_label->background()->get_color());
 
   AddChildView(caption_label);
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc
index 420a8bf..f5939d73 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine.cc
@@ -38,7 +38,7 @@
     const char* extension_id,
     const char* engine_id,
     const char* description,
-    const char* language,
+    const std::vector<std::string>& languages,
     const std::vector<std::string>& layouts,
     const GURL& options_page,
     std::string* error) {
@@ -49,7 +49,7 @@
                      extension_id,
                      engine_id,
                      description,
-                     language,
+                     languages,
                      layouts,
                      options_page,
                      error);
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.h b/chrome/browser/chromeos/input_method/input_method_engine.h
index 320b2bf..fdfc637 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.h
+++ b/chrome/browser/chromeos/input_method/input_method_engine.h
@@ -238,7 +238,7 @@
       const char* extension_id,
       const char* engine_id,
       const char* description,
-      const char* language,
+      const std::vector<std::string>& language,
       const std::vector<std::string>& layouts,
       const GURL& options_page,
       std::string* error);
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_ibus.cc b/chrome/browser/chromeos/input_method/input_method_engine_ibus.cc
index 25c9d4e..54d5d6f 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_ibus.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_ibus.cc
@@ -76,7 +76,7 @@
     const char* extension_id,
     const char* engine_id,
     const char* description,
-    const char* language,
+    const std::vector<std::string>& languages,
     const std::vector<std::string>& layouts,
     const GURL& options_page,
     std::string* error) {
@@ -102,17 +102,15 @@
   component_->set_description(description);
   component_->set_author(engine_name);
 
+  // TODO(nona): Remove IBusComponent once ibus is gone.
   chromeos::IBusComponent::EngineDescription engine_desc;
   engine_desc.engine_id = ibus_id_;
   engine_desc.display_name = description;
   engine_desc.description = description;
-  engine_desc.language_code = language;
+  engine_desc.language_code = (languages.empty()) ? "" : languages[0];
   engine_desc.author = ibus_id_;
 
   component_->mutable_engine_description()->push_back(engine_desc);
-
-  std::vector<std::string> languages;
-  languages.push_back(language);
   manager->AddInputMethodExtension(ibus_id_, engine_name, layouts, languages,
                                    options_page, this);
   // If connection is avaiable, register component. If there are no connection
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_ibus.h b/chrome/browser/chromeos/input_method/input_method_engine_ibus.h
index 232dfe1..5fd408f 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_ibus.h
+++ b/chrome/browser/chromeos/input_method/input_method_engine_ibus.h
@@ -37,7 +37,7 @@
       const char* extension_id,
       const char* engine_id,
       const char* description,
-      const char* language,
+      const std::vector<std::string>& languages,
       const std::vector<std::string>& layouts,
       const GURL& options_page,
       std::string* error);
diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.cc b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.cc
index a9d1686..45cab46 100644
--- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.cc
+++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.cc
@@ -10,10 +10,10 @@
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/ui/idle_logout_dialog_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
@@ -70,7 +70,7 @@
   }
 }
 
-void KioskModeIdleLogout::OnUserActivity() {
+void KioskModeIdleLogout::OnUserActivity(const ui::Event* event) {
   IdleLogoutDialogView::CloseDialog();
   ResetTimer();
 }
diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.h b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.h
index 51d0792..c358277 100644
--- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.h
+++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout.h
@@ -33,8 +33,8 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
-  // UserActivityObserver::Observer overrides:
-  virtual void OnUserActivity() OVERRIDE;
+  // UserActivityObserver overrides:
+  virtual void OnUserActivity(const ui::Event* event) OVERRIDE;
 
   // Begins listening for user activity and calls ResetTimer().
   void Start();
diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout_unittest.cc b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout_unittest.cc
index bf39f4b..c191421 100644
--- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout_unittest.cc
+++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout_unittest.cc
@@ -11,9 +11,9 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "base/synchronization/waitable_event.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc
index 000287a..67e87f5 100644
--- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc
+++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc
@@ -12,6 +12,7 @@
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/extensions/sandboxed_unpacker.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_file_util.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
@@ -51,7 +51,8 @@
   virtual void OnUnpackSuccess(const base::FilePath& temp_dir,
                                const base::FilePath& extension_root,
                                const base::DictionaryValue* original_manifest,
-                               const Extension* extension) OVERRIDE;
+                               const Extension* extension,
+                               const SkBitmap& install_icon) OVERRIDE;
   virtual void OnUnpackFailure(const string16& error) OVERRIDE;
 
  protected:
@@ -74,7 +75,8 @@
     const base::FilePath& temp_dir,
     const base::FilePath& extension_root,
     const base::DictionaryValue* original_manifest,
-    const Extension* extension) {
+    const Extension* extension,
+    const SkBitmap& install_icon) {
   content::BrowserThread::PostTask(
       content::BrowserThread::FILE,
       FROM_HERE,
@@ -186,12 +188,11 @@
   scoped_refptr<SandboxedUnpacker> screensaver_unpacker(
       new SandboxedUnpacker(
           screensaver_crx,
-          true,
           extensions::Manifest::COMPONENT,
           Extension::NO_FLAGS,
           extensions_dir,
           content::BrowserThread::GetMessageLoopProxyForThread(
-              content::BrowserThread::FILE),
+              content::BrowserThread::FILE).get(),
           new ScreensaverUnpackerClient(
               screensaver_crx,
               base::Bind(
@@ -231,7 +232,7 @@
   }
 }
 
-void KioskModeScreensaver::OnUserActivity() {
+void KioskModeScreensaver::OnUserActivity(const ui::Event* event) {
   // We don't want to handle further user notifications; we'll either login
   // the user and close out or or at least close the screensaver.
   ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this);
diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h
index c964017..689e25e 100644
--- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h
+++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h
@@ -24,8 +24,8 @@
  private:
   friend class KioskModeScreensaverTest;
 
-  // UserActivityObserver::Observer overrides:
-  virtual void OnUserActivity() OVERRIDE;
+  // UserActivityObserver overrides:
+  virtual void OnUserActivity(const ui::Event* event) OVERRIDE;
 
   // Initialization functions, in order
   // Get the screensaver path once KioskModeHelper is initialized.
diff --git a/chrome/browser/chromeos/locale_change_guard.cc b/chrome/browser/chromeos/locale_change_guard.cc
index cb25fbf..46ff636 100644
--- a/chrome/browser/chromeos/locale_change_guard.cc
+++ b/chrome/browser/chromeos/locale_change_guard.cc
@@ -12,6 +12,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/notifications/notification_delegate.h"
@@ -19,7 +20,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/host_desktop.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/chromeos/login/auth_prewarmer.cc b/chrome/browser/chromeos/login/auth_prewarmer.cc
index 9f4471b..b7f8a59 100644
--- a/chrome/browser/chromeos/login/auth_prewarmer.cc
+++ b/chrome/browser/chromeos/login/auth_prewarmer.cc
@@ -4,14 +4,14 @@
 
 #include "chrome/browser/chromeos/login/auth_prewarmer.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/net/connectivity_state_helper.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/net/chrome_url_request_context.h"
 #include "chrome/browser/net/preconnect.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "google_apis/gaia/gaia_urls.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
diff --git a/chrome/browser/chromeos/login/authenticator.h b/chrome/browser/chromeos/login/authenticator.h
index bc924ce..7fce86e 100644
--- a/chrome/browser/chromeos/login/authenticator.h
+++ b/chrome/browser/chromeos/login/authenticator.h
@@ -35,12 +35,9 @@
 
   // Given a user credentials in |user_context|,
   // this method attempts to authenticate to login.
-  // Optionally |login_token| and |login_captcha| could be provided.
   // Must be called on the UI thread.
   virtual void AuthenticateToLogin(Profile* profile,
-                                   const UserContext& user_context,
-                                   const std::string& login_token,
-                                   const std::string& login_captcha) = 0;
+                                   const UserContext& user_context) = 0;
 
   // Given a user credentials in |user_context|, this method attempts to
   // authenticate to unlock the computer.
@@ -87,12 +84,6 @@
   // and create a new cryptohome.
   virtual void ResyncEncryptedData() = 0;
 
-  // Attempt to authenticate online again.
-  virtual void RetryAuth(Profile* profile,
-                         const UserContext& user_context,
-                         const std::string& login_token,
-                         const std::string& login_captcha) = 0;
-
   // Profile (usually off the record ) that was used to perform the last
   // authentication process.
   Profile* authentication_profile() { return authentication_profile_; }
diff --git a/chrome/browser/chromeos/login/captive_portal_view.cc b/chrome/browser/chromeos/login/captive_portal_view.cc
index ca53bec..5f52672 100644
--- a/chrome/browser/chromeos/login/captive_portal_view.cc
+++ b/chrome/browser/chromeos/login/captive_portal_view.cc
@@ -6,13 +6,12 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/captive_portal/captive_portal_detector.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/login/captive_portal_window_proxy.h"
 #include "chrome/browser/chromeos/net/connectivity_state_helper.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index 5096919..8cebc93 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -32,7 +32,6 @@
 #include "chromeos/dbus/session_manager_client.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_switches.h"
-#include "googleurl/src/gurl.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
 #include "media/base/media_switches.h"
 #include "ui/base/ui_base_switches.h"
@@ -40,6 +39,7 @@
 #include "ui/gfx/switches.h"
 #include "ui/gl/gl_switches.h"
 #include "ui/views/corewm/corewm_switches.h"
+#include "url/gurl.h"
 #include "webkit/plugins/plugin_switches.h"
 
 using content::BrowserThread;
@@ -75,6 +75,7 @@
       ::switches::kDisableAcceleratedPlugins,
       ::switches::kDisableAcceleratedVideoDecode,
       ::switches::kDisableBrowserPluginCompositing,
+      ::switches::kDisableDelegatedRenderer,
       ::switches::kDisableForceCompositingMode,
       ::switches::kDisableGpuShaderDiskCache,
       ::switches::kDisableGpuWatchdog,
@@ -86,10 +87,13 @@
       ::switches::kDisableTouchDragDrop,
       ::switches::kDisableTouchEditing,
       ::switches::kDisableWebKitMediaSource,
+      ::switches::kDisableAcceleratedFixedRootBackground,
+      ::switches::kEnableAcceleratedFixedRootBackground,
       ::switches::kEnableAcceleratedOverflowScroll,
       ::switches::kEnableBeginFrameScheduling,
       ::switches::kEnableBrowserInputController,
       ::switches::kEnableCompositingForFixedPosition,
+      ::switches::kEnableDelegatedRenderer,
       ::switches::kEnableEncodedScreenCapture,
       ::switches::kEnableEncryptedMedia,
       ::switches::kEnableGestureTapHighlight,
@@ -135,8 +139,10 @@
       ash::switches::kAshDefaultGuestWallpaperSmall,
       ash::switches::kAshDefaultWallpaperLarge,
       ash::switches::kAshDefaultWallpaperSmall,
+#if defined(OS_CHROMEOS)
+      ash::switches::kAshDisableAudioDeviceMenu,
       ash::switches::kAshDisableNewAudioHandler,
-      ash::switches::kAshEnableAudioDeviceMenu,
+#endif
       ash::switches::kAshHostWindowBounds,
       ash::switches::kAshTouchHud,
       ash::switches::kAuraLegacyPowerButton,
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index aa9b0ea..a1daf7a 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -21,9 +21,9 @@
 #include "base/values.h"
 #include "base/version.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/boot_times_loader.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/customization_document.h"
 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
 #include "chrome/browser/chromeos/login/helper.h"
@@ -41,7 +41,6 @@
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/policy/policy_service.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/pref_names.h"
@@ -812,8 +811,6 @@
 }
 
 void ExistingUserController::OnProfilePrepared(Profile* profile) {
-  OptionallyShowReleaseNotes(profile);
-
   // Reenable clicking on other windows and status area.
   login_display_->SetUIEnabled(true);
 
@@ -1086,51 +1083,6 @@
   }
 }
 
-void ExistingUserController::OptionallyShowReleaseNotes(
-    Profile* profile) const {
-  // TODO(nkostylev): Fix WizardControllerFlowTest case.
-  if (!profile || KioskModeSettings::Get()->IsKioskModeEnabled())
-    return;
-  if (UserManager::Get()->GetCurrentUserFlow()->ShouldSkipPostLoginScreens())
-    return;
-  PrefService* prefs = profile->GetPrefs();
-  chrome::VersionInfo version_info;
-  // New users would get this info with default getting started guide.
-  // In password changed case 2 options are available:
-  // 1. Cryptohome removed, pref is gone, not yet synced, recreate
-  //    with latest version.
-  // 2. Cryptohome migrated, pref is available. To simplify implementation
-  //    update version here too. Unlikely that user signs in first time on
-  //    the machine after update with password changed.
-  if (UserManager::Get()->IsCurrentUserNew() || password_changed_) {
-    prefs->SetString(prefs::kChromeOSReleaseNotesVersion,
-                     version_info.Version());
-    return;
-  }
-
-  std::string prev_version_pref =
-      prefs->GetString(prefs::kChromeOSReleaseNotesVersion);
-  Version prev_version(prev_version_pref);
-  if (!prev_version.IsValid())
-    prev_version = Version("0.0.0.0");
-  Version current_version(version_info.Version());
-
-  if (!current_version.components().size()) {
-    NOTREACHED() << "Incorrect version " << current_version.GetString();
-    return;
-  }
-
-  // No "Release Notes" content yet for upgrade from M19 to later release.
-  if (prev_version.components()[0] >= kReleaseNotesTargetRelease)
-    return;
-
-  // Otherwise, trigger on major version change.
-  if (current_version.components()[0] > prev_version.components()[0]) {
-    prefs->SetString(prefs::kChromeOSReleaseNotesVersion,
-                     current_version.GetString());
-  }
-}
-
 void ExistingUserController::ShowError(int error_id,
                                        const std::string& details) {
   // TODO(dpolukhin): show detailed error info. |details| string contains
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h
index 1dc7609..b249219 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.h
+++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -24,8 +24,8 @@
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/rect.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
@@ -154,9 +154,6 @@
   // Adds first-time login URLs.
   void InitializeStartUrls() const;
 
-  // Shows "Release Notes"/"What's new"/Getting started guide on update.
-  void OptionallyShowReleaseNotes(Profile* profile) const;
-
   // Show error message. |error_id| error message ID in resources.
   // If |details| string is not empty, it specify additional error text
   // provided by authenticator, it is not localized.
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
index 6acaf15..d9a2914 100644
--- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
@@ -10,7 +10,7 @@
 #include "base/command_line.h"
 #include "base/location.h"
 #include "base/run_loop.h"
-#include "chrome/browser/chromeos/cros/cros_mock.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/authenticator.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/helper.h"
@@ -33,7 +33,6 @@
 #include "chrome/browser/policy/cloud/cloud_policy_store.h"
 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h"
 #include "chrome/browser/policy/cloud/policy_builder.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
@@ -97,8 +96,6 @@
     SetUpSessionManager();
 
     DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture();
-    cros_mock_->InitStatusAreaMocks();
-    cros_mock_->SetStatusAreaMocksExpectations();
 
     mock_login_utils_ = new MockLoginUtils();
     LoginUtils::Set(mock_login_utils_);
diff --git a/chrome/browser/chromeos/login/hwid_checker.cc b/chrome/browser/chromeos/login/hwid_checker.cc
index 0f1f0f6..49f9874 100644
--- a/chrome/browser/chromeos/login/hwid_checker.cc
+++ b/chrome/browser/chromeos/login/hwid_checker.cc
@@ -43,7 +43,11 @@
   return CalculateHWIDv2Checksum(body) == checksum;
 }
 
-std::string CalculateHWIDv3Checksum(const std::string& data) {
+bool IsExceptionalHWID(const std::string& hwid) {
+  return RE2::PartialMatch(hwid, "^(SPRING [A-D])|(FALCO A)");
+}
+
+std::string CalculateExceptionalHWIDChecksum(const std::string& data) {
   static const char base32_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
   unsigned crc32 = CalculateCRC32(data);
   // We take 10 least significant bits of CRC-32 and encode them in 2 characters
@@ -54,7 +58,9 @@
   return checksum;
 }
 
-bool IsCorrectHWIDv3(const std::string& hwid) {
+bool IsCorrectExceptionalHWID(const std::string& hwid) {
+  if (!IsExceptionalHWID(hwid))
+    return false;
   std::string bom;
   if (!RE2::FullMatch(hwid, "[A-Z0-9]+ ((?:[A-Z2-7]{4}-)*[A-Z2-7]{1,4})", &bom))
     return false;
@@ -67,6 +73,29 @@
       hwid_without_dashes.substr(0, hwid_without_dashes.length() - 2);
   std::string checksum =
       hwid_without_dashes.substr(hwid_without_dashes.length() - 2);
+  return CalculateExceptionalHWIDChecksum(not_checksum) == checksum;
+}
+
+std::string CalculateHWIDv3Checksum(const std::string& data) {
+  static const char base8_alphabet[] = "23456789";
+  static const char base32_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+  unsigned crc32 = CalculateCRC32(data);
+  // We take 8 least significant bits of CRC-32 and encode them in 2 characters.
+  std::string checksum;
+  checksum += base8_alphabet[(crc32 >> 5) & 0x7];
+  checksum += base32_alphabet[crc32 & 0x1f];
+  return checksum;
+}
+
+bool IsCorrectHWIDv3(const std::string& hwid) {
+  if (IsExceptionalHWID(hwid))
+    return false;
+  std::string regex =
+      "([A-Z0-9]+ (?:[A-Z2-7][2-9][A-Z2-7]-)*[A-Z2-7])([2-9][A-Z2-7])";
+  std::string not_checksum, checksum;
+  if (!RE2::FullMatch(hwid, regex, &not_checksum, &checksum))
+    return false;
+  RemoveChars(not_checksum, "-", &not_checksum);
   return CalculateHWIDv3Checksum(not_checksum) == checksum;
 }
 
@@ -75,7 +104,8 @@
 namespace chromeos {
 
 bool IsHWIDCorrect(const std::string& hwid) {
-  return IsCorrectHWIDv2(hwid) || IsCorrectHWIDv3(hwid);
+  return IsCorrectHWIDv2(hwid) || IsCorrectExceptionalHWID(hwid) ||
+      IsCorrectHWIDv3(hwid);
 }
 
 bool IsMachineHWIDCorrect() {
diff --git a/chrome/browser/chromeos/login/hwid_checker_unittest.cc b/chrome/browser/chromeos/login/hwid_checker_unittest.cc
index b7491b5..9de664b 100644
--- a/chrome/browser/chromeos/login/hwid_checker_unittest.cc
+++ b/chrome/browser/chromeos/login/hwid_checker_unittest.cc
@@ -21,45 +21,95 @@
   EXPECT_FALSE(IsHWIDCorrect("SOME DATA7861"));
 }
 
-TEST(HWIDCheckerTest, HWIDv3) {
-  EXPECT_TRUE(IsHWIDCorrect("SPRING 3A7N-BJKZ-F"));
-  EXPECT_TRUE(IsHWIDCorrect("SPRING 3A7N-BJKK-HB"));
-  EXPECT_TRUE(IsHWIDCorrect("SPRING 3A7N-BJKK-EHU"));
-  EXPECT_TRUE(IsHWIDCorrect("SPRING 3A7N-BJKK-MGG"));
-  EXPECT_TRUE(IsHWIDCorrect("SPRING 3A7N-BJKK-M4RF"));
+TEST(HWIDCheckerTest, ExceptionalHWID) {
+  EXPECT_TRUE(IsHWIDCorrect("SPRING A7N3-BJKQ-E"));
+  EXPECT_TRUE(IsHWIDCorrect("SPRING A7N3-BJKK-3K"));
+  EXPECT_TRUE(IsHWIDCorrect("SPRING A7N3-BJKK-2GI"));
+  EXPECT_TRUE(IsHWIDCorrect("SPRING A7N3-BJKK-2MRO"));
+  EXPECT_TRUE(IsHWIDCorrect("SPRING A7N3-BJKK-2MDG-V"));
+  EXPECT_TRUE(IsHWIDCorrect("SPRING DAKB-NM"));
+  EXPECT_TRUE(IsHWIDCorrect("FALCO APOM-3"));
+
+  // Not exceptions.
+  EXPECT_FALSE(IsHWIDCorrect("SPRING 3A7N-BJKZ-F"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING LA7N-BJK7-H"));
+  EXPECT_FALSE(IsHWIDCorrect("FALCO BPO6-C"));
 
   // Degenerate cases.
   EXPECT_FALSE(IsHWIDCorrect("SPRING"));
   EXPECT_FALSE(IsHWIDCorrect("SPRING "));
   EXPECT_FALSE(IsHWIDCorrect("SPRING KD"));
-  EXPECT_TRUE(IsHWIDCorrect("SPRING T7"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING T7"));
 
   // No board name.
-  EXPECT_FALSE(IsHWIDCorrect(" 3A7N-BJKU-Y"));
-  EXPECT_FALSE(IsHWIDCorrect("3A7N-BJKG-Z"));
+  EXPECT_FALSE(IsHWIDCorrect(" CA7N-BJKV-T"));
+  EXPECT_FALSE(IsHWIDCorrect("CA7N-BJKH-S"));
 
   // Excess fields.
-  EXPECT_FALSE(IsHWIDCorrect("SPRING WINTER 3A7N-BJK6-Y"));
-  EXPECT_FALSE(IsHWIDCorrect("SPRING 3A7N-BJKX-G WINTER"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING WINTER CA7N-BJK7-T"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING CA7N-BJKN-D WINTER"));
 
   // Incorrect BOM format.
-  EXPECT_FALSE(IsHWIDCorrect("SPRING 3A7-NBJK-ZF"));
-  EXPECT_FALSE(IsHWIDCorrect("SPRING 3A-7NBJ-KZF"));
-  EXPECT_FALSE(IsHWIDCorrect("SPRING -3A7N-BJKZ-F"));
-  EXPECT_FALSE(IsHWIDCorrect("SPRING 3A7N-BJKK-FSYV-"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING CA7-NBJK-YO"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING CA-7NBJ-KYO"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING -CA7N-BJKY-O"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING CA7N-BJKK-FS-UN"));
 
   // Incorrect characters.
-  EXPECT_FALSE(IsHWIDCorrect("SPRING 3A9N-BJKK-E"));
-  EXPECT_FALSE(IsHWIDCorrect("SPRING 3A7N-B0KS-Z"));
-  EXPECT_FALSE(IsHWIDCorrect("SPrING 3A7N-BJKG-5"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING CA9N-BJKL-P"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING CA7N-B0KT-S"));
+  EXPECT_FALSE(IsHWIDCorrect("SPrING CA7N-BJKH-W"));
 
   // Random changes.
-  EXPECT_FALSE(IsHWIDCorrect("SPRUNG 3A7N-BJKZ-F"));
-  EXPECT_FALSE(IsHWIDCorrect("SPRING 3A7N-8JKZ-F"));
-  EXPECT_FALSE(IsHWIDCorrect("SPRING 3A7N-BJSZ-F"));
-  EXPECT_FALSE(IsHWIDCorrect("SPRINGS 3A7N-BJKZ-F"));
-  EXPECT_FALSE(IsHWIDCorrect("SPRING 3A7N-BJKK-L"));
-  EXPECT_FALSE(IsHWIDCorrect("SPRINGX3A7N-BJKZ-F"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRUNG CA7N-BJKY-O"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING CA7N-8JKY-O"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING CA7N-BJSY-O"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRINGS CA7N-BJKY-O"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING CA7N-BJKM-L"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRINGXCA7N-BJKZ-F"));
+}
+
+TEST(HWIDCheckerTest, HWIDv3) {
+  EXPECT_TRUE(IsHWIDCorrect("SPRING E2B-C3D-E8X"));
+  EXPECT_TRUE(IsHWIDCorrect("SPRING E2B-C3D-E8X-D8J"));
+  EXPECT_TRUE(IsHWIDCorrect("FALCO B67-36Y"));
+
+  // Exceptions.
+  EXPECT_FALSE(IsHWIDCorrect("SPRING D2B-C3D-E5D"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING A2B-C3D-E8X-D7T"));
+  EXPECT_FALSE(IsHWIDCorrect("FALCO A67-35W"));
+
+  // Degenerate cases.
+  EXPECT_FALSE(IsHWIDCorrect("SPRING"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING "));
+  EXPECT_TRUE(IsHWIDCorrect("SPRING Z34"));
+
+  // No board name.
+  EXPECT_FALSE(IsHWIDCorrect(" C7N-J3V-T4J"));
+  EXPECT_FALSE(IsHWIDCorrect("C7N-J3V-T2I"));
+
+  // Excess fields.
+  EXPECT_FALSE(IsHWIDCorrect("SPRING WINTER E2B-C3D-E3K"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING E2B-C3D-E72 WINTER"));
+
+  // Incorrect BOM format.
+  EXPECT_FALSE(IsHWIDCorrect("SPRING E2BC3D-E8X"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING E2-B-C3D-E8X"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING E2B-C3D-E8X-"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING E2B-C3D-E85-Y"));
+
+  // Incorrect characters.
+  EXPECT_FALSE(IsHWIDCorrect("SPrING E2B-C3D-E3P"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING EAB-C3D-E7Y"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING E2B-C1D-E3W"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING E28-C3D-E7Z"));
+
+  // Random changes.
+  EXPECT_FALSE(IsHWIDCorrect("SPRING E2L-C3D-E8X"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING E2B-C3D-X8X"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRINGZE2B-C3D-E8X"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRMNG E2B-C3D-E8X"));
+  EXPECT_FALSE(IsHWIDCorrect("SPRING E2B-C3D-EIX"));
 }
 
 TEST(HWIDCheckerTest, KnownHWIDs) {
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc
index 5f24137..c8f27b9 100644
--- a/chrome/browser/chromeos/login/kiosk_browsertest.cc
+++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/chrome_browser_main.h"
 #include "chrome/browser/chrome_browser_main_extra_parts.h"
 #include "chrome/browser/chrome_content_browser_client.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
diff --git a/chrome/browser/chromeos/login/language_switch_menu.cc b/chrome/browser/chromeos/login/language_switch_menu.cc
index d4dab0f..c30a968 100644
--- a/chrome/browser/chromeos/login/language_switch_menu.cc
+++ b/chrome/browser/chromeos/login/language_switch_menu.cc
@@ -10,7 +10,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/input_method/input_method_util.h"
 #include "chrome/browser/chromeos/login/language_list.h"
 #include "chrome/browser/chromeos/login/screens/screen_observer.h"
diff --git a/chrome/browser/chromeos/login/login_browsertest.cc b/chrome/browser/chromeos/login/login_browsertest.cc
index 4f1eba8..7a228aa 100644
--- a/chrome/browser/chromeos/login/login_browsertest.cc
+++ b/chrome/browser/chromeos/login/login_browsertest.cc
@@ -7,6 +7,7 @@
 #include "chrome/browser/chrome_browser_main.h"
 #include "chrome/browser/chrome_browser_main_extra_parts.h"
 #include "chrome/browser/chrome_content_browser_client.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
 #include "chrome/browser/chromeos/login/login_wizard.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/interactive_test_utils.h"
@@ -40,9 +40,9 @@
 
  protected:
   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
+    CrosInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
+
     mock_cryptohome_library_.reset(new chromeos::MockCryptohomeLibrary());
-    cros_mock_->InitStatusAreaMocks();
-    cros_mock_->SetStatusAreaMocksExpectations();
     EXPECT_CALL(*(mock_cryptohome_library_.get()), GetSystemSalt())
         .WillRepeatedly(Return(std::string("stub_system_salt")));
     EXPECT_CALL(*(mock_cryptohome_library_.get()), InstallAttributesIsReady())
@@ -212,4 +212,4 @@
   runner->Run();
 }
 
-}
+}  // namespace
diff --git a/chrome/browser/chromeos/login/login_display_host_impl.cc b/chrome/browser/chromeos/login/login_display_host_impl.cc
index 67fe948..0d245dc 100644
--- a/chrome/browser/chromeos/login/login_display_host_impl.cc
+++ b/chrome/browser/chromeos/login/login_display_host_impl.cc
@@ -22,7 +22,7 @@
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_shutdown.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/customization_document.h"
 #include "chrome/browser/chromeos/input_method/input_method_util.h"
 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
@@ -48,7 +48,6 @@
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_constants.h"
 #include "chromeos/chromeos_switches.h"
@@ -61,8 +60,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
-#include "googleurl/src/gurl.h"
-#include "ui/aura/env.h"
 #include "ui/aura/root_window.h"
 #include "ui/aura/window.h"
 #include "ui/base/events/event_utils.h"
@@ -76,6 +73,7 @@
 #include "ui/gfx/transform.h"
 #include "ui/views/focus/focus_manager.h"
 #include "ui/views/widget/widget.h"
+#include "url/gurl.h"
 
 namespace {
 
@@ -218,9 +216,6 @@
   initialize_webui_hidden_ =
       kHiddenWebUIInitializationDefault && !zero_delay_enabled;
 
-  // Prevents white flashing on OOBE (http://crbug.com/131569).
-  aura::Env::GetInstance()->set_render_white_bg(false);
-
   // Check if WebUI init type is overriden.
   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshWebUIInit)) {
     const std::string override_type = CommandLine::ForCurrentProcess()->
@@ -603,7 +598,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 // LoginDisplayHostImpl, WebContentsObserver implementation:
 
-void LoginDisplayHostImpl::RenderViewGone(base::TerminationStatus status) {
+void LoginDisplayHostImpl::RenderProcessGone(base::TerminationStatus status) {
   // Do not try to restore on shutdown
   if (browser_shutdown::GetShutdownType() != browser_shutdown::NOT_VALID)
     return;
diff --git a/chrome/browser/chromeos/login/login_display_host_impl.h b/chrome/browser/chromeos/login/login_display_host_impl.h
index 42c279e..481001c 100644
--- a/chrome/browser/chromeos/login/login_display_host_impl.h
+++ b/chrome/browser/chromeos/login/login_display_host_impl.h
@@ -91,7 +91,7 @@
                        const content::NotificationDetails& details) OVERRIDE;
 
   // Overridden from content::WebContentsObserver:
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
 
  private:
   // Marks display host for deletion.
diff --git a/chrome/browser/chromeos/login/login_performer.cc b/chrome/browser/chromeos/login/login_performer.cc
index 7fc1a9a..4840116 100644
--- a/chrome/browser/chromeos/login/login_performer.cc
+++ b/chrome/browser/chromeos/login/login_performer.cc
@@ -14,17 +14,16 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/boot_times_loader.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
 #include "chrome/browser/chromeos/login/managed/locally_managed_user_login_flow.h"
-#include "chrome/browser/chromeos/login/screen_locker.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager_client.h"
@@ -46,29 +45,18 @@
 
 namespace chromeos {
 
-// Initialize default LoginPerformer.
-// static
-LoginPerformer* LoginPerformer::default_performer_ = NULL;
-
 LoginPerformer::LoginPerformer(Delegate* delegate)
     : online_attempt_host_(this),
       last_login_failure_(LoginFailure::LoginFailureNone()),
       delegate_(delegate),
       password_changed_(false),
       password_changed_callback_count_(0),
-      screen_lock_requested_(false),
-      initial_online_auth_pending_(false),
       auth_mode_(AUTH_MODE_INTERNAL),
       weak_factory_(this) {
-  DCHECK(default_performer_ == NULL)
-      << "LoginPerformer should have only one instance.";
-  default_performer_ = this;
 }
 
 LoginPerformer::~LoginPerformer() {
   DVLOG(1) << "Deleting LoginPerformer";
-  DCHECK(default_performer_ != NULL) << "Default instance should exist.";
-  default_performer_ = NULL;
   if (authenticator_.get())
     authenticator_->SetConsumer(NULL);
 }
@@ -88,33 +76,9 @@
   if (delegate_) {
     delegate_->OnLoginFailure(failure);
     return;
-  }
-
-  // Consequent online login failure with blocking UI on.
-  // No difference between cases whether screen was locked by the user or
-  // by LoginPerformer except for the very first screen lock while waiting
-  // for online auth. Otherwise it will be SL active > timeout > screen unlock.
-  // Display recoverable error message using ScreenLocker,
-  // force sign out otherwise.
-  if (ScreenLocker::default_screen_locker() && !initial_online_auth_pending_) {
-    ResolveLockLoginFailure();
-    return;
-  }
-  initial_online_auth_pending_ = false;
-
-  // Offline auth - OK, online auth - failed.
-  if (failure.reason() == LoginFailure::NETWORK_AUTH_FAILED) {
-    ResolveInitialNetworkAuthFailure();
-  } else if (failure.reason() == LoginFailure::LOGIN_TIMED_OUT) {
-    VLOG(1) << "Online login timed out. "
-            << "Granting user access based on offline auth only.";
-    // ScreenLock is not active, it's ok to delete itself.
-    base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
   } else {
     // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS:
     // happens during offline auth only.
-    // UNLOCK_FAILED is used during normal screen lock case.
-    // TODO(nkostylev) DATA_REMOVAL_FAILED - ?
     NOTREACHED();
   }
 }
@@ -146,13 +110,8 @@
   DCHECK(delegate_);
   // After delegate_->OnLoginSuccess(...) is called, delegate_ releases
   // LoginPerformer ownership. LP now manages it's lifetime on its own.
-  // 2 things could make it exist longer:
-  // 1. ScreenLock active (pending correct new password input)
-  // 2. Pending online auth request.
-  if (!pending_requests)
-    base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
-  else
-    initial_online_auth_pending_ = true;
+  DCHECK(!pending_requests);
+  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
 
   delegate_->OnLoginSuccess(user_context,
                             pending_requests,
@@ -175,11 +134,7 @@
   if (delegate_) {
     delegate_->OnPasswordChangeDetected();
   } else {
-    last_login_failure_ =
-        LoginFailure::FromNetworkAuthFailure(GoogleServiceAuthError(
-            GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
-    DVLOG(1) << "Password change detected - locking screen.";
-    RequestScreenLock();
+    NOTREACHED();
   }
 }
 
@@ -195,27 +150,6 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// LoginPerformer, content::NotificationObserver implementation:
-//
-
-void LoginPerformer::Observe(int type,
-                             const content::NotificationSource& source,
-                             const content::NotificationDetails& details) {
-  if (type != chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED)
-    return;
-
-  bool is_screen_locked = *content::Details<bool>(details).ptr();
-  if (is_screen_locked) {
-    if (screen_lock_requested_) {
-      screen_lock_requested_ = false;
-      ResolveScreenLocked();
-    }
-  } else {
-    ResolveScreenUnlocked();
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // LoginPerformer, public:
 
 void LoginPerformer::PerformLogin(const UserContext& user_context,
@@ -225,31 +159,28 @@
 
   CrosSettings* cros_settings = CrosSettings::Get();
 
-  // Whitelist check is always performed during initial login and
-  // should not be performed when ScreenLock is active (pending online auth).
-  if (!ScreenLocker::default_screen_locker()) {
-    CrosSettingsProvider::TrustedStatus status =
-        cros_settings->PrepareTrustedValues(
-            base::Bind(&LoginPerformer::PerformLogin,
-                       weak_factory_.GetWeakPtr(),
-                       user_context_, auth_mode));
-    // Must not proceed without signature verification.
-    if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
-      if (delegate_)
-        delegate_->PolicyLoadFailed();
-      else
-        NOTREACHED();
-      return;
-    } else if (status != CrosSettingsProvider::TRUSTED) {
-      // Value of AllowNewUser setting is still not verified.
-      // Another attempt will be invoked after verification completion.
-      return;
-    }
+  // Whitelist check is always performed during initial login.
+  CrosSettingsProvider::TrustedStatus status =
+      cros_settings->PrepareTrustedValues(
+          base::Bind(&LoginPerformer::PerformLogin,
+                     weak_factory_.GetWeakPtr(),
+                     user_context_, auth_mode));
+  // Must not proceed without signature verification.
+  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
+    if (delegate_)
+      delegate_->PolicyLoadFailed();
+    else
+      NOTREACHED();
+    return;
+  } else if (status != CrosSettingsProvider::TRUSTED) {
+    // Value of AllowNewUser setting is still not verified.
+    // Another attempt will be invoked after verification completion.
+    return;
   }
 
   bool is_whitelisted = LoginUtils::IsWhitelisted(
       gaia::CanonicalizeEmail(user_context.username));
-  if (ScreenLocker::default_screen_locker() || is_whitelisted) {
+  if (is_whitelisted) {
     switch (auth_mode_) {
       case AUTH_MODE_EXTENSION:
         StartLoginCompletion();
@@ -333,149 +264,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // LoginPerformer, private:
 
-void LoginPerformer::RequestScreenLock() {
-  DVLOG(1) << "Screen lock requested";
-  // Will receive notifications on screen unlock and delete itself.
-  registrar_.Add(this,
-                 chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
-                 content::NotificationService::AllSources());
-  if (ScreenLocker::default_screen_locker()) {
-    DVLOG(1) << "Screen already locked";
-    ResolveScreenLocked();
-  } else {
-    screen_lock_requested_ = true;
-    // TODO(antrim) : additional logging for crbug/173178
-    LOG(WARNING) << "Requesting screen lock from LoginPerformer";
-    DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen();
-  }
-}
-
-void LoginPerformer::RequestScreenUnlock() {
-  DVLOG(1) << "Screen unlock requested";
-  if (ScreenLocker::default_screen_locker()) {
-    DBusThreadManager::Get()->GetSessionManagerClient()->RequestUnlockScreen();
-    // Will unsubscribe from notifications once unlock is successful.
-  } else {
-    LOG(ERROR) << "Screen is not locked";
-    NOTREACHED();
-  }
-}
-
-void LoginPerformer::ResolveInitialNetworkAuthFailure() {
-  DVLOG(1) << "auth_error: " << last_login_failure_.error().state();
-
-  switch (last_login_failure_.error().state()) {
-    case GoogleServiceAuthError::CONNECTION_FAILED:
-    case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
-    case GoogleServiceAuthError::TWO_FACTOR:
-    case GoogleServiceAuthError::REQUEST_CANCELED:
-      // Offline auth already done. Online auth will be done next time
-      // or once user accesses web property.
-      VLOG(1) << "Granting user access based on offline auth only. "
-              << "Online login failed with "
-              << last_login_failure_.error().state();
-      // Resolving initial online auth failure, no ScreenLock is active.
-      base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
-      return;
-    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
-      // Offline auth OK, so it might be the case of changed password.
-      password_changed_ = true;
-    case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
-    case GoogleServiceAuthError::ACCOUNT_DELETED:
-    case GoogleServiceAuthError::ACCOUNT_DISABLED:
-      // Access not granted. User has to sign out.
-      // Request screen lock & show error message there.
-    case GoogleServiceAuthError::CAPTCHA_REQUIRED:
-    default:
-      // Unless there's new GoogleServiceAuthErrors state has been added.
-      NOTREACHED();
-      return;
-  }
-}
-
-void LoginPerformer::ResolveLockLoginFailure() {
-  if (last_login_failure_.reason() == LoginFailure::LOGIN_TIMED_OUT) {
-    LOG(WARNING) << "Online login timed out - unlocking screen. "
-                 << "Granting user access based on offline auth only.";
-    RequestScreenUnlock();
-    return;
-  } else if (last_login_failure_.reason() ==
-             LoginFailure::NETWORK_AUTH_FAILED) {
-    ResolveLockNetworkAuthFailure();
-    return;
-  } else if (last_login_failure_.reason() ==
-             LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME ||
-             last_login_failure_.reason() ==
-             LoginFailure::DATA_REMOVAL_FAILED) {
-    LOG(ERROR) << "Cryptohome error, forcing sign out.";
-  } else {
-    // COULD_NOT_MOUNT_TMPFS, UNLOCK_FAILED should not happen here.
-    NOTREACHED();
-  }
-  ScreenLocker::default_screen_locker()->Signout();
-}
-
-void LoginPerformer::ResolveLockNetworkAuthFailure() {
-  DCHECK(ScreenLocker::default_screen_locker())
-      << "ScreenLocker instance doesn't exist.";
-  DCHECK(last_login_failure_.reason() == LoginFailure::NETWORK_AUTH_FAILED);
-
-  int msg_id = IDS_LOGIN_ERROR_AUTHENTICATING;
-  HelpAppLauncher::HelpTopic help_topic =
-      HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT;
-  bool sign_out_only = false;
-
-  DVLOG(1) << "auth_error: " << last_login_failure_.error().state();
-
-  switch (last_login_failure_.error().state()) {
-    case GoogleServiceAuthError::CONNECTION_FAILED:
-    case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
-    case GoogleServiceAuthError::TWO_FACTOR:
-    case GoogleServiceAuthError::REQUEST_CANCELED:
-      // Offline auth already done. Online auth will be done next time
-      // or once user accesses web property.
-      LOG(WARNING) << "Granting user access based on offline auth only. "
-                   << "Online login failed with "
-                   << last_login_failure_.error().state();
-      RequestScreenUnlock();
-      return;
-    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
-      // Password change detected.
-      msg_id = IDS_LOGIN_ERROR_PASSWORD_CHANGED;
-      break;
-    case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
-    case GoogleServiceAuthError::ACCOUNT_DELETED:
-    case GoogleServiceAuthError::ACCOUNT_DISABLED:
-      // Access not granted. User has to sign out.
-      // Show error message using existing screen lock.
-      msg_id = IDS_LOGIN_ERROR_RESTRICTED;
-      help_topic = HelpAppLauncher::HELP_ACCOUNT_DISABLED;
-      sign_out_only = true;
-      break;
-    case GoogleServiceAuthError::CAPTCHA_REQUIRED:
-    default:
-      // Unless there's new GoogleServiceAuthError state has been added.
-      NOTREACHED();
-      break;
-  }
-
-  ScreenLocker::default_screen_locker()->ShowErrorMessage(msg_id,
-                                                          help_topic,
-                                                          sign_out_only);
-}
-
-void LoginPerformer::ResolveScreenLocked() {
-  DVLOG(1) << "Screen locked";
-  ResolveLockNetworkAuthFailure();
-}
-
-void LoginPerformer::ResolveScreenUnlocked() {
-  DVLOG(1) << "Screen unlocked";
-  registrar_.RemoveAll();
-  // If screen was unlocked that was for a reason, should delete itself now.
-  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
-}
-
 void LoginPerformer::StartLoginCompletion() {
   DVLOG(1) << "Login completion started";
   BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
@@ -502,24 +290,12 @@
         BrowserThread::UI, FROM_HERE,
         base::Bind(&Authenticator::AuthenticateToLogin, authenticator_.get(),
                    profile,
-                   user_context_,
-                   std::string(),
-                   std::string()));
+                   user_context_));
     // Make unobtrusive online check. It helps to determine password change
     // state in the case when offline login fails.
     online_attempt_host_.Check(profile, user_context_);
   } else {
-    DCHECK(authenticator_.get())
-        << "Authenticator instance doesn't exist for login attempt retry.";
-    // At this point offline auth has been successful,
-    // retry online auth, using existing Authenticator instance.
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::Bind(&Authenticator::RetryAuth, authenticator_.get(),
-                   profile,
-                   user_context_,
-                   std::string(),
-                   std::string()));
+    NOTREACHED();
   }
   user_context_.password.clear();
   user_context_.auth_code.clear();
diff --git a/chrome/browser/chromeos/login/login_performer.h b/chrome/browser/chromeos/login/login_performer.h
index 377e5a5..72411ed 100644
--- a/chrome/browser/chromeos/login/login_performer.h
+++ b/chrome/browser/chromeos/login/login_performer.h
@@ -27,32 +27,8 @@
 // LP instance ownership. LP waits for online login result.
 // If auth is succeeded, cookie fetcher is executed, LP instance deletes itself.
 //
-// If online login operation fails that means:
-// (1) User password has changed. Ask user for the new password.
-// (2) User password has changed and/or CAPTCHA input is required.
-// (3) User account is deleted/disabled/not signed up.
-// (4) Timeout/service unavailable/connection failed.
-//
-// Actions:
-// (1)-(3): Request screen lock.
-// (1) Ask for new user password.
-// (2) Ask for new user password and/or CAPTCHA.
-// (3) Display error message and allow "Sign Out" as the only action.
-// (4) Delete LP instance since offline auth was OK.
-//
-// If |delegate_| is not NULL it will handle error messages,
-// CAPTCHA dialog, password input.
-// If |delegate_| is NULL that does mean that LoginPerformer instance
-// is waiting for successful online login or blocked on online login failure.
-// In case of failure password/captcha
-// input & error messages display is dedicated to ScreenLocker instance.
-//
-// 2 things make LoginPerfrormer instance exist longer:
-// 1. ScreenLock active (pending correct new password input)
-// 2. Pending online auth request.
-// TODO(nkostylev): Cleanup ClientLogin related code, update class description.
+// If |delegate_| is not NULL it will handle error messages, password input.
 class LoginPerformer : public LoginStatusConsumer,
-                       public content::NotificationObserver,
                        public OnlineAttemptHost::Delegate {
  public:
   typedef enum AuthorizationMode {
@@ -74,13 +50,6 @@
   explicit LoginPerformer(Delegate* delegate);
   virtual ~LoginPerformer();
 
-  // Returns the default instance if it has been created.
-  // This instance is owned by delegate_ till it's destroyed.
-  // When LP instance lives by itself it's used by ScreenLocker instance.
-  static LoginPerformer* default_performer() {
-    return default_performer_;
-  }
-
   // LoginStatusConsumer implementation:
   virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE;
   virtual void OnRetailModeLoginSuccess(
@@ -121,11 +90,6 @@
     return last_login_failure_.error();
   }
 
-  // True if last login operation has timed out.
-  bool login_timed_out() {
-    return last_login_failure_.reason() == LoginFailure::LOGIN_TIMED_OUT;
-  }
-
   // True if password change has been detected.
   bool password_changed() { return password_changed_; }
 
@@ -147,41 +111,12 @@
   virtual void OnChecked(const std::string& username, bool success) OVERRIDE;
 
  private:
-  // content::NotificationObserver implementation:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) OVERRIDE;
-
-  // Requests screen lock and subscribes to screen lock notifications.
-  void RequestScreenLock();
-
-  // Requests screen unlock.
-  void RequestScreenUnlock();
-
-  // Resolves initial LoginFailure::NETWORK_AUTH_FAILED error i.e.
-  // when screen is not locked yet.
-  void ResolveInitialNetworkAuthFailure();
-
-  // Resolves LoginFailure when screen is locked.
-  void ResolveLockLoginFailure();
-
-  // Resolves LoginFailure::NETWORK_AUTH_FAILED error when screen is locked.
-  // Uses ScreenLocker to show error message based on |last_login_failure_|.
-  void ResolveLockNetworkAuthFailure();
-
-  // Resolve ScreenLock changed state.
-  void ResolveScreenLocked();
-  void ResolveScreenUnlocked();
-
   // Starts login completion of externally authenticated user.
   void StartLoginCompletion();
 
   // Starts authentication.
   void StartAuthentication();
 
-  // Default performer. Will be used by ScreenLocker.
-  static LoginPerformer* default_performer_;
-
   // Used for logging in.
   scoped_refptr<Authenticator> authenticator_;
 
@@ -203,18 +138,6 @@
   bool password_changed_;
   int password_changed_callback_count_;
 
-  // Used for ScreenLock notifications.
-  content::NotificationRegistrar registrar_;
-
-  // True if LoginPerformer has requested screen lock. Used to distinguish
-  // such requests with cases when screen is locked on its own.
-  bool screen_lock_requested_;
-
-  // True if LoginPerformer instance is waiting for the initial (very first one)
-  // online authentication response. Used to distinguish cases when screen
-  // is locked during that stage. No need to resolve screen lock action then.
-  bool initial_online_auth_pending_;
-
   // Authorization mode type.
   AuthorizationMode auth_mode_;
 
diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc
index 98f1764..1402338 100644
--- a/chrome/browser/chromeos/login/login_utils.cc
+++ b/chrome/browser/chromeos/login/login_utils.cc
@@ -31,6 +31,7 @@
 #include "chrome/browser/app_mode/app_mode_utils.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/boot_times_loader.h"
 #include "chrome/browser/chromeos/input_method/input_method_util.h"
 #include "chrome/browser/chromeos/login/chrome_restart_request.h"
@@ -59,7 +60,6 @@
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/logging_chrome.h"
@@ -72,10 +72,10 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "google_apis/gaia/gaia_auth_consumer.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/network_change_notifier.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_getter.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
@@ -365,13 +365,6 @@
         UserManager::Get()->GetLoggedInUser()->display_email());
   }
 
-  // Make sure we flip every profile to not share proxies if the user hasn't
-  // specified so explicitly.
-  const PrefService::Preference* use_shared_proxies_pref =
-      user_profile->GetPrefs()->FindPreference(prefs::kUseSharedProxies);
-  if (use_shared_proxies_pref->IsDefaultValue())
-    user_profile->GetPrefs()->SetBoolean(prefs::kUseSharedProxies, false);
-
   RespectLocalePreference(user_profile);
 }
 
@@ -549,7 +542,7 @@
   base::PostTaskAndReplyWithResult(
       base::WorkerPool::GetTaskRunner(false),
       FROM_HERE,
-      base::Bind(&file_util::PathExists, GetRlzDisabledFlagPath()),
+      base::Bind(&base::PathExists, GetRlzDisabledFlagPath()),
       base::Bind(&LoginUtilsImpl::InitRlz, AsWeakPtr(), user_profile));
 #endif
 }
diff --git a/chrome/browser/chromeos/login/login_utils_browsertest.cc b/chrome/browser/chromeos/login/login_utils_browsertest.cc
index 275c521..7bb9ba7 100644
--- a/chrome/browser/chromeos/login/login_utils_browsertest.cc
+++ b/chrome/browser/chromeos/login/login_utils_browsertest.cc
@@ -16,7 +16,8 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "base/threading/thread.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
 #include "chrome/browser/chromeos/login/authenticator.h"
@@ -38,7 +39,6 @@
 #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/rlz/rlz.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -509,7 +509,7 @@
   }
 
  protected:
-  ScopedStubCrosEnabler stub_cros_enabler_;
+  ScopedStubNetworkLibraryEnabler stub_network_library_enabler_;
 
   base::Closure fake_io_thread_work_;
   base::WaitableEvent fake_io_thread_completion_;
@@ -736,4 +736,4 @@
 
 }  // namespace
 
-}
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/login_web_dialog.h b/chrome/browser/chromeos/login/login_web_dialog.h
index dbcca81..c92596c 100644
--- a/chrome/browser/chromeos/login/login_web_dialog.h
+++ b/chrome/browser/chromeos/login/login_web_dialog.h
@@ -10,10 +10,10 @@
 #include "base/compiler_specific.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/size.h"
 #include "ui/web_dialogs/web_dialog_delegate.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
diff --git a/chrome/browser/chromeos/login/merge_session_load_page.cc b/chrome/browser/chromeos/login/merge_session_load_page.cc
index cb5728e..505e69e 100644
--- a/chrome/browser/chromeos/login/merge_session_load_page.cc
+++ b/chrome/browser/chromeos/login/merge_session_load_page.cc
@@ -13,12 +13,12 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/renderer_preferences_util.h"
 #include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/extension_icon_set.h"
diff --git a/chrome/browser/chromeos/login/merge_session_load_page.h b/chrome/browser/chromeos/login/merge_session_load_page.h
index 9556a63..190b589 100644
--- a/chrome/browser/chromeos/login/merge_session_load_page.h
+++ b/chrome/browser/chromeos/login/merge_session_load_page.h
@@ -11,7 +11,7 @@
 #include "base/compiler_specific.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "content/public/browser/interstitial_page_delegate.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace base {
 class DictionaryValue;
diff --git a/chrome/browser/chromeos/login/merge_session_load_page_unittest.cc b/chrome/browser/chromeos/login/merge_session_load_page_unittest.cc
index 5417931..3cab6ed 100644
--- a/chrome/browser/chromeos/login/merge_session_load_page_unittest.cc
+++ b/chrome/browser/chromeos/login/merge_session_load_page_unittest.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/run_loop.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/merge_session_load_page.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
@@ -81,7 +81,7 @@
   }
 
  private:
-  ScopedStubCrosEnabler stub_cros_enabler_;
+  ScopedStubNetworkLibraryEnabler stub_network_library_enabler_;
   ScopedTestDeviceSettingsService test_device_settings_service_;
   ScopedTestCrosSettings test_cros_settings_;
   scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
diff --git a/chrome/browser/chromeos/login/mock_authenticator.cc b/chrome/browser/chromeos/login/mock_authenticator.cc
index 9270f61..47ffe15 100644
--- a/chrome/browser/chromeos/login/mock_authenticator.cc
+++ b/chrome/browser/chromeos/login/mock_authenticator.cc
@@ -13,9 +13,7 @@
 namespace chromeos {
 
 void MockAuthenticator::AuthenticateToLogin(Profile* profile,
-                                            const UserContext& user_context,
-                                            const std::string& login_token,
-                                            const std::string& login_captcha) {
+                                            const UserContext& user_context) {
   if (expected_username_ == user_context.username &&
       expected_password_ == user_context.password) {
     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
@@ -38,8 +36,7 @@
 
 void MockAuthenticator::AuthenticateToUnlock(
     const UserContext& user_context) {
-  AuthenticateToLogin(NULL /* not used */, user_context,
-                      std::string(), std::string());
+  AuthenticateToLogin(NULL /* not used */, user_context);
 }
 
 void MockAuthenticator::LoginAsLocallyManagedUser(
diff --git a/chrome/browser/chromeos/login/mock_authenticator.h b/chrome/browser/chromeos/login/mock_authenticator.h
index f3ddb53..aefe07c 100644
--- a/chrome/browser/chromeos/login/mock_authenticator.h
+++ b/chrome/browser/chromeos/login/mock_authenticator.h
@@ -30,9 +30,7 @@
                              const UserContext& user_context) OVERRIDE;
 
   virtual void AuthenticateToLogin(Profile* profile,
-                                   const UserContext& user_context,
-                                   const std::string& login_token,
-                                   const std::string& login_captcha) OVERRIDE;
+                                   const UserContext& user_context) OVERRIDE;
 
   virtual void AuthenticateToUnlock(const UserContext& user_context) OVERRIDE;
 
@@ -53,11 +51,6 @@
 
   virtual void ResyncEncryptedData() OVERRIDE {}
 
-  virtual void RetryAuth(Profile* profile,
-                         const UserContext& user_context,
-                         const std::string& login_token,
-                         const std::string& login_captcha) OVERRIDE {}
-
   virtual void SetExpectedCredentials(const std::string& expected_username,
                                       const std::string& expected_password);
 
diff --git a/chrome/browser/chromeos/login/mock_login_utils.h b/chrome/browser/chromeos/login/mock_login_utils.h
index 0710c9b..c01726e 100644
--- a/chrome/browser/chromeos/login/mock_login_utils.h
+++ b/chrome/browser/chromeos/login/mock_login_utils.h
@@ -14,8 +14,8 @@
 #include "chrome/browser/chromeos/login/login_display_host.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
 #include "google_apis/gaia/gaia_auth_consumer.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "url/gurl.h"
 
 class PrefService;
 class Profile;
diff --git a/chrome/browser/chromeos/login/mock_url_fetchers.cc b/chrome/browser/chromeos/login/mock_url_fetchers.cc
index a90d84a..aa9da1f 100644
--- a/chrome/browser/chromeos/login/mock_url_fetchers.cc
+++ b/chrome/browser/chromeos/login/mock_url_fetchers.cc
@@ -9,12 +9,12 @@
 #include "base/bind.h"
 #include "base/message_loop.h"
 #include "base/strings/stringprintf.h"
-#include "googleurl/src/gurl.h"
 #include "net/http/http_status_code.h"
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "net/url_request/url_request_status.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
diff --git a/chrome/browser/chromeos/login/mock_url_fetchers.h b/chrome/browser/chromeos/login/mock_url_fetchers.h
index 8756165..f7c351a 100644
--- a/chrome/browser/chromeos/login/mock_url_fetchers.h
+++ b/chrome/browser/chromeos/login/mock_url_fetchers.h
@@ -10,9 +10,9 @@
 #include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "net/url_request/url_request_status.h"
+#include "url/gurl.h"
 
 namespace net {
 class URLFetcherDelegate;
diff --git a/chrome/browser/chromeos/login/mock_user_manager.h b/chrome/browser/chromeos/login/mock_user_manager.h
index 503f04a..0901f56 100644
--- a/chrome/browser/chromeos/login/mock_user_manager.h
+++ b/chrome/browser/chromeos/login/mock_user_manager.h
@@ -84,6 +84,8 @@
       const std::string&));
   MOCK_CONST_METHOD1(GetManagerUserIdForManagedUser, std::string(
       const std::string&));
+  MOCK_CONST_METHOD1(GetManagerDisplayEmailForManagedUser, std::string(
+      const std::string&));
   MOCK_METHOD0(GenerateUniqueLocallyManagedUserId, std::string(void));
   MOCK_METHOD1(StartLocallyManagedUserCreationTransaction,
       void(const string16&));
diff --git a/chrome/browser/chromeos/login/oauth2_login_manager.cc b/chrome/browser/chromeos/login/oauth2_login_manager.cc
index e253754..f35ecbc 100644
--- a/chrome/browser/chromeos/login/oauth2_login_manager.cc
+++ b/chrome/browser/chromeos/login/oauth2_login_manager.cc
@@ -9,11 +9,11 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/signin/token_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -39,7 +39,7 @@
 OAuth2LoginManager::~OAuth2LoginManager() {
 }
 
-void OAuth2LoginManager::RegisterUserPrefs(
+void OAuth2LoginManager::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterStringPref(
       kOAuth1Token, "", user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
diff --git a/chrome/browser/chromeos/login/oauth2_login_manager.h b/chrome/browser/chromeos/login/oauth2_login_manager.h
index ed24654..20f2cdd 100644
--- a/chrome/browser/chromeos/login/oauth2_login_manager.h
+++ b/chrome/browser/chromeos/login/oauth2_login_manager.h
@@ -34,7 +34,7 @@
   explicit OAuth2LoginManager(OAuthLoginManager::Delegate* delegate);
   virtual ~OAuth2LoginManager();
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // OAuthLoginManager overrides.
   virtual void RestoreSession(
diff --git a/chrome/browser/chromeos/login/oauth2_login_verifier.cc b/chrome/browser/chromeos/login/oauth2_login_verifier.cc
index abff7b1..d144f39 100644
--- a/chrome/browser/chromeos/login/oauth2_login_verifier.cc
+++ b/chrome/browser/chromeos/login/oauth2_login_verifier.cc
@@ -11,7 +11,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/net/connectivity_state_helper.h"
 #include "content/public/browser/browser_thread.h"
 #include "google_apis/gaia/gaia_constants.h"
diff --git a/chrome/browser/chromeos/login/oauth2_token_fetcher.cc b/chrome/browser/chromeos/login/oauth2_token_fetcher.cc
index c60d9d7..f66c1ca 100644
--- a/chrome/browser/chromeos/login/oauth2_token_fetcher.cc
+++ b/chrome/browser/chromeos/login/oauth2_token_fetcher.cc
@@ -6,7 +6,6 @@
 
 #include "base/logging.h"
 #include "base/strings/string_util.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/net/connectivity_state_helper.h"
 #include "content/public/browser/browser_thread.h"
 #include "google_apis/gaia/gaia_constants.h"
diff --git a/chrome/browser/chromeos/login/online_attempt.cc b/chrome/browser/chromeos/login/online_attempt.cc
index 7a77776..c1a29f5 100644
--- a/chrome/browser/chromeos/login/online_attempt.cc
+++ b/chrome/browser/chromeos/login/online_attempt.cc
@@ -10,7 +10,6 @@
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/login/auth_attempt_state.h"
 #include "chrome/browser/chromeos/login/auth_attempt_state_resolver.h"
 #include "chrome/browser/chromeos/login/user.h"
diff --git a/chrome/browser/chromeos/login/online_attempt_unittest.cc b/chrome/browser/chromeos/login/online_attempt_unittest.cc
index 34c089f..84abe44 100644
--- a/chrome/browser/chromeos/login/online_attempt_unittest.cc
+++ b/chrome/browser/chromeos/login/online_attempt_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/bind.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/auth_attempt_state.h"
 #include "chrome/browser/chromeos/login/mock_auth_attempt_state_resolver.h"
 #include "chrome/browser/chromeos/login/mock_url_fetchers.h"
@@ -18,9 +18,9 @@
 #include "content/public/test/test_browser_thread.h"
 #include "google_apis/gaia/gaia_auth_consumer.h"
 #include "google_apis/gaia/mock_url_fetcher_factory.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 using ::testing::AnyNumber;
 using ::testing::Invoke;
@@ -85,8 +85,8 @@
   scoped_ptr<MockAuthAttemptStateResolver> resolver_;
   scoped_ptr<OnlineAttempt> attempt_;
 
-  // Initializes / shuts down a stub CrosLibrary.
-  chromeos::ScopedStubCrosEnabler stub_cros_enabler_;
+  // Initializes / shuts down a stub NetworkLibrary.
+  ScopedStubNetworkLibraryEnabler stub_network_library_enabler_;
 };
 
 TEST_F(OnlineAttemptTest, LoginSuccess) {
diff --git a/chrome/browser/chromeos/login/oobe_browsertest.cc b/chrome/browser/chromeos/login/oobe_browsertest.cc
index ec6c1f8..3ee0c8d 100644
--- a/chrome/browser/chromeos/login/oobe_browsertest.cc
+++ b/chrome/browser/chromeos/login/oobe_browsertest.cc
@@ -7,12 +7,12 @@
 #include "chrome/browser/chrome_browser_main.h"
 #include "chrome/browser/chrome_browser_main_extra_parts.h"
 #include "chrome/browser/chrome_content_browser_client.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/webui_login_display.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/chromeos/login/parallel_authenticator.cc b/chrome/browser/chromeos/login/parallel_authenticator.cc
index 5dc92f5..44aef96 100644
--- a/chrome/browser/chromeos/login/parallel_authenticator.cc
+++ b/chrome/browser/chromeos/login/parallel_authenticator.cc
@@ -10,15 +10,14 @@
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/boot_times_loader.h"
 #include "chrome/browser/chromeos/cros/cert_library.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/login/authentication_notification_details.h"
 #include "chrome/browser/chromeos/login/login_status_consumer.h"
 #include "chrome/browser/chromeos/login/user.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chromeos/cryptohome/async_method_caller.h"
 #include "chromeos/cryptohome/cryptohome_library.h"
@@ -36,9 +35,6 @@
 
 namespace {
 
-// Milliseconds until we timeout our attempt to hit ClientLogin.
-const int kClientLoginTimeoutMs = 10000;
-
 // Length of password hashed with SHA-256.
 const int kPasswordHashLength = 32;
 
@@ -164,15 +160,6 @@
       base::Bind(&TriggerResolve, attempt, resolver));
 }
 
-// Returns whether the login failure was connection issue.
-bool WasConnectionIssue(const LoginFailure& online_outcome) {
-  return ((online_outcome.reason() == LoginFailure::LOGIN_TIMED_OUT) ||
-          (online_outcome.error().state() ==
-           GoogleServiceAuthError::CONNECTION_FAILED) ||
-          (online_outcome.error().state() ==
-           GoogleServiceAuthError::REQUEST_CANCELED));
-}
-
 // Returns hash of |password|, salted with the system salt.
 std::string HashPassword(const std::string& password) {
   // Get salt, ascii encode, update sha with that, then update with ascii
@@ -208,9 +195,7 @@
 
 void ParallelAuthenticator::AuthenticateToLogin(
     Profile* profile,
-    const UserContext& user_context,
-    const std::string& login_token,
-    const std::string& login_captcha) {
+    const UserContext& user_context) {
   std::string canonicalized = gaia::CanonicalizeEmail(user_context.username);
   authentication_profile_ = profile;
   current_state_.reset(
@@ -219,8 +204,8 @@
                       user_context.password,
                       user_context.auth_code),
           HashPassword(user_context.password),
-          login_token,
-          login_captcha,
+          std::string(), // login_token, not used.
+          std::string(), // login_captcha, not used.
           User::USER_TYPE_REGULAR,
           !UserManager::Get()->IsKnownUser(canonicalized)));
   // Reset the verified flag.
@@ -269,6 +254,7 @@
     // services not being able to fetch a token, leading to browser crashes.
     // So initiate ClientLogin-based post authentication.
     // TODO(xiyuan): This should not be required.
+    // Context: http://crbug.com/201374
     current_online_.reset(new OnlineAttempt(current_state_.get(),
                                             this));
     current_online_->Initiate(profile);
@@ -426,16 +412,6 @@
     consumer_->OnLoginFailure(error);
 }
 
-void ParallelAuthenticator::RecordOAuthCheckFailure(
-    const std::string& user_name) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(using_oauth_);
-  // Mark this account's OAuth token state as invalid in the local state.
-  UserManager::Get()->SaveUserOAuthStatus(
-      user_name,
-      User::OAUTH2_TOKEN_STATUS_INVALID);
-}
-
 void ParallelAuthenticator::RecoverEncryptedData(
     const std::string& old_password) {
   std::string old_hash = HashPassword(old_password);
@@ -489,30 +465,6 @@
   Resolve();
 }
 
-void ParallelAuthenticator::RetryAuth(Profile* profile,
-                                      const UserContext& user_context,
-                                      const std::string& login_token,
-                                      const std::string& login_captcha) {
-  reauth_state_.reset(
-      new AuthAttemptState(
-          UserContext(gaia::CanonicalizeEmail(user_context.username),
-                      user_context.password,
-                      user_context.auth_code),
-          HashPassword(user_context.password),
-          login_token,
-          login_captcha,
-          User::USER_TYPE_REGULAR,
-          false /* not a new user */));
-  // Always use ClientLogin regardless of using_oauth flag. This is because
-  // we are unable to renew oauth token on lock screen currently and will
-  // stuck with lock screen if we use OAuthLogin here.
-  // TODO(xiyuan): Revisit this after we support Gaia in lock screen.
-  current_online_.reset(new OnlineAttempt(reauth_state_.get(),
-                                          this));
-  current_online_->Initiate(profile);
-}
-
-
 void ParallelAuthenticator::Resolve() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   bool request_pending = false;
@@ -576,57 +528,9 @@
           base::Bind(&ParallelAuthenticator::OnPasswordChangeDetected, this));
       break;
     case ONLINE_FAILED:
-      // In this case, we know online login was rejected because the account
-      // is disabled or something similarly fatal.  Sending the user through
-      // the same path they get when their password is rejected is cleaner
-      // for now.
-      // TODO(cmasone): optimize this so that we don't send the user through
-      // the 'changed password' path when we know doing so won't succeed.
-    case NEED_NEW_PW: {
-        {
-          base::AutoLock for_this_block(success_lock_);
-          if (!already_reported_success_) {
-            // This allows us to present the same behavior for "online:
-            // fail, offline: ok", regardless of the order in which we
-            // receive the results.  There will be cases in which we get
-            // the online failure some time after the offline success,
-            // so we just force all cases in this category to present like this:
-            // OnLoginSuccess(..., ..., true) -> OnLoginFailure().
-            BrowserThread::PostTask(
-                BrowserThread::UI, FROM_HERE,
-                base::Bind(&ParallelAuthenticator::OnLoginSuccess,
-                           this,
-                           true));
-          }
-        }
-        const LoginFailure& login_failure =
-            reauth_state_.get() ? reauth_state_->online_outcome() :
-                                  current_state_->online_outcome();
-        BrowserThread::PostTask(
-            BrowserThread::UI, FROM_HERE,
-            base::Bind(&ParallelAuthenticator::OnLoginFailure, this,
-                       login_failure));
-        // Check if we couldn't verify OAuth token here.
-        if (using_oauth_ &&
-            login_failure.reason() == LoginFailure::NETWORK_AUTH_FAILED) {
-          BrowserThread::PostTask(
-              BrowserThread::UI, FROM_HERE,
-              base::Bind(&ParallelAuthenticator::RecordOAuthCheckFailure, this,
-                         (reauth_state_.get() ?
-                             reauth_state_->user_context.username :
-                             current_state_->user_context.username)));
-        }
-        break;
-    }
+    case NEED_NEW_PW:
     case HAVE_NEW_PW:
-      migrate_attempted_ = true;
-      BrowserThread::PostTask(
-          BrowserThread::UI, FROM_HERE,
-          base::Bind(&Migrate,
-                     reauth_state_.get(),
-                     scoped_refptr<ParallelAuthenticator>(this),
-                     true,
-                     current_state_->ascii_hash));
+      NOTREACHED() << "Using obsolete ClientLogin code path.";
       break;
     case OFFLINE_LOGIN:
       VLOG(2) << "Offline login";
@@ -719,9 +623,7 @@
     return CONTINUE;
   }
 
-  AuthState state = (reauth_state_.get() ? ResolveReauthState() : CONTINUE);
-  if (state != CONTINUE)
-    return state;
+  AuthState state = CONTINUE;
 
   if (current_state_->cryptohome_outcome())
     state = ResolveCryptohomeSuccessState();
@@ -744,36 +646,13 @@
       // Online attempt succeeded as well, so combine the results.
       return ResolveOnlineSuccessState(state);
     }
-    // Online login attempt was rejected or failed to occur.
-    return ResolveOnlineFailureState(state);
+    NOTREACHED() << "Using obsolete ClientLogin code path.";
   }
   // if online isn't complete yet, just return the offline result.
   return state;
 }
 
 ParallelAuthenticator::AuthState
-ParallelAuthenticator::ResolveReauthState() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  if (reauth_state_->cryptohome_complete()) {
-    if (!reauth_state_->cryptohome_outcome()) {
-      // If we've tried to migrate and failed, log the error and just wait
-      // til next time the user logs in to migrate their cryptohome key.
-      LOG(ERROR) << "Failed to migrate cryptohome key: "
-                 << reauth_state_->cryptohome_code();
-    }
-    reauth_state_.reset(NULL);
-    return ONLINE_LOGIN;
-  }
-  // Haven't tried the migrate yet, must be processing the online auth attempt.
-  if (!reauth_state_->online_complete()) {
-    NOTREACHED();  // Shouldn't be here at all, if online reauth isn't done!
-    return CONTINUE;
-  }
-  return (reauth_state_->online_outcome().reason() == LoginFailure::NONE) ?
-      HAVE_NEW_PW : NEED_NEW_PW;
-}
-
-ParallelAuthenticator::AuthState
 ParallelAuthenticator::ResolveCryptohomeFailureState() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   if (remove_attempted_)
@@ -840,25 +719,6 @@
 }
 
 ParallelAuthenticator::AuthState
-ParallelAuthenticator::ResolveOnlineFailureState(
-    ParallelAuthenticator::AuthState offline_state) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  if (offline_state == OFFLINE_LOGIN) {
-    if (WasConnectionIssue(current_state_->online_outcome())) {
-      // Couldn't do an online check, so just go with the offline result.
-      return OFFLINE_LOGIN;
-    }
-    // Otherwise, online login was rejected!
-    if (current_state_->online_outcome().error().state() ==
-        GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) {
-      return NEED_NEW_PW;
-    }
-    return ONLINE_FAILED;
-  }
-  return LOGIN_FAILED;
-}
-
-ParallelAuthenticator::AuthState
 ParallelAuthenticator::ResolveOnlineSuccessState(
     ParallelAuthenticator::AuthState offline_state) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
diff --git a/chrome/browser/chromeos/login/parallel_authenticator.h b/chrome/browser/chromeos/login/parallel_authenticator.h
index cf577f3..ff4064a 100644
--- a/chrome/browser/chromeos/login/parallel_authenticator.h
+++ b/chrome/browser/chromeos/login/parallel_authenticator.h
@@ -27,46 +27,63 @@
 
 class LoginStatusConsumer;
 
-// Authenticates a Chromium OS user against the Google Accounts ClientLogin API.
-//
-// Simultaneously attempts authentication both offline and online.
+// Authenticates a Chromium OS user against cryptohome.
+// Relies on the fact that online authentications has been already performed
+// (i.e. using_oauth_ is true).
 //
 // At a high, level, here's what happens:
-// AuthenticateToLogin() creates an OnlineAttempt and calls a Cryptohome's
-// method to perform online and offline login simultaneously.  When one of
-// these completes, it will store results in a AuthAttemptState owned by
-// ParallelAuthenticator and then call Resolve().  Resolve() will attempt to
+// AuthenticateToLogin() calls a Cryptohome's method to perform offline login.
+// Resultes are stored in a AuthAttemptState owned by ParallelAuthenticator
+// and then call Resolve().  Resolve() will attempt to
 // determine which AuthState we're in, based on the info at hand.
 // It then triggers further action based on the calculated AuthState; this
 // further action might include calling back the passed-in LoginStatusConsumer
 // to signal that login succeeded or failed, waiting for more outstanding
 // operations to complete, or triggering some more Cryptohome method calls.
+//
+// Typical flows
+// -------------
+// Add new user: CONTINUE > CONTINUE > CREATE_NEW > CONTINUE > ONLINE_LOGIN
+// Login as existing user: CONTINUE > OFFLINE_LOGIN
+// Login as existing user (failure): CONTINUE > FAILED_MOUNT
+// Change password detected:
+//   GAIA online ok: CONTINUE > CONTINUE > NEED_OLD_PW
+//     Recreate: CREATE_NEW > CONTINUE > ONLINE_LOGIN
+//     Old password failure: NEED_OLD_PW
+//     Old password ok: RECOVER_MOUNT > CONTINUE > ONLINE_LOGIN
+//
+// TODO(nkostylev): Rename ParallelAuthenticator since it is not doing
+// offline/online login operations in parallel anymore.
 class ParallelAuthenticator : public Authenticator,
                               public AuthAttemptStateResolver {
  public:
   enum AuthState {
-    CONTINUE,        // State indeterminate; try again when more info available.
-    NO_MOUNT,        // Cryptohome doesn't exist yet.
-    FAILED_MOUNT,    // Failed to mount existing cryptohome.
-    FAILED_REMOVE,   // Failed to remove existing cryptohome.
-    FAILED_TMPFS,    // Failed to mount tmpfs for guest user
-    FAILED_TPM,      // Failed to mount/create cryptohome because of TPM error.
-    CREATE_NEW,      // Need to create cryptohome for a new user.
-    RECOVER_MOUNT,   // After RecoverEncryptedData, mount cryptohome.
-    POSSIBLE_PW_CHANGE,  // Offline login failed, user may have changed pw.
-    NEED_NEW_PW,     // User changed pw, and we have the old one.
-    NEED_OLD_PW,     // User changed pw, and we have the new one.
-    HAVE_NEW_PW,     // We have verified new pw, time to migrate key.
-    OFFLINE_LOGIN,   // Login succeeded offline.
-    DEMO_LOGIN,      // Logged in as the demo user.
-    ONLINE_LOGIN,    // Offline and online login succeeded.
-    UNLOCK,          // Screen unlock succeeded.
-    ONLINE_FAILED,   // Online login disallowed, but offline succeeded.
-    GUEST_LOGIN,     // Logged in guest mode.
-    PUBLIC_ACCOUNT_LOGIN,        // Logged into a public account.
-    LOCALLY_MANAGED_USER_LOGIN,  // Logged in as a locally managed user.
-    LOGIN_FAILED,    // Login denied.
-    OWNER_REQUIRED   // Login is restricted to the owner only.
+    CONTINUE = 0,            // State indeterminate; try again with more info.
+    NO_MOUNT = 1,            // Cryptohome doesn't exist yet.
+    FAILED_MOUNT = 2,        // Failed to mount existing cryptohome.
+    FAILED_REMOVE = 3,       // Failed to remove existing cryptohome.
+    FAILED_TMPFS = 4,        // Failed to mount tmpfs for guest user.
+    FAILED_TPM = 5,          // Failed to mount/create cryptohome, TPM error.
+    CREATE_NEW = 6,          // Need to create cryptohome for a new user.
+    RECOVER_MOUNT = 7,       // After RecoverEncryptedData, mount cryptohome.
+    POSSIBLE_PW_CHANGE = 8,  // Offline login failed, user may have changed pw.
+    NEED_NEW_PW = 9,         // Obsolete (ClientLogin): user changed pw,
+                             // we have the old one.
+    NEED_OLD_PW = 10,        // User changed pw, and we have the new one
+                             // (GAIA auth is OK).
+    HAVE_NEW_PW = 11,        // Obsolete (ClientLogin): We have verified new pw,
+                             // time to migrate key.
+    OFFLINE_LOGIN = 12,      // Login succeeded offline.
+    DEMO_LOGIN = 13,         // Logged in as the demo user.
+    ONLINE_LOGIN = 14,       // Offline and online login succeeded.
+    UNLOCK = 15,             // Screen unlock succeeded.
+    ONLINE_FAILED = 16,      // Obsolete (ClientLogin): Online login disallowed,
+                             // but offline succeeded.
+    GUEST_LOGIN = 17,        // Logged in guest mode.
+    PUBLIC_ACCOUNT_LOGIN = 18,        // Logged into a public account.
+    LOCALLY_MANAGED_USER_LOGIN = 19,  // Logged in as a locally managed user.
+    LOGIN_FAILED = 20,       // Login denied.
+    OWNER_REQUIRED = 21      // Login is restricted to the owner only.
   };
 
   explicit ParallelAuthenticator(LoginStatusConsumer* consumer);
@@ -75,35 +92,16 @@
   virtual void CompleteLogin(Profile* profile,
                              const UserContext& user_context) OVERRIDE;
 
-  // Given a |username| and |password|, this method attempts to authenticate to
-  // the Google accounts servers and your Chrome OS device simultaneously.
-  // As soon as we have successfully mounted the encrypted home directory for
-  // |username|, we will call consumer_->OnLoginSuccess() with |username| and a
-  // vector of authentication cookies.  If we're still waiting for an online
-  // result at that time, we'll also pass back a flag indicating that more
-  // callbacks are on the way; if not, we pass back false.  When the pending
-  // request completes, either consumer_->OnLoginSuccess() with an indication
-  // that no more requests are outstanding will be called, or
-  // consumer_->OnLoginFailure() if appropriate.
-  //
-  // Upon failure to login (online fails, then offline fails;
-  // offline fails, then online fails) consumer_->OnLoginFailure() is called
+  // Given |user_context|, this method attempts to authenticate to your
+  // Chrome OS device. As soon as we have successfully mounted the encrypted
+  // home directory for the user, we will call consumer_->OnLoginSuccess()
+  // with the username.
+  // Upon failure to login consumer_->OnLoginFailure() is called
   // with an error message.
   //
-  // In the event that we see an online success and then an offline failure,
-  // consumer_->OnPasswordChangeDetected() is called.
-  //
   // Uses |profile| when doing URL fetches.
-  // Optionally could pass CAPTCHA challenge token - |login_token| and
-  // |login_captcha| string that user has entered.
-  //
-  // NOTE: We do not allow HOSTED accounts to log in.  In the event that
-  // we are asked to authenticate valid HOSTED account creds, we will
-  // call OnLoginFailure() with HOSTED_NOT_ALLOWED.
   virtual void AuthenticateToLogin(Profile* profile,
-                                   const UserContext& user_context,
-                                   const std::string& login_token,
-                                   const std::string& login_captcha) OVERRIDE;
+                                   const UserContext& user_context) OVERRIDE;
 
   // Given |user_context|, this method attempts to authenticate to the cached
   // user_context. This will never contact the server even if it's online.
@@ -139,10 +137,7 @@
   virtual void RecoverEncryptedData(
       const std::string& old_password) OVERRIDE;
   virtual void ResyncEncryptedData() OVERRIDE;
-  virtual void RetryAuth(Profile* profile,
-                         const UserContext& user_context,
-                         const std::string& login_token,
-                         const std::string& login_captcha) OVERRIDE;
+
   // AuthAttemptStateResolver overrides.
   // Attempts to make a decision and call back |consumer_| based on
   // the state we have gathered at the time of call.  If a decision
@@ -172,12 +167,6 @@
   AuthState ResolveState();
 
   // Helper for ResolveState().
-  // Given that we're attempting to auth the user again, with a new password,
-  // determine which state we're in.  Returns CONTINUE if no resolution.
-  // Must be called on the IO thread.
-  AuthState ResolveReauthState();
-
-  // Helper for ResolveState().
   // Given that some cryptohome operation has failed, determine which of the
   // possible failure states we're in.
   // Must be called on the IO thread.
@@ -190,13 +179,6 @@
   AuthState ResolveCryptohomeSuccessState();
 
   // Helper for ResolveState().
-  // Given that some online auth operation has failed, determine which of the
-  // possible failure states we're in.  Handles both failure to complete and
-  // actual failure responses from the server.
-  // Must be called on the IO thread.
-  AuthState ResolveOnlineFailureState(AuthState offline_state);
-
-  // Helper for ResolveState().
   // Given that some online auth operation has succeeded, determine which of
   // the possible success states we're in.
   // Must be called on the IO thread.
@@ -212,7 +194,7 @@
     current_state_.reset(new_state);
   }
 
-  // Sets an online attemp for testing.
+  // Sets an online attempt for testing.
   void set_online_attempt(OnlineAttempt* attempt) {
     current_online_.reset(attempt);
   }
@@ -229,17 +211,10 @@
   void OnOwnershipChecked(DeviceSettingsService::OwnershipStatus status,
                           bool is_owner);
 
-  // Records OAuth1 access token verification failure for |user_account|.
-  void RecordOAuthCheckFailure(const std::string& user_account);
-
   // Signal login completion status for cases when a new user is added via
   // an external authentication provider (i.e. GAIA extension).
   void ResolveLoginCompletionStatus();
 
-  // Used when we need to try online authentication again, after successful
-  // mount, but failed online login.
-  scoped_ptr<AuthAttemptState> reauth_state_;
-
   scoped_ptr<AuthAttemptState> current_state_;
   scoped_ptr<OnlineAttempt> current_online_;
   bool migrate_attempted_;
diff --git a/chrome/browser/chromeos/login/parallel_authenticator_unittest.cc b/chrome/browser/chromeos/login/parallel_authenticator_unittest.cc
index be05b21..71e8041 100644
--- a/chrome/browser/chromeos/login/parallel_authenticator_unittest.cc
+++ b/chrome/browser/chromeos/login/parallel_authenticator_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/message_loop.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/mock_login_status_consumer.h"
 #include "chrome/browser/chromeos/login/mock_url_fetchers.h"
 #include "chrome/browser/chromeos/login/mock_user_manager.h"
@@ -29,12 +29,12 @@
 #include "chromeos/dbus/mock_dbus_thread_manager_without_gmock.h"
 #include "content/public/test/test_browser_thread.h"
 #include "google_apis/gaia/mock_url_fetcher_factory.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/net_errors.h"
 #include "net/url_request/url_request_status.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
+#include "url/gurl.h"
 
 using ::testing::AnyNumber;
 using ::testing::DoAll;
@@ -82,7 +82,6 @@
     io_thread_.Start();
 
     auth_ = new ParallelAuthenticator(&consumer_);
-    auth_->set_using_oauth(false);
     state_.reset(new TestAttemptState(UserContext(username_,
                                                   password_,
                                                   std::string()),
@@ -159,7 +158,7 @@
                                                       std::string(),
                                                       username_hash_),
                                           pending,
-                                          false))
+                                          true /* using_oauth */))
         .WillOnce(Invoke(MockConsumer::OnSuccessQuit))
         .RetiresOnSaturation();
   }
@@ -209,11 +208,10 @@
   std::string username_hash_;
   std::string hash_ascii_;
 
-  ScopedStubCrosEnabler stub_cros_enabler_;
+  ScopedStubNetworkLibraryEnabler stub_network_library_enabler_;
   ScopedDeviceSettingsTestHelper device_settings_test_helper_;
   ScopedTestCrosSettings test_cros_settings_;
 
-  // Mocks, destroyed by CrosLibrary class.
   ScopedUserManagerEnabler user_manager_enabler_;
 
   scoped_ptr<MockCryptohomeLibrary> mock_cryptohome_library_;
@@ -230,7 +228,7 @@
                                                     password_,
                                                     std::string(),
                                                     username_hash_),
-                                        false, false))
+                                        false, true /* using oauth */))
       .Times(1)
       .RetiresOnSaturation();
 
@@ -619,127 +617,11 @@
   // Set up state as though a cryptohome mount attempt has occurred and
   // succeeded.
   state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
-  GoogleServiceAuthError error =
-      GoogleServiceAuthError::FromConnectionError(net::ERR_CONNECTION_RESET);
-  state_->PresetOnlineLoginStatus(LoginFailure::FromNetworkAuthFailure(error));
   SetAttemptState(auth_.get(), state_.release());
 
   RunResolve(auth_.get());
 }
 
-TEST_F(ParallelAuthenticatorTest, DriveOfflineLoginDelayedOnline) {
-  ExpectLoginSuccess(username_, password_, username_hash_, true);
-  FailOnLoginFailure();
-
-  // Set up state as though a cryptohome mount attempt has occurred and
-  // succeeded.
-  state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
-  // state_ is released further down.
-  SetAttemptState(auth_.get(), state_.get());
-  RunResolve(auth_.get());
-
-  // Offline login has completed, so now we "complete" the online request.
-  GoogleServiceAuthError error(
-      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
-  LoginFailure failure = LoginFailure::FromNetworkAuthFailure(error);
-  state_.release()->PresetOnlineLoginStatus(failure);
-  ExpectLoginFailure(failure);
-
-  RunResolve(auth_.get());
-}
-
-TEST_F(ParallelAuthenticatorTest, DriveOfflineLoginGetNewPassword) {
-  ExpectLoginSuccess(username_, password_, username_hash_, true);
-  FailOnLoginFailure();
-
-  // Set up mock cryptohome library to respond successfully to a key migration.
-  mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
-  EXPECT_CALL(*mock_caller_, AsyncMigrateKey(username_,
-                                              state_->ascii_hash,
-                                              _,
-                                              _))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*mock_cryptohome_library_, GetSystemSalt())
-      .WillOnce(Return(std::string()))
-      .RetiresOnSaturation();
-
-  // Set up state as though a cryptohome mount attempt has occurred and
-  // succeeded; also, an online request that never made it.
-  state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
-  // state_ is released further down.
-  SetAttemptState(auth_.get(), state_.get());
-  RunResolve(auth_.get());
-
-  // Offline login has completed, so now we "complete" the online request.
-  GoogleServiceAuthError error(
-      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
-  LoginFailure failure = LoginFailure::FromNetworkAuthFailure(error);
-  state_.release()->PresetOnlineLoginStatus(failure);
-  ExpectLoginFailure(failure);
-
-  RunResolve(auth_.get());
-
-  // After the request below completes, OnLoginSuccess gets called again.
-  ExpectLoginSuccess(username_, password_, username_hash_, false);
-
-  MockURLFetcherFactory<SuccessFetcher> factory;
-  TestingProfile profile;
-
-  auth_->RetryAuth(&profile,
-                   UserContext(username_,
-                               std::string(),
-                               std::string()),
-                   std::string(),
-                   std::string());
-  message_loop_.Run();
-  message_loop_.RunUntilIdle();
-}
-
-TEST_F(ParallelAuthenticatorTest, DriveOfflineLoginGetCaptchad) {
-  ExpectLoginSuccess(username_, password_, username_hash_, true);
-  FailOnLoginFailure();
-  EXPECT_CALL(*mock_cryptohome_library_, GetSystemSalt())
-      .WillOnce(Return(std::string()))
-      .RetiresOnSaturation();
-
-  // Set up state as though a cryptohome mount attempt has occurred and
-  // succeeded; also, an online request that never made it.
-  state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
-  // state_ is released further down.
-  SetAttemptState(auth_.get(), state_.get());
-  RunResolve(auth_.get());
-
-  // Offline login has completed, so now we "complete" the online request.
-  GoogleServiceAuthError error(
-      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
-  LoginFailure failure = LoginFailure::FromNetworkAuthFailure(error);
-  state_.release()->PresetOnlineLoginStatus(failure);
-  ExpectLoginFailure(failure);
-
-  RunResolve(auth_.get());
-
-  // After the request below completes, OnLoginSuccess gets called again.
-  failure = LoginFailure::FromNetworkAuthFailure(
-      GoogleServiceAuthError::FromClientLoginCaptchaChallenge(
-          CaptchaFetcher::GetCaptchaToken(),
-          GURL(CaptchaFetcher::GetCaptchaUrl()),
-          GURL(CaptchaFetcher::GetUnlockUrl())));
-  ExpectLoginFailure(failure);
-
-  MockURLFetcherFactory<CaptchaFetcher> factory;
-  TestingProfile profile;
-
-  auth_->RetryAuth(&profile,
-                   UserContext(username_,
-                               std::string(),
-                               std::string()),
-                   std::string(),
-                   std::string());
-  message_loop_.Run();
-  message_loop_.RunUntilIdle();
-}
-
 TEST_F(ParallelAuthenticatorTest, DriveOnlineLogin) {
   ExpectLoginSuccess(username_, password_, username_hash_, false);
   FailOnLoginFailure();
@@ -753,25 +635,6 @@
   RunResolve(auth_.get());
 }
 
-// http://crbug.com/106538
-TEST_F(ParallelAuthenticatorTest, DISABLED_DriveNeedNewPassword) {
-  FailOnLoginSuccess();  // Set failing on success as the default...
-  // ...but expect ONE successful login first.
-  ExpectLoginSuccess(username_, password_, username_hash_, true);
-  GoogleServiceAuthError error(
-      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
-  LoginFailure failure = LoginFailure::FromNetworkAuthFailure(error);
-  ExpectLoginFailure(failure);
-
-  // Set up state as though a cryptohome mount attempt has occurred and
-  // succeeded.
-  state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
-  state_->PresetOnlineLoginStatus(failure);
-  SetAttemptState(auth_.get(), state_.release());
-
-  RunResolve(auth_.get());
-}
-
 TEST_F(ParallelAuthenticatorTest, DriveUnlock) {
   ExpectLoginSuccess(username_, std::string(), std::string(), false);
   FailOnLoginFailure();
diff --git a/chrome/browser/chromeos/login/proxy_settings_dialog.cc b/chrome/browser/chromeos/login/proxy_settings_dialog.cc
index 559247e..f3d7415 100644
--- a/chrome/browser/chromeos/login/proxy_settings_dialog.cc
+++ b/chrome/browser/chromeos/login/proxy_settings_dialog.cc
@@ -6,8 +6,8 @@
 
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/helper.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "chromeos/network/network_state.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/chromeos/login/resource_loader_browsertest.cc b/chrome/browser/chromeos/login/resource_loader_browsertest.cc
index 969085d..fe106b8 100644
--- a/chrome/browser/chromeos/login/resource_loader_browsertest.cc
+++ b/chrome/browser/chromeos/login/resource_loader_browsertest.cc
@@ -14,9 +14,9 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "grit/browser_resources.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/chromeos/login/screen_locker.cc b/chrome/browser/chromeos/login/screen_locker.cc
index f2b0bda..41761c9 100644
--- a/chrome/browser/chromeos/login/screen_locker.cc
+++ b/chrome/browser/chromeos/login/screen_locker.cc
@@ -19,6 +19,7 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/string_util.h"
 #include "base/timer/timer.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/authenticator.h"
 #include "chrome/browser/chromeos/login/login_performer.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
@@ -36,16 +37,15 @@
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager_client.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/user_metrics.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 using content::UserMetricsAction;
diff --git a/chrome/browser/chromeos/login/screen_locker_browsertest.cc b/chrome/browser/chromeos/login/screen_locker_browsertest.cc
index e4cf63d..7da7320 100644
--- a/chrome/browser/chromeos/login/screen_locker_browsertest.cc
+++ b/chrome/browser/chromeos/login/screen_locker_browsertest.cc
@@ -5,6 +5,7 @@
 #include "base/command_line.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
 #include "chrome/browser/chromeos/login/mock_authenticator.h"
 #include "chrome/browser/chromeos/login/screen_locker.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "chromeos/chromeos_switches.h"
@@ -121,9 +121,6 @@
     CrosInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
     fake_session_manager_client_ =
         mock_dbus_thread_manager->fake_session_manager_client();
-    cros_mock_->InitStatusAreaMocks();
-    // Expectations for the status are on the screen lock window.
-    cros_mock_->SetStatusAreaMocksExpectations();
     zero_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
         ui::ScopedAnimationDurationScaleMode::ZERO_DURATION));
   }
diff --git a/chrome/browser/chromeos/login/screens/eula_screen.h b/chrome/browser/chromeos/login/screens/eula_screen.h
index f93d3dc..bc64809 100644
--- a/chrome/browser/chromeos/login/screens/eula_screen.h
+++ b/chrome/browser/chromeos/login/screens/eula_screen.h
@@ -11,7 +11,7 @@
 #include "chrome/browser/chromeos/login/screens/eula_screen_actor.h"
 #include "chrome/browser/chromeos/login/screens/wizard_screen.h"
 #include "chrome/browser/chromeos/login/tpm_password_fetcher.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
diff --git a/chrome/browser/chromeos/login/screens/eula_screen_actor.h b/chrome/browser/chromeos/login/screens/eula_screen_actor.h
index 948ad24..2e741a6 100644
--- a/chrome/browser/chromeos/login/screens/eula_screen_actor.h
+++ b/chrome/browser/chromeos/login/screens/eula_screen_actor.h
@@ -7,8 +7,8 @@
 
 #include <string>
 
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/size.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
diff --git a/chrome/browser/chromeos/login/screens/network_screen.cc b/chrome/browser/chromeos/login/screens/network_screen.cc
index 167c867..a4632b6 100644
--- a/chrome/browser/chromeos/login/screens/network_screen.cc
+++ b/chrome/browser/chromeos/login/screens/network_screen.cc
@@ -7,7 +7,6 @@
 #include "base/logging.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/login/help_app_launcher.h"
 #include "chrome/browser/chromeos/login/helper.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
diff --git a/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc
index 8e8902d..dcaeda3 100644
--- a/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc
+++ b/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc
@@ -40,6 +40,8 @@
 
  protected:
   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
+    WizardInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
+
     MockDBusThreadManagerWithoutGMock* mock_dbus_thread_manager =
         new MockDBusThreadManagerWithoutGMock;
     DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager);
@@ -50,7 +52,6 @@
     ConnectivityStateHelper::SetForTest(mock_connectivity_state_helper_.get());
     SetDefaultMockConnectivityStateHelperExpectations();
 
-    cros_mock_->InitStatusAreaMocks();
     cellular_.reset(new NetworkDevice("cellular"));
 
     // Minimal set of expectations needed on NetworkScreen initialization.
@@ -59,8 +60,6 @@
                 IsConnectedType(flimflam::kTypeWifi))
         .Times(1)
         .WillRepeatedly(Return(false));
-
-    cros_mock_->SetStatusAreaMocksExpectations();
   }
 
   virtual void SetUpOnMainThread() OVERRIDE {
diff --git a/chrome/browser/chromeos/login/screens/terms_of_service_screen.cc b/chrome/browser/chromeos/login/screens/terms_of_service_screen.cc
index 4cc4060..6a09c70 100644
--- a/chrome/browser/chromeos/login/screens/terms_of_service_screen.cc
+++ b/chrome/browser/chromeos/login/screens/terms_of_service_screen.cc
@@ -17,11 +17,11 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/pref_names.h"
-#include "googleurl/src/gurl.h"
 #include "net/http/http_response_headers.h"
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_status.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
diff --git a/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc
index 508b1b1..aab8b58 100644
--- a/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc
+++ b/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc
@@ -46,8 +46,6 @@
         new MockDBusThreadManagerWithoutGMock;
     DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager);
     WizardInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
-    cros_mock_->InitStatusAreaMocks();
-    cros_mock_->SetStatusAreaMocksExpectations();
 
     fake_update_engine_client_
         = mock_dbus_thread_manager->fake_update_engine_client();
diff --git a/chrome/browser/chromeos/login/screens/user_image_screen.cc b/chrome/browser/chromeos/login/screens/user_image_screen.cc
index def0424..9542be3 100644
--- a/chrome/browser/chromeos/login/screens/user_image_screen.cc
+++ b/chrome/browser/chromeos/login/screens/user_image_screen.cc
@@ -6,6 +6,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/metrics/histogram.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/camera_detector.h"
 #include "chrome/browser/chromeos/login/default_user_images.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/chromeos/login/user_image_manager.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/chromeos/login/simple_web_view_dialog.cc b/chrome/browser/chromeos/login/simple_web_view_dialog.cc
index 5bd9205..f8fdab9 100644
--- a/chrome/browser/chromeos/login/simple_web_view_dialog.cc
+++ b/chrome/browser/chromeos/login/simple_web_view_dialog.cc
@@ -299,8 +299,7 @@
 void SimpleWebViewDialog::ShowWebsiteSettings(
     content::WebContents* web_contents,
     const GURL& url,
-    const content::SSLStatus& ssl,
-    bool show_history) {
+    const content::SSLStatus& ssl) {
   NOTIMPLEMENTED();
   // TODO (ygorshenin@,markusheintz@): implement this
 }
diff --git a/chrome/browser/chromeos/login/simple_web_view_dialog.h b/chrome/browser/chromeos/login/simple_web_view_dialog.h
index 07b02d4..cc867c5 100644
--- a/chrome/browser/chromeos/login/simple_web_view_dialog.h
+++ b/chrome/browser/chromeos/login/simple_web_view_dialog.h
@@ -15,9 +15,9 @@
 #include "components/web_modal/web_contents_modal_dialog_host.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "googleurl/src/gurl.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/widget/widget_delegate.h"
+#include "url/gurl.h"
 
 class CommandUpdater;
 class Profile;
@@ -89,8 +89,7 @@
   GetContentSettingBubbleModelDelegate() OVERRIDE;
   virtual void ShowWebsiteSettings(content::WebContents* web_contents,
                                    const GURL& url,
-                                   const content::SSLStatus& ssl,
-                                   bool show_history) OVERRIDE;
+                                   const content::SSLStatus& ssl) OVERRIDE;
   virtual void OnInputInProgress(bool in_progress) OVERRIDE;
 
   // Implements ToolbarModelDelegate:
@@ -139,6 +138,6 @@
   DISALLOW_COPY_AND_ASSIGN(SimpleWebViewDialog);
 };
 
-}  // chromeos
+}  // namespace chromeos
 
 #endif  // CHROME_BROWSER_CHROMEOS_LOGIN_SIMPLE_WEB_VIEW_DIALOG_H_
diff --git a/chrome/browser/chromeos/login/startup_utils.cc b/chrome/browser/chromeos/login/startup_utils.cc
index a46615a..73fd8a6 100644
--- a/chrome/browser/chromeos/login/startup_utils.cc
+++ b/chrome/browser/chromeos/login/startup_utils.cc
@@ -107,7 +107,7 @@
 static void CreateOobeCompleteFlagFile() {
   // Create flag file for boot-time init scripts.
   base::FilePath oobe_complete_path = GetOobeCompleteFlagPath();
-  if (!file_util::PathExists(oobe_complete_path)) {
+  if (!base::PathExists(oobe_complete_path)) {
     FILE* oobe_flag_file = file_util::OpenFile(oobe_complete_path, "w+b");
     if (oobe_flag_file == NULL)
       DLOG(WARNING) << oobe_complete_path.value() << " doesn't exist.";
@@ -133,7 +133,7 @@
     // IO on UI thread. But it's required for update from old versions.
     base::ThreadRestrictions::ScopedAllowIO allow_io;
     base::FilePath oobe_complete_flag_file_path = GetOobeCompleteFlagPath();
-    bool file_exists = file_util::PathExists(oobe_complete_flag_file_path);
+    bool file_exists = base::PathExists(oobe_complete_flag_file_path);
     SaveIntegerPreferenceForced(kDeviceRegistered, file_exists ? 1 : 0);
     return file_exists;
   }
diff --git a/chrome/browser/chromeos/login/user_image.h b/chrome/browser/chromeos/login/user_image.h
index 1bae8d8..b1e3933 100644
--- a/chrome/browser/chromeos/login/user_image.h
+++ b/chrome/browser/chromeos/login/user_image.h
@@ -7,8 +7,8 @@
 
 #include <vector>
 
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/image/image_skia.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
diff --git a/chrome/browser/chromeos/login/user_image_manager_browsertest.cc b/chrome/browser/chromeos/login/user_image_manager_browsertest.cc
index e485561..19eb7a5 100644
--- a/chrome/browser/chromeos/login/user_image_manager_browsertest.cc
+++ b/chrome/browser/chromeos/login/user_image_manager_browsertest.cc
@@ -10,13 +10,13 @@
 #include "base/path_service.h"
 #include "base/prefs/pref_service.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
 #include "chrome/browser/chromeos/login/default_user_images.h"
 #include "chrome/browser/chromeos/login/mock_user_manager.h"
 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_browser_process.h"
diff --git a/chrome/browser/chromeos/login/user_image_manager_impl.cc b/chrome/browser/chromeos/login/user_image_manager_impl.cc
index f22a8d4..f66f0f0 100644
--- a/chrome/browser/chromeos/login/user_image_manager_impl.cc
+++ b/chrome/browser/chromeos/login/user_image_manager_impl.cc
@@ -18,6 +18,7 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/default_user_images.h"
 #include "chrome/browser/chromeos/login/helper.h"
 #include "chrome/browser/chromeos/login/user_image.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/profiles/profile_downloader.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
@@ -145,7 +145,7 @@
   BrowserThread::PostTask(
       BrowserThread::FILE,
       FROM_HERE,
-      base::Bind(base::IgnoreResult(&base::Delete),
+      base::Bind(base::IgnoreResult(&base::DeleteFile),
                  fp, /* recursive= */  false));
 }
 
diff --git a/chrome/browser/chromeos/login/user_manager.h b/chrome/browser/chromeos/login/user_manager.h
index 2b9b93a..08b0300 100644
--- a/chrome/browser/chromeos/login/user_manager.h
+++ b/chrome/browser/chromeos/login/user_manager.h
@@ -238,6 +238,12 @@
   virtual std::string GetManagerUserIdForManagedUser(
       const std::string& managed_user_id) const = 0;
 
+  // Returns the display email for manager of user |managed_user_id| if it is
+  // known (user is actually a managed user).
+  // Otherwise, returns an empty string.
+  virtual std::string GetManagerDisplayEmailForManagedUser(
+      const std::string& managed_user_id) const = 0;
+
   // Returns true if current user is an owner.
   virtual bool IsCurrentUserOwner() const = 0;
 
diff --git a/chrome/browser/chromeos/login/user_manager_impl.cc b/chrome/browser/chromeos/login/user_manager_impl.cc
index 7edf248..5dea61c 100644
--- a/chrome/browser/chromeos/login/user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/user_manager_impl.cc
@@ -24,8 +24,8 @@
 #include "base/values.h"
 #include "chrome/browser/app_mode/app_mode_utils.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/cros/cert_library.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h"
 #include "chrome/browser/chromeos/login/login_display.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
@@ -41,7 +41,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_switches.h"
@@ -77,6 +76,10 @@
 const char kManagedUserManagerNames[] =
     "ManagedUserManagerNames";
 
+// A map from locally managed user id to manager display e-mail.
+const char kManagedUserManagerDisplayEmails[] =
+    "ManagedUserManagerDisplayEmails";
+
 // A vector pref of the locally managed accounts defined on this device, that
 // had not logged in yet.
 const char kLocallyManagedUsersFirstRun[] = "LocallyManagedUsersFirstRun";
@@ -191,6 +194,7 @@
   registry->RegisterDictionaryPref(kUserDisplayEmail);
   registry->RegisterDictionaryPref(kManagedUserManagers);
   registry->RegisterDictionaryPref(kManagedUserManagerNames);
+  registry->RegisterDictionaryPref(kManagedUserManagerDisplayEmails);
 
   SessionLengthLimiter::RegisterPrefs(registry);
 }
@@ -445,17 +449,20 @@
   prefs_new_users_update->Insert(0, new base::StringValue(e_mail));
   users_.insert(users_.begin(), new_user);
 
-  const User* manager = FindUser(gaia::CanonicalizeEmail(manager_id));
+  const User* manager = FindUser(manager_id);
   CHECK(manager);
 
   DictionaryPrefUpdate manager_update(local_state, kManagedUserManagers);
   DictionaryPrefUpdate manager_name_update(local_state,
                                            kManagedUserManagerNames);
+  DictionaryPrefUpdate manager_email_update(local_state,
+                                            kManagedUserManagerDisplayEmails);
   manager_update->SetWithoutPathExpansion(e_mail,
-      new base::StringValue(manager->display_email()));
+      new base::StringValue(manager->email()));
   manager_name_update->SetWithoutPathExpansion(e_mail,
       new base::StringValue(manager->GetDisplayName()));
-
+  manager_email_update->SetWithoutPathExpansion(e_mail,
+      new base::StringValue(manager->display_email()));
 
   SaveUserDisplayName(e_mail, display_name);
   g_browser_process->local_state()->CommitPendingWrite();
@@ -472,7 +479,7 @@
   if (manager_names->GetStringWithoutPathExpansion(managed_user_id, &result) &&
       !result.empty())
     return result;
-  return UTF8ToUTF16(GetManagerUserIdForManagedUser(managed_user_id));
+  return UTF8ToUTF16(GetManagerDisplayEmailForManagedUser(managed_user_id));
 }
 
 std::string UserManagerImpl::GetManagerUserIdForManagedUser(
@@ -485,6 +492,19 @@
   return result;
 }
 
+std::string UserManagerImpl::GetManagerDisplayEmailForManagedUser(
+      const std::string& managed_user_id) const {
+  PrefService* local_state = g_browser_process->local_state();
+  const DictionaryValue* manager_mails =
+      local_state->GetDictionary(kManagedUserManagerDisplayEmails);
+  std::string result;
+  if (manager_mails->GetStringWithoutPathExpansion(managed_user_id, &result) &&
+      !result.empty()) {
+    return result;
+  }
+  return GetManagerUserIdForManagedUser(managed_user_id);
+}
+
 void UserManagerImpl::RemoveUser(const std::string& email,
                                  RemoveUserDelegate* delegate) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -642,7 +662,7 @@
     std::string manager_id;
     bool has_manager_id = it.value().GetAsString(&manager_id);
     DCHECK(has_manager_id);
-    if (gaia::CanonicalizeEmail(manager_id) == username) {
+    if (manager_id == username) {
       manager_name_update->SetWithoutPathExpansion(
           it.key(),
           new base::StringValue(display_name));
@@ -1318,6 +1338,10 @@
   DictionaryPrefUpdate manager_names_update(prefs,
                                             kManagedUserManagerNames);
   manager_names_update->RemoveWithoutPathExpansion(email, NULL);
+
+  DictionaryPrefUpdate manager_emails_update(prefs,
+                                             kManagedUserManagerDisplayEmails);
+  manager_emails_update->RemoveWithoutPathExpansion(email, NULL);
 }
 
 User* UserManagerImpl::RemoveRegularOrLocallyManagedUserFromList(
@@ -1553,9 +1577,7 @@
 
 UserFlow* UserManagerImpl::GetUserFlow(const std::string& email) const {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  std::string canonical_email = email.empty() ? email :
-      gaia::CanonicalizeEmail(email);
-  FlowMap::const_iterator it = specific_flows_.find(canonical_email);
+  FlowMap::const_iterator it = specific_flows_.find(email);
   if (it != specific_flows_.end())
     return it->second;
   return GetDefaultUserFlow();
@@ -1563,15 +1585,13 @@
 
 void UserManagerImpl::SetUserFlow(const std::string& email, UserFlow* flow) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  std::string canonical_email = gaia::CanonicalizeEmail(email);
-  ResetUserFlow(canonical_email);
-  specific_flows_[canonical_email] = flow;
+  ResetUserFlow(email);
+  specific_flows_[email] = flow;
 }
 
 void UserManagerImpl::ResetUserFlow(const std::string& email) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  std::string canonical_email = gaia::CanonicalizeEmail(email);
-  FlowMap::iterator it = specific_flows_.find(canonical_email);
+  FlowMap::iterator it = specific_flows_.find(email);
   if (it != specific_flows_.end()) {
     delete it->second;
     specific_flows_.erase(it);
diff --git a/chrome/browser/chromeos/login/user_manager_impl.h b/chrome/browser/chromeos/login/user_manager_impl.h
index 19c8d45..189d4b2 100644
--- a/chrome/browser/chromeos/login/user_manager_impl.h
+++ b/chrome/browser/chromeos/login/user_manager_impl.h
@@ -87,6 +87,8 @@
       const std::string& managed_user_id) const OVERRIDE;
   virtual std::string GetManagerUserIdForManagedUser(
       const std::string& managed_user_id) const OVERRIDE;
+  virtual std::string GetManagerDisplayEmailForManagedUser(
+      const std::string& managed_user_id) const OVERRIDE;
   virtual bool IsCurrentUserOwner() const OVERRIDE;
   virtual bool IsCurrentUserNew() const OVERRIDE;
   virtual bool IsCurrentUserNonCryptohomeDataEphemeral() const OVERRIDE;
diff --git a/chrome/browser/chromeos/login/user_manager_unittest.cc b/chrome/browser/chromeos/login/user_manager_unittest.cc
index e2c4773..cb3ca08 100644
--- a/chrome/browser/chromeos/login/user_manager_unittest.cc
+++ b/chrome/browser/chromeos/login/user_manager_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/run_loop.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/user.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/user_manager_impl.h"
@@ -136,7 +136,7 @@
   scoped_ptr<TestingPrefServiceSimple> local_state_;
 
   ScopedTestDeviceSettingsService test_device_settings_service_;
-  ScopedStubCrosEnabler stub_cros_enabler_;
+  ScopedStubNetworkLibraryEnabler stub_network_library_enabler_;
   ScopedTestCrosSettings test_cros_settings_;
 
   scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_;
diff --git a/chrome/browser/chromeos/login/version_info_updater.cc b/chrome/browser/chromeos/login/version_info_updater.cc
index 1d5583d..5d430c7 100644
--- a/chrome/browser/chromeos/login/version_info_updater.cc
+++ b/chrome/browser/chromeos/login/version_info_updater.cc
@@ -13,11 +13,11 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_version_info.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
diff --git a/chrome/browser/chromeos/login/wallpaper_manager.cc b/chrome/browser/chromeos/login/wallpaper_manager.cc
index dcd09ae..8957ecc 100644
--- a/chrome/browser/chromeos/login/wallpaper_manager.cc
+++ b/chrome/browser/chromeos/login/wallpaper_manager.cc
@@ -8,6 +8,7 @@
 
 #include "ash/shell.h"
 #include "base/command_line.h"
+#include "base/debug/trace_event.h"
 #include "base/file_util.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
@@ -23,13 +24,13 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/user.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -392,8 +393,8 @@
                                               int preferred_height) {
   if (layout == ash::WALLPAPER_LAYOUT_CENTER) {
     // TODO(bshe): Generates cropped custom wallpaper for CENTER layout.
-    if (file_util::PathExists(path))
-      base::Delete(path, false);
+    if (base::PathExists(path))
+      base::DeleteFile(path, false);
     return;
   }
   scoped_refptr<base::RefCountedBytes> data;
@@ -670,12 +671,12 @@
 
 void WallpaperManager::DeleteAllExcept(const base::FilePath& path) {
   base::FilePath dir = path.DirName();
-  if (file_util::DirectoryExists(dir)) {
+  if (base::DirectoryExists(dir)) {
     base::FileEnumerator files(dir, false, base::FileEnumerator::FILES);
     for (base::FilePath current = files.Next(); !current.empty();
          current = files.Next()) {
       if (current != path)
-        base::Delete(current, false);
+        base::DeleteFile(current, false);
     }
   }
 }
@@ -687,8 +688,8 @@
     base::FilePath path = *it;
     // Some users may still have legacy wallpapers with png extension. We need
     // to delete these wallpapers too.
-    if (!base::Delete(path, true) &&
-        !base::Delete(path.AddExtension(".png"), false)) {
+    if (!base::DeleteFile(path, true) &&
+        !base::DeleteFile(path.AddExtension(".png"), false)) {
       LOG(ERROR) << "Failed to remove user wallpaper at " << path.value();
     }
   }
@@ -730,16 +731,16 @@
     const std::string& email) {
   base::FilePath dir;
   dir = GetCustomWallpaperDir(kSmallWallpaperSubDir, email);
-  if (!file_util::PathExists(dir))
+  if (!base::PathExists(dir))
     file_util::CreateDirectory(dir);
   dir = GetCustomWallpaperDir(kLargeWallpaperSubDir, email);
-  if (!file_util::PathExists(dir))
+  if (!base::PathExists(dir))
     file_util::CreateDirectory(dir);
   dir = GetCustomWallpaperDir(kOriginalWallpaperSubDir, email);
-  if (!file_util::PathExists(dir))
+  if (!base::PathExists(dir))
     file_util::CreateDirectory(dir);
   dir = GetCustomWallpaperDir(kThumbnailWallpaperSubDir, email);
-  if (!file_util::PathExists(dir))
+  if (!base::PathExists(dir))
     file_util::CreateDirectory(dir);
 }
 
@@ -845,25 +846,25 @@
     EnsureCustomWallpaperDirectories(email);
     from_path = GetWallpaperPathForUser(email, true);
     // Old wallpaper with extension name may still exist.
-    if (!file_util::PathExists(from_path))
+    if (!base::PathExists(from_path))
       from_path = from_path.AddExtension(".png");
-    if (file_util::PathExists(from_path)) {
+    if (base::PathExists(from_path)) {
       // Appends DUMMY to the file name of moved custom wallpaper. This way we
       // do not need to update WallpaperInfo for user.
       to_path = GetCustomWallpaperPath(kSmallWallpaperSubDir, email, "DUMMY");
       base::Move(from_path, to_path);
     }
     from_path = GetWallpaperPathForUser(email, false);
-    if (!file_util::PathExists(from_path))
+    if (!base::PathExists(from_path))
       from_path = from_path.AddExtension(".png");
-    if (file_util::PathExists(from_path)) {
+    if (base::PathExists(from_path)) {
       to_path = GetCustomWallpaperPath(kLargeWallpaperSubDir, email, "DUMMY");
       base::Move(from_path, to_path);
     }
     from_path = GetOriginalWallpaperPathForUser(email);
-    if (!file_util::PathExists(from_path))
+    if (!base::PathExists(from_path))
       from_path = from_path.AddExtension(".png");
-    if (file_util::PathExists(from_path)) {
+    if (base::PathExists(from_path)) {
       to_path = GetCustomWallpaperPath(kOriginalWallpaperSubDir, email,
                                        "DUMMY");
       base::Move(from_path, to_path);
@@ -921,8 +922,8 @@
       IsRunningSequenceOnCurrentThread(sequence_token_));
   std::string file_name = wallpaper_path.BaseName().value();
 
-  if (!file_util::PathExists(wallpaper_path)) {
-    if (file_util::PathExists(wallpaper_path.AddExtension(".png"))) {
+  if (!base::PathExists(wallpaper_path)) {
+    if (base::PathExists(wallpaper_path.AddExtension(".png"))) {
       // Old wallpaper may have a png extension.
       file_name += ".png";
     } else {
@@ -934,7 +935,7 @@
   }
 
   base::FilePath valid_path = wallpaper_path.DirName().Append(file_name);
-  if (!file_util::PathExists(valid_path))
+  if (!base::PathExists(valid_path))
     valid_path = valid_path.AddExtension(".png");
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
@@ -955,7 +956,7 @@
       IsRunningSequenceOnCurrentThread(sequence_token_));
 
   base::FilePath valid_path = wallpaper_path;
-  if (!file_util::PathExists(wallpaper_path)) {
+  if (!base::PathExists(wallpaper_path)) {
     // Falls back on original file if the correct resoltuion file does not
     // exist. This may happen when the original custom wallpaper is small or
     // browser shutdown before resized wallpaper saved.
@@ -963,7 +964,7 @@
                                         info.file);
   }
 
-  if (!file_util::PathExists(valid_path)) {
+  if (!base::PathExists(valid_path)) {
     BrowserThread::PostTask(
         BrowserThread::UI,
         FROM_HERE,
@@ -989,6 +990,7 @@
                                           bool update_wallpaper,
                                           const UserImage& wallpaper) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  TRACE_EVENT_ASYNC_END0("ui", "LoadAndDecodeWallpaper", this);
 
   // If decoded wallpaper is empty, we are probably failed to decode the file.
   // Use default wallpaper in this case.
@@ -1082,6 +1084,7 @@
                                  bool update_wallpaper,
                                  const base::FilePath& wallpaper_path) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  TRACE_EVENT_ASYNC_BEGIN0("ui", "LoadAndDecodeWallpaper", this);
 
   // All wallpaper related operation should run on the same thread. So we pass
   // |sequence_token_| here.
diff --git a/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc b/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
index 77b3be6..aedc8ad 100644
--- a/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
+++ b/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/chromeos/login/wallpaper_manager.h"
 
-#include "ash/ash_resources/grit/ash_wallpaper_resources.h"
+#include "ash/ash_resources/grit/ash_resources.h"
 #include "ash/desktop_background/desktop_background_controller.h"
 #include "ash/desktop_background/desktop_background_controller_observer.h"
 #include "ash/display/display_manager.h"
@@ -94,7 +94,7 @@
                                         const std::string& id) {
     base::FilePath wallpaper_path =
         WallpaperManager::Get()->GetCustomWallpaperPath(sub_dir, email, id);
-    if (!file_util::DirectoryExists(wallpaper_path.DirName()))
+    if (!base::DirectoryExists(wallpaper_path.DirName()))
       file_util::CreateDirectory(wallpaper_path.DirName());
 
     return wallpaper_path;
@@ -291,8 +291,8 @@
   EXPECT_EQ(3, LoadedWallpapers());
   base::FilePath new_wallpaper_path = GetCustomWallpaperPath(
       kOriginalWallpaperSubDir, kTestUser1, "DUMMY");
-  EXPECT_FALSE(file_util::PathExists(old_wallpaper_path));
-  EXPECT_TRUE(file_util::PathExists(new_wallpaper_path));
+  EXPECT_FALSE(base::PathExists(old_wallpaper_path));
+  EXPECT_TRUE(base::PathExists(new_wallpaper_path));
 }
 
 // Some users have old user profiles which may have legacy wallpapers. And these
diff --git a/chrome/browser/chromeos/login/webui_login_display.cc b/chrome/browser/chromeos/login/webui_login_display.cc
index fc4a569..48bcbc4 100644
--- a/chrome/browser/chromeos/login/webui_login_display.cc
+++ b/chrome/browser/chromeos/login/webui_login_display.cc
@@ -364,7 +364,7 @@
   delegate_->Signout();
 }
 
-void WebUILoginDisplay::OnUserActivity() {
+void WebUILoginDisplay::OnUserActivity(const ui::Event* event) {
   if (!password_clear_timer_.IsRunning())
     StartPasswordClearTimer();
   password_clear_timer_.Reset();
diff --git a/chrome/browser/chromeos/login/webui_login_display.h b/chrome/browser/chromeos/login/webui_login_display.h
index de2f8cd..f8a0341 100644
--- a/chrome/browser/chromeos/login/webui_login_display.h
+++ b/chrome/browser/chromeos/login/webui_login_display.h
@@ -86,7 +86,7 @@
   virtual void Signout() OVERRIDE;
 
   // UserActivityDetector implementation:
-  virtual void OnUserActivity() OVERRIDE;
+  virtual void OnUserActivity(const ui::Event* event) OVERRIDE;
 
  private:
   void StartPasswordClearTimer();
diff --git a/chrome/browser/chromeos/login/webui_login_view.cc b/chrome/browser/chromeos/login/webui_login_view.cc
index 39bc5bb..1c3b509 100644
--- a/chrome/browser/chromeos/login/webui_login_view.cc
+++ b/chrome/browser/chromeos/login/webui_login_view.cc
@@ -12,6 +12,7 @@
 #include "base/i18n/rtl.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
 #include "chrome/browser/chromeos/login/proxy_settings_dialog.h"
@@ -22,7 +23,6 @@
 #include "chrome/browser/password_manager/password_manager_delegate_impl.h"
 #include "chrome/browser/renderer_preferences_util.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/render_messages.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager_client.h"
@@ -36,7 +36,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
-#include "ui/aura/env.h"
 #include "ui/gfx/rect.h"
 #include "ui/gfx/size.h"
 #include "ui/views/controls/webview/webview.h"
@@ -464,11 +463,8 @@
     chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
         EmitLoginPromptVisible();
   }
-  login_prompt_visible_handled_ = true;
 
-  // Let RenderWidgetHostViewAura::OnPaint() show white background when
-  // loading page and when backing store is not present.
-  aura::Env::GetInstance()->set_render_white_bg(true);
+  login_prompt_visible_handled_ = true;
 }
 
 void WebUILoginView::ReturnFocus(bool reverse) {
diff --git a/chrome/browser/chromeos/login/webui_screen_locker.cc b/chrome/browser/chromeos/login/webui_screen_locker.cc
index b7ac13e..c5532df 100644
--- a/chrome/browser/chromeos/login/webui_screen_locker.cc
+++ b/chrome/browser/chromeos/login/webui_screen_locker.cc
@@ -12,13 +12,13 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
 #include "chrome/browser/chromeos/login/helper.h"
 #include "chrome/browser/chromeos/login/screen_locker.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/webui_login_display.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "content/public/browser/browser_thread.h"
@@ -319,7 +319,7 @@
       base::Bind(&WebUIScreenLocker::FocusUserPod, weak_factory_.GetWeakPtr()));
 }
 
-void WebUIScreenLocker::RenderViewGone(base::TerminationStatus status) {
+void WebUIScreenLocker::RenderProcessGone(base::TerminationStatus status) {
   if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID &&
       status != base::TERMINATION_STATUS_NORMAL_TERMINATION) {
     LOG(ERROR) << "Renderer crash on lock screen";
diff --git a/chrome/browser/chromeos/login/webui_screen_locker.h b/chrome/browser/chromeos/login/webui_screen_locker.h
index 8c52c81..4da5d30 100644
--- a/chrome/browser/chromeos/login/webui_screen_locker.h
+++ b/chrome/browser/chromeos/login/webui_screen_locker.h
@@ -107,7 +107,7 @@
                                 const base::TimeTicks& time) OVERRIDE;
 
   // Overridden from content::WebContentsObserver:
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
 
  private:
   friend class test::WebUIScreenLockerTester;
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index a8adf9c..ff92afd 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -19,7 +19,9 @@
 #include "base/prefs/pref_service.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
+#include "chrome/app/breakpad_linux.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_launcher.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/customization_document.h"
@@ -52,7 +54,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/options/options_util.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_constants.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -65,10 +66,6 @@
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/base/l10n/l10n_util.h"
 
-#if defined(USE_LINUX_BREAKPAD)
-#include "chrome/app/breakpad_linux.h"
-#endif
-
 using content::BrowserThread;
 
 namespace {
@@ -498,7 +495,7 @@
 
   CrosSettings::Get()->SetBoolean(kStatsReportingPref, uma_enabled);
   if (uma_enabled) {
-#if defined(USE_LINUX_BREAKPAD) && defined(GOOGLE_CHROME_BUILD)
+#if defined(GOOGLE_CHROME_BUILD)
     // The crash reporter initialization needs IO to complete.
     base::ThreadRestrictions::ScopedAllowIO allow_io;
     InitCrashReporter();
diff --git a/chrome/browser/chromeos/login/wizard_controller.h b/chrome/browser/chromeos/login/wizard_controller.h
index 192ef93..8022003 100644
--- a/chrome/browser/chromeos/login/wizard_controller.h
+++ b/chrome/browser/chromeos/login/wizard_controller.h
@@ -15,8 +15,8 @@
 #include "base/timer/timer.h"
 #include "chrome/browser/chromeos/login/screens/screen_observer.h"
 #include "chrome/browser/chromeos/login/screens/wizard_screen.h"
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/rect.h"
+#include "url/gurl.h"
 
 class PrefRegistrySimple;
 
diff --git a/chrome/browser/chromeos/login/wizard_in_process_browser_test.cc b/chrome/browser/chromeos/login/wizard_in_process_browser_test.cc
index 56e5364..ef21753 100644
--- a/chrome/browser/chromeos/login/wizard_in_process_browser_test.cc
+++ b/chrome/browser/chromeos/login/wizard_in_process_browser_test.cc
@@ -6,11 +6,11 @@
 
 #include "base/command_line.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
 #include "chrome/browser/chromeos/login/login_wizard.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "chromeos/chromeos_switches.h"
@@ -25,7 +25,7 @@
 
 void WizardInProcessBrowserTest::SetUp() {
   WizardController::SetZeroDelays();
-  InProcessBrowserTest::SetUp();
+  CrosInProcessBrowserTest::SetUp();
 }
 
 void WizardInProcessBrowserTest::SetUpCommandLine(CommandLine* command_line) {
diff --git a/chrome/browser/chromeos/login/wizard_in_process_browser_test.h b/chrome/browser/chromeos/login/wizard_in_process_browser_test.h
index ad49b74..8b888e3 100644
--- a/chrome/browser/chromeos/login/wizard_in_process_browser_test.h
+++ b/chrome/browser/chromeos/login/wizard_in_process_browser_test.h
@@ -26,7 +26,7 @@
  public:
   explicit WizardInProcessBrowserTest(const char* screen_name);
 
-  // Overriden from InProcessBrowserTest:
+  // Overridden from CrosInProcessBrowserTest:
   virtual void SetUp() OVERRIDE;
 
  protected:
diff --git a/chrome/browser/chromeos/media/media_player.cc b/chrome/browser/chromeos/media/media_player.cc
index 4410142..5b0b683 100644
--- a/chrome/browser/chromeos/media/media_player.cc
+++ b/chrome/browser/chromeos/media/media_player.cc
@@ -8,6 +8,7 @@
 
 #include "ash/shell.h"
 #include "base/bind.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h"
 #include "chrome/browser/chromeos/extensions/media_player_api.h"
 #include "chrome/browser/chromeos/extensions/media_player_event_router.h"
@@ -19,7 +20,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/gfx/screen.h"
diff --git a/chrome/browser/chromeos/memory/oom_priority_manager_browsertest.cc b/chrome/browser/chromeos/memory/oom_priority_manager_browsertest.cc
index 3625a95..66b6272 100644
--- a/chrome/browser/chromeos/memory/oom_priority_manager_browsertest.cc
+++ b/chrome/browser/chromeos/memory/oom_priority_manager_browsertest.cc
@@ -14,7 +14,7 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/test/test_utils.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::OpenURLParams;
 
diff --git a/chrome/browser/chromeos/memory/oom_priority_manager_unittest.cc b/chrome/browser/chromeos/memory/oom_priority_manager_unittest.cc
index cf5fa16..c227ac2 100644
--- a/chrome/browser/chromeos/memory/oom_priority_manager_unittest.cc
+++ b/chrome/browser/chromeos/memory/oom_priority_manager_unittest.cc
@@ -10,8 +10,8 @@
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/memory/oom_priority_manager.h"
 #include "chrome/common/url_constants.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
diff --git a/chrome/browser/chromeos/mobile/mobile_activator.cc b/chrome/browser/chromeos/mobile/mobile_activator.cc
index 2628fb1..5167f5e 100644
--- a/chrome/browser/chromeos/mobile/mobile_activator.cc
+++ b/chrome/browser/chromeos/mobile/mobile_activator.cc
@@ -24,7 +24,6 @@
 #include "base/timer/timer.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
@@ -89,7 +88,7 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
   // Load partner customization startup manifest if it is available.
   base::FilePath config_path(kCellularConfigPath);
-  if (!file_util::PathExists(config_path))
+  if (!base::PathExists(config_path))
     return;
 
   if (LoadFromFile(config_path))
@@ -165,7 +164,7 @@
 
 void MobileActivator::TerminateActivation() {
   // We're exiting; don't continue with termination.
-  if (!CrosLibrary::Get())
+  if (!NetworkLibrary::Get())
     return;
 
   state_duration_timer_.Stop();
@@ -962,7 +961,7 @@
 void MobileActivator::GetDeviceInfo(CellularNetwork* network,
                                     DictionaryValue* value) {
   DCHECK(network);
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   if (!cros)
     return;
   value->SetString("carrier", network->name());
@@ -984,7 +983,7 @@
 }
 
 NetworkLibrary* MobileActivator::GetNetworkLibrary() const {
-  return CrosLibrary::Get()->GetNetworkLibrary();
+  return NetworkLibrary::Get();
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/net/connectivity_state_helper.cc b/chrome/browser/chromeos/net/connectivity_state_helper.cc
index 19ca149..59c626b 100644
--- a/chrome/browser/chromeos/net/connectivity_state_helper.cc
+++ b/chrome/browser/chromeos/net/connectivity_state_helper.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/chromeos/net/connectivity_state_helper.h"
 
 #include "base/command_line.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/network/network_state.h"
@@ -202,7 +201,7 @@
 //
 
 ConnectivityStateHelperNetworkLibrary::ConnectivityStateHelperNetworkLibrary() {
-  network_library_ = CrosLibrary::Get()->GetNetworkLibrary();
+  network_library_ = NetworkLibrary::Get();
   network_library_->AddNetworkManagerObserver(this);
 }
 
diff --git a/chrome/browser/chromeos/net/network_change_notifier_network_library.cc b/chrome/browser/chromeos/net/network_change_notifier_network_library.cc
index 527ac02..d221b66 100644
--- a/chrome/browser/chromeos/net/network_change_notifier_network_library.cc
+++ b/chrome/browser/chromeos/net/network_change_notifier_network_library.cc
@@ -7,7 +7,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/dns/dns_config_service_posix.h"
@@ -25,7 +24,7 @@
          state == chromeos::STATE_PORTAL;
 }
 
-}
+}  // namespace
 
 namespace chromeos {
 
@@ -68,7 +67,7 @@
 
 void NetworkChangeNotifierNetworkLibrary::Init() {
   chromeos::NetworkLibrary* network_library =
-      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+      chromeos::NetworkLibrary::Get();
   network_library->AddNetworkManagerObserver(this);
   DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
 
@@ -84,11 +83,11 @@
 
   dns_config_service_.reset();
 
-  if (!chromeos::CrosLibrary::Get())
+  if (!NetworkLibrary::Get())
     return;
 
   chromeos::NetworkLibrary* lib =
-      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+      chromeos::NetworkLibrary::Get();
   lib->RemoveNetworkManagerObserver(this);
   lib->RemoveObserverForAllNetworks(this);
 
@@ -289,8 +288,7 @@
 // static
 void NetworkChangeNotifierNetworkLibrary::UpdateInitialState(
     NetworkChangeNotifierNetworkLibrary* self) {
-  chromeos::NetworkLibrary* net =
-      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+  chromeos::NetworkLibrary* net = chromeos::NetworkLibrary::Get();
   self->UpdateNetworkState(net);
 }
 
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl.cc b/chrome/browser/chromeos/net/network_portal_detector_impl.cc
index 7d6d097..9d124fd 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl.cc
@@ -9,8 +9,7 @@
 #include "base/logging.h"
 #include "base/message_loop.h"
 #include "base/metrics/histogram.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl.h b/chrome/browser/chromeos/net/network_portal_detector_impl.h
index b523f65..eeeef2e 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl.h
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl.h
@@ -22,8 +22,8 @@
 #include "chromeos/network/network_state_handler_observer.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_fetcher.h"
+#include "url/gurl.h"
 
 namespace net {
 class URLRequestContextGetter;
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
index 16994e8..7d8a0c5 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
@@ -8,7 +8,6 @@
 #include "base/message_loop.h"
 #include "chrome/browser/captive_portal/captive_portal_detector.h"
 #include "chrome/browser/captive_portal/testing_utils.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/net/network_portal_detector_impl.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
diff --git a/chrome/browser/chromeos/net/onc_utils.cc b/chrome/browser/chromeos/net/onc_utils.cc
index 0ce54db..430af00 100644
--- a/chrome/browser/chromeos/net/onc_utils.cc
+++ b/chrome/browser/chromeos/net/onc_utils.cc
@@ -9,10 +9,10 @@
 #include "chrome/browser/chromeos/ui_proxy_config.h"
 #include "chrome/browser/prefs/proxy_config_dictionary.h"
 #include "chromeos/network/onc/onc_utils.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/host_port_pair.h"
 #include "net/proxy/proxy_bypass_rules.h"
 #include "net/proxy/proxy_server.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 namespace onc {
diff --git a/chrome/browser/chromeos/net/proxy_config_handler.cc b/chrome/browser/chromeos/net/proxy_config_handler.cc
index b1d2f1e..adb4c86 100644
--- a/chrome/browser/chromeos/net/proxy_config_handler.cc
+++ b/chrome/browser/chromeos/net/proxy_config_handler.cc
@@ -9,30 +9,18 @@
 #include "base/logging.h"
 #include "base/values.h"
 #include "chrome/browser/prefs/proxy_config_dictionary.h"
+#include "chrome/common/pref_names.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/shill_service_client.h"
 #include "chromeos/network/network_handler_callbacks.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
+#include "components/user_prefs/pref_registry_syncable.h"
 #include "dbus/object_path.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace chromeos {
 
-namespace {
-
-void LogError(const std::string& network,
-              const std::string& error_name,
-              const std::string& error_message) {
-  network_handler::ShillErrorCallbackFunction(
-      network,
-      network_handler::ErrorCallback(),
-      "Could not clear or set ProxyConfig",
-      error_message);
-}
-
-}  // namespace
-
 namespace proxy_config {
 
 scoped_ptr<ProxyConfigDictionary> GetProxyConfigForNetwork(
@@ -56,7 +44,9 @@
         dbus::ObjectPath(network.path()),
         flimflam::kProxyConfigProperty,
         base::Bind(&base::DoNothing),
-        base::Bind(&LogError, network.path()));
+        base::Bind(&network_handler::ShillErrorCallbackFunction,
+                   "SetProxyConfig.ClearProperty Failed",
+                   network.path(), network_handler::ErrorCallback()));
   } else {
     std::string proxy_config_str;
     base::JSONWriter::Write(&proxy_config.GetDictionary(), &proxy_config_str);
@@ -65,7 +55,9 @@
         flimflam::kProxyConfigProperty,
         base::StringValue(proxy_config_str),
         base::Bind(&base::DoNothing),
-        base::Bind(&LogError, network.path()));
+        base::Bind(&network_handler::ShillErrorCallbackFunction,
+                   "SetProxyConfig.SetProperty Failed",
+                   network.path(), network_handler::ErrorCallback()));
   }
 
   if (NetworkHandler::IsInitialized()) {
@@ -74,6 +66,14 @@
   }
 }
 
+void RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  registry->RegisterBooleanPref(
+      prefs::kUseSharedProxies,
+      false,
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+}
+
 }  // namespace proxy_config
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/net/proxy_config_handler.h b/chrome/browser/chromeos/net/proxy_config_handler.h
index 5162c5c..b8455dc 100644
--- a/chrome/browser/chromeos/net/proxy_config_handler.h
+++ b/chrome/browser/chromeos/net/proxy_config_handler.h
@@ -9,6 +9,10 @@
 
 class ProxyConfigDictionary;
 
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
 namespace chromeos {
 
 class NetworkState;
@@ -21,6 +25,8 @@
 void SetProxyConfigForNetwork(const ProxyConfigDictionary& proxy_config,
                               const NetworkState& network);
 
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
 }  // namespace proxy_config
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/offline/offline_load_page.cc b/chrome/browser/chromeos/offline/offline_load_page.cc
index 4c8a714..d752d1d 100644
--- a/chrome/browser/chromeos/offline/offline_load_page.cc
+++ b/chrome/browser/chromeos/offline/offline_load_page.cc
@@ -13,14 +13,13 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/renderer_preferences_util.h"
 #include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/extension_icon_set.h"
@@ -195,12 +194,12 @@
 }
 
 bool OfflineLoadPage::ShowActivationMessage() {
-  CrosLibrary* cros = CrosLibrary::Get();
-  if (!cros || !cros->GetNetworkLibrary()->cellular_available())
+  NetworkLibrary* network_library = NetworkLibrary::Get();
+  if (!network_library || !network_library->cellular_available())
     return false;
 
   const CellularNetworkVector& cell_networks =
-      cros->GetNetworkLibrary()->cellular_networks();
+      network_library->cellular_networks();
   for (size_t i = 0; i < cell_networks.size(); ++i) {
     chromeos::ActivationState activation_state =
         cell_networks[i]->activation_state();
diff --git a/chrome/browser/chromeos/offline/offline_load_page.h b/chrome/browser/chromeos/offline/offline_load_page.h
index 9d007bc..df8835d 100644
--- a/chrome/browser/chromeos/offline/offline_load_page.h
+++ b/chrome/browser/chromeos/offline/offline_load_page.h
@@ -10,8 +10,8 @@
 #include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "content/public/browser/interstitial_page_delegate.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/network_change_notifier.h"
+#include "url/gurl.h"
 
 namespace base {
 class DictionaryValue;
diff --git a/chrome/browser/chromeos/offline/offline_load_page_unittest.cc b/chrome/browser/chromeos/offline/offline_load_page_unittest.cc
index 52b0e7c..b0b4bec 100644
--- a/chrome/browser/chromeos/offline/offline_load_page_unittest.cc
+++ b/chrome/browser/chromeos/offline/offline_load_page_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/offline/offline_load_page.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "content/public/browser/interstitial_page.h"
@@ -85,8 +85,8 @@
 
   UserResponse user_response_;
 
-  // Initializes / shuts down a stub CrosLibrary.
-  chromeos::ScopedStubCrosEnabler stub_cros_enabler_;
+  // Initializes / shuts down a stub NetworkLibrary.
+  ScopedStubNetworkLibraryEnabler stub_network_library_enabler_;
 };
 
 void TestOfflineLoadPage::NotifyBlockingPageComplete(bool proceed) {
diff --git a/chrome/browser/chromeos/options/network_connect.cc b/chrome/browser/chromeos/options/network_connect.cc
index 4daccc2..c44822b 100644
--- a/chrome/browser/chromeos/options/network_connect.cc
+++ b/chrome/browser/chromeos/options/network_connect.cc
@@ -12,7 +12,6 @@
 #include "base/command_line.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
 #include "chrome/browser/chromeos/options/network_config_view.h"
@@ -34,7 +33,7 @@
 namespace {
 
 void DoConnect(Network* network, gfx::NativeWindow parent_window) {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   if (network->type() == TYPE_VPN) {
     VirtualNetwork* vpn = static_cast<VirtualNetwork*>(network);
     if (vpn->NeedMoreInfoToConnect()) {
@@ -80,7 +79,7 @@
 
 void ActivateCellular(const std::string& service_path) {
   chromeos::NetworkLibrary* cros =
-      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+      chromeos::NetworkLibrary::Get();
   if (!cros->CellularDeviceUsesDirectActivation()) {
     // For non direct activation, show the mobile setup dialog which can be
     // used to activate the network.
@@ -97,7 +96,7 @@
 }
 
 void ShowMobileSetup(const std::string& service_path) {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   const CellularNetwork* cellular =
       cros->FindCellularNetworkByPath(service_path);
   if (cellular && !cellular->activated() &&
@@ -130,7 +129,7 @@
     return CONNECT_STARTED;
   }
 
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   Network* network = cros->FindNetworkByPath(service_path);
   if (!network)
     return NETWORK_NOT_FOUND;
@@ -172,7 +171,7 @@
 
 void HandleUnconfiguredNetwork(const std::string& service_path,
                                gfx::NativeWindow parent_window) {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   Network* network = cros->FindNetworkByPath(service_path);
   if (!network) {
     LOG(WARNING) << "Unknown network: " << service_path;
diff --git a/chrome/browser/chromeos/options/vpn_config_view.cc b/chrome/browser/chromeos/options/vpn_config_view.cc
index f35536e..943e781 100644
--- a/chrome/browser/chromeos/options/vpn_config_view.cc
+++ b/chrome/browser/chromeos/options/vpn_config_view.cc
@@ -7,7 +7,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -302,7 +301,7 @@
 }
 
 bool VPNConfigView::Login() {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   if (service_path_.empty()) {
     NetworkLibrary::VPNConfigData config_data;
     switch (provider_type_) {
@@ -715,7 +714,7 @@
 }
 
 void VPNConfigView::Refresh() {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
 
   UpdateControls();
 
@@ -819,7 +818,7 @@
 }
 
 void VPNConfigView::UpdateErrorLabel() {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
 
   // Error message.
   std::string error_msg;
@@ -901,7 +900,7 @@
                                        Network* network,
                                        const std::string& dict_key,
                                        const std::string& key) {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   const base::DictionaryValue* onc =
       network_library->FindOncForNetwork(network->unique_id());
   VLOG_IF(1, !onc) << "No ONC found for VPN network " << network->unique_id();
diff --git a/chrome/browser/chromeos/options/wifi_config_view.cc b/chrome/browser/chromeos/options/wifi_config_view.cc
index 4e7257d..b2338e7 100644
--- a/chrome/browser/chromeos/options/wifi_config_view.cc
+++ b/chrome/browser/chromeos/options/wifi_config_view.cc
@@ -7,7 +7,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -569,7 +568,7 @@
     }
   }
   if (error_msg.empty() && !service_path_.empty()) {
-    NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+    NetworkLibrary* cros = NetworkLibrary::Get();
     const WifiNetwork* wifi = cros->FindWifiNetworkByPath(service_path_);
     if (wifi && wifi->failed()) {
       bool passphrase_empty = wifi->GetPassphrase().empty();
@@ -652,7 +651,7 @@
 }
 
 bool WifiConfigView::Login() {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   if (service_path_.empty()) {
     const bool share_default = true;  // share networks by default
     if (!eap_method_combobox_) {
@@ -1247,7 +1246,7 @@
     NetworkPropertyUIData* property_ui_data,
     Network* network,
     const std::string& key) {
-  NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_library = NetworkLibrary::Get();
   property_ui_data->ParseOncProperty(
       network->ui_data().onc_source(),
       network_library->FindOncForNetwork(network->unique_id()),
diff --git a/chrome/browser/chromeos/options/wimax_config_view.cc b/chrome/browser/chromeos/options/wimax_config_view.cc
index d1260dd..5ae075b 100644
--- a/chrome/browser/chromeos/options/wimax_config_view.cc
+++ b/chrome/browser/chromeos/options/wimax_config_view.cc
@@ -7,7 +7,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
@@ -79,7 +78,7 @@
 void WimaxConfigView::UpdateErrorLabel() {
   std::string error_msg;
   if (!service_path_.empty()) {
-    NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+    NetworkLibrary* cros = NetworkLibrary::Get();
     const WimaxNetwork* wimax = cros->FindWimaxNetworkByPath(service_path_);
     if (wimax && wimax->failed()) {
       bool passphrase_empty = wimax->eap_passphrase().empty();
@@ -138,7 +137,7 @@
 }
 
 bool WimaxConfigView::Login() {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   WimaxNetwork* wimax = cros->FindWimaxNetworkByPath(service_path_);
   if (!wimax) {
     // Shill no longer knows about this wimax network (edge case).
diff --git a/chrome/browser/chromeos/policy/app_pack_updater.cc b/chrome/browser/chromeos/policy/app_pack_updater.cc
index 628150f..ad89025 100644
--- a/chrome/browser/chromeos/policy/app_pack_updater.cc
+++ b/chrome/browser/chromeos/policy/app_pack_updater.cc
@@ -14,6 +14,7 @@
 #include "base/values.h"
 #include "base/version.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/extensions/external_loader.h"
 #include "chrome/browser/extensions/external_provider_impl.h"
 #include "chrome/browser/extensions/updater/extension_downloader.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "content/public/browser/browser_thread.h"
@@ -240,7 +240,7 @@
     CacheEntryMap* entries) {
   // Start by verifying that the cache dir exists.
   base::FilePath dir(kAppPackCacheDir);
-  if (!file_util::DirectoryExists(dir)) {
+  if (!base::DirectoryExists(dir)) {
     // Create it now.
     if (!file_util::CreateDirectory(dir))
       LOG(ERROR) << "Failed to create AppPack directory at " << dir.value();
@@ -261,7 +261,7 @@
 
     if (info.IsDirectory() || file_util::IsLink(info.GetName())) {
       LOG(ERROR) << "Erasing bad file in AppPack directory: " << basename;
-      base::Delete(path, true /* recursive */);
+      base::DeleteFile(path, true /* recursive */);
       continue;
     }
 
@@ -294,7 +294,7 @@
 
     if (id.empty() || version.empty()) {
       LOG(ERROR) << "Invalid file in AppPack cache, erasing: " << basename;
-      base::Delete(path, true /* recursive */);
+      base::DeleteFile(path, true /* recursive */);
       continue;
     }
 
@@ -313,10 +313,10 @@
       DCHECK(vEntry.IsValid());
       DCHECK(vCurrent.IsValid());
       if (vEntry.CompareTo(vCurrent) < 0) {
-        base::Delete(base::FilePath(entry.path), true /* recursive */);
+        base::DeleteFile(base::FilePath(entry.path), true /* recursive */);
         entry.path = path.value();
       } else {
-        base::Delete(path, true /* recursive */);
+        base::DeleteFile(path, true /* recursive */);
       }
       continue;
     }
@@ -470,7 +470,7 @@
   if (!version_validator.IsValid()) {
     LOG(ERROR) << "AppPack downloaded extension " << id << " but got bad "
                << "version: " << version;
-    base::Delete(path, true /* recursive */);
+    base::DeleteFile(path, true /* recursive */);
     return;
   }
 
@@ -478,18 +478,18 @@
   base::FilePath cache_dir(kAppPackCacheDir);
   base::FilePath cached_crx_path = cache_dir.Append(basename);
 
-  if (file_util::PathExists(cached_crx_path)) {
+  if (base::PathExists(cached_crx_path)) {
     LOG(WARNING) << "AppPack downloaded a crx whose filename will overwrite "
                  << "an existing cached crx.";
-    base::Delete(cached_crx_path, true /* recursive */);
+    base::DeleteFile(cached_crx_path, true /* recursive */);
   }
 
-  if (!file_util::DirectoryExists(cache_dir)) {
+  if (!base::DirectoryExists(cache_dir)) {
     LOG(ERROR) << "AppPack cache directory does not exist, creating now: "
                << cache_dir.value();
     if (!file_util::CreateDirectory(cache_dir)) {
       LOG(ERROR) << "Failed to create the AppPack cache dir!";
-      base::Delete(path, true /* recursive */);
+      base::DeleteFile(path, true /* recursive */);
       return;
     }
   }
@@ -497,7 +497,7 @@
   if (!base::Move(path, cached_crx_path)) {
     LOG(ERROR) << "Failed to move AppPack crx from " << path.value()
                << " to " << cached_crx_path.value();
-    base::Delete(path, true /* recursive */);
+    base::DeleteFile(path, true /* recursive */);
     return;
   }
 
@@ -539,7 +539,7 @@
       // The file will be downloaded again on the next restart.
       BrowserThread::PostTask(
           BrowserThread::FILE, FROM_HERE,
-          base::Bind(base::IgnoreResult(base::Delete), path, true));
+          base::Bind(base::IgnoreResult(base::DeleteFile), path, true));
 
       // Don't try to DownloadMissingExtensions() from here,
       // since it can cause a fail/retry loop.
diff --git a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
index bf64d56..353b7d6 100644
--- a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
+++ b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
@@ -7,12 +7,14 @@
 #include <string>
 
 #include "ash/magnifier/magnifier_constants.h"
+#include "base/callback.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/prefs/pref_value_map.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_error_map.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
@@ -103,7 +105,8 @@
   if (!sanitized_config)
     sanitized_config = base::Value::CreateNullValue();
 
-  policies->Set(policy_name(), entry->level, entry->scope, sanitized_config);
+  policies->Set(policy_name(), entry->level, entry->scope,
+                sanitized_config, NULL);
 }
 
 NetworkConfigurationPolicyHandler::NetworkConfigurationPolicyHandler(
diff --git a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc
index 9d158ab..5e10990 100644
--- a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc
@@ -4,7 +4,9 @@
 
 #include "chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h"
 
+#include "base/callback.h"
 #include "base/prefs/pref_value_map.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_error_map.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
@@ -42,7 +44,8 @@
   policy_map.Set(key::kOpenNetworkConfiguration,
                  POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER,
-                 Value::CreateStringValue(kTestONC));
+                 Value::CreateStringValue(kTestONC),
+                 NULL);
   scoped_ptr<NetworkConfigurationPolicyHandler> handler(
       NetworkConfigurationPolicyHandler::CreateForUserPolicy());
   PolicyErrorMap errors;
@@ -55,7 +58,8 @@
   policy_map.Set(key::kOpenNetworkConfiguration,
                  POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER,
-                 Value::CreateBooleanValue(false));
+                 Value::CreateBooleanValue(false),
+                 NULL);
   scoped_ptr<NetworkConfigurationPolicyHandler> handler(
       NetworkConfigurationPolicyHandler::CreateForUserPolicy());
   PolicyErrorMap errors;
@@ -69,7 +73,8 @@
   policy_map.Set(key::kOpenNetworkConfiguration,
                  POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER,
-                 Value::CreateStringValue(kTestONC));
+                 Value::CreateStringValue(kTestONC),
+                 NULL);
   scoped_ptr<NetworkConfigurationPolicyHandler> handler(
       NetworkConfigurationPolicyHandler::CreateForUserPolicy());
   PolicyErrorMap errors;
@@ -96,7 +101,8 @@
   policy_map.Set(key::kOpenNetworkConfiguration,
                  POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER,
-                 Value::CreateStringValue(kTestONC));
+                 Value::CreateStringValue(kTestONC),
+                 NULL);
   scoped_ptr<NetworkConfigurationPolicyHandler> handler(
       NetworkConfigurationPolicyHandler::CreateForUserPolicy());
   PolicyErrorMap errors;
@@ -118,7 +124,7 @@
   PinnedLauncherAppsPolicyHandler handler;
 
   policy_map.Set(key::kPinnedLauncherApps, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   handler.ApplyPolicySettings(policy_map, &prefs);
   EXPECT_TRUE(prefs.GetValue(prefs::kPinnedLauncherApps, &value));
   EXPECT_TRUE(base::Value::Equals(&expected_pinned_apps, value));
@@ -129,7 +135,7 @@
   expected_pinned_apps.Append(entry1_dict);
   list.Append(entry1.DeepCopy());
   policy_map.Set(key::kPinnedLauncherApps, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   EXPECT_TRUE(prefs.GetValue(prefs::kPinnedLauncherApps, &value));
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
index 2c7c0be..7b8f004 100644
--- a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
 #include "chrome/browser/policy/cloud/cloud_policy_client.h"
 #include "chrome/browser/policy/cloud/mock_device_management_service.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
 #include "chrome/browser/prefs/browser_prefs.h"
@@ -149,7 +150,8 @@
       .Set(key::kDeviceMetricsReportingEnabled,
            POLICY_LEVEL_MANDATORY,
            POLICY_SCOPE_MACHINE,
-           Value::CreateBooleanValue(false));
+           Value::CreateBooleanValue(false),
+           NULL);
   EXPECT_TRUE(manager_.policies().Equals(bundle));
 
   manager_.Connect(&local_state_,
@@ -251,7 +253,8 @@
         .Set(key::kDeviceMetricsReportingEnabled,
              POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_MACHINE,
-             Value::CreateBooleanValue(false));
+             Value::CreateBooleanValue(false),
+             NULL);
     EXPECT_TRUE(manager_.policies().Equals(bundle));
   }
 
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
index ac604d6..1fd8106 100644
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/login_display_host.h"
 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
@@ -36,7 +37,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/dbus/cryptohome_client.h"
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc
index a538826..72fa5a4 100644
--- a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/policy/device_local_account.h"
 #include "chrome/browser/chromeos/policy/device_local_account_policy_store.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
@@ -20,7 +21,6 @@
 #include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h"
 #include "chrome/browser/policy/cloud/device_management_service.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chromeos/dbus/session_manager_client.h"
 #include "content/public/browser/notification_details.h"
 #include "policy/policy_constants.h"
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc b/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc
index f764b91..baae74b 100644
--- a/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/chromeos/policy/device_local_account.h"
 #include "chrome/browser/chromeos/policy/device_local_account_policy_provider.h"
@@ -17,6 +18,7 @@
 #include "chrome/browser/policy/cloud/cloud_policy_service.h"
 #include "chrome/browser/policy/cloud/mock_device_management_service.h"
 #include "chrome/browser/policy/cloud/policy_builder.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h"
 #include "chromeos/dbus/power_policy_controller.h"
@@ -61,27 +63,32 @@
                              POLICY_SCOPE_USER,
                              base::Value::CreateIntegerValue(
                                  chromeos::PowerPolicyController::
-                                     ACTION_STOP_SESSION));
+                                     ACTION_STOP_SESSION),
+                             NULL);
     expected_policy_map_.Set(key::kShelfAutoHideBehavior,
                              POLICY_LEVEL_MANDATORY,
                              POLICY_SCOPE_USER,
-                             Value::CreateStringValue("Never"));
+                             Value::CreateStringValue("Never"),
+                             NULL);
     expected_policy_map_.Set(key::kShowLogoutButtonInTray,
                              POLICY_LEVEL_MANDATORY,
                              POLICY_SCOPE_USER,
-                             Value::CreateBooleanValue(true));
+                             Value::CreateBooleanValue(true),
+                             NULL);
     scoped_ptr<base::ListValue> allowed_extension_types(new base::ListValue());
     allowed_extension_types->AppendString("hosted_app");
     expected_policy_map_.Set(key::kExtensionAllowedTypes,
                              POLICY_LEVEL_MANDATORY,
                              POLICY_SCOPE_USER,
-                             allowed_extension_types.release());
+                             allowed_extension_types.release(),
+                             NULL);
 
     // Explicitly set value.
     expected_policy_map_.Set(key::kDisableSpdy,
                              POLICY_LEVEL_MANDATORY,
                              POLICY_SCOPE_USER,
-                             Value::CreateBooleanValue(true));
+                             Value::CreateBooleanValue(true),
+                             NULL);
 
     device_local_account_policy_.payload().mutable_disablespdy()->set_value(
         true);
@@ -479,7 +486,8 @@
       .Set(key::kDisableSpdy,
            POLICY_LEVEL_MANDATORY,
            POLICY_SCOPE_USER,
-           Value::CreateBooleanValue(false));
+           Value::CreateBooleanValue(false),
+           NULL);
   EXPECT_TRUE(expected_policy_bundle.Equals(provider_.policies()));
 
   // Any values set for the |ShelfAutoHideBehavior|, |ShowLogoutButtonInTray|
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_store.cc b/chrome/browser/chromeos/policy/device_local_account_policy_store.cc
index 133a4c8..786a2c9 100644
--- a/chrome/browser/chromeos/policy/device_local_account_policy_store.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_policy_store.cc
@@ -5,8 +5,10 @@
 #include "chrome/browser/chromeos/policy/device_local_account_policy_store.h"
 
 #include "base/bind.h"
+#include "base/callback.h"
 #include "base/values.h"
 #include "chrome/browser/policy/cloud/device_management_service.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_types.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
 #include "chromeos/dbus/power_policy_controller.h"
@@ -82,20 +84,23 @@
                   POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_USER,
                   base::Value::CreateIntegerValue(
-                      chromeos::PowerPolicyController::ACTION_STOP_SESSION));
+                      chromeos::PowerPolicyController::ACTION_STOP_SESSION),
+                  NULL);
 
   // Force the |ShelfAutoHideBehavior| policy to |Never|, ensuring that the ash
   // shelf does not auto-hide.
   policy_map_.Set(key::kShelfAutoHideBehavior,
                   POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_USER,
-                  Value::CreateStringValue("Never"));
+                  Value::CreateStringValue("Never"),
+                  NULL);
   // Force the |ShowLogoutButtonInTray| policy to |true|, ensuring that a big,
   // red logout button is shown in the ash system tray.
   policy_map_.Set(key::kShowLogoutButtonInTray,
                   POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_USER,
-                  Value::CreateBooleanValue(true));
+                  Value::CreateBooleanValue(true),
+                  NULL);
   // Restrict device-local accounts to hosted apps for now (i.e. no extensions,
   // packaged apps etc.) for security/privacy reasons (i.e. we'd like to
   // prevent the admin from stealing private information from random people).
@@ -104,7 +109,8 @@
   policy_map_.Set(key::kExtensionAllowedTypes,
                   POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_USER,
-                  allowed_extension_types.release());
+                  allowed_extension_types.release(),
+                  NULL);
 
   status_ = STATUS_OK;
   NotifyStoreLoaded();
@@ -159,8 +165,9 @@
     bool is_owner) {
   DCHECK_NE(chromeos::DeviceSettingsService::OWNERSHIP_UNKNOWN,
             ownership_status);
-  chromeos::OwnerKey* key = device_settings_service_->GetOwnerKey();
-  if (!key || !key->public_key()) {
+  scoped_refptr<chromeos::OwnerKey> key =
+      device_settings_service_->GetOwnerKey();
+  if (!key.get() || !key->public_key()) {
     status_ = CloudPolicyStore::STATUS_BAD_STATE;
     NotifyStoreLoaded();
     return;
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
index 15359ec..92f1fc4 100644
--- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
+++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -6,11 +6,13 @@
 
 #include <limits>
 
+#include "base/callback.h"
 #include "base/logging.h"
 #include "base/values.h"
 #include "chrome/browser/chromeos/policy/device_local_account.h"
 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -63,7 +65,8 @@
       policies->Set(key::kDeviceGuestModeEnabled,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    Value::CreateBooleanValue(container.guest_mode_enabled()));
+                    Value::CreateBooleanValue(container.guest_mode_enabled()),
+                    NULL);
     }
   }
 
@@ -73,7 +76,8 @@
       policies->Set(key::kDeviceShowUserNamesOnSignin,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    Value::CreateBooleanValue(container.show_user_names()));
+                    Value::CreateBooleanValue(container.show_user_names()),
+                    NULL);
     }
   }
 
@@ -83,7 +87,8 @@
       policies->Set(key::kDeviceAllowNewUsers,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    Value::CreateBooleanValue(container.allow_new_users()));
+                    Value::CreateBooleanValue(container.allow_new_users()),
+                    NULL);
     }
   }
 
@@ -99,7 +104,8 @@
     policies->Set(key::kDeviceUserWhitelist,
                   POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_MACHINE,
-                  whitelist);
+                  whitelist,
+                  NULL);
   }
 
   if (policy.has_ephemeral_users_enabled()) {
@@ -110,7 +116,8 @@
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateBooleanValue(
-                        container.ephemeral_users_enabled()));
+                        container.ephemeral_users_enabled()),
+                    NULL);
     }
   }
 
@@ -156,25 +163,29 @@
     policies->Set(key::kDeviceLocalAccounts,
                   POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_MACHINE,
-                  account_list.release());
+                  account_list.release(),
+                  NULL);
     if (container.has_auto_login_id()) {
       policies->Set(key::kDeviceLocalAccountAutoLoginId,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    Value::CreateStringValue(container.auto_login_id()));
+                    Value::CreateStringValue(container.auto_login_id()),
+                    NULL);
     }
     if (container.has_auto_login_delay()) {
       policies->Set(key::kDeviceLocalAccountAutoLoginDelay,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    DecodeIntegerValue(container.auto_login_delay()));
+                    DecodeIntegerValue(container.auto_login_delay()),
+                    NULL);
     }
     if (container.has_enable_auto_login_bailout()) {
       policies->Set(key::kDeviceLocalAccountAutoLoginBailoutEnabled,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateBooleanValue(
-                        container.enable_auto_login_bailout()));
+                        container.enable_auto_login_bailout()),
+                    NULL);
     }
   }
 
@@ -187,7 +198,8 @@
       policies->Set(key::kSupervisedUsersEnabled,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    value);
+                    value,
+                    NULL);
     }
   }
 }
@@ -206,14 +218,16 @@
       policies->Set(key::kDeviceIdleLogoutTimeout,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    DecodeIntegerValue(container.idle_logout_timeout()));
+                    DecodeIntegerValue(container.idle_logout_timeout()),
+                    NULL);
     }
     if (container.has_idle_logout_warning_duration()) {
       policies->Set(key::kDeviceIdleLogoutWarningDuration,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     DecodeIntegerValue(
-                        container.idle_logout_warning_duration()));
+                        container.idle_logout_warning_duration()),
+                    NULL);
     }
   }
 
@@ -225,13 +239,15 @@
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateStringValue(
-                        container.screen_saver_extension_id()));
+                        container.screen_saver_extension_id()),
+                    NULL);
     }
     if (container.has_screen_saver_timeout()) {
       policies->Set(key::kDeviceLoginScreenSaverTimeout,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    DecodeIntegerValue(container.screen_saver_timeout()));
+                    DecodeIntegerValue(container.screen_saver_timeout()),
+                    NULL);
     }
   }
 
@@ -250,7 +266,8 @@
     policies->Set(key::kDeviceAppPack,
                   POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_MACHINE,
-                  app_pack_list);
+                  app_pack_list,
+                  NULL);
   }
 
   if (policy.has_pinned_apps()) {
@@ -262,7 +279,8 @@
     policies->Set(key::kPinnedLauncherApps,
                   POLICY_LEVEL_RECOMMENDED,
                   POLICY_SCOPE_MACHINE,
-                  pinned_apps_list);
+                  pinned_apps_list,
+                  NULL);
   }
 }
 
@@ -293,7 +311,8 @@
       policies->Set(key::kProxySettings,
                     level,
                     POLICY_SCOPE_MACHINE,
-                    proxy_settings.release());
+                    proxy_settings.release(),
+                    NULL);
     }
   }
 
@@ -304,7 +323,8 @@
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateBooleanValue(
-                        container.data_roaming_enabled()));
+                        container.data_roaming_enabled()),
+                    NULL);
     }
   }
 
@@ -315,7 +335,8 @@
     policies->Set(key::kDeviceOpenNetworkConfiguration,
                   POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_MACHINE,
-                  Value::CreateStringValue(config));
+                  Value::CreateStringValue(config),
+                  NULL);
   }
 }
 
@@ -327,26 +348,38 @@
       policies->Set(key::kReportDeviceVersionInfo,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    Value::CreateBooleanValue(container.report_version_info()));
+                    Value::CreateBooleanValue(container.report_version_info()),
+                    NULL);
     }
     if (container.has_report_activity_times()) {
       policies->Set(key::kReportDeviceActivityTimes,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateBooleanValue(
-                        container.report_activity_times()));
+                        container.report_activity_times()),
+                    NULL);
     }
     if (container.has_report_boot_mode()) {
       policies->Set(key::kReportDeviceBootMode,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    Value::CreateBooleanValue(container.report_boot_mode()));
+                    Value::CreateBooleanValue(container.report_boot_mode()),
+                    NULL);
     }
     if (container.has_report_location()) {
       policies->Set(key::kReportDeviceLocation,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    Value::CreateBooleanValue(container.report_location()));
+                    Value::CreateBooleanValue(container.report_location()),
+                    NULL);
+    }
+    if (container.has_report_network_interfaces()) {
+      policies->Set(key::kReportDeviceNetworkInterfaces,
+                    POLICY_LEVEL_MANDATORY,
+                    POLICY_SCOPE_MACHINE,
+                    Value::CreateBooleanValue(
+                        container.report_network_interfaces()),
+                    NULL);
     }
   }
 }
@@ -360,7 +393,8 @@
       policies->Set(key::kChromeOsReleaseChannel,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    Value::CreateStringValue(channel));
+                    Value::CreateStringValue(channel),
+                    NULL);
       // TODO(dubroy): Once http://crosbug.com/17015 is implemented, we won't
       // have to pass the channel in here, only ping the update engine to tell
       // it to fetch the channel from the policy.
@@ -372,7 +406,8 @@
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateBooleanValue(
-                        container.release_channel_delegated()));
+                        container.release_channel_delegated()),
+                    NULL);
     }
   }
 
@@ -382,7 +417,8 @@
       policies->Set(key::kDeviceAutoUpdateDisabled,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    Value::CreateBooleanValue(container.update_disabled()));
+                    Value::CreateBooleanValue(container.update_disabled()),
+                    NULL);
     }
 
     if (container.has_target_version_prefix()) {
@@ -390,7 +426,8 @@
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateStringValue(
-                        container.target_version_prefix()));
+                        container.target_version_prefix()),
+                    NULL);
     }
 
     // target_version_display_name is not actually a policy, but a display
@@ -401,7 +438,8 @@
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateIntegerValue(
-                        container.scatter_factor_in_seconds()));
+                        container.scatter_factor_in_seconds()),
+                    NULL);
     }
 
     if (container.allowed_connection_types_size()) {
@@ -417,14 +455,16 @@
       policies->Set(key::kDeviceUpdateAllowedConnectionTypes,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    allowed_connection_types);
+                    allowed_connection_types,
+                    NULL);
     }
 
     if (container.has_reboot_after_update()) {
       policies->Set(key::kRebootAfterUpdate,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    Value::CreateBooleanValue(container.reboot_after_update()));
+                    Value::CreateBooleanValue(container.reboot_after_update()),
+                    NULL);
     }
   }
 }
@@ -441,7 +481,8 @@
           POLICY_LEVEL_MANDATORY,
           POLICY_SCOPE_MACHINE,
           Value::CreateBooleanValue(
-              container.login_screen_default_large_cursor_enabled()));
+              container.login_screen_default_large_cursor_enabled()),
+          NULL);
     }
 
     if (container.has_login_screen_default_spoken_feedback_enabled()) {
@@ -450,7 +491,8 @@
           POLICY_LEVEL_MANDATORY,
           POLICY_SCOPE_MACHINE,
           Value::CreateBooleanValue(
-              container.login_screen_default_spoken_feedback_enabled()));
+              container.login_screen_default_spoken_feedback_enabled()),
+          NULL);
     }
 
     if (container.has_login_screen_default_high_contrast_enabled()) {
@@ -459,7 +501,8 @@
           POLICY_LEVEL_MANDATORY,
           POLICY_SCOPE_MACHINE,
           Value::CreateBooleanValue(
-              container.login_screen_default_high_contrast_enabled()));
+              container.login_screen_default_high_contrast_enabled()),
+          NULL);
     }
 
     if (container.has_login_screen_default_screen_magnifier_type()) {
@@ -468,7 +511,8 @@
           POLICY_LEVEL_MANDATORY,
           POLICY_SCOPE_MACHINE,
           DecodeIntegerValue(
-              container.login_screen_default_screen_magnifier_type()));
+              container.login_screen_default_screen_magnifier_type()),
+          NULL);
     }
   }
 }
@@ -482,7 +526,8 @@
       policies->Set(key::kDevicePolicyRefreshRate,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    DecodeIntegerValue(container.device_policy_refresh_rate()));
+                    DecodeIntegerValue(container.device_policy_refresh_rate()),
+                    NULL);
     }
   }
 
@@ -492,7 +537,8 @@
       policies->Set(key::kDeviceMetricsReportingEnabled,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    Value::CreateBooleanValue(container.metrics_enabled()));
+                    Value::CreateBooleanValue(container.metrics_enabled()),
+                    NULL);
     }
   }
 
@@ -508,7 +554,8 @@
     policies->Set(key::kDeviceStartUpUrls,
                   POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_MACHINE,
-                  urls);
+                  urls,
+                  NULL);
   }
 
   if (policy.has_system_timezone()) {
@@ -517,7 +564,8 @@
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateStringValue(
-                        policy.system_timezone().timezone()));
+                        policy.system_timezone().timezone()),
+                    NULL);
     }
   }
 
@@ -529,7 +577,8 @@
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateBooleanValue(
-                        container.allow_redeem_offers()));
+                        container.allow_redeem_offers()),
+                    NULL);
     }
   }
 
@@ -539,7 +588,8 @@
       policies->Set(key::kUptimeLimit,
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
-                    DecodeIntegerValue(container.uptime_limit()));
+                    DecodeIntegerValue(container.uptime_limit()),
+                    NULL);
     }
   }
 
@@ -555,7 +605,8 @@
     policies->Set(key::kDeviceStartUpFlags,
                   POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_MACHINE,
-                  flags);
+                  flags,
+                  NULL);
   }
 
   if (policy.has_variations_parameter()) {
@@ -564,7 +615,8 @@
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateStringValue(
-                        policy.variations_parameter().parameter()));
+                        policy.variations_parameter().parameter()),
+                    NULL);
     }
   }
 
@@ -574,7 +626,8 @@
                     POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE,
                     Value::CreateBooleanValue(
-                        policy.attestation_settings().attestation_enabled()));
+                        policy.attestation_settings().attestation_enabled()),
+                    NULL);
     }
   }
 }
diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc
index 2c31a3a..4df62a7 100644
--- a/chrome/browser/chromeos/policy/device_status_collector.cc
+++ b/chrome/browser/chromeos/policy/device_status_collector.cc
@@ -15,17 +15,21 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
 #include "chrome/browser/chromeos/system/statistics_provider.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/network/device_state.h"
+#include "chromeos/network/network_handler.h"
+#include "chromeos/network/network_state_handler.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
 
 using base::Time;
 using base::TimeDelta;
@@ -48,20 +52,14 @@
 
 const int64 kMillisecondsPerDay = Time::kMicrosecondsPerDay / 1000;
 
+// Keys for the geolocation status dictionary in local state.
 const char kLatitude[] = "latitude";
-
 const char kLongitude[] = "longitude";
-
 const char kAltitude[] = "altitude";
-
 const char kAccuracy[] = "accuracy";
-
 const char kAltitudeAccuracy[] = "altitude_accuracy";
-
 const char kHeading[] = "heading";
-
 const char kSpeed[] = "speed";
-
 const char kTimestamp[] = "timestamp";
 
 // Determine the day key (milliseconds since epoch for corresponding day in UTC)
@@ -134,6 +132,7 @@
       report_activity_times_(false),
       report_boot_mode_(false),
       report_location_(false),
+      report_network_interfaces_(false),
       context_(new Context()) {
   if (location_update_requester) {
     location_update_requester_ = *location_update_requester;
@@ -154,6 +153,8 @@
                                       this);
   cros_settings_->AddSettingsObserver(chromeos::kReportDeviceBootMode, this);
   cros_settings_->AddSettingsObserver(chromeos::kReportDeviceLocation, this);
+  cros_settings_->AddSettingsObserver(chromeos::kReportDeviceNetworkInterfaces,
+                                      this);
 
   // The last known location is persisted in local state. This makes location
   // information available immediately upon startup and avoids the need to
@@ -196,6 +197,8 @@
                                          this);
   cros_settings_->RemoveSettingsObserver(chromeos::kReportDeviceBootMode, this);
   cros_settings_->RemoveSettingsObserver(chromeos::kReportDeviceLocation, this);
+  cros_settings_->RemoveSettingsObserver(
+      chromeos::kReportDeviceNetworkInterfaces, this);
 }
 
 // static
@@ -230,6 +233,8 @@
       chromeos::kReportDeviceBootMode, &report_boot_mode_);
   cros_settings_->GetBoolean(
       chromeos::kReportDeviceLocation, &report_location_);
+  cros_settings_->GetBoolean(
+      chromeos::kReportDeviceNetworkInterfaces, &report_network_interfaces_);
 
   if (report_location_) {
     ScheduleGeolocationUpdateRequest();
@@ -405,6 +410,49 @@
   }
 }
 
+void DeviceStatusCollector::GetNetworkInterfaces(
+    em::DeviceStatusReportRequest* request) {
+  // Maps flimflam device type strings to proto enum constants.
+  static const struct {
+    const char* type_string;
+    em::NetworkInterface::NetworkDeviceType type_constant;
+  } kDeviceTypeMap[] = {
+    { flimflam::kTypeEthernet,  em::NetworkInterface::TYPE_ETHERNET,  },
+    { flimflam::kTypeWifi,      em::NetworkInterface::TYPE_WIFI,      },
+    { flimflam::kTypeWimax,     em::NetworkInterface::TYPE_WIMAX,     },
+    { flimflam::kTypeBluetooth, em::NetworkInterface::TYPE_BLUETOOTH, },
+    { flimflam::kTypeCellular,  em::NetworkInterface::TYPE_CELLULAR,  },
+  };
+
+  chromeos::NetworkStateHandler::DeviceStateList device_list;
+  chromeos::NetworkHandler::Get()->network_state_handler()->GetDeviceList(
+      &device_list);
+
+  chromeos::NetworkStateHandler::DeviceStateList::const_iterator device;
+  for (device = device_list.begin(); device != device_list.end(); ++device) {
+    // Determine the type enum constant for |device|.
+    size_t type_idx = 0;
+    for (; type_idx < ARRAYSIZE_UNSAFE(kDeviceTypeMap); ++type_idx) {
+      if ((*device)->type() == kDeviceTypeMap[type_idx].type_string)
+        break;
+    }
+
+    // If the type isn't in |kDeviceTypeMap|, the interface is not relevant for
+    // reporting. This filters out VPN devices.
+    if (type_idx >= ARRAYSIZE_UNSAFE(kDeviceTypeMap))
+      continue;
+
+    em::NetworkInterface* interface = request->add_network_interface();
+    interface->set_type(kDeviceTypeMap[type_idx].type_constant);
+    if (!(*device)->mac_address().empty())
+      interface->set_mac_address((*device)->mac_address());
+    if (!(*device)->meid().empty())
+      interface->set_meid((*device)->meid());
+    if (!(*device)->imei().empty())
+      interface->set_imei((*device)->imei());
+  }
+}
+
 void DeviceStatusCollector::GetStatus(em::DeviceStatusReportRequest* request) {
   // TODO(mnissler): Remove once the old cloud policy stack is retired. The old
   // stack doesn't support reporting successful submissions back to here, so
@@ -427,6 +475,9 @@
   if (report_location_)
     GetLocation(status);
 
+  if (report_network_interfaces_)
+    GetNetworkInterfaces(status);
+
   return true;
 }
 
diff --git a/chrome/browser/chromeos/policy/device_status_collector.h b/chrome/browser/chromeos/policy/device_status_collector.h
index 2144019..b19ed94 100644
--- a/chrome/browser/chromeos/policy/device_status_collector.h
+++ b/chrome/browser/chromeos/policy/device_status_collector.h
@@ -38,8 +38,8 @@
 class DeviceStatusReportRequest;
 }
 
-class PrefService;
 class PrefRegistrySimple;
+class PrefService;
 
 namespace policy {
 
@@ -145,6 +145,8 @@
       enterprise_management::DeviceStatusReportRequest* request);
   void GetLocation(
       enterprise_management::DeviceStatusReportRequest* request);
+  void GetNetworkInterfaces(
+      enterprise_management::DeviceStatusReportRequest* request);
 
   // Update the cached values of the reporting settings.
   void UpdateReportingSettings();
@@ -204,6 +206,7 @@
   bool report_activity_times_;
   bool report_boot_mode_;
   bool report_location_;
+  bool report_network_interfaces_;
 
   scoped_refptr<Context> context_;
 
diff --git a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
index 12af15e..1d16d25 100644
--- a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
@@ -10,6 +10,7 @@
 #include "base/message_loop.h"
 #include "base/prefs/pref_service.h"
 #include "base/prefs/testing_pref_service.h"
+#include "base/run_loop.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
@@ -20,12 +21,16 @@
 #include "chrome/browser/chromeos/system/statistics_provider.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/shill_device_client.h"
+#include "chromeos/network/network_handler.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/geolocation_provider.h"
 #include "content/public/test/test_browser_thread.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
 
 using ::testing::DoAll;
 using ::testing::NotNull;
@@ -582,4 +587,119 @@
   CheckThatALocationErrorIsReported();
 }
 
+// Fake device state.
+struct FakeDeviceData {
+  const char* device_path;
+  const char* type;
+  const char* object_path;
+  const char* mac_address;
+  const char* meid;
+  const char* imei;
+  int expected_type; // proto enum type value, -1 for not present.
+};
+
+static const FakeDeviceData kFakeDevices[] = {
+  { "/device/ethernet", flimflam::kTypeEthernet, "ethernet",
+    "112233445566", "", "",
+    em::NetworkInterface::TYPE_ETHERNET },
+  { "/device/cellular1", flimflam::kTypeCellular, "cellular1",
+    "abcdefabcdef", "A10000009296F2", "",
+    em::NetworkInterface::TYPE_CELLULAR },
+  { "/device/cellular2", flimflam::kTypeCellular, "cellular2",
+    "abcdefabcdef", "", "352099001761481",
+    em::NetworkInterface::TYPE_CELLULAR },
+  { "/device/wifi", flimflam::kTypeWifi, "wifi",
+    "aabbccddeeff", "", "",
+    em::NetworkInterface::TYPE_WIFI },
+  { "/device/bluetooth", flimflam::kTypeBluetooth, "bluetooth",
+    "", "", "",
+    em::NetworkInterface::TYPE_BLUETOOTH },
+  { "/device/vpn", flimflam::kTypeVPN, "vpn",
+    "", "", "",
+    -1 },
+};
+
+class DeviceStatusCollectorNetworkInterfacesTest
+    : public DeviceStatusCollectorTest {
+ protected:
+  virtual void SetUp() OVERRIDE {
+    chromeos::DBusThreadManager::InitializeWithStub();
+    chromeos::NetworkHandler::Initialize();
+    chromeos::ShillDeviceClient::TestInterface* test_device_client =
+        chromeos::DBusThreadManager::Get()->GetShillDeviceClient()->
+            GetTestInterface();
+    test_device_client->ClearDevices();
+    for (size_t i = 0; i < arraysize(kFakeDevices); ++i) {
+      const FakeDeviceData& dev = kFakeDevices[i];
+      test_device_client->AddDevice(dev.device_path, dev.type,
+                                    dev.object_path);
+      if (*dev.mac_address) {
+        test_device_client->SetDeviceProperty(
+            dev.device_path, flimflam::kAddressProperty,
+            base::StringValue(dev.mac_address));
+      }
+      if (*dev.meid) {
+        test_device_client->SetDeviceProperty(
+            dev.device_path, flimflam::kMeidProperty,
+            base::StringValue(dev.meid));
+      }
+      if (*dev.imei) {
+        test_device_client->SetDeviceProperty(
+            dev.device_path, flimflam::kImeiProperty,
+            base::StringValue(dev.imei));
+      }
+    }
+
+    // Flush out pending state updates.
+    base::RunLoop().RunUntilIdle();
+  }
+
+  virtual void TearDown() OVERRIDE {
+    chromeos::NetworkHandler::Shutdown();
+    chromeos::DBusThreadManager::Shutdown();
+  }
+};
+
+TEST_F(DeviceStatusCollectorNetworkInterfacesTest, NetworkInterfaces) {
+  // No interfaces should be reported if the policy is off.
+  GetStatus();
+  EXPECT_EQ(0, status_.network_interface_size());
+
+  // Switch the policy on and verify the interface list is present.
+  cros_settings_->SetBoolean(chromeos::kReportDeviceNetworkInterfaces, true);
+  GetStatus();
+
+  int count = 0;
+  for (size_t i = 0; i < arraysize(kFakeDevices); ++i) {
+    const FakeDeviceData& dev = kFakeDevices[i];
+    if (dev.expected_type == -1)
+      continue;
+
+    // Find the corresponding entry in reporting data.
+    bool found_match = false;
+    google::protobuf::RepeatedPtrField<em::NetworkInterface>::const_iterator
+        iface;
+    for (iface = status_.network_interface().begin();
+         iface != status_.network_interface().end();
+         ++iface) {
+      // Check whether type, field presence and field values match.
+      if (dev.expected_type == iface->type() &&
+          iface->has_mac_address() == !!*dev.mac_address &&
+          iface->has_meid() == !!*dev.meid &&
+          iface->has_imei() == !!*dev.imei &&
+          iface->mac_address() == dev.mac_address &&
+          iface->meid() == dev.meid &&
+          iface->imei() == dev.imei) {
+        found_match = true;
+        break;
+      }
+    }
+
+    EXPECT_TRUE(found_match) << "No matching interface for fake device " << i;
+    count++;
+  }
+
+  EXPECT_EQ(count, status_.network_interface_size());
+}
+
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/enterprise_install_attributes.cc b/chrome/browser/chromeos/policy/enterprise_install_attributes.cc
index 0f04454..c4eef36 100644
--- a/chrome/browser/chromeos/policy/enterprise_install_attributes.cc
+++ b/chrome/browser/chromeos/policy/enterprise_install_attributes.cc
@@ -100,7 +100,7 @@
 
 void EnterpriseInstallAttributes::ReadCacheFile(
     const base::FilePath& cache_file) {
-  if (device_locked_ || !file_util::PathExists(cache_file))
+  if (device_locked_ || !base::PathExists(cache_file))
     return;
 
   device_locked_ = true;
diff --git a/chrome/browser/chromeos/policy/login_profile_policy_provider.cc b/chrome/browser/chromeos/policy/login_profile_policy_provider.cc
index da88bea..5eefa6b 100644
--- a/chrome/browser/chromeos/policy/login_profile_policy_provider.cc
+++ b/chrome/browser/chromeos/policy/login_profile_policy_provider.cc
@@ -7,8 +7,10 @@
 #include <string>
 
 #include "base/bind.h"
+#include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/values.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_bundle.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_types.h"
@@ -30,7 +32,8 @@
     user_policy_map->Set(user_policy,
                          POLICY_LEVEL_RECOMMENDED,
                          POLICY_SCOPE_USER,
-                         value->DeepCopy());
+                         value->DeepCopy(),
+                         NULL);
   }
 }
 
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_impl.cc b/chrome/browser/chromeos/policy/network_configuration_updater_impl.cc
index 5fa896c..fae76ac 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_impl.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_impl.cc
@@ -94,7 +94,7 @@
 
   base::ListValue network_configs;
   base::ListValue certificates;
-  ParseAndValidateOncForImport(
+  chromeos::onc::ParseAndValidateOncForImport(
       onc_blob, onc_source, "", &network_configs, &certificates);
 
   chromeos::CertificateHandler::CertsByGUID imported_server_and_ca_certs;
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros.cc b/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros.cc
index ea60fc2..654382e 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros.cc
@@ -162,7 +162,7 @@
 
   base::ListValue network_configs;
   base::ListValue certificates;
-  ParseAndValidateOncForImport(
+  chromeos::onc::ParseAndValidateOncForImport(
       onc_blob, onc_source, "", &network_configs, &certificates);
 
   chromeos::CertificateHandler::CertsByGUID imported_server_and_ca_certs;
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros_unittest.cc b/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros_unittest.cc
index afbdb9f..3376538 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros_unittest.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros_unittest.cc
@@ -4,12 +4,14 @@
 
 #include "chrome/browser/chromeos/policy/network_configuration_updater_impl_cros.h"
 
+#include "base/callback.h"
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "base/run_loop.h"
 #include "base/values.h"
 #include "chrome/browser/chromeos/cros/mock_network_library.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_service_impl.h"
@@ -172,7 +174,7 @@
 
   PolicyMap policy;
   policy.Set(key::kOpenNetworkConfiguration, POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, Value::CreateStringValue(onc_policy));
+             POLICY_SCOPE_USER, Value::CreateStringValue(onc_policy), NULL);
   UpdateProviderPolicy(policy);
 
   EXPECT_CALL(network_library_, AddNetworkProfileObserver(_));
@@ -224,7 +226,7 @@
 TEST_P(NetworkConfigurationUpdaterTestWithParam, InitialUpdates) {
   PolicyMap policy;
   policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             Value::CreateStringValue(kFakeONC));
+             Value::CreateStringValue(kFakeONC), NULL);
   UpdateProviderPolicy(policy);
 
   EXPECT_CALL(network_library_, AddNetworkProfileObserver(_));
@@ -380,7 +382,7 @@
 
   PolicyMap policy;
   policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             Value::CreateStringValue(kFakeONC));
+             Value::CreateStringValue(kFakeONC), NULL);
   UpdateProviderPolicy(policy);
   Mock::VerifyAndClearExpectations(&network_library_);
   Mock::VerifyAndClearExpectations(&certificate_handler);
diff --git a/chrome/browser/chromeos/policy/power_policy_browsertest.cc b/chrome/browser/chromeos/policy/power_policy_browsertest.cc
index 72d4a44..718d31e 100644
--- a/chrome/browser/chromeos/policy/power_policy_browsertest.cc
+++ b/chrome/browser/chromeos/policy/power_policy_browsertest.cc
@@ -4,11 +4,13 @@
 
 #include <string>
 
+#include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/run_loop.h"
 #include "base/values.h"
 #include "chrome/browser/extensions/api/power/power_api_manager.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_types.h"
@@ -68,7 +70,7 @@
     base::Value* user_policy_value) {
   PolicyMap policy_map;
   policy_map.Set(user_policy_name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 user_policy_value);
+                 user_policy_value, NULL);
   provider_.UpdateChromePolicy(policy_map);
   base::RunLoop().RunUntilIdle();
 }
diff --git a/chrome/browser/chromeos/policy/proxy_policy_provider_unittest.cc b/chrome/browser/chromeos/policy/proxy_policy_provider_unittest.cc
index 7a28f94..922c547 100644
--- a/chrome/browser/chromeos/policy/proxy_policy_provider_unittest.cc
+++ b/chrome/browser/chromeos/policy/proxy_policy_provider_unittest.cc
@@ -3,7 +3,9 @@
 // found in the LICENSE file.
 
 #include "base/basictypes.h"
+#include "base/callback.h"
 #include "chrome/browser/chromeos/policy/proxy_policy_provider.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -50,7 +52,8 @@
       .Set("policy",
            POLICY_LEVEL_MANDATORY,
            POLICY_SCOPE_USER,
-           Value::CreateStringValue("value"));
+           Value::CreateStringValue("value"),
+           NULL);
   mock_provider_.UpdatePolicy(CopyBundle(bundle));
 
   EXPECT_CALL(observer_, OnUpdatePolicy(&proxy_provider_));
@@ -63,7 +66,8 @@
       .Set("policy",
            POLICY_LEVEL_MANDATORY,
            POLICY_SCOPE_USER,
-           Value::CreateStringValue("new value"));
+           Value::CreateStringValue("new value"),
+           NULL);
   mock_provider_.UpdatePolicy(CopyBundle(bundle));
   Mock::VerifyAndClearExpectations(&observer_);
   EXPECT_TRUE(bundle.Equals(proxy_provider_.policies()));
diff --git a/chrome/browser/chromeos/policy/recommendation_restorer.cc b/chrome/browser/chromeos/policy/recommendation_restorer.cc
index ba2945c..aaf19e0 100644
--- a/chrome/browser/chromeos/policy/recommendation_restorer.cc
+++ b/chrome/browser/chromeos/policy/recommendation_restorer.cc
@@ -13,9 +13,9 @@
 #include "base/prefs/pref_service.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
@@ -79,7 +79,7 @@
   }
 }
 
-void RecommendationRestorer::OnUserActivity() {
+void RecommendationRestorer::OnUserActivity(const ui::Event* event) {
   if (restore_timer_.IsRunning())
     restore_timer_.Reset();
 }
diff --git a/chrome/browser/chromeos/policy/recommendation_restorer.h b/chrome/browser/chromeos/policy/recommendation_restorer.h
index 1d67159..0f192de 100644
--- a/chrome/browser/chromeos/policy/recommendation_restorer.h
+++ b/chrome/browser/chromeos/policy/recommendation_restorer.h
@@ -41,8 +41,8 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
-  // ash::UserActivityObserver::Observer:
-  virtual void OnUserActivity() OVERRIDE;
+  // ash::UserActivityObserver:
+  virtual void OnUserActivity(const ui::Event* event) OVERRIDE;
 
   // If a recommended value and a user setting exist for |pref_name|, clears the
   // user setting so that the recommended value can take effect. If
diff --git a/chrome/browser/chromeos/policy/recommendation_restorer_unittest.cc b/chrome/browser/chromeos/policy/recommendation_restorer_unittest.cc
index c5d5b3a..664681e 100644
--- a/chrome/browser/chromeos/policy/recommendation_restorer_unittest.cc
+++ b/chrome/browser/chromeos/policy/recommendation_restorer_unittest.cc
@@ -13,11 +13,11 @@
 #include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/policy/recommendation_restorer_factory.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_pref_service_syncable.h"
@@ -43,6 +43,9 @@
   // testing::Test:
   virtual void SetUp() OVERRIDE;
 
+  void RegisterUserProfilePrefs();
+  void RegisterLoginProfilePrefs();
+
   void SetRecommendedValues();
   void SetUserSettings();
 
@@ -91,7 +94,6 @@
       runner_handler_(runner_),
       prefs_owner_(prefs_),
       profile_manager_(TestingBrowserProcess::GetGlobal()) {
-  chrome::RegisterUserPrefs(prefs_->registry());
 }
 
 void RecommendationRestorerTest::SetUp() {
@@ -99,6 +101,14 @@
   ASSERT_TRUE(profile_manager_.SetUp());
 }
 
+void RecommendationRestorerTest::RegisterUserProfilePrefs() {
+  chrome::RegisterUserProfilePrefs(prefs_->registry());
+}
+
+void RecommendationRestorerTest::RegisterLoginProfilePrefs() {
+  chrome::RegisterLoginProfilePrefs(prefs_->registry());
+}
+
 void RecommendationRestorerTest::SetRecommendedValues() {
   recommended_prefs_->SetBoolean(prefs::kLargeCursorEnabled, false);
   recommended_prefs_->SetBoolean(prefs::kSpokenFeedbackEnabled, false);
@@ -141,7 +151,7 @@
 
 void RecommendationRestorerTest::NotifyOfUserActivity() {
   ASSERT_TRUE(restorer_);
-  restorer_->OnUserActivity();
+  restorer_->OnUserActivity(NULL);
 }
 
 void RecommendationRestorerTest::VerifyPrefFollowsUser(
@@ -218,6 +228,7 @@
   // it does not start listening for any notifications, does not clear user
   // settings on initialization and does not start a timer that will clear user
   // settings eventually.
+  RegisterUserProfilePrefs();
   SetRecommendedValues();
   SetUserSettings();
 
@@ -232,6 +243,7 @@
   // RecommendationRestorer is created for the login profile, it does not clear
   // user settings on initialization and does not start a timer that will clear
   // user settings eventually.
+  RegisterLoginProfilePrefs();
   SetUserSettings();
 
   CreateLoginProfile();
@@ -243,6 +255,7 @@
   // Verifies that when recommended values have been set and a
   // RecommendationRestorer is created for the login profile, it clears user
   // settings on initialization.
+  RegisterLoginProfilePrefs();
   SetRecommendedValues();
   SetUserSettings();
 
@@ -254,6 +267,7 @@
 TEST_F(RecommendationRestorerTest, RestoreOnRecommendationChangeOnLoginScreen) {
   // Verifies that if recommended values change while the login screen is being
   // shown, a timer is started that will clear user settings eventually.
+  RegisterLoginProfilePrefs();
   SetUserSettings();
 
   CreateLoginProfile();
@@ -305,6 +319,7 @@
 TEST_F(RecommendationRestorerTest, RestoreOnRecommendationChangeInUserSession) {
   // Verifies that if recommended values change while a user session is in
   // progress, user settings are cleared immediately.
+  RegisterLoginProfilePrefs();
   SetUserSettings();
 
   CreateLoginProfile();
@@ -348,6 +363,7 @@
   // Verifies that if no recommended values have been set and user settings
   // change, the user settings are not cleared immediately and no timer is
   // started that will clear the user settings eventually.
+  RegisterLoginProfilePrefs();
   CreateLoginProfile();
 
   prefs_->SetBoolean(prefs::kLargeCursorEnabled, true);
@@ -383,6 +399,7 @@
   // Verifies that if recommended values have been set and user settings change
   // while the login screen is being shown, a timer is started that will clear
   // the user settings eventually.
+  RegisterLoginProfilePrefs();
   SetRecommendedValues();
 
   CreateLoginProfile();
@@ -436,6 +453,7 @@
   // changed and a session is then started, the user settings are cleared
   // immediately and the timer that would have cleared them eventually on the
   // login screen is stopped.
+  RegisterLoginProfilePrefs();
   SetRecommendedValues();
 
   CreateLoginProfile();
@@ -450,6 +468,7 @@
   // Verifies that if recommended values have not been set, user settings have
   // changed and a session is then started, the user settings are not cleared
   // immediately.
+  RegisterLoginProfilePrefs();
   CreateLoginProfile();
   SetUserSettings();
 
@@ -460,6 +479,8 @@
 
 TEST_F(RecommendationRestorerTest, UserActivityResetsTimer) {
   // Verifies that user activity resets the timer which clears user settings.
+  RegisterLoginProfilePrefs();
+
   recommended_prefs_->SetBoolean(prefs::kLargeCursorEnabled, false);
 
   CreateLoginProfile();
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
index fce36a9..78f3aff 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/basictypes.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "base/prefs/pref_registry_simple.h"
@@ -21,6 +22,7 @@
 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h"
 #include "chrome/browser/policy/cloud/mock_device_management_service.h"
 #include "chrome/browser/policy/cloud/resource_cache.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
 #include "chrome/browser/prefs/browser_prefs.h"
@@ -103,7 +105,8 @@
     // Set up a policy map for testing.
     policy_map_.Set("HomepageLocation",
                     POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                    base::Value::CreateStringValue("http://chromium.org"));
+                    base::Value::CreateStringValue("http://chromium.org"),
+                    NULL);
     expected_bundle_.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
         .CopyFrom(policy_map_);
 
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc
index ae9b79c..c6cb989 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc
@@ -409,7 +409,7 @@
 // static
 void UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir(
     const base::FilePath& dir) {
-  if (file_util::PathExists(dir) && !base::Delete(dir, true))
+  if (base::PathExists(dir) && !base::DeleteFile(dir, true))
     LOG(ERROR) << "Failed to remove cache dir " << dir.value();
 }
 
@@ -430,7 +430,7 @@
 // static
 void UserCloudPolicyStoreChromeOS::LoadPolicyKey(const base::FilePath& path,
                                                  std::vector<uint8>* key) {
-  if (!file_util::PathExists(path)) {
+  if (!base::PathExists(path)) {
     // There is no policy key the first time that a user fetches policy. If
     // |path| does not exist then that is the most likely scenario, so there's
     // no need to sample a failure.
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc
index ec73418..01bfd31 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc
@@ -160,7 +160,7 @@
       previous_policy.Set(key::kHomepageLocation,
                           POLICY_LEVEL_MANDATORY,
                           POLICY_SCOPE_USER,
-                          base::Value::CreateStringValue(previous_value));
+                          base::Value::CreateStringValue(previous_value), NULL);
     }
     EXPECT_TRUE(previous_policy.Equals(store_->policy_map()));
     EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
@@ -239,7 +239,7 @@
 
 TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStore) {
   // Start without any public key to trigger the initial key checks.
-  ASSERT_TRUE(base::Delete(user_policy_key_file(), false));
+  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
   // Make the policy blob contain a new public key.
   policy_.set_new_signing_key(PolicyBuilder::CreateTestNewSigningKey());
   policy_.Build();
@@ -383,7 +383,7 @@
 
 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadNoKey) {
   // The loaded policy can't be verified without the public key.
-  ASSERT_TRUE(base::Delete(user_policy_key_file(), false));
+  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
   ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
   ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
   VerifyStoreHasValidationError();
@@ -480,7 +480,7 @@
 
 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationAndStoreNew) {
   // Start without an existing public key.
-  ASSERT_TRUE(base::Delete(user_policy_key_file(), false));
+  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
 
   std::string data;
   em::CachedCloudPolicyResponse cached_policy;
@@ -502,7 +502,7 @@
             store_->policy()->SerializeAsString());
   VerifyPolicyMap(kDefaultHomepage);
   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
-  EXPECT_TRUE(file_util::PathExists(policy_file()));
+  EXPECT_TRUE(base::PathExists(policy_file()));
 
   // Now store a new policy using the new homepage location.
   const char kNewHomepage[] = "http://google.com";
@@ -516,7 +516,7 @@
   VerifyPolicyMap(kNewHomepage);
 
   // Verify that the legacy cache has been removed.
-  EXPECT_FALSE(file_util::PathExists(policy_file()));
+  EXPECT_FALSE(base::PathExists(policy_file()));
 }
 
 }  // namespace
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.cc b/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.cc
index c441c5a..cba9426 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.h"
 
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
 #include "chrome/browser/signin/token_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 
 namespace policy {
diff --git a/chrome/browser/chromeos/policy/user_policy_disk_cache.cc b/chrome/browser/chromeos/policy/user_policy_disk_cache.cc
index 456e1c7..bb93e89 100644
--- a/chrome/browser/chromeos/policy/user_policy_disk_cache.cc
+++ b/chrome/browser/chromeos/policy/user_policy_disk_cache.cc
@@ -66,7 +66,7 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
 
   em::CachedCloudPolicyResponse cached_response;
-  if (!file_util::PathExists(backing_file_path_)) {
+  if (!base::PathExists(backing_file_path_)) {
     LoadDone(LOAD_RESULT_NOT_FOUND, cached_response);
     return;
   }
diff --git a/chrome/browser/chromeos/policy/user_policy_token_loader.cc b/chrome/browser/chromeos/policy/user_policy_token_loader.cc
index 666e2be..b20c4d2 100644
--- a/chrome/browser/chromeos/policy/user_policy_token_loader.cc
+++ b/chrome/browser/chromeos/policy/user_policy_token_loader.cc
@@ -58,7 +58,7 @@
   std::string device_token;
   std::string device_id;
 
-  if (file_util::PathExists(cache_file_)) {
+  if (base::PathExists(cache_file_)) {
     std::string data;
     em::DeviceCredentials device_credentials;
     if (file_util::ReadFileToString(cache_file_, &data) &&
diff --git a/chrome/browser/chromeos/power/power_button_observer.cc b/chrome/browser/chromeos/power/power_button_observer.cc
index 38874d9..f7b407b 100644
--- a/chrome/browser/chromeos/power/power_button_observer.cc
+++ b/chrome/browser/chromeos/power/power_button_observer.cc
@@ -9,9 +9,9 @@
 #include "ash/system/user/login_status.h"
 #include "ash/wm/power_button_controller.h"
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/screen_locker.h"
 #include "chrome/browser/chromeos/power/session_state_controller_delegate_chromeos.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/chromeos/power/user_activity_notifier.cc b/chrome/browser/chromeos/power/user_activity_notifier.cc
index 2273963..48fa344 100644
--- a/chrome/browser/chromeos/power/user_activity_notifier.cc
+++ b/chrome/browser/chromeos/power/user_activity_notifier.cc
@@ -8,6 +8,9 @@
 #include "ash/wm/user_activity_detector.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/power_manager_client.h"
+#include "ui/base/events/event.h"
+#include "ui/base/events/event_constants.h"
+#include "ui/base/keycodes/keyboard_codes_posix.h"
 
 namespace {
 
@@ -26,13 +29,27 @@
   ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this);
 }
 
-void UserActivityNotifier::OnUserActivity() {
+void UserActivityNotifier::OnUserActivity(const ui::Event* event) {
   base::TimeTicks now = base::TimeTicks::Now();
   // InSeconds() truncates rather than rounding, so it's fine for this
   // comparison.
   if (last_notify_time_.is_null() ||
       (now - last_notify_time_).InSeconds() >= kNotifyIntervalSec) {
-    DBusThreadManager::Get()->GetPowerManagerClient()->NotifyUserActivity();
+    power_manager::UserActivityType type = power_manager::USER_ACTIVITY_OTHER;
+    if (event && event->type() == ui::ET_KEY_PRESSED) {
+      switch (static_cast<const ui::KeyEvent*>(event)->key_code()) {
+        case ui::VKEY_BRIGHTNESS_UP:
+          type = power_manager::USER_ACTIVITY_BRIGHTNESS_UP_KEY_PRESS;
+          break;
+        case ui::VKEY_BRIGHTNESS_DOWN:
+          type = power_manager::USER_ACTIVITY_BRIGHTNESS_DOWN_KEY_PRESS;
+          break;
+        default:
+          break;
+      }
+    }
+
+    DBusThreadManager::Get()->GetPowerManagerClient()->NotifyUserActivity(type);
     last_notify_time_ = now;
   }
 }
diff --git a/chrome/browser/chromeos/power/user_activity_notifier.h b/chrome/browser/chromeos/power/user_activity_notifier.h
index f1189ef..e44a42b 100644
--- a/chrome/browser/chromeos/power/user_activity_notifier.h
+++ b/chrome/browser/chromeos/power/user_activity_notifier.h
@@ -19,7 +19,7 @@
   virtual ~UserActivityNotifier();
 
   // ash::UserActivityObserver implementation.
-  virtual void OnUserActivity() OVERRIDE;
+  virtual void OnUserActivity(const ui::Event* event) OVERRIDE;
 
  private:
   // Last time that the power manager was notified.
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index c73dadf..2971210 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/chromeos/preferences.h"
 
 #include "ash/magnifier/magnifier_constants.h"
-#include "ash/shell_delegate.h"
+#include "ash/shell.h"
 #include "base/chromeos/chromeos_version.h"
 #include "base/command_line.h"
 #include "base/i18n/time_formatting.h"
@@ -16,6 +16,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/browser/chromeos/input_method/input_method_util.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/download/download_util.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_switches.h"
@@ -35,27 +35,43 @@
 #include "chromeos/ime/input_method_manager.h"
 #include "chromeos/ime/xkeyboard.h"
 #include "components/user_prefs/pref_registry_syncable.h"
-#include "googleurl/src/gurl.h"
 #include "third_party/icu/public/i18n/unicode/timezone.h"
 #include "ui/base/events/event_constants.h"
 #include "ui/base/events/event_utils.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
 static const char kFallbackInputMethodLocale[] = "en-US";
 
+// TODO(achuith): Remove deprecated pref in M31. crbug.com/223480.
+static const char kEnableTouchpadThreeFingerSwipe[] =
+    "settings.touchpad.enable_three_finger_swipe";
+
 Preferences::Preferences()
     : prefs_(NULL),
       input_method_manager_(input_method::InputMethodManager::Get()) {
+  // Do not observe shell, if there is no shell instance; e.g., in some unit
+  // tests.
+  if (ash::Shell::HasInstance())
+    ash::Shell::GetInstance()->AddShellObserver(this);
 }
 
 Preferences::Preferences(input_method::InputMethodManager* input_method_manager)
     : prefs_(NULL),
       input_method_manager_(input_method_manager) {
+  // Do not observe shell, if there is no shell instance; e.g., in some unit
+  // tests.
+  if (ash::Shell::HasInstance())
+    ash::Shell::GetInstance()->AddShellObserver(this);
 }
 
 Preferences::~Preferences() {
   prefs_->RemoveObserver(this);
+  // If shell instance is destoryed before this preferences instance, there is
+  // no need to remove this shell observer.
+  if (ash::Shell::HasInstance())
+    ash::Shell::GetInstance()->RemoveShellObserver(this);
 }
 
 // static
@@ -66,7 +82,7 @@
 }
 
 // static
-void Preferences::RegisterUserPrefs(
+void Preferences::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   std::string hardware_keyboard_id;
   // TODO(yusukes): Remove the runtime hack.
@@ -94,10 +110,6 @@
       false,
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
   registry->RegisterBooleanPref(
-      prefs::kEnableTouchpadThreeFingerSwipe,
-      false,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-  registry->RegisterBooleanPref(
       prefs::kNaturalScroll,
       CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kNaturalScrollDefault),
@@ -406,6 +418,17 @@
       prefs::kTermsOfServiceURL,
       "",
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+
+  // TODO(achuith): Remove deprecated pref in M31. crbug.com/223480.
+  registry->RegisterBooleanPref(
+      kEnableTouchpadThreeFingerSwipe,
+      false,
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+
+  registry->RegisterBooleanPref(
+      prefs::kTouchHudProjectionEnabled,
+      false,
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 }
 
 void Preferences::InitUserPrefs(PrefServiceSyncable* prefs) {
@@ -418,8 +441,6 @@
   tap_dragging_enabled_.Init(prefs::kTapDraggingEnabled, prefs, callback);
   three_finger_click_enabled_.Init(prefs::kEnableTouchpadThreeFingerClick,
       prefs, callback);
-  three_finger_swipe_enabled_.Init(prefs::kEnableTouchpadThreeFingerSwipe,
-      prefs, callback);
   natural_scroll_.Init(prefs::kNaturalScroll, prefs, callback);
   a11y_spoken_feedback_enabled_.Init(prefs::kSpokenFeedbackEnabled,
                                      prefs, callback);
@@ -445,6 +466,8 @@
                                    prefs, callback);
   save_file_default_directory_.Init(prefs::kSaveFileDefaultDirectory,
                                     prefs, callback);
+  touch_hud_projection_enabled_.Init(prefs::kTouchHudProjectionEnabled,
+                                     prefs, callback);
   primary_mouse_button_right_.Init(prefs::kPrimaryMouseButtonRight,
                                    prefs, callback);
   preferred_languages_.Init(prefs::kLanguagePreferredLanguages,
@@ -539,6 +562,9 @@
       prefs::kPowerPresentationScreenDimDelayFactor, prefs, callback);
   power_user_activity_screen_dim_delay_factor_.Init(
       prefs::kPowerUserActivityScreenDimDelayFactor, prefs, callback);
+
+  // TODO(achuith): Remove deprecated pref in M31. crbug.com/223480.
+  prefs->ClearPref(kEnableTouchpadThreeFingerSwipe);
 }
 
 void Preferences::Init(PrefServiceSyncable* prefs) {
@@ -602,14 +628,6 @@
     else
       UMA_HISTOGRAM_BOOLEAN("Touchpad.ThreeFingerClick.Started", enabled);
   }
-  if (!pref_name || *pref_name == prefs::kEnableTouchpadThreeFingerSwipe) {
-    const bool enabled = three_finger_swipe_enabled_.GetValue();
-    system::touchpad_settings::SetThreeFingerSwipe(enabled);
-    if (pref_name)
-      UMA_HISTOGRAM_BOOLEAN("Touchpad.ThreeFingerSwipe.Changed", enabled);
-    else
-      UMA_HISTOGRAM_BOOLEAN("Touchpad.ThreeFingerSwipe.Started", enabled);
-  }
   if (!pref_name || *pref_name == prefs::kNaturalScroll) {
     // Force natural scroll default if we've sync'd and if the cmd line arg is
     // set.
@@ -703,6 +721,10 @@
                           drive::util::ConvertToMyDriveNamespace(pref_path));
     }
   }
+  if (!pref_name || *pref_name == prefs::kTouchHudProjectionEnabled) {
+    const bool enabled = touch_hud_projection_enabled_.GetValue();
+    ash::Shell::GetInstance()->SetTouchHudProjectionEnabled(enabled);
+  }
 
   if (!pref_name || *pref_name == prefs::kLanguagePreferredLanguages) {
     // Unlike kLanguagePreloadEngines and some other input method
@@ -1028,4 +1050,11 @@
   input_method::XKeyboard::SetAutoRepeatRate(rate);
 }
 
+void Preferences::OnTouchHudProjectionToggled(bool enabled) {
+  if (touch_hud_projection_enabled_.GetValue() == enabled)
+    return;
+
+  touch_hud_projection_enabled_.SetValue(enabled);
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/preferences.h b/chrome/browser/chromeos/preferences.h
index e1e3c81..970013d 100644
--- a/chrome/browser/chromeos/preferences.h
+++ b/chrome/browser/chromeos/preferences.h
@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include "ash/shell_observer.h"
 #include "base/compiler_specific.h"
 #include "base/prefs/pref_member.h"
 #include "chrome/browser/chromeos/language_preferences.h"
@@ -31,7 +32,8 @@
 // is first initialized, it will initialize the OS settings to what's stored in
 // the preferences. These include touchpad settings, etc.
 // When the preferences change, we change the settings to reflect the new value.
-class Preferences : public PrefServiceSyncableObserver {
+class Preferences : public PrefServiceSyncableObserver,
+                    public ash::ShellObserver {
  public:
   Preferences();
   explicit Preferences(
@@ -40,7 +42,7 @@
 
   // These method will register the prefs associated with Chrome OS settings.
   static void RegisterPrefs(PrefRegistrySimple* registry);
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // This method will initialize Chrome OS settings to values in user prefs.
   void Init(PrefServiceSyncable* prefs);
@@ -106,6 +108,9 @@
   // PrefServiceSyncableObserver implementation.
   virtual void OnIsSyncingChanged() OVERRIDE;
 
+  // Overriden from ash::ShellObserver.
+  virtual void OnTouchHudProjectionToggled(bool enabled) OVERRIDE;
+
   PrefServiceSyncable* prefs_;
 
   input_method::InputMethodManager* input_method_manager_;
@@ -113,7 +118,6 @@
   BooleanPrefMember tap_to_click_enabled_;
   BooleanPrefMember tap_dragging_enabled_;
   BooleanPrefMember three_finger_click_enabled_;
-  BooleanPrefMember three_finger_swipe_enabled_;
   BooleanPrefMember natural_scroll_;
   BooleanPrefMember vert_edge_scroll_enabled_;
   BooleanPrefMember a11y_spoken_feedback_enabled_;
@@ -132,6 +136,7 @@
   FilePathPrefMember download_default_directory_;
   FilePathPrefMember select_file_last_directory_;
   FilePathPrefMember save_file_default_directory_;
+  BooleanPrefMember touch_hud_projection_enabled_;
 
   // Input method preferences.
   StringPrefMember preferred_languages_;
diff --git a/chrome/browser/chromeos/preferences_unittest.cc b/chrome/browser/chromeos/preferences_unittest.cc
index 888c0b6..cbab4a6 100644
--- a/chrome/browser/chromeos/preferences_unittest.cc
+++ b/chrome/browser/chromeos/preferences_unittest.cc
@@ -56,8 +56,8 @@
 
 TEST(PreferencesTest, TestUpdatePrefOnBrowserScreenDetails) {
   TestingPrefServiceSyncable prefs;
-  Preferences::RegisterUserPrefs(prefs.registry());
-  DownloadPrefs::RegisterUserPrefs(prefs.registry());
+  Preferences::RegisterProfilePrefs(prefs.registry());
+  DownloadPrefs::RegisterProfilePrefs(prefs.registry());
   // kSelectFileLastDirectory is registered for Profile. Here we register it for
   // testing.
   prefs.registry()->RegisterStringPref(
diff --git a/chrome/browser/chromeos/profiles/profile_helper.cc b/chrome/browser/chromeos/profiles/profile_helper.cc
index 3d83458..9ec1de9 100644
--- a/chrome/browser/chromeos/profiles/profile_helper.cc
+++ b/chrome/browser/chromeos/profiles/profile_helper.cc
@@ -8,7 +8,6 @@
 #include "base/command_line.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/sms_observer.h"
@@ -109,7 +108,7 @@
   if (process_startup) {
     static chromeos::SmsObserver* sms_observer =
         new chromeos::SmsObserver();
-    chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
+    chromeos::NetworkLibrary::Get()->
         AddNetworkManagerObserver(sms_observer);
 
     profile->SetupChromeOSEnterpriseExtensionObserver();
diff --git a/chrome/browser/chromeos/proxy_config_service_impl.cc b/chrome/browser/chromeos/proxy_config_service_impl.cc
index 1210319..95f4f19 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl.cc
+++ b/chrome/browser/chromeos/proxy_config_service_impl.cc
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
-#include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
@@ -23,7 +22,6 @@
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
 #include "chromeos/network/onc/onc_utils.h"
-#include "components/user_prefs/pref_registry_syncable.h"
 
 namespace chromeos {
 
@@ -43,15 +41,19 @@
 
 }  // namespace
 
-ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* pref_service)
-    : PrefProxyConfigTrackerImpl(pref_service),
+ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* profile_prefs,
+                                               PrefService* local_state_prefs)
+    : PrefProxyConfigTrackerImpl(profile_prefs ? profile_prefs
+                                               : local_state_prefs),
       active_config_state_(ProxyPrefs::CONFIG_UNSET),
+      profile_prefs_(profile_prefs),
       pointer_factory_(this) {
-
   // Register for notifications of UseSharedProxies user preference.
-  if (pref_service->FindPreference(prefs::kUseSharedProxies)) {
+  if (profile_prefs) {
+    DCHECK(profile_prefs->FindPreference(prefs::kUseSharedProxies));
     use_shared_proxies_.Init(
-        prefs::kUseSharedProxies, pref_service,
+        prefs::kUseSharedProxies,
+        profile_prefs,
         base::Bind(&ProxyConfigServiceImpl::OnUseSharedProxiesChanged,
                    base::Unretained(this)));
   }
@@ -79,24 +81,8 @@
   DetermineEffectiveConfigFromDefaultNetwork();
 }
 
-// static
-void ProxyConfigServiceImpl::RegisterPrefs(PrefRegistrySimple* registry) {
-  // Use shared proxies default to off.  GetUseSharedProxies will return the
-  // correct value based on pre-login and login.
-  registry->RegisterBooleanPref(prefs::kUseSharedProxies, true);
-}
-
-// static
-void ProxyConfigServiceImpl::RegisterUserPrefs(
-    user_prefs::PrefRegistrySyncable* registry) {
-  registry->RegisterBooleanPref(
-      prefs::kUseSharedProxies,
-      true,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-}
-
 void ProxyConfigServiceImpl::OnUseSharedProxiesChanged() {
-  VLOG(1) << "New use-shared-proxies = " << GetUseSharedProxies(prefs());
+  VLOG(1) << "use-shared-proxies pref changed.";
   DetermineEffectiveConfigFromDefaultNetwork();
 }
 
@@ -119,43 +105,30 @@
 }
 
 // static
-bool ProxyConfigServiceImpl::GetUseSharedProxies(
-    const PrefService* pref_service) {
-  const PrefService::Preference* use_shared_proxies_pref =
-      pref_service->FindPreference(prefs::kUseSharedProxies);
-  if (!use_shared_proxies_pref || !use_shared_proxies_pref->GetValue()) {
-    if (UserManager::Get()->IsUserLoggedIn()) {
-      VLOG(1) << "use-shared-proxies not set, defaulting to false/IgnoreProxy.";
-      return false;
-    } else {
-      // Make sure that proxies are always enabled at sign in screen.
-      VLOG(1) << "Use proxy on login screen.";
-      return true;
-    }
-  }
-  bool use_shared_proxies = false;
-  use_shared_proxies_pref->GetValue()->GetAsBoolean(&use_shared_proxies);
-  return use_shared_proxies;
-}
-
-// static
-bool ProxyConfigServiceImpl::IgnoreProxy(const PrefService* pref_service,
+bool ProxyConfigServiceImpl::IgnoreProxy(const PrefService* profile_prefs,
                                          const std::string network_profile_path,
                                          onc::ONCSource onc_source) {
+  if (!profile_prefs) {
+    // If the profile preference are not available, this must be the object
+    // associated to local state used for system requests or login-profile. Make
+    // sure that proxies are enabled.
+    VLOG(1) << "Use proxy for system requests and sign-in screen.";
+    return false;
+  }
+
   const NetworkProfile* profile =
       NetworkHandler::Get()->network_profile_handler()->
       GetProfileForPath(network_profile_path);
   if (!profile) {
-    LOG(WARNING) << "Unknown profile_path " << network_profile_path;
+    LOG(WARNING) << "Unknown profile_path '" << network_profile_path
+                 << "'. Ignoring proxy.";
     return true;
   }
   if (profile->type() == NetworkProfile::TYPE_USER) {
     VLOG(1) << "Respect proxy of not-shared networks.";
     return false;
   }
-
-  if (onc_source == onc::ONC_SOURCE_DEVICE_POLICY &&
-      UserManager::Get()->IsUserLoggedIn()) {
+  if (onc_source == onc::ONC_SOURCE_DEVICE_POLICY) {
     policy::BrowserPolicyConnector* connector =
         g_browser_process->browser_policy_connector();
     const User* logged_in_user = UserManager::Get()->GetLoggedInUser();
@@ -167,7 +140,10 @@
     }
   }
 
-  return !GetUseSharedProxies(pref_service);
+  // This network is shared and not managed by the user's domain.
+  bool use_shared_proxies = profile_prefs->GetBoolean(prefs::kUseSharedProxies);
+  VLOG(1) << "Use proxy of shared network: " << use_shared_proxies;
+  return !use_shared_proxies;
 }
 
 void ProxyConfigServiceImpl::DetermineEffectiveConfigFromDefaultNetwork() {
@@ -184,8 +160,8 @@
       net::ProxyConfigService::CONFIG_UNSET;
   bool ignore_proxy = true;
   if (network) {
-    ignore_proxy =
-        IgnoreProxy(prefs(), network->profile_path(), network->onc_source());
+    ignore_proxy = IgnoreProxy(
+        profile_prefs_, network->profile_path(), network->onc_source());
     // If network is shared but use-shared-proxies is off, use direct mode.
     if (ignore_proxy) {
       VLOG(1) << "Shared network && !use-shared-proxies, use direct";
diff --git a/chrome/browser/chromeos/proxy_config_service_impl.h b/chrome/browser/chromeos/proxy_config_service_impl.h
index 2d813ea..de8f493 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl.h
+++ b/chrome/browser/chromeos/proxy_config_service_impl.h
@@ -38,14 +38,18 @@
  public:
   // ProxyConfigServiceImpl is created in ProxyServiceFactory::
   // CreatePrefProxyConfigTrackerImpl via Profile::GetProxyConfigTracker() for
-  // profile or IOThread constructor for local state and is owned by the
+  // profile or via IOThread constructor for local state and is owned by the
   // respective classes.
   //
-  // The new modified proxy config, together with proxy from prefs if available,
-  // are used to determine the effective proxy config, which is then pushed
-  // through PrefProxyConfigTrackerImpl to ChromeProxyConfigService to the
+  // The user's proxy config, proxy policies and proxy from prefs, are used to
+  // determine the effective proxy config, which is then pushed through
+  // PrefProxyConfigTrackerImpl to ChromeProxyConfigService to the
   // network stack.
-  explicit ProxyConfigServiceImpl(PrefService* pref_service);
+  //
+  // |profile_prefs| can be NULL if this object should only track prefs from
+  // local state (e.g., for system request context or sigin-in screen).
+  explicit ProxyConfigServiceImpl(PrefService* profile_prefs,
+                                  PrefService* local_state_prefs);
   virtual ~ProxyConfigServiceImpl();
 
   // PrefProxyConfigTrackerImpl implementation.
@@ -55,21 +59,13 @@
   // NetworkStateHandlerObserver implementation.
   virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE;
 
-  // Register UseShardProxies preference.
-  static void RegisterPrefs(PrefRegistrySimple* registry);
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
-
  protected:
   friend class UIProxyConfigService;
 
-  // Returns value of UseSharedProxies preference if it's not default, else
-  // returns false if user is logged in and true otherwise.
-  static bool GetUseSharedProxies(const PrefService* pref_service);
-
-  // Returns true if proxy is to be ignored for this profile and |onc_source|,
-  // e.g. this happens if the network is shared and use-shared-proxies is turned
-  // off.
-  static bool IgnoreProxy(const PrefService* pref_service,
+  // Returns true if proxy is to be ignored for this network profile and
+  // |onc_source|, e.g. this happens if the network is shared and
+  // use-shared-proxies is turned off. |profile_prefs| may be NULL.
+  static bool IgnoreProxy(const PrefService* profile_prefs,
                           const std::string network_profile_path,
                           onc::ONCSource onc_source);
 
@@ -93,6 +89,10 @@
   // Track changes in UseSharedProxies user preference.
   BooleanPrefMember use_shared_proxies_;
 
+  // Not owned. NULL if tracking only local state prefs (e.g. in the system
+  // request context or sign-in screen).
+  PrefService* profile_prefs_;
+
   base::WeakPtrFactory<ProxyConfigServiceImpl> pointer_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceImpl);
diff --git a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
index feffd4d..7ecb8cb 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
+++ b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
@@ -221,9 +221,11 @@
     SetUpNetwork();
 
     PrefProxyConfigTrackerImpl::RegisterPrefs(pref_service_.registry());
-    ProxyConfigServiceImpl::RegisterPrefs(pref_service_.registry());
     proxy_config_service_.reset(new ChromeProxyConfigService(NULL));
-    config_service_impl_.reset(new ProxyConfigServiceImpl(&pref_service_));
+    // Create a ProxyConfigServiceImpl like for the system request context.
+    config_service_impl_.reset(
+        new ProxyConfigServiceImpl(NULL,  // no profile prefs
+                                   &pref_service_));
     config_service_impl_->SetChromeProxyConfigService(
         proxy_config_service_.get());
     // SetChromeProxyConfigService triggers update of initial prefs proxy
diff --git a/chrome/browser/chromeos/screensaver/screensaver_controller.cc b/chrome/browser/chromeos/screensaver/screensaver_controller.cc
index 9eca8e7..55e6199 100644
--- a/chrome/browser/chromeos/screensaver/screensaver_controller.cc
+++ b/chrome/browser/chromeos/screensaver/screensaver_controller.cc
@@ -10,10 +10,10 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -45,7 +45,7 @@
   for (ExtensionSet::const_iterator it = extensions->begin();
       it != extensions->end();
       ++it) {
-    const extensions::Extension* extension = *it;
+    const extensions::Extension* extension = it->get();
     if (extension &&
         extension->id() != exclude_id &&
         extension->HasAPIPermission(extensions::APIPermission::kScreensaver)) {
@@ -142,7 +142,7 @@
     ash::Shell::GetInstance()->user_activity_detector()->AddObserver(this);
 }
 
-void ScreensaverController::OnUserActivity() {
+void ScreensaverController::OnUserActivity(const ui::Event* event) {
   // We don't want to handle further user notifications; we'll either login
   // the user and close out or or at least close the screensaver.
   if (ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this))
diff --git a/chrome/browser/chromeos/screensaver/screensaver_controller.h b/chrome/browser/chromeos/screensaver/screensaver_controller.h
index 1223415..aa69b29 100644
--- a/chrome/browser/chromeos/screensaver/screensaver_controller.h
+++ b/chrome/browser/chromeos/screensaver/screensaver_controller.h
@@ -48,8 +48,8 @@
   // Overridden from PowerManagerClient::Observer:
   virtual void IdleNotify(int64 threshold) OVERRIDE;
 
-  // UserActivityObserver::Observer overrides:
-  virtual void OnUserActivity() OVERRIDE;
+  // UserActivityObserver overrides:
+  virtual void OnUserActivity(const ui::Event* event) OVERRIDE;
 
   void SetupScreensaver(const std::string& screensaver_extension_id);
   void TeardownScreensaver();
diff --git a/chrome/browser/chromeos/screensaver/screensaver_controller_browsertest.cc b/chrome/browser/chromeos/screensaver/screensaver_controller_browsertest.cc
index 17baf41..781c9a1 100644
--- a/chrome/browser/chromeos/screensaver/screensaver_controller_browsertest.cc
+++ b/chrome/browser/chromeos/screensaver/screensaver_controller_browsertest.cc
@@ -63,7 +63,7 @@
   EXPECT_TRUE(ash::IsScreensaverShown());
 
   // Trigger active.
-  controller_->OnUserActivity();
+  controller_->OnUserActivity(NULL);
   EXPECT_FALSE(ash::IsScreensaverShown());
 };
 
@@ -77,7 +77,7 @@
   base::MessageLoop::current()->RunUntilIdle();
 
   // Trigger active.
-  controller_->OnUserActivity();
+  controller_->OnUserActivity(NULL);
   EXPECT_FALSE(ash::IsScreensaverShown());
 
   // Trigger idle.
@@ -90,7 +90,7 @@
   EXPECT_TRUE(ash::IsScreensaverShown());
 
   // Trigger active.
-  controller_->OnUserActivity();
+  controller_->OnUserActivity(NULL);
   EXPECT_FALSE(ash::IsScreensaverShown());
 };
 
diff --git a/chrome/browser/chromeos/settings/cros_settings.cc b/chrome/browser/chromeos/settings/cros_settings.cc
index a17cf1f..901ebcf 100644
--- a/chrome/browser/chromeos/settings/cros_settings.cc
+++ b/chrome/browser/chromeos/settings/cros_settings.cc
@@ -10,11 +10,11 @@
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/settings/device_settings_provider.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
 #include "chrome/browser/chromeos/settings/system_settings_provider.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chromeos/chromeos_switches.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/chromeos/settings/cros_settings_names.cc b/chrome/browser/chromeos/settings/cros_settings_names.cc
index 0468c6c..cea9665 100644
--- a/chrome/browser/chromeos/settings/cros_settings_names.cc
+++ b/chrome/browser/chromeos/settings/cros_settings_names.cc
@@ -78,6 +78,11 @@
 // along with device policy requests.
 const char kReportDeviceLocation[] = "cros.device_status.report_location";
 
+// Determines whether the device reports network interface types and addresses
+// in device status reports to the device management server.
+const char kReportDeviceNetworkInterfaces[] =
+    "cros.device_status.report_network_interfaces";
+
 // A list of dictionaries, each detailing one extension to install as part of
 // the AppPack and including the following fields:
 // "extension-id": ID of the extension to install
diff --git a/chrome/browser/chromeos/settings/cros_settings_names.h b/chrome/browser/chromeos/settings/cros_settings_names.h
index cd6a9be..226e9301 100644
--- a/chrome/browser/chromeos/settings/cros_settings_names.h
+++ b/chrome/browser/chromeos/settings/cros_settings_names.h
@@ -43,6 +43,7 @@
 extern const char kReportDeviceActivityTimes[];
 extern const char kReportDeviceBootMode[];
 extern const char kReportDeviceLocation[];
+extern const char kReportDeviceNetworkInterfaces[];
 
 extern const char kAppPack[];
 extern const char kAppPackKeyExtensionId[];
diff --git a/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc b/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc
index c01fda7..395b6b5 100644
--- a/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc
+++ b/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc
@@ -61,7 +61,7 @@
         scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()),
         request_context_getter_(new net::TestURLRequestContextGetter(
             message_loop_.message_loop_proxy())),
-        oauth2_service_(request_context_getter_,
+        oauth2_service_(request_context_getter_.get(),
                         scoped_testing_local_state_.Get()) {
     oauth2_service_.max_refresh_token_validation_retries_ = 0;
     oauth2_service_.set_max_authorization_token_fetch_retries_for_testing(0);
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc
index 98293ad..14c02e6 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider.cc
+++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -15,7 +15,6 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/policy/device_local_account.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
@@ -62,6 +61,7 @@
   kReportDeviceActivityTimes,
   kReportDeviceBootMode,
   kReportDeviceLocation,
+  kReportDeviceNetworkInterfaces,
   kReportDeviceVersionInfo,
   kScreenSaverExtensionId,
   kScreenSaverTimeout,
@@ -378,6 +378,7 @@
     //   kReportDeviceBootMode
     //   kReportDeviceLocation
     //   kReportDeviceVersionInfo
+    //   kReportDeviceNetworkInterfaces
     //   kScreenSaverExtensionId
     //   kScreenSaverTimeout
     //   kStartUpUrls
@@ -612,50 +613,50 @@
 void DeviceSettingsProvider::DecodeAutoUpdatePolicies(
     const em::ChromeDeviceSettingsProto& policy,
     PrefValueMap* new_values_cache) const {
-  if (!policy.has_auto_update_settings())
-    return;
-  const em::AutoUpdateSettingsProto& au_settings_proto =
-      policy.auto_update_settings();
-  if (au_settings_proto.has_update_disabled()) {
-    new_values_cache->SetBoolean(kUpdateDisabled,
-                                 au_settings_proto.update_disabled());
+  if (policy.has_auto_update_settings()) {
+    const em::AutoUpdateSettingsProto& au_settings_proto =
+        policy.auto_update_settings();
+    if (au_settings_proto.has_update_disabled()) {
+      new_values_cache->SetBoolean(kUpdateDisabled,
+                                   au_settings_proto.update_disabled());
+    }
+    const RepeatedField<int>& allowed_connection_types =
+        au_settings_proto.allowed_connection_types();
+    base::ListValue* list = new base::ListValue();
+    for (RepeatedField<int>::const_iterator i(allowed_connection_types.begin());
+         i != allowed_connection_types.end(); ++i) {
+      list->Append(new base::FundamentalValue(*i));
+    }
+    new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list);
   }
-  const RepeatedField<int>& allowed_connection_types =
-      au_settings_proto.allowed_connection_types();
-  base::ListValue* list = new base::ListValue();
-  for (RepeatedField<int>::const_iterator i = allowed_connection_types.begin(),
-           e = allowed_connection_types.end(); i != e; ++i) {
-    list->Append(new base::FundamentalValue(*i));
-  }
-  new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list);
 }
 
 void DeviceSettingsProvider::DecodeReportingPolicies(
     const em::ChromeDeviceSettingsProto& policy,
     PrefValueMap* new_values_cache) const {
   if (policy.has_device_reporting()) {
-    if (policy.device_reporting().has_report_version_info()) {
+    const em::DeviceReportingProto& reporting_policy =
+        policy.device_reporting();
+    if (reporting_policy.has_report_version_info()) {
       new_values_cache->SetBoolean(
           kReportDeviceVersionInfo,
-          policy.device_reporting().report_version_info());
+          reporting_policy.report_version_info());
     }
-    if (policy.device_reporting().has_report_activity_times()) {
+    if (reporting_policy.has_report_activity_times()) {
       new_values_cache->SetBoolean(
           kReportDeviceActivityTimes,
-          policy.device_reporting().report_activity_times());
+          reporting_policy.report_activity_times());
     }
-    if (policy.device_reporting().has_report_boot_mode()) {
+    if (reporting_policy.has_report_boot_mode()) {
       new_values_cache->SetBoolean(
           kReportDeviceBootMode,
-          policy.device_reporting().report_boot_mode());
+          reporting_policy.report_boot_mode());
     }
-    // Device location reporting needs to pass privacy review before it can be
-    // enabled. crosbug.com/24681
-    // if (policy.device_reporting().has_report_location()) {
-    //   new_values_cache->SetBoolean(
-    //       kReportDeviceLocation,
-    //       policy.device_reporting().report_location());
-    // }
+    if (reporting_policy.has_report_network_interfaces()) {
+      new_values_cache->SetBoolean(
+          kReportDeviceNetworkInterfaces,
+          reporting_policy.report_network_interfaces());
+    }
   }
 }
 
@@ -777,9 +778,9 @@
 }
 
 void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) {
-  if (!CrosLibrary::Get())
+  if (!NetworkLibrary::Get())
     return;  // May not be initialized in tests.
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   const NetworkDevice* cellular = cros->FindCellularDevice();
   if (cellular) {
     bool device_value = cellular->data_roaming_allowed();
diff --git a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
index 503cd0f..8cca8f5 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
+++ b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/path_service.h"
 #include "base/test/scoped_path_override.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/policy/device_local_account.h"
 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
@@ -58,7 +58,7 @@
     DeviceSettingsTestBase::TearDown();
   }
 
-  ScopedStubCrosEnabler stub_cros_enabler_;
+  ScopedStubNetworkLibraryEnabler stub_network_library_enabler_;
 
   ScopedTestingLocalState local_state_;
 
diff --git a/chrome/browser/chromeos/settings/device_settings_service.cc b/chrome/browser/chromeos/settings/device_settings_service.cc
index 814df79..cce94a4 100644
--- a/chrome/browser/chromeos/settings/device_settings_service.cc
+++ b/chrome/browser/chromeos/settings/device_settings_service.cc
@@ -8,11 +8,11 @@
 #include "base/logging.h"
 #include "base/message_loop.h"
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/settings/owner_key_util.h"
 #include "chrome/browser/chromeos/settings/session_manager_operation.h"
 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/chromeos/settings/device_settings_service_unittest.cc b/chrome/browser/chromeos/settings/device_settings_service_unittest.cc
index 990b2bb..0864a42 100644
--- a/chrome/browser/chromeos/settings/device_settings_service_unittest.cc
+++ b/chrome/browser/chromeos/settings/device_settings_service_unittest.cc
@@ -267,7 +267,7 @@
   owner_key_util_->Clear();
 
   EXPECT_FALSE(device_settings_service_.HasPrivateOwnerKey());
-  EXPECT_FALSE(device_settings_service_.GetOwnerKey());
+  EXPECT_FALSE(device_settings_service_.GetOwnerKey().get());
   EXPECT_EQ(DeviceSettingsService::OWNERSHIP_UNKNOWN,
             device_settings_service_.GetOwnershipStatus());
 
@@ -276,7 +276,7 @@
                  base::Unretained(this)));
   FlushDeviceSettings();
   EXPECT_FALSE(device_settings_service_.HasPrivateOwnerKey());
-  ASSERT_TRUE(device_settings_service_.GetOwnerKey());
+  ASSERT_TRUE(device_settings_service_.GetOwnerKey().get());
   EXPECT_FALSE(device_settings_service_.GetOwnerKey()->public_key());
   EXPECT_FALSE(device_settings_service_.GetOwnerKey()->private_key());
   EXPECT_EQ(DeviceSettingsService::OWNERSHIP_NONE,
@@ -291,7 +291,7 @@
                  base::Unretained(this)));
   FlushDeviceSettings();
   EXPECT_FALSE(device_settings_service_.HasPrivateOwnerKey());
-  ASSERT_TRUE(device_settings_service_.GetOwnerKey());
+  ASSERT_TRUE(device_settings_service_.GetOwnerKey().get());
   ASSERT_TRUE(device_settings_service_.GetOwnerKey()->public_key());
   std::vector<uint8> key;
   ASSERT_TRUE(device_policy_.signing_key()->ExportPublicKey(&key));
@@ -309,7 +309,7 @@
                  base::Unretained(this)));
   FlushDeviceSettings();
   EXPECT_TRUE(device_settings_service_.HasPrivateOwnerKey());
-  ASSERT_TRUE(device_settings_service_.GetOwnerKey());
+  ASSERT_TRUE(device_settings_service_.GetOwnerKey().get());
   ASSERT_TRUE(device_settings_service_.GetOwnerKey()->public_key());
   ASSERT_TRUE(device_policy_.signing_key()->ExportPublicKey(&key));
   EXPECT_EQ(*device_settings_service_.GetOwnerKey()->public_key(), key);
diff --git a/chrome/browser/chromeos/settings/owner_key_util.cc b/chrome/browser/chromeos/settings/owner_key_util.cc
index d1bbbd4..2b333d1 100644
--- a/chrome/browser/chromeos/settings/owner_key_util.cc
+++ b/chrome/browser/chromeos/settings/owner_key_util.cc
@@ -71,7 +71,7 @@
 }
 
 bool OwnerKeyUtilImpl::IsPublicKeyPresent() {
-  return file_util::PathExists(key_file_);
+  return base::PathExists(key_file_);
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/session_manager_operation.cc b/chrome/browser/chromeos/settings/session_manager_operation.cc
index 5339f3f..67188e8 100644
--- a/chrome/browser/chromeos/settings/session_manager_operation.cc
+++ b/chrome/browser/chromeos/settings/session_manager_operation.cc
@@ -236,7 +236,7 @@
 }
 
 void SignAndStoreSettingsOperation::StartSigning() {
-  if (!owner_key() || !owner_key()->private_key() || username_.empty()) {
+  if (!owner_key().get() || !owner_key()->private_key() || username_.empty()) {
     ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
     return;
   }
diff --git a/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc b/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc
index e2f1a44..7dc419a 100644
--- a/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc
+++ b/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc
@@ -172,7 +172,7 @@
   op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
   device_settings_test_helper_.FlushLoops();
   device_settings_test_helper_.FlushRetrieve();
-  EXPECT_TRUE(op.owner_key());
+  EXPECT_TRUE(op.owner_key().get());
   EXPECT_TRUE(op.owner_key()->public_key());
   Mock::VerifyAndClearExpectations(this);
 
diff --git a/chrome/browser/chromeos/sms_observer.cc b/chrome/browser/chromeos/sms_observer.cc
index 8d8c788..6a29b04 100644
--- a/chrome/browser/chromeos/sms_observer.cc
+++ b/chrome/browser/chromeos/sms_observer.cc
@@ -9,7 +9,6 @@
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_notifier.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chromeos/network/cros_network_functions.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
@@ -18,20 +17,16 @@
 namespace chromeos {
 
 SmsObserver::SmsObserver() {
-  UpdateObservers(chromeos::CrosLibrary::Get()->GetNetworkLibrary());
+  UpdateObservers(chromeos::NetworkLibrary::Get());
 }
 
 SmsObserver::~SmsObserver() {
-  NetworkLibrary* library = chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* library = chromeos::NetworkLibrary::Get();
   library->RemoveNetworkManagerObserver(this);
   DisconnectAll();
 }
 
 void SmsObserver::UpdateObservers(NetworkLibrary* library) {
-  // Guard against calls to libcros (http://crosbug.com/17863).
-  if (!CrosLibrary::Get()->libcros_loaded())
-    return;
-
   const CellularNetworkVector& networks = library->cellular_networks();
   // Remove monitors for networks that are not in the list anymore.
   for (ObserversMap::iterator it_observer = observers_.begin();
@@ -77,10 +72,6 @@
 }
 
 void SmsObserver::DisconnectAll() {
-  // Guard against calls to libcros (http://crosbug.com/17863).
-  if (!CrosLibrary::Get()->libcros_loaded())
-    return;
-
   for (ObserversMap::iterator it = observers_.begin();
        it != observers_.end(); ++it) {
     VLOG(1) << "Remove SMS monitor for " << it->first;
diff --git a/chrome/browser/chromeos/status/data_promo_notification.cc b/chrome/browser/chromeos/status/data_promo_notification.cc
index eb16239..7c1f57b 100644
--- a/chrome/browser/chromeos/status/data_promo_notification.cc
+++ b/chrome/browser/chromeos/status/data_promo_notification.cc
@@ -13,7 +13,6 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/helper.h"
 #include "chrome/browser/chromeos/mobile_config.h"
diff --git a/chrome/browser/chromeos/status/network_menu_icon.cc b/chrome/browser/chromeos/status/network_menu_icon.cc
index 2de9077..b57c923 100644
--- a/chrome/browser/chromeos/status/network_menu_icon.cc
+++ b/chrome/browser/chromeos/status/network_menu_icon.cc
@@ -12,7 +12,6 @@
 #include "ash/system/chromeos/network/network_icon_animation.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
 #include "grit/generated_resources.h"
@@ -381,7 +380,7 @@
   if (network->type() == TYPE_VPN)
     return false;  // Never show the VPN badge for a VPN network.
   chromeos::NetworkLibrary* cros =
-      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+      chromeos::NetworkLibrary::Get();
   bool vpn_connected = (network->connected() &&
                         cros->virtual_network() &&
                         cros->virtual_network()->connected());
@@ -394,7 +393,7 @@
 
 void NetworkIcon::Update() {
   chromeos::NetworkLibrary* cros =
-      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+      chromeos::NetworkLibrary::Get();
   // First look for a visible network.
   const Network* network = cros->FindNetworkByPath(service_path_);
   if (!network) {
@@ -494,7 +493,7 @@
 void NetworkIcon::SetBadges(const Network* network) {
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   chromeos::NetworkLibrary* cros =
-      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+      chromeos::NetworkLibrary::Get();
 
   bool use_dark_icons = resource_color_theme_ == NetworkMenuIcon::COLOR_DARK;
   switch (network->type()) {
@@ -560,7 +559,7 @@
     return true;
   if (!Network::IsConnectedState(state_))
     return true;
-  NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* crosnet = NetworkLibrary::Get();
   if (crosnet->virtual_network())
     return true;
   return false;
@@ -674,7 +673,7 @@
 // If disconnected: returns any connecting non-ethernet network.
 // Otherwise, only return a network if the conenction was user initiated.
 const Network* NetworkMenuIcon::GetConnectingNetwork() {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   const Network* connecting_network = cros->connecting_network();
   if (connecting_network &&
       connecting_network->type() != TYPE_ETHERNET &&
@@ -752,7 +751,7 @@
 
 // Sets up the icon and badges for GenerateBitmap().
 bool NetworkMenuIcon::SetIconAndText() {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   DCHECK(cros);
 
   icon_->ClearIconAndBadges();
@@ -796,7 +795,7 @@
 }
 
 bool NetworkMenuIcon::SetVpnIconAndText() {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   DCHECK(cros);
 
   icon_->ClearIconAndBadges();
@@ -816,7 +815,7 @@
 }
 
 bool NetworkMenuIcon::SetActiveNetworkIconAndText(const Network* network) {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   bool animating = false;
 
@@ -981,4 +980,4 @@
   return (type == ARCS) ? kNumArcsImages : kNumBarsImages;
 }
 
-}  // chromeos
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/status/network_menu_icon_unittest.cc b/chrome/browser/chromeos/status/network_menu_icon_unittest.cc
index a63bd11..ba8c9fe 100644
--- a/chrome/browser/chromeos/status/network_menu_icon_unittest.cc
+++ b/chrome/browser/chromeos/status/network_menu_icon_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/chromeos/status/network_menu_icon.h"
 
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "grit/ash_resources.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -81,7 +81,7 @@
 
   // testing::Test implementation.
   virtual void SetUp() OVERRIDE {
-    cros_ = CrosLibrary::Get()->GetNetworkLibrary();
+    cros_ = NetworkLibrary::Get();
     // Ethernet connected = WIRED icon, no badges.
     ethernet_connected_image_ = NetworkMenuIcon::GenerateImageFromComponents(
         *rb_.GetImageSkiaNamed(IDR_AURA_UBER_TRAY_NETWORK_WIRED),
@@ -198,7 +198,7 @@
   }
 
  protected:
-  ScopedStubCrosEnabler cros_stub_;
+  ScopedStubNetworkLibraryEnabler stub_network_library_enabler_;
   NetworkLibrary* cros_;
   ResourceBundle& rb_;
   gfx::ImageSkia ethernet_connected_image_;
diff --git a/chrome/browser/chromeos/swap_metrics.cc b/chrome/browser/chromeos/swap_metrics.cc
index 6b25be0..efebac3 100644
--- a/chrome/browser/chromeos/swap_metrics.cc
+++ b/chrome/browser/chromeos/swap_metrics.cc
@@ -348,7 +348,7 @@
 }
 
 SwapMetrics::~SwapMetrics() {
-  if (backend_)
+  if (backend_.get())
     backend_->CancelOnUIThread();
   ash::Shell::GetInstance()->RemovePreTargetHandler(this);
   BrowserList::RemoveObserver(this);
@@ -413,7 +413,7 @@
 
 void SwapMetrics::StartMetricsCollection(const std::string& reason) {
   // Cancel any existing metrics run.
-  if (backend_)
+  if (backend_.get())
     backend_->CancelOnUIThread();
   backend_ = new Backend(reason);
   PostTaskRecordMetrics(backend_, 0, kMetricsDelayMs[0]);
diff --git a/chrome/browser/chromeos/system/ash_system_tray_delegate.cc b/chrome/browser/chromeos/system/ash_system_tray_delegate.cc
index f4a6030..4d6b796 100644
--- a/chrome/browser/chromeos/system/ash_system_tray_delegate.cc
+++ b/chrome/browser/chromeos/system/ash_system_tray_delegate.cc
@@ -45,12 +45,12 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
 #include "chrome/browser/chromeos/audio/audio_handler.h"
 #include "chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.h"
 #include "chrome/browser/chromeos/choose_mobile_network_dialog.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
 #include "chrome/browser/chromeos/drive/job_list.h"
@@ -86,7 +86,6 @@
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/upgrade_detector.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/time_format.h"
 #include "chrome/common/url_constants.h"
@@ -279,9 +278,6 @@
     registrar_->Add(this,
                    chrome::NOTIFICATION_PROFILE_DESTROYED,
                    content::NotificationService::AllSources());
-    registrar_->Add(this,
-                   chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
-                   content::NotificationService::AllSources());
     registrar_->Add(
         this,
         chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER,
@@ -303,7 +299,7 @@
     DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
     DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
 
-    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
+    NetworkLibrary* crosnet = NetworkLibrary::Get();
     crosnet->AddNetworkManagerObserver(this);
     OnNetworkManagerChanged(crosnet);
 
@@ -373,7 +369,7 @@
     DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
     DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
     DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver(this);
-    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
+    NetworkLibrary* crosnet = NetworkLibrary::Get();
     if (crosnet)
       crosnet->RemoveNetworkManagerObserver(this);
     input_method::InputMethodManager::Get()->RemoveObserver(this);
@@ -384,11 +380,8 @@
     ash::Shell::GetInstance()->session_state_delegate()->
         RemoveSessionStateObserver(this);
 
-    // Stop observing gdata operations.
-    DriveIntegrationService* integration_service =
-        FindDriveIntegrationService();
-    if (integration_service)
-      integration_service->job_list()->RemoveObserver(this);
+    // Stop observing Drive operations.
+    UnobserveDriveUpdates();
 
     policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
         g_browser_process->browser_policy_connector()->
@@ -465,7 +458,7 @@
   virtual const std::string GetLocallyManagedUserManager() const OVERRIDE {
     if (GetUserLoginStatus() != ash::user::LOGGED_IN_LOCALLY_MANAGED)
       return std::string();
-    return UserManager::Get()->GetManagerUserIdForManagedUser(
+    return UserManager::Get()->GetManagerDisplayEmailForManagedUser(
         chromeos::UserManager::Get()->GetActiveUser()->email());
   }
 
@@ -836,7 +829,7 @@
                                       std::string* topup_url,
                                       std::string* setup_url) OVERRIDE {
     bool result = false;
-    NetworkLibrary* crosnet = CrosLibrary::Get()->GetNetworkLibrary();
+    NetworkLibrary* crosnet = NetworkLibrary::Get();
     const NetworkDevice* cellular = crosnet->FindCellularDevice();
     if (!cellular)
       return false;
@@ -925,7 +918,14 @@
   }
 
   void SetProfile(Profile* profile) {
+    // Stop observing the current |user_profile_| on Drive integration status.
+    UnobserveDriveUpdates();
+
     user_profile_ = profile;
+
+    // Restart observation, now for the newly set |profile|.
+    ObserveDriveUpdates();
+
     PrefService* prefs = profile->GetPrefs();
     user_pref_registrar_.reset(new PrefChangeRegistrar);
     user_pref_registrar_->Init(prefs);
@@ -965,13 +965,20 @@
     return true;
   }
 
-  void ObserveGDataUpdates() {
+  void ObserveDriveUpdates() {
     DriveIntegrationService* integration_service =
         FindDriveIntegrationService();
     if (integration_service)
       integration_service->job_list()->AddObserver(this);
   }
 
+  void UnobserveDriveUpdates() {
+    DriveIntegrationService* integration_service =
+        FindDriveIntegrationService();
+    if (integration_service)
+      integration_service->job_list()->RemoveObserver(this);
+  }
+
   void UpdateClockType() {
     if (!user_pref_registrar_)
       return;
@@ -1103,11 +1110,6 @@
         }
         break;
       }
-      case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
-        // GData system service exists by the time if enabled.
-        ObserveGDataUpdates();
-        break;
-      }
       case chrome::NOTIFICATION_PROFILE_CREATED: {
         SetProfile(content::Source<Profile>(source).ptr());
         registrar_->Remove(this,
@@ -1182,8 +1184,8 @@
   }
 
   DriveIntegrationService* FindDriveIntegrationService() {
-    Profile* profile = ProfileManager::GetDefaultProfile();
-    return DriveIntegrationServiceFactory::FindForProfile(profile);
+    return user_profile_ ?
+        DriveIntegrationServiceFactory::FindForProfile(user_profile_) : NULL;
   }
 
   // Overridden from system::TimezoneSettings::Observer.
@@ -1243,7 +1245,7 @@
       size_t link_index) OVERRIDE {
     if (message_type == ash::NetworkObserver::ERROR_OUT_OF_CREDITS) {
       const CellularNetwork* cellular =
-          CrosLibrary::Get()->GetNetworkLibrary()->cellular_network();
+          NetworkLibrary::Get()->cellular_network();
       if (cellular)
         ConnectToNetwork(cellular->service_path());
       ash::Shell::GetInstance()->system_tray_notifier()->
@@ -1266,7 +1268,7 @@
         deal_url_to_open = deal_topup_url;
       } else {
         const Network* cellular =
-            CrosLibrary::Get()->GetNetworkLibrary()->cellular_network();
+            NetworkLibrary::Get()->cellular_network();
         if (!cellular)
           return;
         ShowNetworkSettings(cellular->service_path());
@@ -1309,7 +1311,7 @@
 
   void UpdateCellular() {
     const CellularNetworkVector& cellular_networks =
-        CrosLibrary::Get()->GetNetworkLibrary()->cellular_networks();
+        NetworkLibrary::Get()->cellular_networks();
     if (cellular_networks.empty())
       return;
     // We only care about the first cellular network (in practice there will
diff --git a/chrome/browser/chromeos/system/automatic_reboot_manager.cc b/chrome/browser/chromeos/system/automatic_reboot_manager.cc
index c77d06e..5ac91e7 100644
--- a/chrome/browser/chromeos/system/automatic_reboot_manager.cc
+++ b/chrome/browser/chromeos/system/automatic_reboot_manager.cc
@@ -32,9 +32,9 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/time/tick_clock.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/system/automatic_reboot_manager_observer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_paths.h"
 #include "chromeos/chromeos_switches.h"
@@ -178,7 +178,7 @@
         content::NotificationService::AllSources());
     login_screen_idle_timer_.reset(
         new base::OneShotTimer<AutomaticRebootManager>);
-    OnUserActivity();
+    OnUserActivity(NULL);
   }
 
   // In a regular browser, base::ThreadTaskRunnerHandle::Get() and
@@ -240,7 +240,7 @@
   Reschedule();
 }
 
-void AutomaticRebootManager::OnUserActivity() {
+void AutomaticRebootManager::OnUserActivity(const ui::Event* event) {
   if (!login_screen_idle_timer_)
     return;
 
diff --git a/chrome/browser/chromeos/system/automatic_reboot_manager.h b/chrome/browser/chromeos/system/automatic_reboot_manager.h
index faafcd4..83e5398 100644
--- a/chrome/browser/chromeos/system/automatic_reboot_manager.h
+++ b/chrome/browser/chromeos/system/automatic_reboot_manager.h
@@ -104,7 +104,7 @@
       const UpdateEngineClient::Status& status) OVERRIDE;
 
   // ash::UserActivityObserver:
-  virtual void OnUserActivity() OVERRIDE;
+  virtual void OnUserActivity(const ui::Event* event) OVERRIDE;
 
   // content::NotificationObserver:
   virtual void Observe(int type,
diff --git a/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc b/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc
index fbd2178..31fd458 100644
--- a/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc
+++ b/chrome/browser/chromeos/system/automatic_reboot_manager_unittest.cc
@@ -26,9 +26,9 @@
 #include "base/threading/sequenced_worker_pool.h"
 #include "base/time/tick_clock.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/mock_user_manager.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/chromeos_paths.h"
@@ -644,7 +644,7 @@
     FastForwardBy(base::TimeDelta::FromSeconds(50), false);
 
     // Simulate user activity.
-    automatic_reboot_manager_->OnUserActivity();
+    automatic_reboot_manager_->OnUserActivity(NULL);
   }
 
   // Fast forward the uptime by 60 seconds without simulating user activity.
@@ -1381,7 +1381,7 @@
   FastForwardBy(base::TimeDelta::FromHours(6), false);
 
   // Simulate user activity.
-  automatic_reboot_manager_->OnUserActivity();
+  automatic_reboot_manager_->OnUserActivity(NULL);
 
   // Enable automatic reboot after an update has been applied. Verify that the
   // device does not reboot immediately.
@@ -1418,7 +1418,7 @@
                 false);
 
   // Simulate user activity.
-  automatic_reboot_manager_->OnUserActivity();
+  automatic_reboot_manager_->OnUserActivity(NULL);
 
   // Enable automatic rebooting after an update has been applied. Verify that
   // unless a non-kiosk-app session is in progress, the the device immediately
diff --git a/chrome/browser/chromeos/system/device_change_handler.cc b/chrome/browser/chromeos/system/device_change_handler.cc
index 12f5ac4..6df0aab 100644
--- a/chrome/browser/chromeos/system/device_change_handler.cc
+++ b/chrome/browser/chromeos/system/device_change_handler.cc
@@ -45,10 +45,6 @@
       prefs->GetBoolean(prefs::kEnableTouchpadThreeFingerClick);
   system::touchpad_settings::SetThreeFingerClick(three_finger_click);
 
-  const bool three_finger_swipe =
-      prefs->GetBoolean(prefs::kEnableTouchpadThreeFingerSwipe);
-  system::touchpad_settings::SetThreeFingerSwipe(three_finger_swipe);
-
   const int sensitivity = prefs->GetInteger(prefs::kTouchpadSensitivity);
   system::touchpad_settings::SetSensitivity(sensitivity);
 
diff --git a/chrome/browser/chromeos/system/input_device_settings.cc b/chrome/browser/chromeos/system/input_device_settings.cc
index 68e6f01..67c054b 100644
--- a/chrome/browser/chromeos/system/input_device_settings.cc
+++ b/chrome/browser/chromeos/system/input_device_settings.cc
@@ -13,10 +13,12 @@
 #include "base/command_line.h"
 #include "base/file_util.h"
 #include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
 #include "base/message_loop.h"
 #include "base/process.h"
 #include "base/process_util.h"
 #include "base/strings/stringprintf.h"
+#include "base/task_runner.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -28,9 +30,11 @@
 const char kTpControl[] = "/opt/google/touchpad/tpcontrol";
 const char kMouseControl[] = "/opt/google/mouse/mousecontrol";
 
+typedef base::RefCountedData<bool> RefCountedBool;
+
 bool ScriptExists(const std::string& script) {
   DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
-  return file_util::PathExists(base::FilePath(script));
+  return base::PathExists(base::FilePath(script));
 }
 
 // Executes the input control script asynchronously, if it exists.
@@ -75,9 +79,10 @@
   ExecuteScript(3, kTpControl, control, enabled ? "on" : "off");
 }
 
-void DeviceExistsBlockingPool(const char* script, bool* exists) {
+void DeviceExistsBlockingPool(const char* script,
+                              scoped_refptr<RefCountedBool> exists) {
   DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
-  *exists = false;
+  exists->data = false;
   if (!ScriptExists(script))
     return;
 
@@ -86,23 +91,32 @@
   argv.push_back("status");
   std::string output;
   // Output is empty if the device is not found.
-  *exists = base::GetAppOutput(CommandLine(argv), &output) && !output.empty();
-  DVLOG(1) << "DeviceExistsBlockingPool:" << script << "=" << *exists;
+  exists->data = base::GetAppOutput(CommandLine(argv), &output) &&
+      !output.empty();
+  DVLOG(1) << "DeviceExistsBlockingPool:" << script << "=" << exists->data;
 }
 
-void RunCallbackUIThread(bool* exists, const DeviceExistsCallback& callback) {
+void RunCallbackUIThread(scoped_refptr<RefCountedBool> exists,
+                         const DeviceExistsCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-  DVLOG(1) << "RunCallbackUIThread " << *exists;
-  callback.Run(*exists);
+  DVLOG(1) << "RunCallbackUIThread " << exists->data;
+  callback.Run(exists->data);
 }
 
 void DeviceExists(const char* script, const DeviceExistsCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 
-  bool* exists = new bool(false);
-  content::BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE,
+  // One or both of the control scripts can apparently hang during shutdown
+  // (http://crbug.com/255546). Run the blocking pool task with
+  // CONTINUE_ON_SHUTDOWN so it won't be joined when Chrome shuts down.
+  scoped_refptr<RefCountedBool> exists(new RefCountedBool(false));
+  base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
+  scoped_refptr<base::TaskRunner> runner =
+      pool->GetTaskRunnerWithShutdownBehavior(
+          base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
+  runner->PostTaskAndReply(FROM_HERE,
       base::Bind(&DeviceExistsBlockingPool, script, exists),
-      base::Bind(&RunCallbackUIThread, base::Owned(exists), callback));
+      base::Bind(&RunCallbackUIThread, exists, callback));
 }
 
 }  // namespace
@@ -132,11 +146,6 @@
   SetTPControl("t5r2_three_finger_click", enabled);
 }
 
-void SetThreeFingerSwipe(bool enabled) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-  SetTPControl("three_finger_swipe", enabled);
-}
-
 void SetTapDragging(bool enabled) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   SetTPControl("tap_dragging", enabled);
diff --git a/chrome/browser/chromeos/system/input_device_settings.h b/chrome/browser/chromeos/system/input_device_settings.h
index 821c179..ac3c65a 100644
--- a/chrome/browser/chromeos/system/input_device_settings.h
+++ b/chrome/browser/chromeos/system/input_device_settings.h
@@ -31,9 +31,6 @@
 // Switch for three-finger click.
 void SetThreeFingerClick(bool enabled);
 
-// Switch for three-finger swipe.
-void SetThreeFingerSwipe(bool enabled);
-
 // Turns tap-dragging on/off.
 void SetTapDragging(bool enabled);
 
diff --git a/chrome/browser/chromeos/system/syslogs_provider.cc b/chrome/browser/chromeos/system/syslogs_provider.cc
index 643d355..279d837 100644
--- a/chrome/browser/chromeos/system/syslogs_provider.cc
+++ b/chrome/browser/chromeos/system/syslogs_provider.cc
@@ -146,7 +146,7 @@
                                                   &data);
   // if we were using an internal temp file, the user does not need the
   // logs to stay past the ReadFile call - delete the file
-  base::Delete(temp_filename, false);
+  base::DeleteFile(temp_filename, false);
 
   if (!read_success)
     return NULL;
@@ -321,7 +321,7 @@
     // Load compressed logs.
     zip_content = new std::string();
     LoadCompressedLogs(zip_file, zip_content);
-    base::Delete(zip_file, false);
+    base::DeleteFile(zip_file, false);
   }
 
   // Include dbus statistics summary
diff --git a/chrome/browser/chromeos/system/timezone_settings.cc b/chrome/browser/chromeos/system/timezone_settings.cc
index 5aa6593..6ebffc9 100644
--- a/chrome/browser/chromeos/system/timezone_settings.cc
+++ b/chrome/browser/chromeos/system/timezone_settings.cc
@@ -201,14 +201,14 @@
   base::FilePath timezone_file(kTimezoneFilesDir + id);
 
   // Make sure timezone_file exists.
-  if (!file_util::PathExists(timezone_file)) {
+  if (!base::PathExists(timezone_file)) {
     LOG(ERROR) << "SetTimezoneID: Cannot find timezone file "
                << timezone_file.value();
     return;
   }
 
   // Delete old symlink2 if it exists.
-  base::Delete(timezone_symlink2, false);
+  base::DeleteFile(timezone_symlink2, false);
 
   // Create new symlink2.
   if (symlink(timezone_file.value().c_str(),
diff --git a/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc b/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
index 3154c96..5370b98 100644
--- a/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
+++ b/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
@@ -7,9 +7,11 @@
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray_accessibility.h"
 #include "ash/system/user/login_status.h"
+#include "base/callback.h"
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
 #include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h"
@@ -19,12 +21,12 @@
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/user_manager_impl.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
@@ -94,7 +96,8 @@
       policy_map.Set(policy::key::kShowAccessibilityOptionsInSystemTrayMenu,
                      policy::POLICY_LEVEL_MANDATORY,
                      policy::POLICY_SCOPE_USER,
-                     base::Value::CreateBooleanValue(value));
+                     base::Value::CreateBooleanValue(value),
+                     NULL);
       provider_.UpdateChromePolicy(policy_map);
       base::RunLoop().RunUntilIdle();
     } else {
diff --git a/chrome/browser/chromeos/system_logs/chrome_internal_log_source.cc b/chrome/browser/chromeos/system_logs/chrome_internal_log_source.cc
index 5375012..9370a61 100644
--- a/chrome/browser/chromeos/system_logs/chrome_internal_log_source.cc
+++ b/chrome/browser/chromeos/system_logs/chrome_internal_log_source.cc
@@ -94,7 +94,7 @@
   for (ExtensionSet::const_iterator it = extensions->begin();
        it != extensions->end();
        ++it) {
-    const extensions::Extension* extension = *it;
+    const extensions::Extension* extension = it->get();
     if (extensions_list.empty()) {
       extensions_list = extension->name();
     } else {
diff --git a/chrome/browser/chromeos/ui/app_launch_view.cc b/chrome/browser/chromeos/ui/app_launch_view.cc
index 9975b1c..f5354f3 100644
--- a/chrome/browser/chromeos/ui/app_launch_view.cc
+++ b/chrome/browser/chromeos/ui/app_launch_view.cc
@@ -19,7 +19,6 @@
 #include "content/public/browser/web_contents.h"
 #include "grit/generated_resources.h"
 #include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/aura/env.h"
 #include "ui/aura/root_window.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/screen.h"
@@ -34,9 +33,6 @@
 internal::AppLaunchView* g_instance = NULL;
 
 void ShowAppLaunchSplashScreen(const std::string& app_id) {
-  // Disables the default white rendering from RenderWidgetHostViewAura.
-  aura::Env::GetInstance()->set_render_white_bg(false);
-
   // TODO(zelidrag): Come up with a better UI for this purpose.
   internal::AppLaunchView::ShowAppLaunchSplashScreen(app_id);
 }
@@ -47,9 +43,6 @@
 
 void CloseAppLaunchSplashScreen() {
   internal::AppLaunchView::CloseAppLaunchSplashScreen();
-
-  // Re-enables the default white rendering from RenderWidgetHostViewAura.
-  aura::Env::GetInstance()->set_render_white_bg(true);
 }
 
 namespace internal {
@@ -98,7 +91,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // AppLaunchView, content::WebContentsObserver implementation.
-void AppLaunchView::RenderViewGone(
+void AppLaunchView::RenderProcessGone(
     base::TerminationStatus status) {
   LOG(ERROR) << "Splash screen terminated with status " << status;
   AppLaunchView::CloseAppLaunchSplashScreen();
diff --git a/chrome/browser/chromeos/ui/app_launch_view.h b/chrome/browser/chromeos/ui/app_launch_view.h
index 51b5854..838fd7e 100644
--- a/chrome/browser/chromeos/ui/app_launch_view.h
+++ b/chrome/browser/chromeos/ui/app_launch_view.h
@@ -10,8 +10,8 @@
 #include "ash/ash_export.h"
 #include "base/callback.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "googleurl/src/gurl.h"
 #include "ui/views/widget/widget_delegate.h"
+#include "url/gurl.h"
 
 namespace content {
 class BrowserContent;
@@ -54,7 +54,7 @@
   virtual views::View* GetContentsView() OVERRIDE;
 
   // content::WebContentsObserver overrides.
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
 
   void Show();
   void Close();
diff --git a/chrome/browser/chromeos/ui/echo_dialog_view.cc b/chrome/browser/chromeos/ui/echo_dialog_view.cc
index 15b8ed8..fde9b23 100644
--- a/chrome/browser/chromeos/ui/echo_dialog_view.cc
+++ b/chrome/browser/chromeos/ui/echo_dialog_view.cc
@@ -58,9 +58,9 @@
       ui::Range(offsets[0], offsets[0] + service_name.length()),
       service_name_style);
 
-  views::StyledLabel::RangeStyleInfo link_style;
+  views::StyledLabel::RangeStyleInfo link_style =
+      views::StyledLabel::RangeStyleInfo::CreateForLink();
   link_style.font_style = gfx::Font::NORMAL;
-  link_style.is_link = true;
   label_->AddStyleRange(ui::Range(offsets[1], offsets[1] + link.length()),
                         link_style);
 
@@ -82,9 +82,9 @@
 
   label_ = new views::StyledLabel(text, this);
 
-  views::StyledLabel::RangeStyleInfo link_style;
+  views::StyledLabel::RangeStyleInfo link_style =
+      views::StyledLabel::RangeStyleInfo::CreateForLink();
   link_style.font_style = gfx::Font::NORMAL;
-  link_style.is_link = true;
   label_->AddStyleRange(ui::Range(offset, offset + link.length()), link_style);
 
   SetLabelBorderAndBounds();
diff --git a/chrome/browser/chromeos/ui_proxy_config.h b/chrome/browser/chromeos/ui_proxy_config.h
index 4541c8f..08fa47f 100644
--- a/chrome/browser/chromeos/ui_proxy_config.h
+++ b/chrome/browser/chromeos/ui_proxy_config.h
@@ -8,9 +8,9 @@
 #include <string>
 
 #include "chrome/browser/prefs/proxy_prefs.h"
-#include "googleurl/src/gurl.h"
 #include "net/proxy/proxy_bypass_rules.h"
 #include "net/proxy/proxy_server.h"
+#include "url/gurl.h"
 
 namespace base {
 class DictionaryValue;
diff --git a/chrome/browser/chromeos/ui_proxy_config_service.cc b/chrome/browser/chromeos/ui_proxy_config_service.cc
index 0f6988a..a7925a9 100644
--- a/chrome/browser/chromeos/ui_proxy_config_service.cc
+++ b/chrome/browser/chromeos/ui_proxy_config_service.cc
@@ -56,13 +56,17 @@
 
 }  // namespace
 
-UIProxyConfigService::UIProxyConfigService() {
+UIProxyConfigService::UIProxyConfigService()
+    : signin_screen_(false),
+      pref_service_(NULL) {
 }
 
 UIProxyConfigService::~UIProxyConfigService() {
 }
 
-void UIProxyConfigService::SetPrefs(PrefService* pref_service) {
+void UIProxyConfigService::SetPrefs(bool signin_screen,
+                                    PrefService* pref_service) {
+  signin_screen_ = signin_screen;
   pref_service_ = pref_service;
 }
 
@@ -157,10 +161,10 @@
     current_ui_config_.state = ProxyPrefs::CONFIG_POLICY;
     current_ui_config_.user_modifiable = false;
   } else {
-    current_ui_config_.user_modifiable =
-        !ProxyConfigServiceImpl::IgnoreProxy(pref_service_,
-                                             network.profile_path(),
-                                             network.onc_source());
+    current_ui_config_.user_modifiable = !ProxyConfigServiceImpl::IgnoreProxy(
+        signin_screen_ ? NULL : pref_service_,
+        network.profile_path(),
+        network.onc_source());
   }
 }
 
diff --git a/chrome/browser/chromeos/ui_proxy_config_service.h b/chrome/browser/chromeos/ui_proxy_config_service.h
index 05d867e..f9d0de3 100644
--- a/chrome/browser/chromeos/ui_proxy_config_service.h
+++ b/chrome/browser/chromeos/ui_proxy_config_service.h
@@ -28,7 +28,13 @@
   UIProxyConfigService();
   ~UIProxyConfigService();
 
-  void SetPrefs(PrefService* prefs);
+  // |signin_screen| indicates whether this object is used for the
+  // signin screen, in which case proxies of (shared) networks are
+  // unconditionally respected. After signin, proxy settings of shared networks
+  // may be ignored, e.g. depending on the kUseSharedProxies flag. After this
+  // call, proxy settings are read from
+  // |prefs|.
+  void SetPrefs(bool signin_screen, PrefService* prefs);
 
   // Called by UI to set the network with service path |current_network| to be
   // displayed or edited.  Subsequent Set*/Get* methods will use this
@@ -58,6 +64,7 @@
   // Proxy configuration of |current_ui_network_|.
   UIProxyConfig current_ui_config_;
 
+  bool signin_screen_;
   PrefService* pref_service_;
 
   DISALLOW_COPY_AND_ASSIGN(UIProxyConfigService);
diff --git a/chrome/browser/chromeos/web_socket_proxy.cc b/chrome/browser/chromeos/web_socket_proxy.cc
index 13d36e7..8081dc8 100644
--- a/chrome/browser/chromeos/web_socket_proxy.cc
+++ b/chrome/browser/chromeos/web_socket_proxy.cc
@@ -38,17 +38,15 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/sys_byteorder.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/web_socket_proxy_helper.h"
 #include "chrome/browser/internal_auth.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/common/url_constants.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/gurl.h"
-#include "googleurl/src/url_parse.h"
 #include "net/base/address_list.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/io_buffer.h"
@@ -62,6 +60,8 @@
 #include "net/ssl/ssl_config_service.h"
 #include "third_party/libevent/evdns.h"
 #include "third_party/libevent/event.h"
+#include "url/gurl.h"
+#include "url/url_parse.h"
 
 using content::BrowserThread;
 
diff --git a/chrome/browser/chromeos/web_socket_proxy_controller.cc b/chrome/browser/chromeos/web_socket_proxy_controller.cc
index 4cc3c28..0c7447b 100644
--- a/chrome/browser/chromeos/web_socket_proxy_controller.cc
+++ b/chrome/browser/chromeos/web_socket_proxy_controller.cc
@@ -17,8 +17,8 @@
 #include "base/message_loop.h"
 #include "base/threading/thread.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/web_socket_proxy.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/url_constants.h"
@@ -26,8 +26,8 @@
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/common/url_constants.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/network_change_notifier.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/component_updater/component_patcher.cc b/chrome/browser/component_updater/component_patcher.cc
index 54bc62d..de082a7 100644
--- a/chrome/browser/component_updater/component_patcher.cc
+++ b/chrome/browser/component_updater/component_patcher.cc
@@ -20,7 +20,7 @@
 base::ListValue* ReadCommands(const base::FilePath& unpack_path) {
   const base::FilePath commands =
       unpack_path.Append(FILE_PATH_LITERAL("commands.json"));
-  if (!file_util::PathExists(commands))
+  if (!base::PathExists(commands))
     return NULL;
 
   JSONFileValueSerializer serializer(commands);
diff --git a/chrome/browser/component_updater/component_patcher_operation.cc b/chrome/browser/component_updater/component_patcher_operation.cc
index f814238..3f5f46a 100644
--- a/chrome/browser/component_updater/component_patcher_operation.cc
+++ b/chrome/browser/component_updater/component_patcher_operation.cc
@@ -72,7 +72,7 @@
     return parse_result;
 
   const base::FilePath parent = output_abs_path_.DirName();
-  if (!file_util::DirectoryExists(parent)) {
+  if (!base::DirectoryExists(parent)) {
     if (!file_util::CreateDirectory(parent))
       return ComponentUnpacker::kIoError;
   }
@@ -125,7 +125,7 @@
 ComponentUnpacker::Error DeltaUpdateOpCopy::DoRun(ComponentPatcher*,
                                                   int* error) {
   *error = 0;
-  if (!file_util::CopyFile(input_abs_path_, output_abs_path_))
+  if (!base::CopyFile(input_abs_path_, output_abs_path_))
     return ComponentUnpacker::kDeltaOperationFailure;
 
   return ComponentUnpacker::kNone;
diff --git a/chrome/browser/component_updater/component_patcher_win.cc b/chrome/browser/component_updater/component_patcher_win.cc
index a2f6865..76a72c5 100644
--- a/chrome/browser/component_updater/component_patcher_win.cc
+++ b/chrome/browser/component_updater/component_patcher_win.cc
@@ -42,12 +42,12 @@
   base::FilePath setup_path = exe_dir;
   setup_path = setup_path.AppendASCII(installer_dir);
   setup_path = setup_path.AppendASCII(setup_exe);
-  if (file_util::PathExists(setup_path))
+  if (base::PathExists(setup_path))
     return setup_path;
 
   setup_path = exe_dir;
   setup_path = setup_path.AppendASCII(setup_exe);
-  if (file_util::PathExists(setup_path))
+  if (base::PathExists(setup_path))
     return setup_path;
 
   return base::FilePath();
diff --git a/chrome/browser/component_updater/component_unpacker.cc b/chrome/browser/component_updater/component_unpacker.cc
index de7cfcb..744d90f 100644
--- a/chrome/browser/component_updater/component_unpacker.cc
+++ b/chrome/browser/component_updater/component_unpacker.cc
@@ -92,7 +92,7 @@
 base::DictionaryValue* ReadManifest(const base::FilePath& unpack_path) {
   base::FilePath manifest =
       unpack_path.Append(FILE_PATH_LITERAL("manifest.json"));
-  if (!file_util::PathExists(manifest))
+  if (!base::PathExists(manifest))
     return NULL;
   JSONFileValueSerializer serializer(manifest);
   std::string error;
@@ -109,8 +109,8 @@
 // This method doesn't take any special steps to prevent files from
 // being inserted into the target directory by another process or thread.
 bool MakeEmptyDirectory(const base::FilePath& path) {
-  if (file_util::PathExists(path)) {
-    if (!base::Delete(path, true))
+  if (base::PathExists(path)) {
+    if (!base::DeleteFile(path, true))
       return false;
   }
   if (!file_util::CreateDirectory(path))
@@ -186,7 +186,7 @@
                                                               patcher,
                                                               installer,
                                                               &extended_error_);
-    base::Delete(unpack_diff_path, true);
+    base::DeleteFile(unpack_diff_path, true);
     unpack_diff_path.clear();
     error_ = result;
     if (error_ != kNone) {
@@ -223,5 +223,5 @@
 
 ComponentUnpacker::~ComponentUnpacker() {
   if (!unpack_path_.empty())
-    base::Delete(unpack_path_, true);
+    base::DeleteFile(unpack_path_, true);
 }
diff --git a/chrome/browser/component_updater/component_updater_service.cc b/chrome/browser/component_updater/component_updater_service.cc
index 7b3d683..8b4b88b 100644
--- a/chrome/browser/component_updater/component_updater_service.cc
+++ b/chrome/browser/component_updater/component_updater_service.cc
@@ -22,9 +22,9 @@
 #include "base/strings/stringprintf.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/component_updater/component_patcher.h"
 #include "chrome/browser/component_updater/component_unpacker.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_utility_messages.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/extensions/extension.h"
@@ -929,7 +929,7 @@
                              context->fingerprint,
                              component_patcher_.get(),
                              context->installer);
-  if (!base::Delete(crx_path, false))
+  if (!base::DeleteFile(crx_path, false))
     NOTREACHED() << crx_path.value();
   // Why unretained? See comment at top of file.
   BrowserThread::PostDelayedTask(
diff --git a/chrome/browser/component_updater/pepper_flash_component_installer.cc b/chrome/browser/component_updater/pepper_flash_component_installer.cc
index c7cf4da..0b1e359 100644
--- a/chrome/browser/component_updater/pepper_flash_component_installer.cc
+++ b/chrome/browser/component_updater/pepper_flash_component_installer.cc
@@ -274,13 +274,13 @@
     return false;
   if (current_version_.CompareTo(version) > 0)
     return false;
-  if (!file_util::PathExists(unpack_path.Append(
+  if (!base::PathExists(unpack_path.Append(
           chrome::kPepperFlashPluginFilename)))
     return false;
   // Passed the basic tests. Time to install it.
   base::FilePath path =
       GetPepperFlashBaseDirectory().AppendASCII(version.GetString());
-  if (file_util::PathExists(path))
+  if (base::PathExists(path))
     return false;
   if (!base::Move(unpack_path, path))
     return false;
@@ -358,7 +358,7 @@
 void StartPepperFlashUpdateRegistration(ComponentUpdateService* cus) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
   base::FilePath path = GetPepperFlashBaseDirectory();
-  if (!file_util::PathExists(path)) {
+  if (!base::PathExists(path)) {
     if (!file_util::CreateDirectory(path)) {
       NOTREACHED() << "Could not create Pepper Flash directory.";
       return;
@@ -369,7 +369,7 @@
   std::vector<base::FilePath> older_dirs;
   if (GetPepperFlashDirectory(&path, &version, &older_dirs)) {
     path = path.Append(chrome::kPepperFlashPluginFilename);
-    if (file_util::PathExists(path)) {
+    if (base::PathExists(path)) {
       BrowserThread::PostTask(
           BrowserThread::UI, FROM_HERE,
           base::Bind(&RegisterPepperFlashWithChrome, path, version));
@@ -385,7 +385,7 @@
   // Remove older versions of Pepper Flash.
   for (std::vector<base::FilePath>::iterator iter = older_dirs.begin();
        iter != older_dirs.end(); ++iter) {
-    base::Delete(*iter, true);
+    base::DeleteFile(*iter, true);
   }
 }
 #endif  // defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX)
diff --git a/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc b/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc
index 44b66f3..0e47304 100644
--- a/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc
+++ b/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc
@@ -122,7 +122,7 @@
 base::DictionaryValue* ReadPnaclManifest(const base::FilePath& unpack_path) {
   base::FilePath manifest_path = GetPlatformDir(unpack_path).AppendASCII(
       "pnacl_public_pnacl_json");
-  if (!file_util::PathExists(manifest_path))
+  if (!base::PathExists(manifest_path))
     return NULL;
   return ReadJSONManifest(manifest_path);
 }
@@ -132,7 +132,7 @@
     const base::FilePath& unpack_path) {
   base::FilePath manifest_path = unpack_path.Append(
       FILE_PATH_LITERAL("manifest.json"));
-  if (!file_util::PathExists(manifest_path))
+  if (!base::PathExists(manifest_path))
     return NULL;
   return ReadJSONManifest(manifest_path);
 }
@@ -265,7 +265,7 @@
   // Passed the basic tests. Time to install it.
   base::FilePath path = GetPnaclBaseDirectory().AppendASCII(
       version.GetString());
-  if (file_util::PathExists(path)) {
+  if (base::PathExists(path)) {
     LOG(WARNING) << "Target path already exists, not installing.";
     NotifyInstallError();
     return false;
@@ -372,7 +372,7 @@
 void StartPnaclUpdateRegistration(PnaclComponentInstaller* pci) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
   base::FilePath path = pci->GetPnaclBaseDirectory();
-  if (!file_util::PathExists(path)) {
+  if (!base::PathExists(path)) {
     if (!file_util::CreateDirectory(path)) {
       NOTREACHED() << "Could not create base Pnacl directory.";
       return;
@@ -415,7 +415,7 @@
   // Remove older versions of PNaCl.
   for (std::vector<base::FilePath>::iterator iter = older_dirs.begin();
        iter != older_dirs.end(); ++iter) {
-    base::Delete(*iter, true);
+    base::DeleteFile(*iter, true);
   }
 }
 
diff --git a/chrome/browser/component_updater/pnacl/pnacl_profile_observer.cc b/chrome/browser/component_updater/pnacl/pnacl_profile_observer.cc
index a3f9e34..bf959c3 100644
--- a/chrome/browser/component_updater/pnacl/pnacl_profile_observer.cc
+++ b/chrome/browser/component_updater/pnacl/pnacl_profile_observer.cc
@@ -5,8 +5,8 @@
 #include "chrome/browser/component_updater/pnacl/pnacl_profile_observer.h"
 
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 
 PnaclProfileObserver::PnaclProfileObserver(
diff --git a/chrome/browser/component_updater/pnacl/pnacl_updater_observer.cc b/chrome/browser/component_updater/pnacl/pnacl_updater_observer.cc
index 2a3a6fa..066867a 100644
--- a/chrome/browser/component_updater/pnacl/pnacl_updater_observer.cc
+++ b/chrome/browser/component_updater/pnacl/pnacl_updater_observer.cc
@@ -5,8 +5,8 @@
 #include "chrome/browser/component_updater/pnacl/pnacl_updater_observer.h"
 
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 
 PnaclUpdaterObserver::PnaclUpdaterObserver(
diff --git a/chrome/browser/component_updater/recovery_component_installer.cc b/chrome/browser/component_updater/recovery_component_installer.cc
index 4891aab..625afd6 100644
--- a/chrome/browser/component_updater/recovery_component_installer.cc
+++ b/chrome/browser/component_updater/recovery_component_installer.cc
@@ -112,7 +112,7 @@
   if (current_version_.CompareTo(version) >= 0)
     return false;
   base::FilePath main_file = unpack_path.Append(kRecoveryFileName);
-  if (!file_util::PathExists(main_file))
+  if (!base::PathExists(main_file))
     return false;
   // Passed the basic tests. The installation continues with the
   // recovery component itself running from the temp directory.
diff --git a/chrome/browser/component_updater/swiftshader_component_installer.cc b/chrome/browser/component_updater/swiftshader_component_installer.cc
index 9aa42e0..110c0e9 100644
--- a/chrome/browser/component_updater/swiftshader_component_installer.cc
+++ b/chrome/browser/component_updater/swiftshader_component_installer.cc
@@ -72,8 +72,8 @@
     if (!version.IsValid())
       continue;
     if (version.CompareTo(*latest) > 0 &&
-        file_util::PathExists(path.Append(kSwiftShaderEglName)) &&
-        file_util::PathExists(path.Append(kSwiftShaderGlesName))) {
+        base::PathExists(path.Append(kSwiftShaderEglName)) &&
+        base::PathExists(path.Append(kSwiftShaderGlesName))) {
       if (found && older_dirs)
           older_dirs->push_back(*result);
       *latest = version;
@@ -135,13 +135,13 @@
     return false;
   if (current_version_.CompareTo(version) >= 0)
     return false;
-  if (!file_util::PathExists(unpack_path.Append(kSwiftShaderEglName)) ||
-      !file_util::PathExists(unpack_path.Append(kSwiftShaderGlesName)))
+  if (!base::PathExists(unpack_path.Append(kSwiftShaderEglName)) ||
+      !base::PathExists(unpack_path.Append(kSwiftShaderGlesName)))
     return false;
   // Passed the basic tests. Time to install it.
   base::FilePath path =
       GetSwiftShaderBaseDirectory().AppendASCII(version.GetString());
-  if (file_util::PathExists(path))
+  if (base::PathExists(path))
     return false;
   if (!base::Move(unpack_path, path))
     return false;
@@ -208,7 +208,7 @@
 void RegisterSwiftShaderPath(ComponentUpdateService* cus) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
   base::FilePath path = GetSwiftShaderBaseDirectory();
-  if (!file_util::PathExists(path)) {
+  if (!base::PathExists(path)) {
     if (!file_util::CreateDirectory(path)) {
       NOTREACHED() << "Could not create SwiftShader directory.";
       return;
@@ -230,7 +230,7 @@
   // Remove older versions of SwiftShader.
   for (std::vector<base::FilePath>::iterator iter = older_dirs.begin();
        iter != older_dirs.end(); ++iter) {
-    base::Delete(*iter, true);
+    base::DeleteFile(*iter, true);
   }
 }
 
diff --git a/chrome/browser/component_updater/test/component_installers_unittest.cc b/chrome/browser/component_updater/test/component_installers_unittest.cc
index 91b59bb..a97bb18 100644
--- a/chrome/browser/component_updater/test/component_installers_unittest.cc
+++ b/chrome/browser/component_updater/test/component_installers_unittest.cc
@@ -65,7 +65,7 @@
   manifest = manifest.Append(kDataPath);
   manifest = manifest.AppendASCII("manifest.json");
 
-  if (!file_util::PathExists(manifest)) {
+  if (!base::PathExists(manifest)) {
     LOG(WARNING) << "No test manifest available. Skipping.";
     return;
   }
diff --git a/chrome/browser/component_updater/test/component_patcher_unittest.cc b/chrome/browser/component_updater/test/component_patcher_unittest.cc
index 7593a4b..f121fc0 100644
--- a/chrome/browser/component_updater/test/component_patcher_unittest.cc
+++ b/chrome/browser/component_updater/test/component_patcher_unittest.cc
@@ -64,7 +64,7 @@
 
 // Verify that a 'create' delta update operation works correctly.
 TEST_F(ComponentPatcherOperationTest, CheckCreateOperation) {
-  EXPECT_TRUE(file_util::CopyFile(
+  EXPECT_TRUE(base::CopyFile(
       test_file("binary_output.bin"),
       input_dir_.path().Append(FILE_PATH_LITERAL("binary_output.bin"))));
 
@@ -85,14 +85,14 @@
 
   EXPECT_EQ(ComponentUnpacker::kNone, result);
   EXPECT_EQ(0, error);
-  EXPECT_TRUE(file_util::ContentsEqual(
+  EXPECT_TRUE(base::ContentsEqual(
       unpack_dir_.path().Append(FILE_PATH_LITERAL("output.bin")),
       test_file("binary_output.bin")));
 }
 
 // Verify that a 'copy' delta update operation works correctly.
 TEST_F(ComponentPatcherOperationTest, CheckCopyOperation) {
-  EXPECT_TRUE(file_util::CopyFile(
+  EXPECT_TRUE(base::CopyFile(
       test_file("binary_output.bin"),
       installed_dir_.path().Append(FILE_PATH_LITERAL("binary_output.bin"))));
 
@@ -112,7 +112,7 @@
                                      &error);
   EXPECT_EQ(ComponentUnpacker::kNone, result);
   EXPECT_EQ(0, error);
-  EXPECT_TRUE(file_util::ContentsEqual(
+  EXPECT_TRUE(base::ContentsEqual(
       unpack_dir_.path().Append(FILE_PATH_LITERAL("output.bin")),
       test_file("binary_output.bin")));
 }
diff --git a/chrome/browser/component_updater/test/component_patcher_unittest_win.cc b/chrome/browser/component_updater/test/component_patcher_unittest_win.cc
index 896cf59..afec59d 100644
--- a/chrome/browser/component_updater/test/component_patcher_unittest_win.cc
+++ b/chrome/browser/component_updater/test/component_patcher_unittest_win.cc
@@ -21,10 +21,10 @@
 
 // Verify that a 'courgette' delta update operation works correctly.
 TEST_F(ComponentPatcherOperationTest, CheckCourgetteOperation) {
-  EXPECT_TRUE(file_util::CopyFile(
+  EXPECT_TRUE(base::CopyFile(
       test_file("binary_input.bin"),
       installed_dir_.path().Append(FILE_PATH_LITERAL("binary_input.bin"))));
-  EXPECT_TRUE(file_util::CopyFile(
+  EXPECT_TRUE(base::CopyFile(
       test_file("binary_courgette_patch.bin"),
       input_dir_.path().Append(
           FILE_PATH_LITERAL("binary_courgette_patch.bin"))));
@@ -46,17 +46,17 @@
                                      &error);
   EXPECT_EQ(ComponentUnpacker::kNone, result);
   EXPECT_EQ(0, error);
-  EXPECT_TRUE(file_util::ContentsEqual(
+  EXPECT_TRUE(base::ContentsEqual(
       unpack_dir_.path().Append(FILE_PATH_LITERAL("output.bin")),
       test_file("binary_output.bin")));
 }
 
 // Verify that a 'bsdiff' delta update operation works correctly.
 TEST_F(ComponentPatcherOperationTest, CheckBsdiffOperation) {
-  EXPECT_TRUE(file_util::CopyFile(
+  EXPECT_TRUE(base::CopyFile(
       test_file("binary_input.bin"),
       installed_dir_.path().Append(FILE_PATH_LITERAL("binary_input.bin"))));
-  EXPECT_TRUE(file_util::CopyFile(
+  EXPECT_TRUE(base::CopyFile(
       test_file("binary_bsdiff_patch.bin"),
       input_dir_.path().Append(FILE_PATH_LITERAL("binary_bsdiff_patch.bin"))));
 
@@ -77,7 +77,7 @@
                                      &error);
   EXPECT_EQ(ComponentUnpacker::kNone, result);
   EXPECT_EQ(0, error);
-  EXPECT_TRUE(file_util::ContentsEqual(
+  EXPECT_TRUE(base::ContentsEqual(
       unpack_dir_.path().Append(FILE_PATH_LITERAL("output.bin")),
       test_file("binary_output.bin")));
 }
diff --git a/chrome/browser/component_updater/test/component_updater_service_unittest.cc b/chrome/browser/component_updater/test/component_updater_service_unittest.cc
index 9277e88..5bbd3cf 100644
--- a/chrome/browser/component_updater/test/component_updater_service_unittest.cc
+++ b/chrome/browser/component_updater/test/component_updater_service_unittest.cc
@@ -13,11 +13,11 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/component_updater/component_updater_service.h"
 #include "chrome/browser/component_updater/test/component_patcher_mock.h"
 #include "chrome/browser/component_updater/test/component_updater_service_unittest.h"
 #include "chrome/browser/component_updater/test/test_installer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/component_updater/test/component_updater_service_unittest_win.cc b/chrome/browser/component_updater/test/component_updater_service_unittest_win.cc
index 973f037..4a4617f 100644
--- a/chrome/browser/component_updater/test/component_updater_service_unittest_win.cc
+++ b/chrome/browser/component_updater/test/component_updater_service_unittest_win.cc
@@ -13,11 +13,11 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/component_updater/component_updater_service.h"
 #include "chrome/browser/component_updater/test/component_patcher_mock.h"
 #include "chrome/browser/component_updater/test/component_updater_service_unittest.h"
 #include "chrome/browser/component_updater/test/test_installer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/component_updater/test/test_installer.cc b/chrome/browser/component_updater/test/test_installer.cc
index 3f9b0e0..28ff22d 100644
--- a/chrome/browser/component_updater/test/test_installer.cc
+++ b/chrome/browser/component_updater/test/test_installer.cc
@@ -19,7 +19,7 @@
 bool TestInstaller::Install(const base::DictionaryValue& manifest,
                             const base::FilePath& unpack_path) {
   ++install_count_;
-  return base::Delete(unpack_path, true);
+  return base::DeleteFile(unpack_path, true);
 }
 
 bool TestInstaller::GetInstalledFile(const std::string& file,
@@ -52,7 +52,7 @@
 }
 
 VersionedTestInstaller::~VersionedTestInstaller() {
-  base::Delete(install_directory_, true);
+  base::DeleteFile(install_directory_, true);
 }
 
 
diff --git a/chrome/browser/component_updater/widevine_cdm_component_installer.cc b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
index bbfebbd..400b94f 100644
--- a/chrome/browser/component_updater/widevine_cdm_component_installer.cc
+++ b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
@@ -221,25 +221,25 @@
   if (current_version_.CompareTo(version) > 0)
     return false;
 
-  if (!file_util::PathExists(unpack_path.AppendASCII(kWidevineCdmFileName)))
+  if (!base::PathExists(unpack_path.AppendASCII(kWidevineCdmFileName)))
     return false;
 
   base::FilePath adapter_source_path;
   PathService::Get(chrome::FILE_WIDEVINE_CDM_ADAPTER, &adapter_source_path);
-  if (!file_util::PathExists(adapter_source_path))
+  if (!base::PathExists(adapter_source_path))
     return false;
 
   // Passed the basic tests. Time to install it.
   base::FilePath install_path =
       GetWidevineCdmBaseDirectory().AppendASCII(version.GetString());
-  if (file_util::PathExists(install_path))
+  if (base::PathExists(install_path))
     return false;
   if (!base::Move(unpack_path, install_path))
     return false;
 
   base::FilePath adapter_install_path =
       install_path.AppendASCII(kWidevineCdmAdapterFileName);
-  if (!file_util::CopyFile(adapter_source_path, adapter_install_path))
+  if (!base::CopyFile(adapter_source_path, adapter_install_path))
     return false;
 
   // Installation is done. Now register the Widevine CDM with chrome.
@@ -281,7 +281,7 @@
 void StartWidevineCdmUpdateRegistration(ComponentUpdateService* cus) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
   base::FilePath base_dir = GetWidevineCdmBaseDirectory();
-  if (!file_util::PathExists(base_dir) &&
+  if (!base::PathExists(base_dir) &&
       !file_util::CreateDirectory(base_dir)) {
     NOTREACHED() << "Could not create Widevine CDM directory.";
     return;
@@ -296,13 +296,13 @@
         latest_dir.AppendASCII(kWidevineCdmAdapterFileName);
     base::FilePath cdm_path = latest_dir.AppendASCII(kWidevineCdmFileName);
 
-    if (file_util::PathExists(adapter_path) &&
-        file_util::PathExists(cdm_path)) {
+    if (base::PathExists(adapter_path) &&
+        base::PathExists(cdm_path)) {
       BrowserThread::PostTask(
           BrowserThread::UI, FROM_HERE,
           base::Bind(&RegisterWidevineCdmWithChrome, adapter_path, version));
     } else {
-      base::Delete(latest_dir, true);
+      base::DeleteFile(latest_dir, true);
       version = base::Version(kNullVersion);
     }
   }
@@ -314,7 +314,7 @@
   // Remove older versions of Widevine CDM.
   for (std::vector<base::FilePath>::iterator iter = older_dirs.begin();
        iter != older_dirs.end(); ++iter) {
-    base::Delete(*iter, true);
+    base::DeleteFile(*iter, true);
   }
 }
 
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc
index 857612c..bee7ee8 100644
--- a/chrome/browser/content_settings/content_settings_browsertest.cc
+++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -6,6 +6,7 @@
 #include "base/path_service.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/cookie_settings.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -496,7 +496,7 @@
     base::FilePath plugin_dir;
     EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir));
     base::FilePath plugin_lib = plugin_dir.AppendASCII(kLibraryName);
-    EXPECT_TRUE(file_util::PathExists(plugin_lib));
+    EXPECT_TRUE(base::PathExists(plugin_lib));
     base::FilePath::StringType pepper_plugin = plugin_lib.value();
     pepper_plugin.append(FILE_PATH_LITERAL(
         "#Clear Key CDM#Clear Key CDM 0.1.0.0#0.1.0.0;"));
diff --git a/chrome/browser/content_settings/content_settings_default_provider.cc b/chrome/browser/content_settings/content_settings_default_provider.cc
index af80637..60e1bb6 100644
--- a/chrome/browser/content_settings/content_settings_default_provider.cc
+++ b/chrome/browser/content_settings/content_settings_default_provider.cc
@@ -12,10 +12,10 @@
 #include "base/command_line.h"
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_rule.h"
 #include "chrome/browser/content_settings/content_settings_utils.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/content_settings_pattern.h"
 #include "chrome/common/pref_names.h"
@@ -49,6 +49,7 @@
   CONTENT_SETTING_ASK,      // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
   CONTENT_SETTING_DEFAULT,  // CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
   CONTENT_SETTING_ASK,      // CONTENT_SETTINGS_TYPE_PPAPI_BROKER
+  CONTENT_SETTING_ASK,      // CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
 #if defined(OS_WIN)
   CONTENT_SETTING_ASK,      // CONTENT_SETTINGS_TYPE_METRO_SWITCH_TO_DESKTOP
 #endif
@@ -87,7 +88,7 @@
 }  // namespace
 
 // static
-void DefaultProvider::RegisterUserPrefs(
+void DefaultProvider::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   // The registration of the preference prefs::kDefaultContentSettings should
   // also include the default values for default content settings. This allows
diff --git a/chrome/browser/content_settings/content_settings_default_provider.h b/chrome/browser/content_settings/content_settings_default_provider.h
index 92c2e3e..0f3b406 100644
--- a/chrome/browser/content_settings/content_settings_default_provider.h
+++ b/chrome/browser/content_settings/content_settings_default_provider.h
@@ -28,7 +28,7 @@
 // default values.
 class DefaultProvider : public ObservableProvider {
  public:
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   DefaultProvider(PrefService* prefs,
                   bool incognito);
diff --git a/chrome/browser/content_settings/content_settings_internal_extension_provider.cc b/chrome/browser/content_settings/content_settings_internal_extension_provider.cc
index c6527c1..723dc43 100644
--- a/chrome/browser/content_settings/content_settings_internal_extension_provider.cc
+++ b/chrome/browser/content_settings/content_settings_internal_extension_provider.cc
@@ -4,10 +4,10 @@
 
 #include "chrome/browser/content_settings/content_settings_internal_extension_provider.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_rule.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/content_settings_pattern.h"
 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
diff --git a/chrome/browser/content_settings/content_settings_policy_provider.cc b/chrome/browser/content_settings/content_settings_policy_provider.cc
index f6c2ca1..1ac77eb 100644
--- a/chrome/browser/content_settings/content_settings_policy_provider.cc
+++ b/chrome/browser/content_settings/content_settings_policy_provider.cc
@@ -10,9 +10,9 @@
 #include "base/json/json_reader.h"
 #include "base/prefs/pref_service.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_rule.h"
 #include "chrome/browser/content_settings/content_settings_utils.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/content_settings_pattern.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -42,6 +42,7 @@
   NULL,  // No policy for default value of media stream camera
   NULL,  // No policy for default value of protocol handlers
   NULL,  // No policy for default value of PPAPI broker
+  NULL,  // No policy for default value of multiple automatic downloads
 #if defined(OS_WIN)
   NULL,  // No policy for default value of "switch to desktop"
 #endif
@@ -117,7 +118,7 @@
 namespace content_settings {
 
 // static
-void PolicyProvider::RegisterUserPrefs(
+void PolicyProvider::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(prefs::kManagedAutoSelectCertificateForUrls,
                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
diff --git a/chrome/browser/content_settings/content_settings_policy_provider.h b/chrome/browser/content_settings/content_settings_policy_provider.h
index a586820..6366df7 100644
--- a/chrome/browser/content_settings/content_settings_policy_provider.h
+++ b/chrome/browser/content_settings/content_settings_policy_provider.h
@@ -28,7 +28,7 @@
  public:
   explicit PolicyProvider(PrefService* prefs);
   virtual ~PolicyProvider();
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // ProviderInterface implementations.
   virtual RuleIterator* GetRuleIterator(
diff --git a/chrome/browser/content_settings/content_settings_pref_provider.cc b/chrome/browser/content_settings/content_settings_pref_provider.cc
index d5b4894..569c06c 100644
--- a/chrome/browser/content_settings/content_settings_pref_provider.cc
+++ b/chrome/browser/content_settings/content_settings_pref_provider.cc
@@ -13,11 +13,11 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_rule.h"
 #include "chrome/browser/content_settings/content_settings_utils.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/content_settings_pattern.h"
@@ -72,7 +72,7 @@
 //
 
 // static
-void PrefProvider::RegisterUserPrefs(
+void PrefProvider::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       prefs::kContentSettingsVersion,
@@ -398,7 +398,8 @@
         ParsePatternString(pattern_str);
     if (!pattern_pair.first.IsValid() ||
         !pattern_pair.second.IsValid()) {
-      LOG(DFATAL) << "Invalid pattern strings: " << pattern_str;
+      // TODO: Change this to DFATAL when crbug.com/132659 is fixed.
+      LOG(ERROR) << "Invalid pattern strings: " << pattern_str;
       continue;
     }
 
diff --git a/chrome/browser/content_settings/content_settings_pref_provider.h b/chrome/browser/content_settings/content_settings_pref_provider.h
index edecd92..ad78aee 100644
--- a/chrome/browser/content_settings/content_settings_pref_provider.h
+++ b/chrome/browser/content_settings/content_settings_pref_provider.h
@@ -32,7 +32,7 @@
 // preference.
 class PrefProvider : public ObservableProvider {
  public:
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   PrefProvider(PrefService* prefs, bool incognito);
   virtual ~PrefProvider();
diff --git a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
index efbe7cf..138cddf 100644
--- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
+++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
@@ -140,14 +140,14 @@
       new user_prefs::PrefRegistrySyncable);
   PrefServiceSyncable* regular_prefs = builder.CreateSyncable(registry.get());
 
-  chrome::RegisterUserPrefs(registry.get());
+  chrome::RegisterUserProfilePrefs(registry.get());
 
   builder.WithUserPrefs(otr_user_prefs);
   scoped_refptr<user_prefs::PrefRegistrySyncable> otr_registry(
       new user_prefs::PrefRegistrySyncable);
   PrefServiceSyncable* otr_prefs = builder.CreateSyncable(otr_registry.get());
 
-  chrome::RegisterUserPrefs(otr_registry.get());
+  chrome::RegisterUserProfilePrefs(otr_registry.get());
 
   TestingProfile::Builder profile_builder;
   profile_builder.SetPrefService(make_scoped_ptr(regular_prefs));
@@ -420,7 +420,7 @@
 // http://crosbug.com/17760
 TEST_F(PrefProviderTest, Deadlock) {
   TestingPrefServiceSyncable prefs;
-  PrefProvider::RegisterUserPrefs(prefs.registry());
+  PrefProvider::RegisterProfilePrefs(prefs.registry());
 
   // Chain of events: a preference changes, |PrefProvider| notices it, and reads
   // and writes the preference. When the preference is written, a notification
diff --git a/chrome/browser/content_settings/content_settings_utils.cc b/chrome/browser/content_settings/content_settings_utils.cc
index 52f1650..6c1f056 100644
--- a/chrome/browser/content_settings/content_settings_utils.cc
+++ b/chrome/browser/content_settings/content_settings_utils.cc
@@ -39,6 +39,7 @@
   "media-stream-camera",
   "register-protocol-handler",
   "ppapi-broker",
+  "multiple-automatic-downloads",
 #if defined(OS_WIN)
   "metro-switch-to-desktop",
 #endif
diff --git a/chrome/browser/content_settings/cookie_settings.cc b/chrome/browser/content_settings/cookie_settings.cc
index bd82c1d..529df81 100644
--- a/chrome/browser/content_settings/cookie_settings.cc
+++ b/chrome/browser/content_settings/cookie_settings.cc
@@ -6,11 +6,11 @@
 
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_utils.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/content_settings_pattern.h"
 #include "chrome/common/pref_names.h"
@@ -66,7 +66,7 @@
 
 CookieSettings::Factory::~Factory() {}
 
-void CookieSettings::Factory::RegisterUserPrefs(
+void CookieSettings::Factory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kBlockThirdPartyCookies,
diff --git a/chrome/browser/content_settings/cookie_settings.h b/chrome/browser/content_settings/cookie_settings.h
index eec000b..a8137b7 100644
--- a/chrome/browser/content_settings/cookie_settings.h
+++ b/chrome/browser/content_settings/cookie_settings.h
@@ -99,7 +99,7 @@
       bool setting_cookie,
       content_settings::SettingSource* source) const;
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   class Factory : public RefcountedBrowserContextKeyedServiceFactory {
    public:
@@ -117,7 +117,7 @@
     virtual ~Factory();
 
     // |BrowserContextKeyedBaseFactory| methods:
-    virtual void RegisterUserPrefs(
+    virtual void RegisterProfilePrefs(
         user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
     virtual content::BrowserContext* GetBrowserContextToUse(
         content::BrowserContext* context) const OVERRIDE;
diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc
index fad7c9d..ed8fd91 100644
--- a/chrome/browser/content_settings/host_content_settings_map.cc
+++ b/chrome/browser/content_settings/host_content_settings_map.cc
@@ -12,6 +12,7 @@
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_custom_extension_provider.h"
 #include "chrome/browser/content_settings/content_settings_default_provider.h"
 #include "chrome/browser/content_settings/content_settings_details.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/content_settings/content_settings_rule.h"
 #include "chrome/browser/content_settings/content_settings_utils.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/content_settings_pattern.h"
 #include "chrome/common/pref_names.h"
@@ -138,7 +138,7 @@
 #endif
 
 // static
-void HostContentSettingsMap::RegisterUserPrefs(
+void HostContentSettingsMap::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       prefs::kContentSettingsWindowLastTabIndex,
@@ -154,9 +154,9 @@
       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
 
   // Register the prefs for the content settings providers.
-  content_settings::DefaultProvider::RegisterUserPrefs(registry);
-  content_settings::PrefProvider::RegisterUserPrefs(registry);
-  content_settings::PolicyProvider::RegisterUserPrefs(registry);
+  content_settings::DefaultProvider::RegisterProfilePrefs(registry);
+  content_settings::PrefProvider::RegisterProfilePrefs(registry);
+  content_settings::PolicyProvider::RegisterProfilePrefs(registry);
 }
 
 ContentSetting HostContentSettingsMap::GetDefaultContentSettingFromProvider(
@@ -385,6 +385,7 @@
     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
     case CONTENT_SETTINGS_TYPE_PPAPI_BROKER:
+    case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
       return setting == CONTENT_SETTING_ASK;
     default:
       return false;
diff --git a/chrome/browser/content_settings/host_content_settings_map.h b/chrome/browser/content_settings/host_content_settings_map.h
index b68e09d..d7ef947 100644
--- a/chrome/browser/content_settings/host_content_settings_map.h
+++ b/chrome/browser/content_settings/host_content_settings_map.h
@@ -60,7 +60,7 @@
   void RegisterExtensionService(ExtensionService* extension_service);
 #endif
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Returns the default setting for a particular content type. If |provider_id|
   // is not NULL, the id of the provider which provided the default setting is
diff --git a/chrome/browser/content_settings/mock_settings_observer.cc b/chrome/browser/content_settings/mock_settings_observer.cc
index 0640a2e..816914f 100644
--- a/chrome/browser/content_settings/mock_settings_observer.cc
+++ b/chrome/browser/content_settings/mock_settings_observer.cc
@@ -4,9 +4,9 @@
 
 #include "chrome/browser/content_settings/mock_settings_observer.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_details.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
 #include "url/gurl.h"
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc
index ea8d293..1ddd3e9 100644
--- a/chrome/browser/content_settings/tab_specific_content_settings.cc
+++ b/chrome/browser/content_settings/tab_specific_content_settings.cc
@@ -16,11 +16,11 @@
 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
 #include "chrome/browser/browsing_data/cookies_tree_model.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_details.h"
 #include "chrome/browser/content_settings/content_settings_utils.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/render_messages.h"
 #include "content/public/browser/browser_thread.h"
@@ -210,8 +210,10 @@
       content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM ||
       content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
       content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
-      content_type == CONTENT_SETTINGS_TYPE_PPAPI_BROKER)
+      content_type == CONTENT_SETTINGS_TYPE_PPAPI_BROKER ||
+      content_type == CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS) {
     return content_blocked_[content_type];
+  }
 
   return false;
 }
@@ -229,12 +231,13 @@
 bool TabSpecificContentSettings::IsContentAllowed(
     ContentSettingsType content_type) const {
   // This method currently only returns meaningful values for the content type
-  // cookies, mediastream, and PPAPI broker.
+  // cookies, mediastream, PPAPI broker, and downloads.
   if (content_type != CONTENT_SETTINGS_TYPE_COOKIES &&
       content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM &&
       content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC &&
       content_type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA &&
-      content_type != CONTENT_SETTINGS_TYPE_PPAPI_BROKER) {
+      content_type != CONTENT_SETTINGS_TYPE_PPAPI_BROKER &&
+      content_type != CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS) {
     return false;
   }
 
@@ -522,6 +525,17 @@
       content::NotificationService::NoDetails());
 }
 
+void TabSpecificContentSettings::SetDownloadsBlocked(bool blocked) {
+  content_blocked_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = blocked;
+  content_allowed_[CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = !blocked;
+  content_blockage_indicated_to_user_[
+    CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS] = false;
+  content::NotificationService::current()->Notify(
+      chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
+      content::Source<WebContents>(web_contents()),
+      content::NotificationService::NoDetails());
+}
+
 void TabSpecificContentSettings::SetPopupsBlocked(bool blocked) {
   content_blocked_[CONTENT_SETTINGS_TYPE_POPUPS] = blocked;
   content_blockage_indicated_to_user_[CONTENT_SETTINGS_TYPE_POPUPS] = false;
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.h b/chrome/browser/content_settings/tab_specific_content_settings.h
index d409e51..ad1fa63 100644
--- a/chrome/browser/content_settings/tab_specific_content_settings.h
+++ b/chrome/browser/content_settings/tab_specific_content_settings.h
@@ -162,6 +162,9 @@
   // Changes the |content_blocked_| entry for popups.
   void SetPopupsBlocked(bool blocked);
 
+  // Changes the |content_blocked_| entry for downloads.
+  void SetDownloadsBlocked(bool blocked);
+
   // Updates Geolocation settings on navigation.
   void GeolocationDidNavigate(
       const content::LoadCommittedDetails& details);
diff --git a/chrome/browser/crash_handler_host_linux.h b/chrome/browser/crash_handler_host_linux.h
index bcd9dd7..64a01d2 100644
--- a/chrome/browser/crash_handler_host_linux.h
+++ b/chrome/browser/crash_handler_host_linux.h
@@ -5,22 +5,19 @@
 #ifndef CHROME_BROWSER_CRASH_HANDLER_HOST_LINUX_H_
 #define CHROME_BROWSER_CRASH_HANDLER_HOST_LINUX_H_
 
-#include "base/compiler_specific.h"
-#include "base/message_loop.h"
-
-#if defined(USE_LINUX_BREAKPAD)
 #include <sys/types.h>
 
 #include <string>
 
+#include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/message_loop.h"
 
 struct BreakpadInfo;
 
 namespace base {
 class Thread;
 }
-#endif  // defined(USE_LINUX_BREAKPAD)
 
 template <typename T> struct DefaultSingletonTraits;
 
@@ -50,26 +47,21 @@
   // MessageLoop::DestructionObserver impl:
   virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
 
-#if defined(USE_LINUX_BREAKPAD)
   // Whether we are shutting down or not.
   bool IsShuttingDown() const;
-#endif
 
  protected:
   CrashHandlerHostLinux();
   virtual ~CrashHandlerHostLinux();
 
-#if defined(USE_LINUX_BREAKPAD)
   // Only called in concrete subclasses.
   void InitCrashUploaderThread();
 
   std::string process_type_;
-#endif
 
  private:
   void Init();
 
-#if defined(USE_LINUX_BREAKPAD)
   // This is here on purpose to make CrashHandlerHostLinux abstract.
   virtual void SetProcessType() = 0;
 
@@ -81,16 +73,13 @@
 
   // Continue OnFileCanReadWithoutBlocking()'s work on the IO thread.
   void QueueCrashDumpTask(BreakpadInfo* info, int signal_fd);
-#endif
 
   int process_socket_;
   int browser_socket_;
 
-#if defined(USE_LINUX_BREAKPAD)
   base::MessageLoopForIO::FileDescriptorWatcher file_descriptor_watcher_;
   scoped_ptr<base::Thread> uploader_thread_;
   bool shutting_down_;
-#endif
 
 #if defined(ADDRESS_SANITIZER)
   char* asan_report_str_;
@@ -109,9 +98,7 @@
   ExtensionCrashHandlerHostLinux();
   virtual ~ExtensionCrashHandlerHostLinux();
 
-#if defined(USE_LINUX_BREAKPAD)
   virtual void SetProcessType() OVERRIDE;
-#endif
 
   DISALLOW_COPY_AND_ASSIGN(ExtensionCrashHandlerHostLinux);
 };
@@ -126,9 +113,7 @@
   GpuCrashHandlerHostLinux();
   virtual ~GpuCrashHandlerHostLinux();
 
-#if defined(USE_LINUX_BREAKPAD)
   virtual void SetProcessType() OVERRIDE;
-#endif
 
   DISALLOW_COPY_AND_ASSIGN(GpuCrashHandlerHostLinux);
 };
@@ -143,9 +128,7 @@
   PluginCrashHandlerHostLinux();
   virtual ~PluginCrashHandlerHostLinux();
 
-#if defined(USE_LINUX_BREAKPAD)
   virtual void SetProcessType() OVERRIDE;
-#endif
 
   DISALLOW_COPY_AND_ASSIGN(PluginCrashHandlerHostLinux);
 };
@@ -160,9 +143,7 @@
   PpapiCrashHandlerHostLinux();
   virtual ~PpapiCrashHandlerHostLinux();
 
-#if defined(USE_LINUX_BREAKPAD)
   virtual void SetProcessType() OVERRIDE;
-#endif
 
   DISALLOW_COPY_AND_ASSIGN(PpapiCrashHandlerHostLinux);
 };
@@ -177,9 +158,7 @@
   RendererCrashHandlerHostLinux();
   virtual ~RendererCrashHandlerHostLinux();
 
-#if defined(USE_LINUX_BREAKPAD)
   virtual void SetProcessType() OVERRIDE;
-#endif
 
   DISALLOW_COPY_AND_ASSIGN(RendererCrashHandlerHostLinux);
 };
diff --git a/chrome/browser/crash_handler_host_linux_stub.cc b/chrome/browser/crash_handler_host_linux_stub.cc
deleted file mode 100644
index fc81c27..0000000
--- a/chrome/browser/crash_handler_host_linux_stub.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is a stub file which is compiled in when we are building without
-// breakpad support.
-
-#include "chrome/browser/crash_handler_host_linux.h"
-
-#include "base/memory/singleton.h"
-
-CrashHandlerHostLinux::CrashHandlerHostLinux()
-    : process_socket_(-1),
-      browser_socket_(-1) {
-}
-
-CrashHandlerHostLinux::~CrashHandlerHostLinux() {
-}
-
-void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) {
-}
-
-void CrashHandlerHostLinux::OnFileCanWriteWithoutBlocking(int fd) {
-}
-
-void CrashHandlerHostLinux::WillDestroyCurrentMessageLoop() {
-}
-
-ExtensionCrashHandlerHostLinux::ExtensionCrashHandlerHostLinux() {
-}
-
-ExtensionCrashHandlerHostLinux::~ExtensionCrashHandlerHostLinux() {
-}
-
-// static
-ExtensionCrashHandlerHostLinux* ExtensionCrashHandlerHostLinux::GetInstance() {
-  return Singleton<ExtensionCrashHandlerHostLinux>::get();
-}
-
-GpuCrashHandlerHostLinux::GpuCrashHandlerHostLinux() {
-}
-
-GpuCrashHandlerHostLinux::~GpuCrashHandlerHostLinux() {
-}
-
-// static
-GpuCrashHandlerHostLinux* GpuCrashHandlerHostLinux::GetInstance() {
-  return Singleton<GpuCrashHandlerHostLinux>::get();
-}
-
-PluginCrashHandlerHostLinux::PluginCrashHandlerHostLinux() {
-}
-
-PluginCrashHandlerHostLinux::~PluginCrashHandlerHostLinux() {
-}
-
-// static
-PluginCrashHandlerHostLinux* PluginCrashHandlerHostLinux::GetInstance() {
-  return Singleton<PluginCrashHandlerHostLinux>::get();
-}
-
-PpapiCrashHandlerHostLinux::PpapiCrashHandlerHostLinux() {
-}
-
-PpapiCrashHandlerHostLinux::~PpapiCrashHandlerHostLinux() {
-}
-
-// static
-PpapiCrashHandlerHostLinux* PpapiCrashHandlerHostLinux::GetInstance() {
-  return Singleton<PpapiCrashHandlerHostLinux>::get();
-}
-
-RendererCrashHandlerHostLinux::RendererCrashHandlerHostLinux() {
-}
-
-RendererCrashHandlerHostLinux::~RendererCrashHandlerHostLinux() {
-}
-
-// static
-RendererCrashHandlerHostLinux* RendererCrashHandlerHostLinux::GetInstance() {
-  return Singleton<RendererCrashHandlerHostLinux>::get();
-}
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
index de1e871..d00fe82 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -10,10 +10,10 @@
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h"
 #include "chrome/browser/net/chrome_url_request_context.h"
 #include "chrome/browser/profiles/profile_io_data.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/custom_handlers/protocol_handler.h"
 #include "chrome/common/pref_names.h"
@@ -707,7 +707,7 @@
 }
 
 // static
-void ProtocolHandlerRegistry::RegisterUserPrefs(
+void ProtocolHandlerRegistry::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(prefs::kRegisteredProtocolHandlers,
                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.h b/chrome/browser/custom_handlers/protocol_handler_registry.h
index 79e44aa..fd9e385 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.h
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.h
@@ -235,7 +235,7 @@
   virtual void Shutdown() OVERRIDE;
 
   // Registers the preferences that we store registered protocol handlers in.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   bool enabled() const { return enabled_; }
 
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
index 0471735..f3686f0 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
@@ -10,8 +10,8 @@
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/waitable_event.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/custom_handlers/protocol_handler.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.cc b/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.cc
index 3572ba7..d7f6aa1 100644
--- a/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.cc
+++ b/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.cc
@@ -13,10 +13,6 @@
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
-using content::OpenURLParams;
-using content::Referrer;
-using content::UserMetricsAction;
-
 // static
 void RegisterProtocolHandlerInfoBarDelegate::Create(
     InfoBarService* infobar_service,
@@ -52,13 +48,17 @@
       handler_(handler) {
 }
 
+RegisterProtocolHandlerInfoBarDelegate::
+    ~RegisterProtocolHandlerInfoBarDelegate() {
+}
+
 InfoBarDelegate::InfoBarAutomationType
     RegisterProtocolHandlerInfoBarDelegate::GetInfoBarAutomationType() const {
   return RPH_INFOBAR;
 }
 
 InfoBarDelegate::Type
-RegisterProtocolHandlerInfoBarDelegate::GetInfoBarType() const {
+    RegisterProtocolHandlerInfoBarDelegate::GetInfoBarType() const {
   return PAGE_ACTION_TYPE;
 }
 
@@ -70,13 +70,13 @@
 
 string16 RegisterProtocolHandlerInfoBarDelegate::GetMessageText() const {
   ProtocolHandler old_handler = registry_->GetHandlerFor(handler_.protocol());
-  return !old_handler.IsEmpty() ?
-      l10n_util::GetStringFUTF16(IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM_REPLACE,
-          handler_.title(), UTF8ToUTF16(handler_.url().host()),
-          GetProtocolName(handler_), old_handler.title()) :
+  return old_handler.IsEmpty() ?
       l10n_util::GetStringFUTF16(IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM,
           handler_.title(), UTF8ToUTF16(handler_.url().host()),
-          GetProtocolName(handler_));
+          GetProtocolName(handler_)) :
+      l10n_util::GetStringFUTF16(IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM_REPLACE,
+          handler_.title(), UTF8ToUTF16(handler_.url().host()),
+          GetProtocolName(handler_), old_handler.title());
 }
 
 string16 RegisterProtocolHandlerInfoBarDelegate::GetButtonLabel(
@@ -94,14 +94,14 @@
 
 bool RegisterProtocolHandlerInfoBarDelegate::Accept() {
   content::RecordAction(
-      UserMetricsAction("RegisterProtocolHandler.Infobar_Accept"));
+      content::UserMetricsAction("RegisterProtocolHandler.Infobar_Accept"));
   registry_->OnAcceptRegisterProtocolHandler(handler_);
   return true;
 }
 
 bool RegisterProtocolHandlerInfoBarDelegate::Cancel() {
   content::RecordAction(
-      UserMetricsAction("RegisterProtocolHandler.InfoBar_Deny"));
+      content::UserMetricsAction("RegisterProtocolHandler.InfoBar_Deny"));
   registry_->OnIgnoreRegisterProtocolHandler(handler_);
   return true;
 }
@@ -113,14 +113,11 @@
 bool RegisterProtocolHandlerInfoBarDelegate::LinkClicked(
     WindowOpenDisposition disposition) {
   content::RecordAction(
-      UserMetricsAction("RegisterProtocolHandler.InfoBar_LearnMore"));
-  OpenURLParams params(
-      GURL(chrome::kLearnMoreRegisterProtocolHandlerURL),
-      Referrer(),
+      content::UserMetricsAction("RegisterProtocolHandler.InfoBar_LearnMore"));
+  web_contents()->OpenURL(content::OpenURLParams(
+      GURL(chrome::kLearnMoreRegisterProtocolHandlerURL), content::Referrer(),
       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
-      content::PAGE_TRANSITION_LINK,
-      false);
-  web_contents()->OpenURL(params);
+      content::PAGE_TRANSITION_LINK, false));
   return false;
 }
 
diff --git a/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h b/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h
index abd389e..3e73c14 100644
--- a/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h
+++ b/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h
@@ -27,6 +27,7 @@
   RegisterProtocolHandlerInfoBarDelegate(InfoBarService* infobar_service,
                                          ProtocolHandlerRegistry* registry,
                                          const ProtocolHandler& handler);
+  virtual ~RegisterProtocolHandlerInfoBarDelegate();
 
   // ConfirmInfoBarDelegate:
   virtual InfoBarAutomationType GetInfoBarAutomationType() const OVERRIDE;
diff --git a/chrome/browser/devtools/adb/android_rsa.cc b/chrome/browser/devtools/adb/android_rsa.cc
new file mode 100644
index 0000000..5333632
--- /dev/null
+++ b/chrome/browser/devtools/adb/android_rsa.cc
@@ -0,0 +1,289 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/devtools/adb/android_rsa.h"
+
+#include "base/base64.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/prefs/pref_service_syncable.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/pref_names.h"
+#include "crypto/rsa_private_key.h"
+#include "crypto/signature_creator.h"
+#include "net/cert/asn1_util.h"
+
+namespace {
+
+const size_t kRSANumWords = 64;
+const size_t kBigIntSize = 1024;
+
+static const char kDummyRSAPublicKey[] =
+    "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6OSJ64q+ZLg7VV2ojEPh5TRbYjwbT"
+    "TifSPeFIV45CHnbTWYiiIn41wrozpYizNsMWZUBjdah1N78WVhbyDrnr0bDgFp+gXjfVppa3I"
+    "gjiohEcemK3omXi3GDMK8ERhriLUKfQS842SXtQ8I+KoZtpCkGM//0h7+P+Rhm0WwdipIRMhR"
+    "8haNAeyDiiCvqJcvevv2T52vqKtS3aWz+GjaTJJLVWydEpz9WdvWeLfFVhe2ZnqwwZNa30Qoj"
+    "fsnvjaMwK2MU7uYfRBPuvLyK5QESWBpArNDd6ULl8Y+NU6kwNOVDc87OASCVEM1gw2IMi2mo2"
+    "WO5ywp0UWRiGZCkK+wOFQIDAQAB";
+
+typedef struct RSAPublicKey {
+    int len;                // Length of n[] in number of uint32
+    uint32 n0inv;           // -1 / n[0] mod 2^32
+    uint32 n[kRSANumWords];  // modulus as little endian array
+    uint32 rr[kRSANumWords]; // R^2 as little endian array
+    int exponent;           // 3 or 65537
+} RSAPublicKey;
+
+// http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
+// a * x + b * y = gcd(a, b) = d
+void ExtendedEuclid(uint64 a, uint64 b, uint64 *x, uint64 *y, uint64 *d) {
+  uint64 x1 = 0, x2 = 1, y1 = 1, y2 = 0;
+
+  while (b > 0) {
+    uint64 q = a / b;
+    uint64 r = a % b;
+    *x = x2 - q * x1;
+    *y = y2 - q * y1;
+    a = b;
+    b = r;
+    x2 = x1;
+    x1 = *x;
+    y2 = y1;
+    y1 = *y;
+  }
+
+  *d = a;
+  *x = x2;
+  *y = y2;
+}
+
+uint32 ModInverse(uint64 a, uint64 m)
+{
+  uint64 d, x, y;
+  ExtendedEuclid(a, m, &x, &y, &d);
+  if (d == 1)
+    return static_cast<uint32>(x);
+  return 0;
+}
+
+uint32* BnNew() {
+  uint32* result = new uint32[kBigIntSize];
+  memset(result, 0, kBigIntSize * sizeof(uint32));
+  return result;
+}
+
+void BnFree(uint32* a) {
+  delete[] a;
+}
+
+void BnPrint(const std::string& title, uint32_t* a) {
+    int i = kBigIntSize - 1;
+    fprintf(stderr, "%s: ", title.c_str());
+    while (!a[i]) --i;
+    for (; i >= 0; --i)
+        fprintf(stderr, "%08x", a[i]);
+    fprintf(stderr, "\n");
+}
+
+uint32* BnCopy(uint32* a) {
+  uint32* result = new uint32[kBigIntSize];
+  memcpy(result, a, kBigIntSize * sizeof(uint32));
+  return result;
+}
+
+void BnAdd(uint32* a, uint32* b) {
+  uint64 carry_over = 0;
+  for (size_t i = 0; i < kBigIntSize; ++i) {
+    carry_over += static_cast<uint64>(a[i]) + b[i];
+    a[i] = carry_over & kuint32max;
+    carry_over >>= 32;
+  }
+}
+
+uint32* BnMul(uint32* a, uint32 b) {
+  uint32* result = BnNew();
+  uint64 carry_over = 0;
+  for (size_t i = 0; i < kBigIntSize; ++i) {
+    carry_over += static_cast<uint64>(a[i]) * b;
+    result[i] = carry_over & kuint32max;
+    carry_over >>= 32;
+  }
+  return result;
+}
+
+void BnSub(uint32* a, uint32* b) {
+  int carry_over = 0;
+  for (size_t i = 0; i < kBigIntSize; ++i) {
+    int64 sub = static_cast<int64>(a[i]) - b[i] - carry_over;
+    carry_over = 0;
+    if (sub < 0) {
+      carry_over = 1;
+      sub += GG_LONGLONG(0x100000000);
+    }
+    a[i] = static_cast<uint32>(sub);
+  }
+}
+
+void BnLeftShift(uint32* a, int offset) {
+  for (int i = kBigIntSize - offset - 1; i >= 0; --i)
+    a[i + offset] = a[i];
+  for (int i = 0; i < offset; ++i)
+    a[i] = 0;
+}
+
+int BnCompare(uint32* a, uint32* b) {
+  for (int i = kBigIntSize - 1; i >= 0; --i) {
+    if (a[i] > b[i])
+      return 1;
+    if (a[i] < b[i])
+      return -1;
+  }
+  return 0;
+}
+
+uint64 BnGuess(uint32* a, uint32* b, uint64 from, uint64 to) {
+  if (from + 1 >= to)
+    return from;
+
+  uint64 guess = (from + to) / 2;
+  uint32* t = BnMul(b, static_cast<uint32>(guess));
+  int result = BnCompare(a, t);
+  BnFree(t);
+  if (result > 0)
+    return BnGuess(a, b, guess, to);
+  if (result < 0)
+    return BnGuess(a, b, from, guess);
+  return guess;
+}
+
+void BnDiv(uint32* a, uint32* b, uint32** pq, uint32** pr) {
+  if (BnCompare(a, b) < 0) {
+    if (pq)
+      *pq = BnNew();
+    if (pr)
+      *pr = BnCopy(a);
+    return;
+  }
+
+  int oa = kBigIntSize - 1;
+  int ob = kBigIntSize - 1;
+  for (; oa > 0 && !a[oa]; --oa) {}
+  for (; ob > 0 && !b[ob]; --ob) {}
+  uint32* q = BnNew();
+  uint32* ca = BnCopy(a);
+
+  int digit = a[oa] < b[ob] ? oa - ob - 1 : oa - ob;
+
+  for (; digit >= 0; --digit) {
+    uint32* shifted_b = BnCopy(b);
+    BnLeftShift(shifted_b, digit);
+    uint32 value = static_cast<uint32>(
+        BnGuess(ca, shifted_b, 0, static_cast<uint64>(kuint32max) + 1));
+    q[digit] = value;
+    uint32* t = BnMul(shifted_b, value);
+    BnSub(ca, t);
+    BnFree(t);
+    BnFree(shifted_b);
+  }
+
+  if (pq)
+    *pq = q;
+  else
+    BnFree(q);
+  if (pr)
+    *pr = ca;
+  else
+    BnFree(ca);
+}
+
+}  // namespace
+
+crypto::RSAPrivateKey* AndroidRSAPrivateKey(Profile* profile) {
+  std::string encoded_key =
+      profile->GetPrefs()->GetString(prefs::kDevToolsAdbKey);
+  std::string decoded_key;
+  scoped_ptr<crypto::RSAPrivateKey> key;
+  if (!encoded_key.empty() && base::Base64Decode(encoded_key, &decoded_key)) {
+    std::vector<uint8> key_info(decoded_key.begin(), decoded_key.end());
+    key.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info));
+  }
+  if (!key) {
+    key.reset(crypto::RSAPrivateKey::Create(2048));
+    std::vector<uint8> key_info;
+    if (!key || !key->ExportPrivateKey(&key_info))
+      return NULL;
+
+    std::string key_string(key_info.begin(), key_info.end());
+    if (base::Base64Encode(key_string, &encoded_key)) {
+      profile->GetPrefs()->SetString(prefs::kDevToolsAdbKey,
+                                     encoded_key);
+    }
+  }
+  return key.release();
+}
+
+std::string AndroidRSAPublicKey(crypto::RSAPrivateKey* key) {
+  std::vector<uint8> public_key;
+  if (!key)
+    return kDummyRSAPublicKey;
+
+  key->ExportPublicKey(&public_key);
+  std::string asn1(public_key.begin(), public_key.end());
+
+  base::StringPiece pk;
+  if (!net::asn1::ExtractSubjectPublicKeyFromSPKI(asn1, &pk))
+    return kDummyRSAPublicKey;
+
+  // Skip 10 byte asn1 prefix to the modulus.
+  std::vector<uint8> pk_data(pk.data() + 10, pk.data() + pk.length());
+  uint32* n = BnNew();
+  for (size_t i = 0; i < kRSANumWords; ++i) {
+    uint32 t = pk_data[4 * i];
+    t = t << 8;
+    t += pk_data[4 * i + 1];
+    t = t << 8;
+    t += pk_data[4 * i + 2];
+    t = t << 8;
+    t += pk_data[4 * i + 3];
+    n[kRSANumWords - i - 1] = t;
+  }
+  uint64 n0 = n[0];
+
+  RSAPublicKey pkey;
+  pkey.len = kRSANumWords;
+  pkey.exponent = 65537; // Fixed public exponent
+  pkey.n0inv = 0 - ModInverse(n0, GG_LONGLONG(0x100000000));
+  if (pkey.n0inv == 0)
+    return kDummyRSAPublicKey;
+
+  uint32* r = BnNew();
+  r[kRSANumWords * 2] = 1;
+
+  uint32* rr;
+  BnDiv(r, n, NULL, &rr);
+
+  for (size_t i = 0; i < kRSANumWords; ++i) {
+    pkey.n[i] = n[i];
+    pkey.rr[i] = rr[i];
+  }
+
+  BnFree(n);
+  BnFree(r);
+  BnFree(rr);
+
+  std::string output;
+  std::string input(reinterpret_cast<char*>(&pkey), sizeof(pkey));
+  base::Base64Encode(input, &output);
+  return output;
+}
+
+std::string AndroidRSASign(crypto::RSAPrivateKey* key,
+                           const std::string& body) {
+  std::vector<uint8> digest(body.begin(), body.end());
+  std::vector<uint8> result;
+  if (!crypto::SignatureCreator::Sign(key, vector_as_array(&digest),
+                                      digest.size(), &result)) {
+    return std::string();
+  }
+  return std::string(result.begin(), result.end());
+}
diff --git a/chrome/browser/devtools/adb/android_rsa.h b/chrome/browser/devtools/adb/android_rsa.h
new file mode 100644
index 0000000..d413228
--- /dev/null
+++ b/chrome/browser/devtools/adb/android_rsa.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_DEVTOOLS_ADB_ANDROID_RSA_H_
+#define CHROME_BROWSER_DEVTOOLS_ADB_ANDROID_RSA_H_
+
+#include <string>
+
+namespace crypto {
+class RSAPrivateKey;
+}
+
+class Profile;
+
+crypto::RSAPrivateKey* AndroidRSAPrivateKey(Profile* profile);
+
+std::string AndroidRSAPublicKey(crypto::RSAPrivateKey* key);
+
+std::string AndroidRSASign(crypto::RSAPrivateKey* key,
+                           const std::string& body);
+
+#endif  // CHROME_BROWSER_DEVTOOLS_ADB_ANDROID_RSA_H_
diff --git a/chrome/browser/devtools/adb/android_usb_device.cc b/chrome/browser/devtools/adb/android_usb_device.cc
index c77fd4e..82a8b8c 100644
--- a/chrome/browser/devtools/adb/android_usb_device.cc
+++ b/chrome/browser/devtools/adb/android_usb_device.cc
@@ -4,13 +4,18 @@
 
 #include "chrome/browser/devtools/adb/android_usb_device.h"
 
+#include <set>
+
 #include "base/base64.h"
+#include "base/lazy_instance.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/devtools/adb/android_rsa.h"
 #include "chrome/browser/devtools/adb/android_usb_socket.h"
 #include "chrome/browser/usb/usb_interface.h"
 #include "chrome/browser/usb/usb_service.h"
 #include "chrome/browser/usb/usb_service_factory.h"
+#include "crypto/rsa_private_key.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "net/socket/stream_socket.h"
@@ -26,27 +31,92 @@
 const int kAdbSubclass = 0x42;
 const int kAdbProtocol = 0x1;
 
-const int kUsbTimeout = 1000;
+const int kUsbTimeout = 0;
 
 const uint32 kMaxPayload = 4096;
 const uint32 kVersion = 0x01000000;
 
 static const char kHostConnectMessage[] = "host::";
-static const char kRSAPublicKey[] =
-    "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6OSJ64q+ZLg7VV2ojEPh5TRbYjwbT"
-    "TifSPeFIV45CHnbTWYiiIn41wrozpYizNsMWZUBjdah1N78WVhbyDrnr0bDgFp+gXjfVppa3I"
-    "gjiohEcemK3omXi3GDMK8ERhriLUKfQS842SXtQ8I+KoZtpCkGM//0h7+P+Rhm0WwdipIRMhR"
-    "8haNAeyDiiCvqJcvevv2T52vqKtS3aWz+GjaTJJLVWydEpz9WdvWeLfFVhe2ZnqwwZNa30Qoj"
-    "fsnvjaMwK2MU7uYfRBPuvLyK5QESWBpArNDd6ULl8Y+NU6kwNOVDc87OASCVEM1gw2IMi2mo2"
-    "WO5ywp0UWRiGZCkK+wOFQIDAQAB";
 
-static bool CheckUsbInterface(
+typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices;
+
+base::LazyInstance<AndroidUsbDevices>::Leaky g_devices =
+    LAZY_INSTANCE_INITIALIZER;
+
+static std::string ReadSerialNumSync(libusb_device_handle* handle) {
+  libusb_device* device = libusb_get_device(handle);
+  libusb_device_descriptor descriptor;
+  if (libusb_get_device_descriptor(device, &descriptor) != LIBUSB_SUCCESS)
+    return std::string();
+
+  if (!descriptor.iSerialNumber)
+    return std::string();
+
+  uint16 languages[128] = {0};
+  memset(languages, 0, sizeof(languages));
+
+  int res = libusb_control_transfer(
+      handle,
+      LIBUSB_ENDPOINT_IN |  LIBUSB_REQUEST_TYPE_STANDARD |
+          LIBUSB_RECIPIENT_DEVICE,
+      LIBUSB_REQUEST_GET_DESCRIPTOR, LIBUSB_DT_STRING << 8, 0,
+      reinterpret_cast<uint8*>(languages), sizeof(languages), 0);
+
+  if (res <= 0) {
+    LOG(ERROR) << "Failed to get languages count";
+    return std::string();
+  }
+
+  int language_count = (res - 2) / 2;
+  uint16 buffer[128] = {0};
+  for (int i = 1; i <= language_count; ++i) {
+    memset(buffer, 0, sizeof(buffer));
+
+    res = libusb_control_transfer(
+        handle,
+        LIBUSB_ENDPOINT_IN |  LIBUSB_REQUEST_TYPE_STANDARD |
+            LIBUSB_RECIPIENT_DEVICE,
+        LIBUSB_REQUEST_GET_DESCRIPTOR,
+        (LIBUSB_DT_STRING << 8) | descriptor.iSerialNumber,
+        languages[i], reinterpret_cast<uint8*>(buffer), sizeof(buffer), 0);
+
+    if (res > 0) {
+        res /= 2;
+        char serial[256] = {0};
+        int j;
+        for (j = 1; j < res; ++j)
+          serial[j - 1] = buffer[j];
+        serial[j - 1] = '\0';
+        return std::string(serial, j);
+    }
+  }
+  return std::string();
+}
+
+static void InterfaceClaimed(crypto::RSAPrivateKey* rsa_key,
+                             scoped_refptr<UsbDevice> usb_device,
+                             int inbound_address,
+                             int outbound_address,
+                             int zero_mask,
+                             AndroidUsbDevices* devices,
+                             bool success) {
+  if (!success)
+    return;
+
+  std::string serial = ReadSerialNumSync(usb_device->handle());
+  scoped_refptr<AndroidUsbDevice> device =
+      new AndroidUsbDevice(rsa_key, usb_device, serial, inbound_address,
+                           outbound_address, zero_mask);
+  devices->push_back(device);
+}
+
+static void ClaimInterface(
+    crypto::RSAPrivateKey* rsa_key,
+    scoped_refptr<UsbDevice> usb_device,
     const UsbInterface* interface,
-    int* inbound_address,
-    int* outbound_address,
-    int* zero_mask) {
+    AndroidUsbDevices* devices) {
   if (interface->GetNumAltSettings() == 0)
-    return false;
+    return;
 
   scoped_refptr<const UsbInterfaceDescriptor> idesc =
       interface->GetAltSetting(0).get();
@@ -55,24 +125,32 @@
       idesc->GetInterfaceSubclass() != kAdbSubclass ||
       idesc->GetInterfaceProtocol() != kAdbProtocol ||
       idesc->GetNumEndpoints() != 2) {
-    return false;
+    return;
   }
 
+  int inbound_address = 0;
+  int outbound_address = 0;
+  int zero_mask = 0;
+
   for (size_t i = 0; i < idesc->GetNumEndpoints(); ++i) {
     scoped_refptr<const UsbEndpointDescriptor> edesc =
         idesc->GetEndpoint(i).get();
     if (edesc->GetTransferType() != USB_TRANSFER_BULK)
       continue;
     if (edesc->GetDirection() == USB_DIRECTION_INBOUND)
-      *inbound_address = edesc->GetAddress();
+      inbound_address = edesc->GetAddress();
     else
-      *outbound_address = edesc->GetAddress();
-    *zero_mask = edesc->GetMaximumPacketSize() - 1;
+      outbound_address = edesc->GetAddress();
+    zero_mask = edesc->GetMaximumPacketSize() - 1;
   }
 
   if (inbound_address == 0 || outbound_address == 0)
-    return false;
-  return true;
+    return;
+
+  usb_device->ClaimInterface(1, base::Bind(&InterfaceClaimed,
+                                           rsa_key, usb_device,
+                                           inbound_address, outbound_address,
+                                           zero_mask, devices));
 }
 
 static uint32 Checksum(const std::string& data) {
@@ -129,50 +207,74 @@
 }
 
 // static
-void AndroidUsbDevice::Enumerate(
-    Profile* profile,
-    std::vector<scoped_refptr<AndroidUsbDevice> >* devices) {
+void AndroidUsbDevice::Enumerate(Profile* profile,
+                                 crypto::RSAPrivateKey* rsa_key,
+                                 AndroidUsbDevices* devices) {
   UsbService* service =
       UsbServiceFactory::GetInstance()->GetForProfile(profile);
-
-  // Enumerate usb devices.
-  std::vector<scoped_refptr<UsbDevice> > usb_devices;
+  UsbDevices usb_devices;
   service->EnumerateDevices(&usb_devices);
-  for (size_t i = 0; i < usb_devices.size(); ++i) {
-    scoped_refptr<UsbDevice> usb_device = usb_devices[i];
 
-    // Enumerate device interfaces.
-    scoped_refptr<UsbConfigDescriptor> config = new UsbConfigDescriptor();
-    usb_device->ListInterfaces(config.get(), base::Bind(&BoolNoop));
-    for (size_t i = 0; i < config->GetNumInterfaces(); ++i) {
-      scoped_refptr<const UsbInterface> interface = config->GetInterface(i);
-
-      int inbound_address = 0;
-      int outbound_address = 0;
-      int zero_mask = 0;
-      if (CheckUsbInterface(interface, &inbound_address, &outbound_address,
-                            &zero_mask)) {
-        devices->push_back(new AndroidUsbDevice(usb_device, inbound_address,
-                                                outbound_address, zero_mask));
+  // GC Android devices with no actual usb device.
+  AndroidUsbDevices::iterator it = g_devices.Get().begin();
+  std::set<UsbDevice*> claimed_devices;
+  while (it != g_devices.Get().end()) {
+    bool found_device = false;
+    for (UsbDevices::iterator it2 = usb_devices.begin();
+         it2 != usb_devices.end() && !found_device; ++it2) {
+      UsbDevice* usb_device = it2->get();
+      AndroidUsbDevice* device = it->get();
+      if (usb_device == device->usb_device_) {
+        found_device = true;
+        claimed_devices.insert(*it2);
       }
     }
+
+    if (!found_device)
+      it = g_devices.Get().erase(it);
+    else
+      ++it;
   }
+
+  // Add new devices.
+  AndroidUsbDevices new_devices;
+  for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
+       ++it) {
+    UsbDevice* usb_device = *it;
+    if (claimed_devices.find(usb_device) != claimed_devices.end())
+      continue;
+    scoped_refptr<UsbConfigDescriptor> config = new UsbConfigDescriptor();
+    usb_device->ListInterfaces(config.get(), base::Bind(&BoolNoop));
+    for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
+      ClaimInterface(rsa_key, usb_device, config->GetInterface(j),
+                     &g_devices.Get());
+    }
+  }
+
+  *devices = g_devices.Get();
 }
 
-AndroidUsbDevice::AndroidUsbDevice(scoped_refptr<UsbDevice> usb_device,
+AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
+                                   scoped_refptr<UsbDevice> usb_device,
+                                   const std::string& serial,
                                    int inbound_address,
                                    int outbound_address,
                                    int zero_mask)
     : message_loop_(NULL),
+      rsa_key_(rsa_key->Copy()),
       usb_device_(usb_device),
+      serial_(serial),
       inbound_address_(inbound_address),
       outbound_address_(outbound_address),
       zero_mask_(zero_mask),
       is_connected_(false),
-      last_socket_id_(256) {
+      signature_sent_(false),
+      last_socket_id_(256),
+      terminated_(false) {
   message_loop_ = base::MessageLoop::current();
-  usb_device_->ClaimInterface(1, base::Bind(&AndroidUsbDevice::InterfaceClaimed,
-                                            this));
+  Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload,
+                       kHostConnectMessage));
+  ReadHeader(true);
 }
 
 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) {
@@ -196,16 +298,7 @@
 }
 
 AndroidUsbDevice::~AndroidUsbDevice() {
-  usb_device_->ReleaseInterface(1, base::Bind(&BoolNoop));
-  usb_device_->Close(base::Bind(&Noop));
-}
-
-void AndroidUsbDevice::InterfaceClaimed(bool success) {
-  if (!success)
-    return;
-  Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload,
-                       kHostConnectMessage));
-  ReadHeader();
+  Terminate();
 }
 
 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) {
@@ -264,8 +357,8 @@
                                      this));
 }
 
-void AndroidUsbDevice::ReadHeader() {
-  if (HasOneRef())
+void AndroidUsbDevice::ReadHeader(bool initial) {
+  if (!initial && HasOneRef())
     return;  // Stop polling.
   scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize);
   usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_,
@@ -278,17 +371,13 @@
                                    size_t result) {
   if (status == USB_TRANSFER_TIMEOUT) {
     message_loop_->PostTask(FROM_HERE,
-                            base::Bind(&AndroidUsbDevice::ReadHeader, this));
+                            base::Bind(&AndroidUsbDevice::ReadHeader, this,
+                                       false));
     return;
   }
 
-  if (status != USB_TRANSFER_COMPLETED) {
-    LOG(ERROR) << "Unexpeced transfer status: " << status;
-    return;
-  }
-
-  if (result != kHeaderSize) {
-    LOG(ERROR) << "Unexpeced header size: " << result;
+  if (status != USB_TRANSFER_COMPLETED || result != kHeaderSize) {
+    TransferError(status);
     return;
   }
 
@@ -300,8 +389,10 @@
   uint32 data_length = header[3];
   uint32 data_check = header[4];
   uint32 magic = header[5];
-  if ((message->command ^ 0xffffffff) != magic)
+  if ((message->command ^ 0xffffffff) != magic) {
+    TransferError(USB_TRANSFER_ERROR);
     return;
+  }
 
   if (data_length == 0) {
     message_loop_->PostTask(FROM_HERE,
@@ -338,21 +429,16 @@
     return;
   }
 
-  if (status != USB_TRANSFER_COMPLETED) {
-    LOG(ERROR) << "Unexpeced transfer status: " << status;
-    return;
-  }
-
-  if (static_cast<uint32>(result) != data_length) {
-    LOG(ERROR) << "Unexpeced body length: " << result << ", expecteced" <<
-        data_length;
+  if (status != USB_TRANSFER_COMPLETED ||
+      static_cast<uint32>(result) != data_length) {
+    TransferError(status);
     return;
   }
 
   DumpMessage(false, buffer->data(), data_length);
   message->body = std::string(buffer->data(), result);
   if (Checksum(message->body) != data_check) {
-    LOG(ERROR) << "Wrong body checksum";
+    TransferError(USB_TRANSFER_ERROR);
     return;
   }
 
@@ -366,9 +452,23 @@
     case AdbMessage::kCommandAUTH:
       {
         DCHECK_EQ(message->arg0, static_cast<uint32>(AdbMessage::kAuthToken));
-        Queue(new AdbMessage(AdbMessage::kCommandAUTH,
-                             AdbMessage::kAuthRSAPublicKey, 0,
-                             kRSAPublicKey));
+        if (signature_sent_) {
+          Queue(new AdbMessage(AdbMessage::kCommandAUTH,
+                               AdbMessage::kAuthRSAPublicKey, 0,
+                               AndroidRSAPublicKey(rsa_key_.get())));
+        } else {
+          signature_sent_ = true;
+          std::string signature = AndroidRSASign(rsa_key_.get(), message->body);
+          if (!signature.empty()) {
+            Queue(new AdbMessage(AdbMessage::kCommandAUTH,
+                                 AdbMessage::kAuthSignature, 0,
+                                 signature));
+          } else {
+            Queue(new AdbMessage(AdbMessage::kCommandAUTH,
+                                 AdbMessage::kAuthRSAPublicKey, 0,
+                                 AndroidRSAPublicKey(rsa_key_.get())));
+          }
+        }
       }
       break;
     case AdbMessage::kCommandCNXN:
@@ -386,7 +486,6 @@
     case AdbMessage::kCommandWRTE:
     case AdbMessage::kCommandCLSE:
       {
-        // Route these to sockets
         AndroidUsbSockets::iterator it = sockets_.find(message->arg1);
         if (it != sockets_.end())
           it->second->HandleIncoming(message);
@@ -395,7 +494,30 @@
     default:
       break;
   }
-  ReadHeader();
+  ReadHeader(false);
+}
+
+void AndroidUsbDevice::TransferError(UsbTransferStatus status) {
+  message_loop_->PostTask(FROM_HERE,
+                          base::Bind(&AndroidUsbDevice::Terminate,
+                                     this));
+}
+
+void AndroidUsbDevice::Terminate() {
+  if (terminated_)
+    return;
+
+  terminated_ = true;
+
+  // Iterate over copy.
+  AndroidUsbSockets sockets(sockets_);
+  for (AndroidUsbSockets::iterator it = sockets.begin();
+       it != sockets.end(); ++it) {
+    it->second->Terminated();
+  }
+
+  usb_device_->ReleaseInterface(1, base::Bind(&BoolNoop));
+  usb_device_->Close(base::Bind(&Noop));
 }
 
 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) {
diff --git a/chrome/browser/devtools/adb/android_usb_device.h b/chrome/browser/devtools/adb/android_usb_device.h
index 4b27a13..67f50ff 100644
--- a/chrome/browser/devtools/adb/android_usb_device.h
+++ b/chrome/browser/devtools/adb/android_usb_device.h
@@ -15,6 +15,10 @@
 class MessageLoop;
 }
 
+namespace crypto {
+class RSAPrivateKey;
+}
+
 namespace net {
 class StreamSocket;
 }
@@ -56,14 +60,18 @@
   DISALLOW_COPY_AND_ASSIGN(AdbMessage);
 };
 
-typedef base::Callback<void(int, AdbMessage*)> AdbCallback;
+class AndroidUsbDevice;
+typedef std::vector<scoped_refptr<AndroidUsbDevice> > AndroidUsbDevices;
 
 class AndroidUsbDevice : public base::RefCountedThreadSafe<AndroidUsbDevice> {
  public:
-  static void Enumerate(
-      Profile* profile,
-      std::vector<scoped_refptr<AndroidUsbDevice> >* devices);
-  AndroidUsbDevice(scoped_refptr<UsbDevice> device,
+  static void Enumerate(Profile* profile,
+                        crypto::RSAPrivateKey* rsa_key,
+                        AndroidUsbDevices* devices);
+
+  AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
+                   scoped_refptr<UsbDevice> device,
+                   const std::string& serial,
                    int inbound_address,
                    int outbound_address,
                    int zero_mask);
@@ -75,19 +83,21 @@
             uint32 arg1,
             const std::string& body);
 
+  std::string serial() { return serial_; }
+
+  bool terminated() { return terminated_; }
+
  private:
   friend class base::RefCountedThreadSafe<AndroidUsbDevice>;
   virtual ~AndroidUsbDevice();
 
-  void InterfaceClaimed(bool success);
-
   void Queue(scoped_refptr<AdbMessage> message);
   void ProcessOutgoing();
   void OutgoingMessageSent(UsbTransferStatus status,
                            scoped_refptr<net::IOBuffer> buffer,
                            size_t result);
 
-  void ReadHeader();
+  void ReadHeader(bool initial);
   void ParseHeader(UsbTransferStatus status,
                    scoped_refptr<net::IOBuffer> buffer,
                    size_t result);
@@ -104,20 +114,29 @@
 
   void HandleIncoming(scoped_refptr<AdbMessage> message);
 
+  void TransferError(UsbTransferStatus status);
+
+  void Terminate();
+
   void SocketDeleted(uint32 socket_id);
 
   base::MessageLoop* message_loop_;
 
+  scoped_ptr<crypto::RSAPrivateKey> rsa_key_;
+
   // Device info
   scoped_refptr<UsbDevice> usb_device_;
+  std::string serial_;
   int inbound_address_;
   int outbound_address_;
   int zero_mask_;
 
   bool is_connected_;
+  bool signature_sent_;
 
   // Created sockets info
   uint32 last_socket_id_;
+  bool terminated_;
   typedef std::map<uint32, AndroidUsbSocket*> AndroidUsbSockets;
   AndroidUsbSockets sockets_;
 
diff --git a/chrome/browser/devtools/adb/android_usb_socket.cc b/chrome/browser/devtools/adb/android_usb_socket.cc
index 2baefe1..63d1787 100644
--- a/chrome/browser/devtools/adb/android_usb_socket.cc
+++ b/chrome/browser/devtools/adb/android_usb_socket.cc
@@ -34,7 +34,8 @@
       delete_callback_(delete_callback),
       local_id_(socket_id),
       remote_id_(0),
-      is_connected_(false) {
+      is_connected_(false),
+      is_closed_(false) {
 }
 
 AndroidUsbSocket::~AndroidUsbSocket() {
@@ -51,37 +52,62 @@
       if (!is_connected_) {
         remote_id_ = message->arg0;
         is_connected_ = true;
-        connect_callback_.Run(net::OK);
-        // Can be NULL after response.
+        net::CompletionCallback callback = connect_callback_;
+        connect_callback_.Reset();
+        callback.Run(net::OK);
+        // "this" can be NULL.
       } else {
         RespondToWriters();
-        // Can be NULL after response.
+        // "this" can be NULL.
       }
       break;
     case AdbMessage::kCommandWRTE:
+      device_->Send(AdbMessage::kCommandOKAY, local_id_, message->arg0, "");
       read_buffer_ += message->body;
-      device_->Send(AdbMessage::kCommandOKAY, local_id_, remote_id_, "");
-      RespondToReaders(false);
-      // Can be NULL after response.
+      // Allow WRTE over new connection even though OKAY ack was not received.
+      if (!is_connected_) {
+        remote_id_ = message->arg0;
+        is_connected_ = true;
+        net::CompletionCallback callback = connect_callback_;
+        connect_callback_.Reset();
+        callback.Run(net::OK);
+        // "this" can be NULL.
+      } else {
+        RespondToReaders(false);
+        // "this" can be NULL.
+      }
       break;
     case AdbMessage::kCommandCLSE:
-      if (is_connected_) {
+      if (is_connected_)
         device_->Send(AdbMessage::kCommandCLSE, local_id_, 0, "");
-      }
       is_connected_ = false;
+      is_closed_ = true;
       RespondToReaders(true);
-      // Can be NULL after response.
+      // "this" can be NULL.
       break;
     default:
       break;
   }
 }
 
+void AndroidUsbSocket::Terminated() {
+  is_connected_ = false;
+  is_closed_ = true;
+  if (!connect_callback_.is_null()) {
+    net::CompletionCallback callback = connect_callback_;
+    connect_callback_.Reset();
+    callback.Run(net::ERR_FAILED);
+    // "this" can be NULL.
+    return;
+  }
+  RespondToReaders(true);
+}
+
 int AndroidUsbSocket::Read(net::IOBuffer* buffer,
                            int length,
                            const net::CompletionCallback& callback) {
   if (!is_connected_)
-    return net::ERR_SOCKET_NOT_CONNECTED;
+    return is_closed_ ? 0 : net::ERR_SOCKET_NOT_CONNECTED;
 
   if (read_buffer_.empty()) {
     read_requests_.push_back(IORequest(buffer, length, callback));
@@ -124,6 +150,8 @@
 
 int AndroidUsbSocket::Connect(const net::CompletionCallback& callback) {
   CHECK_EQ(message_loop_, base::MessageLoop::current());
+  if (device_->terminated())
+    return net::ERR_FAILED;
   connect_callback_ = callback;
   device_->Send(AdbMessage::kCommandOPEN, local_id_, 0, command_);
   return net::ERR_IO_PENDING;
@@ -131,7 +159,7 @@
 
 void AndroidUsbSocket::Disconnect() {
   is_connected_ = false;
-  device_->Send(AdbMessage::kCommandCLSE, local_id_, remote_id_, "");
+  device_->Send(AdbMessage::kCommandCLSE, local_id_, 0, "");
   RespondToReaders(true);
 }
 
diff --git a/chrome/browser/devtools/adb/android_usb_socket.h b/chrome/browser/devtools/adb/android_usb_socket.h
index d6367f8..8479040 100644
--- a/chrome/browser/devtools/adb/android_usb_socket.h
+++ b/chrome/browser/devtools/adb/android_usb_socket.h
@@ -29,6 +29,8 @@
 
   void HandleIncoming(scoped_refptr<AdbMessage> message);
 
+  void Terminated();
+
   // net::StreamSocket implementation.
   virtual int Read(net::IOBuffer* buf, int buf_len,
                    const net::CompletionCallback& callback) OVERRIDE;
@@ -75,6 +77,7 @@
   uint32 remote_id_;
   net::BoundNetLog net_log_;
   bool is_connected_;
+  bool is_closed_;
   std::string read_buffer_;
   net::CompletionCallback connect_callback_;
   std::deque<IORequest> read_requests_;
diff --git a/chrome/browser/devtools/adb_client_socket.cc b/chrome/browser/devtools/adb_client_socket.cc
index 0871c0a..f316e77 100644
--- a/chrome/browser/devtools/adb_client_socket.cc
+++ b/chrome/browser/devtools/adb_client_socket.cc
@@ -21,7 +21,6 @@
 const int kResponseBufferSize = 16;
 const char kOkayResponse[] = "OKAY";
 const char kHostTransportCommand[] = "host:transport:%s";
-const char kLocalAbstractCommand[] = "localabstract:%s";
 const char kLocalhost[] = "127.0.0.1";
 
 typedef base::Callback<void(int, const std::string&)> CommandCallback;
@@ -69,9 +68,9 @@
   void SendLocalAbstract(int result, const std::string& response) {
     if (!CheckNetResultOrDie(result))
       return;
-    SendCommand(base::StringPrintf(kLocalAbstractCommand, socket_name_.c_str()),
-        true, base::Bind(&AdbTransportSocket::OnSocketAvailable,
-                         base::Unretained(this)));
+    SendCommand(socket_name_, true,
+                base::Bind(&AdbTransportSocket::OnSocketAvailable,
+                           base::Unretained(this)));
   }
 
   void OnSocketAvailable(int result, const std::string& response) {
@@ -96,52 +95,33 @@
 
 class HttpOverAdbSocket {
  public:
-  HttpOverAdbSocket(int port,
-                    const std::string& serial,
-                    const std::string& socket_name,
+  HttpOverAdbSocket(net::StreamSocket* socket,
                     const std::string& request,
                     const CommandCallback& callback)
-    : request_(request),
+    : socket_(socket),
       command_callback_(callback),
       body_pos_(0) {
-    Connect(port, serial, socket_name);
+    SendRequest(request);
   }
 
-  HttpOverAdbSocket(int port,
-                    const std::string& serial,
-                    const std::string& socket_name,
+  HttpOverAdbSocket(net::StreamSocket* socket,
                     const std::string& request,
                     const SocketCallback& callback)
-    : request_(request),
+    : socket_(socket),
       socket_callback_(callback),
       body_pos_(0) {
-    Connect(port, serial, socket_name);
+    SendRequest(request);
   }
 
  private:
   ~HttpOverAdbSocket() {
   }
 
-  void Connect(int port,
-               const std::string& serial,
-               const std::string& socket_name) {
-    AdbClientSocket::TransportQuery(
-        port, serial, socket_name,
-        base::Bind(&HttpOverAdbSocket::OnSocketAvailable,
-                   base::Unretained(this)));
-  }
-
-  void OnSocketAvailable(int result,
-                         net::StreamSocket* socket) {
-    if (!CheckNetResultOrDie(result))
-      return;
-
-    socket_.reset(socket);
-
+  void SendRequest(const std::string& request) {
     scoped_refptr<net::StringIOBuffer> request_buffer =
-        new net::StringIOBuffer(request_);
+        new net::StringIOBuffer(request);
 
-    result = socket_->Write(
+    int result = socket_->Write(
         request_buffer.get(),
         request_buffer->size(),
         base::Bind(&HttpOverAdbSocket::ReadResponse, base::Unretained(this)));
@@ -152,7 +132,6 @@
   void ReadResponse(int result) {
     if (!CheckNetResultOrDie(result))
       return;
-
     scoped_refptr<net::IOBuffer> response_buffer =
         new net::IOBuffer(kBufferSize);
 
@@ -231,7 +210,6 @@
   }
 
   scoped_ptr<net::StreamSocket> socket_;
-  std::string request_;
   std::string response_;
   CommandCallback command_callback_;
   SocketCallback socket_callback_;
@@ -337,23 +315,17 @@
 }
 
 // static
-void AdbClientSocket::HttpQuery(int port,
-                                const std::string& serial,
-                                const std::string& socket_name,
+void AdbClientSocket::HttpQuery(net::StreamSocket* socket,
                                 const std::string& request_path,
                                 const CommandCallback& callback) {
-  new HttpOverAdbSocket(port, serial, socket_name, request_path,
-      callback);
+  new HttpOverAdbSocket(socket, request_path, callback);
 }
 
 // static
-void AdbClientSocket::HttpQuery(int port,
-                                const std::string& serial,
-                                const std::string& socket_name,
+void AdbClientSocket::HttpQuery(net::StreamSocket* socket,
                                 const std::string& request_path,
                                 const SocketCallback& callback) {
-  new HttpOverAdbSocket(port, serial, socket_name, request_path,
-      callback);
+  new HttpOverAdbSocket(socket, request_path, callback);
 }
 
 AdbClientSocket::AdbClientSocket(int port)
diff --git a/chrome/browser/devtools/adb_client_socket.h b/chrome/browser/devtools/adb_client_socket.h
index 9146d78..6382cdb 100644
--- a/chrome/browser/devtools/adb_client_socket.h
+++ b/chrome/browser/devtools/adb_client_socket.h
@@ -19,24 +19,21 @@
                        const std::string& query,
                        const CommandCallback& callback);
 
+
+  static void HttpQuery(net::StreamSocket* socket,
+                        const std::string& request,
+                        const CommandCallback& callback);
+
+  static void HttpQuery(net::StreamSocket* socket,
+                        const std::string& request,
+                        const SocketCallback& callback);
+
   static void TransportQuery(int port,
                              const std::string& serial,
                              const std::string& socket_name,
                              const SocketCallback& callback);
 
-  static void HttpQuery(int port,
-                        const std::string& serial,
-                        const std::string& socket_name,
-                        const std::string& request,
-                        const CommandCallback& callback);
-
-  static void HttpQuery(int port,
-                        const std::string& serial,
-                        const std::string& socket_name,
-                        const std::string& request,
-                        const SocketCallback& callback);
-
-  AdbClientSocket(int port);
+  explicit AdbClientSocket(int port);
   ~AdbClientSocket();
 
  protected:
diff --git a/chrome/browser/devtools/devtools_adb_bridge.cc b/chrome/browser/devtools/devtools_adb_bridge.cc
index c903b5a..81fc801 100644
--- a/chrome/browser/devtools/devtools_adb_bridge.cc
+++ b/chrome/browser/devtools/devtools_adb_bridge.cc
@@ -7,11 +7,14 @@
 #include <map>
 #include <vector>
 
+#include "base/base64.h"
 #include "base/bind.h"
+#include "base/command_line.h"
 #include "base/compiler_specific.h"
 #include "base/json/json_reader.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
+#include "base/memory/singleton.h"
 #include "base/message_loop/message_loop_proxy.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -19,16 +22,21 @@
 #include "base/strings/stringprintf.h"
 #include "base/threading/thread.h"
 #include "base/values.h"
+#include "chrome/browser/devtools/adb/android_rsa.h"
+#include "chrome/browser/devtools/adb/android_usb_device.h"
 #include "chrome/browser/devtools/adb_client_socket.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/devtools/tethering_adb_filter.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_switches.h"
+#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/devtools_client_host.h"
 #include "content/public/browser/devtools_external_agent_proxy.h"
 #include "content/public/browser/devtools_external_agent_proxy_delegate.h"
 #include "content/public/browser/devtools_manager.h"
+#include "crypto/rsa_private_key.h"
 #include "net/base/net_errors.h"
 #include "net/server/web_socket.h"
 
@@ -39,11 +47,11 @@
 
 static const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread";
 static const char kHostDevicesCommand[] = "host:devices";
-static const char kDeviceModelCommand[] =
-    "host:transport:%s|shell:getprop ro.product.model";
+static const char kHostTransportCommand[] = "host:transport:%s|%s";
+static const char kLocalAbstractCommand[] = "localabstract:%s";
+static const char kDeviceModelCommand[] = "shell:getprop ro.product.model";
 static const char kUnknownModel[] = "Unknown";
-static const char kOpenedUnixSocketsCommand[] =
-    "host:transport:%s|shell:cat /proc/net/unix";
+static const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix";
 
 static const char kPageListRequest[] = "GET /json HTTP/1.1\r\n\r\n";
 static const char kVersionRequest[] = "GET /json/version HTTP/1.1\r\n\r\n";
@@ -58,6 +66,104 @@
 
 typedef DevToolsAdbBridge::Callback Callback;
 typedef DevToolsAdbBridge::PagesCallback PagesCallback;
+typedef std::vector<scoped_refptr<DevToolsAdbBridge::AndroidDevice> >
+    AndroidDevices;
+typedef base::Callback<void(const AndroidDevices&)> AndroidDevicesCallback;
+
+class AdbDeviceImpl : public DevToolsAdbBridge::AndroidDevice {
+ public:
+  explicit AdbDeviceImpl(const std::string& serial)
+      : AndroidDevice(serial) {
+  }
+
+  virtual void RunCommand(const std::string& command,
+                          const CommandCallback& callback) OVERRIDE {
+    std::string query = base::StringPrintf(kHostTransportCommand,
+                                           serial().c_str(), command.c_str());
+    AdbClientSocket::AdbQuery(kAdbPort, query, callback);
+  }
+
+  virtual void OpenSocket(const std::string& name,
+                          const SocketCallback& callback) OVERRIDE {
+    std::string socket_name =
+        base::StringPrintf(kLocalAbstractCommand, name.c_str());
+    AdbClientSocket::TransportQuery(kAdbPort, serial(), socket_name, callback);
+  }
+ private:
+  virtual ~AdbDeviceImpl() {}
+};
+
+class UsbDeviceImpl : public DevToolsAdbBridge::AndroidDevice {
+ public:
+  explicit UsbDeviceImpl(AndroidUsbDevice* device)
+      : AndroidDevice(device->serial()),
+        device_(device) {
+  }
+
+  virtual void RunCommand(const std::string& command,
+                          const CommandCallback& callback) OVERRIDE {
+    net::StreamSocket* socket = device_->CreateSocket(command);
+    int result = socket->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand,
+                                            this, callback, socket));
+    if (result != net::ERR_IO_PENDING)
+      callback.Run(result, std::string());
+  }
+
+  virtual void OpenSocket(const std::string& name,
+                          const SocketCallback& callback) OVERRIDE {
+    std::string socket_name =
+        base::StringPrintf(kLocalAbstractCommand, name.c_str());
+    net::StreamSocket* socket = device_->CreateSocket(socket_name);
+    int result = socket->Connect(base::Bind(&UsbDeviceImpl::OnOpenSocket, this,
+                                            callback, socket));
+    if (result != net::ERR_IO_PENDING)
+      callback.Run(result, NULL);
+  }
+
+ private:
+  void OnOpenSocket(const SocketCallback& callback,
+                    net::StreamSocket* socket,
+                    int result) {
+    callback.Run(result, result == net::OK ? socket : NULL);
+  }
+
+  void OpenedForCommand(const CommandCallback& callback,
+                        net::StreamSocket* socket,
+                        int result) {
+    if (result != net::OK) {
+      callback.Run(result, std::string());
+      return;
+    }
+    scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize);
+    result = socket->Read(buffer, kBufferSize,
+                          base::Bind(&UsbDeviceImpl::OnRead, this,
+                                     socket, buffer, std::string(), callback));
+    if (result != net::ERR_IO_PENDING)
+      OnRead(socket, buffer, std::string(), callback, result);
+  }
+
+  void OnRead(net::StreamSocket* socket,
+              scoped_refptr<net::IOBuffer> buffer,
+              const std::string& data,
+              const CommandCallback& callback,
+              int result) {
+    if (result <= 0) {
+      callback.Run(result, result == 0 ? data : std::string());
+      delete socket;
+      return;
+    }
+
+    std::string new_data = data + std::string(buffer->data(), result);
+    result = socket->Read(buffer, kBufferSize,
+                          base::Bind(&UsbDeviceImpl::OnRead, this,
+                                     socket, buffer, new_data, callback));
+    if (result != net::ERR_IO_PENDING)
+      OnRead(socket, buffer, new_data, callback, result);
+  }
+
+  virtual ~UsbDeviceImpl() {}
+  scoped_refptr<AndroidUsbDevice> device_;
+};
 
 class AdbQueryCommand : public base::RefCounted<AdbQueryCommand> {
  public:
@@ -92,114 +198,99 @@
 
 class AdbPagesCommand : public base::RefCounted<AdbPagesCommand> {
  public:
-  explicit AdbPagesCommand(const PagesCallback& callback)
-     : callback_(callback) {
+  explicit AdbPagesCommand(DevToolsAdbBridge* bridge,
+                           const PagesCallback& callback)
+     : bridge_(bridge),
+       callback_(callback) {
     pages_.reset(new DevToolsAdbBridge::RemotePages());
-#if defined(DEBUG_DEVTOOLS)
-    serials_.push_back(std::string()); // For desktop remote debugging.
-#endif  // defined(DEBUG_DEVTOOLS)
   }
 
   void Run() {
-    AdbClientSocket::AdbQuery(
-        kAdbPort, kHostDevicesCommand,
-        base::Bind(&AdbPagesCommand::ReceivedDevices, this));
+    bridge_->EnumerateDevices(base::Bind(&AdbPagesCommand::ReceivedDevices,
+                                         this));
   }
 
  private:
   friend class base::RefCounted<AdbPagesCommand>;
   virtual ~AdbPagesCommand() {}
 
-  void ReceivedDevices(int result, const std::string& response) {
-    if (result != net::OK) {
-      ProcessSerials();
-      return;
-    }
-
-    std::vector<std::string> devices;
-    Tokenize(response, "\n", &devices);
-    for (size_t i = 0; i < devices.size(); ++i) {
-      std::vector<std::string> tokens;
-      Tokenize(devices[i], "\t ", &tokens);
-      std::string serial = tokens[0];
-      serials_.push_back(serial);
-    }
-
+  void ReceivedDevices(const AndroidDevices& devices) {
+    devices_ = devices;
     ProcessSerials();
   }
 
   void ProcessSerials() {
-    if (serials_.size() == 0) {
+    if (devices_.size() == 0) {
       BrowserThread::PostTask(
           BrowserThread::UI, FROM_HERE,
           base::Bind(&AdbPagesCommand::Respond, this));
       return;
     }
 
-    AdbClientSocket::AdbQuery(
-      kAdbPort,
-      base::StringPrintf(kDeviceModelCommand, serials_.back().c_str()),
-      base::Bind(&AdbPagesCommand::ReceivedModel, this));
+#if defined(DEBUG_DEVTOOLS)
+    // For desktop remote debugging.
+    if (devices_.back()->serial().empty()) {
+      scoped_refptr<DevToolsAdbBridge::AndroidDevice> device =
+          devices_.back();
+      sockets_.push_back(std::string());
+      device->set_model(kUnknownModel);
+      device->HttpQuery(
+          std::string(), kVersionRequest,
+          base::Bind(&AdbPagesCommand::ReceivedVersion, this));
+      return;
+    }
+#endif  // defined(DEBUG_DEVTOOLS)
+
+    scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = devices_.back();
+    device->RunCommand(kDeviceModelCommand,
+                       base::Bind(&AdbPagesCommand::ReceivedModel, this));
   }
 
   void ReceivedModel(int result, const std::string& response) {
-    std::string model;
-    if (result == net::OK) {
-      model = response;
-    } else {
-      model = kUnknownModel;
-#if defined(DEBUG_DEVTOOLS)
-      // For desktop remote debugging.
-      if (serials_.back().empty()) {
-        sockets_.push_back(std::string());
-        AdbClientSocket::HttpQuery(
-            kAdbPort, serials_.back(), sockets_.back(), kVersionRequest,
-            base::Bind(&AdbPagesCommand::ReceivedVersion, this, model));
-        return;
-      }
-#endif  // defined(DEBUG_DEVTOOLS)
+    if (result < 0) {
+      devices_.pop_back();
+      ProcessSerials();
+      return;
     }
-    AdbClientSocket::AdbQuery(
-        kAdbPort,
-        base::StringPrintf(kOpenedUnixSocketsCommand, serials_.back().c_str()),
-        base::Bind(&AdbPagesCommand::ReceivedSockets, this, model));
+    scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = devices_.back();
+    device->set_model(response);
+    device->RunCommand(kOpenedUnixSocketsCommand,
+                       base::Bind(&AdbPagesCommand::ReceivedSockets, this));
   }
 
-  void ReceivedSockets(const std::string& model,
-                       int result,
+  void ReceivedSockets(int result,
                        const std::string& response) {
     if (result < 0) {
-      serials_.pop_back();
+      devices_.pop_back();
       ProcessSerials();
       return;
     }
 
     ParseSocketsList(response);
     if (sockets_.size() == 0) {
-      serials_.pop_back();
+      devices_.pop_back();
       ProcessSerials();
     } else {
-      ProcessSockets(model);
+      ProcessSockets();
     }
   }
 
-  void ProcessSockets(const std::string& model) {
+  void ProcessSockets() {
     if (sockets_.size() == 0) {
-      serials_.pop_back();
+      devices_.pop_back();
       ProcessSerials();
     } else {
-      AdbClientSocket::HttpQuery(
-          kAdbPort, serials_.back(), sockets_.back(), kVersionRequest,
-          base::Bind(&AdbPagesCommand::ReceivedVersion, this, model));
+      scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = devices_.back();
+      device->HttpQuery(sockets_.back(), kVersionRequest,
+                        base::Bind(&AdbPagesCommand::ReceivedVersion, this));
     }
   }
 
-  void ReceivedVersion(const std::string& model,
-                       int result,
+  void ReceivedVersion(int result,
                        const std::string& response) {
     if (result < 0) {
       sockets_.pop_back();
-      ProcessSockets(model);
+      ProcessSockets();
       return;
     }
 
@@ -216,31 +307,29 @@
       }
     }
 
-    AdbClientSocket::HttpQuery(
-          kAdbPort, serials_.back(), sockets_.back(), kPageListRequest,
-          base::Bind(&AdbPagesCommand::ReceivedPages, this, model));
+    scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = devices_.back();
+    device->HttpQuery(sockets_.back(), kPageListRequest,
+                      base::Bind(&AdbPagesCommand::ReceivedPages, this));
   }
 
-  void ReceivedPages(const std::string& model,
-                     int result,
+  void ReceivedPages(int result,
                      const std::string& response) {
     std::string socket = sockets_.back();
     sockets_.pop_back();
     if (result < 0) {
-      ProcessSockets(model);
+      ProcessSockets();
       return;
     }
 
-    std::string serial = serials_.back();
-
     std::string body = response.substr(result);
     scoped_ptr<base::Value> value(base::JSONReader::Read(body));
     base::ListValue* list_value;
     if (!value || !value->GetAsList(&list_value)) {
-      ProcessSockets(model);
+      ProcessSockets();
       return;
     }
 
+    scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = devices_.back();
     base::Value* item;
     for (size_t i = 0; i < list_value->GetSize(); ++i) {
       list_value->Get(i, &item);
@@ -249,9 +338,10 @@
         continue;
       pages_->push_back(
           new DevToolsAdbBridge::RemotePage(
-              serial, model, socket_to_package_[socket], socket, *dict));
+              device->serial(), device->model(), socket_to_package_[socket],
+              socket, *dict));
     }
-    ProcessSockets(model);
+    ProcessSockets();
   }
 
   void Respond() {
@@ -290,7 +380,7 @@
         continue;
       std::string socket = path_field.substr(1, path_field.size() - 2);
       sockets_.push_back(socket);
-      std::string package = path_field.substr(1, socket_name_pos - 2);
+      std::string package = path_field.substr(1, socket_name_pos - 1);
       if (socket_name_pos + channel_pattern.size() < path_field.size() - 1) {
         package += path_field.substr(
             socket_name_pos + channel_pattern.size(), path_field.size() - 1);
@@ -300,8 +390,9 @@
     }
   }
 
+  scoped_refptr<DevToolsAdbBridge> bridge_;
   PagesCallback callback_;
-  std::vector<std::string> serials_;
+  AndroidDevices devices_;
   std::vector<std::string> sockets_;
   std::map<std::string, std::string> socket_to_package_;
   scoped_ptr<DevToolsAdbBridge::RemotePages> pages_;
@@ -318,6 +409,89 @@
 base::LazyInstance<AgentHostDelegates>::Leaky g_host_delegates =
     LAZY_INSTANCE_INITIALIZER;
 
+DevToolsAdbBridge::Wrapper::Wrapper(Profile* profile)
+    : bridge_(new DevToolsAdbBridge(profile)) {
+}
+
+DevToolsAdbBridge::Wrapper::~Wrapper() {
+}
+
+DevToolsAdbBridge* DevToolsAdbBridge::Wrapper::Get() {
+  return bridge_.get();
+}
+
+// static
+DevToolsAdbBridge::Factory* DevToolsAdbBridge::Factory::GetInstance() {
+  return Singleton<DevToolsAdbBridge::Factory>::get();
+}
+
+// static
+DevToolsAdbBridge* DevToolsAdbBridge::Factory::GetForProfile(
+    Profile* profile) {
+  return static_cast<DevToolsAdbBridge::Wrapper*>(
+      GetInstance()->GetServiceForBrowserContext(profile, true))->Get();
+}
+
+DevToolsAdbBridge::Factory::Factory()
+    : BrowserContextKeyedServiceFactory(
+          "DevToolsAdbBridge",
+          BrowserContextDependencyManager::GetInstance()) {}
+
+DevToolsAdbBridge::Factory::~Factory() {}
+
+BrowserContextKeyedService*
+DevToolsAdbBridge::Factory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  return new DevToolsAdbBridge::Wrapper(Profile::FromBrowserContext(context));
+}
+
+DevToolsAdbBridge::AndroidDevice::AndroidDevice(const std::string& serial)
+    : serial_(serial) {
+}
+
+void DevToolsAdbBridge::AndroidDevice::HttpQuery(
+    const std::string& la_name,
+    const std::string& request,
+    const CommandCallback& callback) {
+  OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened, this,
+                                 request, callback));
+}
+
+void DevToolsAdbBridge::AndroidDevice::HttpQuery(
+    const std::string& la_name,
+    const std::string& request,
+    const SocketCallback& callback) {
+  OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened2, this,
+                                 request, callback));
+}
+
+DevToolsAdbBridge::AndroidDevice::~AndroidDevice() {
+}
+
+void DevToolsAdbBridge::AndroidDevice::OnHttpSocketOpened(
+    const std::string& request,
+    const CommandCallback& callback,
+    int result,
+    net::StreamSocket* socket) {
+  if (result != net::OK) {
+    callback.Run(result, std::string());
+    return;
+  }
+  AdbClientSocket::HttpQuery(socket, request, callback);
+}
+
+void DevToolsAdbBridge::AndroidDevice::OnHttpSocketOpened2(
+    const std::string& request,
+    const SocketCallback& callback,
+    int result,
+    net::StreamSocket* socket) {
+  if (result != net::OK) {
+    callback.Run(result, NULL);
+    return;
+  }
+  AdbClientSocket::HttpQuery(socket, request, callback);
+}
+
 class AgentHostDelegate : public base::RefCountedThreadSafe<AgentHostDelegate>,
                           public content::DevToolsExternalAgentProxyDelegate {
  public:
@@ -384,7 +558,7 @@
       return;
 
     if (result <= 0) {
-      CloseIfNecessary(net::ERR_CONNECTION_CLOSED);
+      CloseConnection(net::ERR_CONNECTION_CLOSED, true);
       return;
     }
 
@@ -408,7 +582,7 @@
 
     if (parse_result == WebSocket::FRAME_ERROR ||
         parse_result == WebSocket::FRAME_CLOSE) {
-      CloseIfNecessary(net::ERR_CONNECTION_CLOSED);
+      CloseConnection(net::ERR_CONNECTION_CLOSED, true);
       return;
     }
 
@@ -424,16 +598,29 @@
     tethering_adb_filter_.ProcessOutgoingMessage(data);
     int mask = base::RandInt(0, 0x7FFFFFFF);
     std::string encoded_frame = WebSocket::EncodeFrameHybi17(data, mask);
-    scoped_refptr<net::StringIOBuffer> request_buffer =
-        new net::StringIOBuffer(encoded_frame);
+    request_buffer_ += encoded_frame;
+    if (request_buffer_.length() == encoded_frame.length())
+      SendPendingRequests(0);
+  }
+
+  void SendPendingRequests(int result) {
     if (!socket_)
       return;
-    int result =
-        socket_->Write(request_buffer.get(),
-                       request_buffer->size(),
-                       base::Bind(&AgentHostDelegate::CloseIfNecessary, this));
+    if (result < 0) {
+      CloseConnection(result, true);
+      return;
+    }
+    request_buffer_ = request_buffer_.substr(result);
+    if (request_buffer_.empty())
+      return;
+
+    scoped_refptr<net::StringIOBuffer> buffer =
+        new net::StringIOBuffer(request_buffer_);
+    result = socket_->Write(buffer.get(), buffer->size(),
+                            base::Bind(&AgentHostDelegate::SendPendingRequests,
+                                       this));
     if (result != net::ERR_IO_PENDING)
-      CloseIfNecessary(result);
+      SendPendingRequests(result);
   }
 
   void CloseConnection(int result, bool initiated_by_me) {
@@ -453,12 +640,6 @@
     Release();  // Balanced in constructor.
   }
 
-  void CloseIfNecessary(int result) {
-    if (result >= 0)
-      return;
-    CloseConnection(result, true);
-  }
-
   void OnFrameRead(const std::string& message) {
     proxy_->DispatchOnClientHost(message);
   }
@@ -473,13 +654,14 @@
   scoped_ptr<net::StreamSocket> socket_;
   scoped_ptr<content::DevToolsExternalAgentProxy> proxy_;
   std::string response_buffer_;
+  std::string request_buffer_;
   TetheringAdbFilter tethering_adb_filter_;
   DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate);
 };
 
 class AdbAttachCommand : public base::RefCounted<AdbAttachCommand> {
  public:
-  AdbAttachCommand(const base::WeakPtr<DevToolsAdbBridge>& bridge,
+  AdbAttachCommand(DevToolsAdbBridge* bridge,
                    const std::string& serial,
                    const std::string& socket,
                    const std::string& debug_url,
@@ -492,16 +674,27 @@
   }
 
   void Run() {
-    AdbClientSocket::HttpQuery(
-        kAdbPort, serial_, socket_,
-        base::StringPrintf(kWebSocketUpgradeRequest, debug_url_.c_str()),
-        base::Bind(&AdbAttachCommand::Handle, this));
+    bridge_->EnumerateDevices(base::Bind(&AdbAttachCommand::ReceivedDevices,
+                                         this));
   }
 
  private:
   friend class base::RefCounted<AdbAttachCommand>;
   virtual ~AdbAttachCommand() {}
 
+  void ReceivedDevices(const AndroidDevices& devices) {
+    for (AndroidDevices::const_iterator it = devices.begin();
+         it != devices.end(); ++it) {
+      if ((*it)->serial() == serial_) {
+        (*it)->HttpQuery(
+            socket_,
+            base::StringPrintf(kWebSocketUpgradeRequest, debug_url_.c_str()),
+            base::Bind(&AdbAttachCommand::Handle, this));
+        break;
+      }
+    }
+  }
+
   void Handle(int result, net::StreamSocket* socket) {
     if (result != net::OK || socket == NULL)
       return;
@@ -513,10 +706,6 @@
   void OpenDevToolsWindow(net::StreamSocket* socket) {
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-    DevToolsAdbBridge* bridge = bridge_.get();
-    if (!bridge)
-      return;
-
     std::string id = base::StringPrintf("%s:%s", serial_.c_str(),
                                         debug_url_.c_str());
     AgentHostDelegates::iterator it = g_host_delegates.Get().find(id);
@@ -524,13 +713,13 @@
     if (it != g_host_delegates.Get().end())
       delegate = it->second;
     else
-      delegate = new AgentHostDelegate(id, serial_, bridge->adb_thread_,
+      delegate = new AgentHostDelegate(id, serial_, bridge_->adb_thread_,
                                        socket);
     DevToolsWindow::OpenExternalFrontend(
-        bridge->profile_, frontend_url_, delegate->GetAgentHost().get());
+        bridge_->profile_, frontend_url_, delegate->GetAgentHost().get());
   }
 
-  base::WeakPtr<DevToolsAdbBridge> bridge_;
+  scoped_refptr<DevToolsAdbBridge> bridge_;
   std::string serial_;
   std::string socket_;
   std::string debug_url_;
@@ -615,12 +804,15 @@
 DevToolsAdbBridge::DevToolsAdbBridge(Profile* profile)
     : profile_(profile),
       adb_thread_(RefCountedAdbThread::GetInstance()),
-      weak_factory_(this),
       has_message_loop_(adb_thread_->message_loop() != NULL) {
+  rsa_key_.reset(AndroidRSAPrivateKey(profile));
 }
 
-DevToolsAdbBridge::~DevToolsAdbBridge() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+void DevToolsAdbBridge::EnumerateDevices(
+    const AndroidDevicesCallback& callback) {
+  AdbClientSocket::AdbQuery(
+      kAdbPort, kHostDevicesCommand,
+      base::Bind(&DevToolsAdbBridge::ReceivedDevices, this, callback));
 }
 
 void DevToolsAdbBridge::Query(
@@ -641,7 +833,8 @@
   if (!has_message_loop_)
     return;
 
-  scoped_refptr<AdbPagesCommand> command(new AdbPagesCommand(callback));
+  scoped_refptr<AdbPagesCommand> command(
+      new AdbPagesCommand(this, callback));
   adb_thread_->message_loop()->PostTask(FROM_HERE,
       base::Bind(&AdbPagesCommand::Run, command));
 }
@@ -655,9 +848,46 @@
     return;
 
   scoped_refptr<AdbAttachCommand> command(
-      new AdbAttachCommand(weak_factory_.GetWeakPtr(), serial, socket,
+      new AdbAttachCommand(this, serial, socket,
                            debug_url, frontend_url));
   adb_thread_->message_loop()->PostTask(
       FROM_HERE,
       base::Bind(&AdbAttachCommand::Run, command));
 }
+
+DevToolsAdbBridge::~DevToolsAdbBridge() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+}
+
+void DevToolsAdbBridge::ReceivedDevices(const AndroidDevicesCallback& callback,
+                                        int result,
+                                        const std::string& response) {
+  AndroidDevices devices;
+#if defined(DEBUG_DEVTOOLS)
+  devices.push_back(new AdbDeviceImpl(""));  // For desktop remote debugging.
+#endif  // defined(DEBUG_DEVTOOLS)
+
+  if (CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kRemoteDebuggingRawUSB)) {
+    AndroidUsbDevices usb_devices;
+    AndroidUsbDevice::Enumerate(profile_, rsa_key_.get(), &usb_devices);
+    for (AndroidUsbDevices::iterator it = usb_devices.begin();
+         it != usb_devices.end(); ++it) {
+      devices.push_back(new UsbDeviceImpl(*it));
+    }
+  }
+
+  if (result != net::OK) {
+    callback.Run(devices);
+    return;
+  }
+
+  std::vector<std::string> serials;
+  Tokenize(response, "\n", &serials);
+  for (size_t i = 0; i < serials.size(); ++i) {
+    std::vector<std::string> tokens;
+    Tokenize(serials[i], "\t ", &tokens);
+    devices.push_back(new AdbDeviceImpl(tokens[0]));
+  }
+  callback.Run(devices);
+}
diff --git a/chrome/browser/devtools/devtools_adb_bridge.h b/chrome/browser/devtools/devtools_adb_bridge.h
index a828cb1..775bbec 100644
--- a/chrome/browser/devtools/devtools_adb_bridge.h
+++ b/chrome/browser/devtools/devtools_adb_bridge.h
@@ -11,25 +11,71 @@
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
+#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
+#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
 #include "net/socket/tcp_client_socket.h"
 
+template<typename T> struct DefaultSingletonTraits;
+
 namespace base {
 class MessageLoop;
 class DictionaryValue;
 class Thread;
 }
 
+namespace content {
+class BrowserContext;
+}
+
+namespace crypto {
+class RSAPrivateKey;
+}
+
 class Profile;
 
 // The format used for constructing DevTools server socket names.
 extern const char kDevToolsChannelNameFormat[];
 
-class DevToolsAdbBridge {
+typedef base::Callback<void(int, const std::string&)> CommandCallback;
+typedef base::Callback<void(int result, net::StreamSocket*)> SocketCallback;
+
+class DevToolsAdbBridge :
+    public base::RefCountedThreadSafe<DevToolsAdbBridge> {
  public:
   typedef base::Callback<void(int result,
                               const std::string& response)> Callback;
 
+  class Wrapper : public BrowserContextKeyedService {
+   public:
+    Wrapper(Profile* profile);
+    virtual ~Wrapper();
+
+    DevToolsAdbBridge* Get();
+   private:
+    scoped_refptr<DevToolsAdbBridge> bridge_;
+  };
+
+  class Factory : public BrowserContextKeyedServiceFactory {
+   public:
+    // Returns singleton instance of DevToolsAdbBridge.
+    static Factory* GetInstance();
+
+    // Returns DevToolsAdbBridge associated with |profile|.
+    static DevToolsAdbBridge* GetForProfile(Profile* profile);
+
+   private:
+    friend struct DefaultSingletonTraits<Factory>;
+    friend class DevToolsAdbBridge;
+
+    Factory();
+    virtual ~Factory();
+
+    // BrowserContextKeyedServiceFactory overrides:
+    virtual BrowserContextKeyedService* BuildServiceInstanceFor(
+        content::BrowserContext* context) const OVERRIDE;
+    DISALLOW_COPY_AND_ASSIGN(Factory);
+  };
+
   class RemotePage : public base::RefCounted<RemotePage> {
    public:
     RemotePage(const std::string& serial,
@@ -70,9 +116,52 @@
   typedef std::vector<scoped_refptr<RemotePage> > RemotePages;
   typedef base::Callback<void(int, RemotePages*)> PagesCallback;
 
-  explicit DevToolsAdbBridge(Profile* profile);
-  ~DevToolsAdbBridge();
+  class AndroidDevice : public base::RefCounted<AndroidDevice> {
+   public:
+    explicit AndroidDevice(const std::string& serial);
 
+    virtual void RunCommand(const std::string& command,
+                            const CommandCallback& callback) = 0;
+    virtual void OpenSocket(const std::string& socket_name,
+                            const SocketCallback& callback) = 0;
+    virtual void HttpQuery(const std::string& la_name,
+                           const std::string& request,
+                           const CommandCallback& callback);
+    virtual void HttpQuery(const std::string& la_name,
+                           const std::string& request,
+                           const SocketCallback& callback);
+
+    std::string serial() { return serial_; }
+
+    std::string model() { return model_; }
+    void set_model(const std::string& model) { model_ = model; }
+
+   protected:
+    friend class base::RefCounted<AndroidDevice>;
+    virtual ~AndroidDevice();
+
+   private:
+    void OnHttpSocketOpened(const std::string& request,
+                            const CommandCallback& callback,
+                            int result,
+                            net::StreamSocket* socket);
+    void OnHttpSocketOpened2(const std::string& request,
+                             const SocketCallback& callback,
+                             int result,
+                             net::StreamSocket* socket);
+
+    std::string serial_;
+    std::string model_;
+
+    DISALLOW_COPY_AND_ASSIGN(AndroidDevice);
+  };
+
+  typedef std::vector<scoped_refptr<AndroidDevice> > AndroidDevices;
+  typedef base::Callback<void(const AndroidDevices&)> AndroidDevicesCallback;
+
+  explicit DevToolsAdbBridge(Profile* profile);
+
+  void EnumerateDevices(const AndroidDevicesCallback& callback);
   void Query(const std::string query, const Callback& callback);
   void Pages(const PagesCallback& callback);
   void Attach(const std::string& serial,
@@ -81,9 +170,12 @@
               const std::string& frontend_url);
 
  private:
+  friend class base::RefCountedThreadSafe<DevToolsAdbBridge>;
   friend class AdbAttachCommand;
   friend class AgentHostDelegate;
 
+  virtual ~DevToolsAdbBridge();
+
   class RefCountedAdbThread : public base::RefCounted<RefCountedAdbThread> {
    public:
     static scoped_refptr<RefCountedAdbThread> GetInstance();
@@ -99,10 +191,14 @@
     base::Thread* thread_;
   };
 
+  void ReceivedDevices(const AndroidDevicesCallback& callback,
+                       int result,
+                       const std::string& response);
+
   Profile* profile_;
   scoped_refptr<RefCountedAdbThread> adb_thread_;
-  base::WeakPtrFactory<DevToolsAdbBridge> weak_factory_;
   bool has_message_loop_;
+  scoped_ptr<crypto::RSAPrivateKey> rsa_key_;
   DISALLOW_COPY_AND_ASSIGN(DevToolsAdbBridge);
 };
 
diff --git a/chrome/browser/devtools/devtools_file_helper.cc b/chrome/browser/devtools/devtools_file_helper.cc
index 452602a..cb596d6 100644
--- a/chrome/browser/devtools/devtools_file_helper.cc
+++ b/chrome/browser/devtools/devtools_file_helper.cc
@@ -16,6 +16,7 @@
 #include "base/value_conversions.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/download/download_prefs.h"
+#include "chrome/browser/platform_util.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/chrome_select_file_policy.h"
@@ -27,6 +28,7 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/url_constants.h"
 #include "grit/generated_resources.h"
@@ -59,9 +61,11 @@
                          public base::RefCounted<SelectFileDialog> {
  public:
   SelectFileDialog(const SelectedCallback& selected_callback,
-                   const CanceledCallback& canceled_callback)
+                   const CanceledCallback& canceled_callback,
+                   WebContents* web_contents)
       : selected_callback_(selected_callback),
-        canceled_callback_(canceled_callback) {
+        canceled_callback_(canceled_callback),
+        web_contents_(web_contents) {
     select_file_dialog_ = ui::SelectFileDialog::Create(
         this, new ChromeSelectFilePolicy(NULL));
   }
@@ -69,14 +73,15 @@
   void Show(ui::SelectFileDialog::Type type,
             const base::FilePath& default_path) {
     AddRef();  // Balanced in the three listener outcomes.
-    select_file_dialog_->SelectFile(type,
-                                    string16(),
-                                    default_path,
-                                    NULL,
-                                    0,
-                                    base::FilePath::StringType(),
-                                    NULL,
-                                    NULL);
+    select_file_dialog_->SelectFile(
+      type,
+      string16(),
+      default_path,
+      NULL,
+      0,
+      base::FilePath::StringType(),
+      platform_util::GetTopLevel(web_contents_->GetView()->GetNativeView()),
+      NULL);
   }
 
   // ui::SelectFileDialog::Listener implementation.
@@ -105,6 +110,7 @@
   scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   SelectedCallback selected_callback_;
   CanceledCallback canceled_callback_;
+  WebContents* web_contents_;
 };
 
 void WriteToFile(const base::FilePath& path, const std::string& content) {
@@ -238,7 +244,8 @@
            content,
            callback),
       Bind(&DevToolsFileHelper::SaveAsFileSelectionCanceled,
-           weak_factory_.GetWeakPtr()));
+           weak_factory_.GetWeakPtr()),
+      web_contents_);
   select_file_dialog->Show(ui::SelectFileDialog::SELECT_SAVEAS_FILE,
                            initial_path);
 }
@@ -282,7 +289,8 @@
            weak_factory_.GetWeakPtr(),
            callback,
            show_info_bar_callback),
-      Bind(callback, FileSystem()));
+      Bind(callback, FileSystem()),
+      web_contents_);
   select_file_dialog->Show(ui::SelectFileDialog::SELECT_FOLDER,
                            base::FilePath());
 }
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc
index aba2865..746fe56 100644
--- a/chrome/browser/devtools/devtools_sanity_browsertest.cc
+++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -12,6 +12,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/test_timeouts.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/browser_list_tabcontents_provider.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/extension_apitest.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -529,7 +529,8 @@
 }
 
 // Tests that console messages are not duplicated on navigation back.
-IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestConsoleOnNavigateBack) {
+// Disabled: http://crbug.com/260341
+IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, DISABLED_TestConsoleOnNavigateBack) {
   RunTest("testConsoleOnNavigateBack", kNavigateBackTestPage);
 }
 
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc
index 78005c0..21fa114 100644
--- a/chrome/browser/devtools/devtools_window.cc
+++ b/chrome/browser/devtools/devtools_window.cc
@@ -14,6 +14,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/debugger/debugger_api.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -35,7 +36,6 @@
 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/devtools_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/manifest_url_handler.h"
 #include "chrome/common/pref_names.h"
@@ -181,7 +181,7 @@
 }
 
 // static
-void DevToolsWindow::RegisterUserPrefs(
+void DevToolsWindow::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kDevToolsOpenDocked,
@@ -197,6 +197,10 @@
   registry->RegisterDictionaryPref(
       prefs::kDevToolsFileSystemPaths,
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+  registry->RegisterStringPref(
+      prefs::kDevToolsAdbKey,
+      std::string(),
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 
   registry->RegisterDictionaryPref(
       GetDevToolsWindowPlacementPrefKey().c_str(),
@@ -635,7 +639,7 @@
   nav_params.source_contents = source;
   nav_params.tabstrip_add_types = TabStripModel::ADD_NONE;
   nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
-  nav_params.user_gesture = true;
+  nav_params.user_gesture = params.user_gesture;
   chrome::Navigate(&nav_params);
   return nav_params.target_contents;
 }
diff --git a/chrome/browser/devtools/devtools_window.h b/chrome/browser/devtools/devtools_window.h
index 9225994..cce9d81 100644
--- a/chrome/browser/devtools/devtools_window.h
+++ b/chrome/browser/devtools/devtools_window.h
@@ -58,7 +58,7 @@
  public:
   static const char kDevToolsApp[];
   static std::string GetDevToolsWindowPlacementPrefKey();
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
   static DevToolsWindow* GetDockedInstanceForInspectedTab(
       content::WebContents* inspected_tab);
   static bool IsDevToolsWindow(content::RenderViewHost* window_rvh);
diff --git a/chrome/browser/devtools/tethering_adb_filter.cc b/chrome/browser/devtools/tethering_adb_filter.cc
index c06c2bc..b0989de 100644
--- a/chrome/browser/devtools/tethering_adb_filter.cc
+++ b/chrome/browser/devtools/tethering_adb_filter.cc
@@ -11,6 +11,7 @@
 #include "base/json/json_reader.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
 #include "base/values.h"
 #include "chrome/browser/devtools/adb_client_socket.h"
 #include "net/base/address_list.h"
@@ -31,6 +32,7 @@
 static const char kTetheringAccepted[] = "Tethering.accepted";
 static const char kTetheringBind[] = "Tethering.bind";
 static const char kTetheringUnbind[] = "Tethering.unbind";
+static const char kLocalAbstractCommand[] = "localabstract:%s";
 
 class SocketTunnel {
  public:
@@ -229,8 +231,10 @@
   std::string location = it->second;
 
   SocketTunnel* tunnel = new SocketTunnel(location);
+  std::string command = base::StringPrintf(kLocalAbstractCommand,
+                                           connection_id.c_str());
   AdbClientSocket::TransportQuery(
-      adb_port_, serial_, connection_id,
+      adb_port_, serial_, command,
       base::Bind(&SocketTunnel::Start, base::Unretained(tunnel)));
   return true;
 }
diff --git a/chrome/browser/diagnostics/diagnostics_controller.cc b/chrome/browser/diagnostics/diagnostics_controller.cc
new file mode 100644
index 0000000..a578beb
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_controller.cc
@@ -0,0 +1,49 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/diagnostics/diagnostics_controller.h"
+
+#include <string>
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
+#include "chrome/browser/diagnostics/diagnostics_model.h"
+#include "chrome/browser/diagnostics/diagnostics_writer.h"
+#include "chrome/common/chrome_switches.h"
+
+namespace diagnostics {
+
+DiagnosticsController* DiagnosticsController::GetInstance() {
+  return Singleton<DiagnosticsController>::get();
+}
+
+DiagnosticsController::DiagnosticsController() : writer_(NULL) {}
+
+DiagnosticsController::~DiagnosticsController() {}
+
+const DiagnosticsModel& DiagnosticsController::GetResults() const {
+  return *model_;
+}
+
+bool DiagnosticsController::HasResults() {
+  return (model_.get() && model_->GetTestRunCount() > 0);
+}
+
+void DiagnosticsController::ClearResults() { model_.reset(); }
+
+// This entry point is called from ChromeMain() when very few things
+// have been initialized, so be careful what you use.
+int DiagnosticsController::Run(const CommandLine& command_line,
+                               DiagnosticsWriter* writer) {
+  writer_ = writer;
+
+  model_.reset(MakeDiagnosticsModel(command_line));
+  model_->RunAll(writer_);
+
+  return 0;
+}
+
+}  // namespace diagnostics
diff --git a/chrome/browser/diagnostics/diagnostics_controller.h b/chrome/browser/diagnostics/diagnostics_controller.h
new file mode 100644
index 0000000..706a10f
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_controller.h
@@ -0,0 +1,51 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_CONTROLLER_H_
+#define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_CONTROLLER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
+
+class CommandLine;
+
+namespace diagnostics {
+
+class DiagnosticsWriter;
+class DiagnosticsModel;
+
+class DiagnosticsController {
+ public:
+  static DiagnosticsController* GetInstance();
+
+  // Entry point for the diagnostics mode. Returns zero if able to run
+  // diagnostics successfully, regardless of the results of the diagnostics.
+  int Run(const CommandLine& command_line, DiagnosticsWriter* writer);
+
+  // Returns a model with the results that have accumulated.  They can then be
+  // queried for their attributes for human consumption later.
+  const DiagnosticsModel& GetResults() const;
+
+  // Returns true if there are any results available.
+  bool HasResults();
+
+  // Clears any results that have accumulated. After calling this, do not call
+  // GetResults until after Run is called again.
+  void ClearResults();
+
+ private:
+  friend struct DefaultSingletonTraits<DiagnosticsController>;
+
+  DiagnosticsController();
+  ~DiagnosticsController();
+
+  scoped_ptr<DiagnosticsModel> model_;
+  DiagnosticsWriter* writer_;
+
+  DISALLOW_COPY_AND_ASSIGN(DiagnosticsController);
+};
+
+}  // namespace diagnostics
+
+#endif  // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_CONTROLLER_H_
diff --git a/chrome/browser/diagnostics/diagnostics_main.cc b/chrome/browser/diagnostics/diagnostics_main.cc
deleted file mode 100644
index 7d02a23..0000000
--- a/chrome/browser/diagnostics/diagnostics_main.cc
+++ /dev/null
@@ -1,367 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/diagnostics/diagnostics_main.h"
-
-#include "build/build_config.h"
-
-#if defined(OS_POSIX)
-#include <stdio.h>
-#include <unistd.h>
-#endif
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/command_line.h"
-#include "base/i18n/icu_util.h"
-#include "base/logging.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
-#include "chrome/browser/diagnostics/diagnostics_model.h"
-#include "chrome/common/chrome_paths.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/base/ui_base_paths.h"
-
-namespace {
-// This is a minimalistic interface to wrap the platform console.  This will be
-// eventually replaced by a view that can be subclassed for each platform and
-// that the approved look and feel.
-class SimpleConsole {
- public:
-  enum Color {
-    DEFAULT,
-    RED,
-    GREEN,
-  };
-
-  virtual ~SimpleConsole() { }
-
-  // Init must be called before using any other method. If it returns
-  // false there would be no console output.
-  virtual bool Init() = 0;
-
-  // Writes a string to the console with the current color.
-  virtual bool Write(const std::wstring& text) = 0;
-
-  // Called when the program is about to exit.
-  virtual void OnQuit() = 0;
-
-  // Sets the foreground and background color.
-  virtual bool SetColor(Color color) = 0;
-
-  // Create an appropriate SimpleConsole instance.  May return NULL if there is
-  // no implementation for the current platform.
-  static SimpleConsole* Create();
-};
-
-#if defined(OS_WIN)
-// Wrapper for the windows console operating in high-level IO mode.
-class WinConsole : public SimpleConsole {
- public:
-  // The ctor allocates a console always. This avoids having to ask
-  // the user to start chrome from a command prompt.
-  WinConsole()
-      : std_out_(INVALID_HANDLE_VALUE),
-        std_in_(INVALID_HANDLE_VALUE)  {
-  }
-
-  virtual ~WinConsole() {
-    ::FreeConsole();
-  }
-
-  virtual bool Init() {
-    ::AllocConsole();
-    return SetIOHandles();
-  }
-
-  virtual bool Write(const std::wstring& txt) {
-    DWORD sz = txt.size();
-    return (TRUE == ::WriteConsoleW(std_out_, txt.c_str(), sz, &sz, NULL));
-  }
-
-  // Reads a string from the console. Internally it is limited to 256
-  // characters.
-  virtual void OnQuit() {
-    // Block here so the user can see the results.
-    SetColor(SimpleConsole::DEFAULT);
-    Write(L"Press [enter] to continue\n");
-    wchar_t buf[256];
-    DWORD read = arraysize(buf);
-    ::ReadConsoleW(std_in_, buf, read, &read, NULL);
-  }
-
-  // Sets the foreground and background color.
-  virtual bool SetColor(Color color) {
-    uint16 color_combo =
-        FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY;
-    switch (color) {
-      case RED:
-        color_combo = FOREGROUND_RED|FOREGROUND_INTENSITY;
-        break;
-      case GREEN:
-        color_combo = FOREGROUND_GREEN|FOREGROUND_INTENSITY;
-        break;
-      case DEFAULT:
-        break;
-      default:
-        NOTREACHED();
-    }
-    return (TRUE == ::SetConsoleTextAttribute(std_out_, color_combo));
-  }
-
- private:
-  bool SetIOHandles() {
-    std_out_ = ::GetStdHandle(STD_OUTPUT_HANDLE);
-    std_in_ = ::GetStdHandle(STD_INPUT_HANDLE);
-    return ((std_out_ != INVALID_HANDLE_VALUE) &&
-            (std_in_ != INVALID_HANDLE_VALUE));
-  }
-
-  // The input and output handles to the screen. They seem to be
-  // implemented as pipes but they have non-documented protocol.
-  HANDLE std_out_;
-  HANDLE std_in_;
-
-  DISALLOW_COPY_AND_ASSIGN(WinConsole);
-};
-
-SimpleConsole* SimpleConsole::Create() {
-  return new WinConsole();
-}
-
-#elif defined(OS_POSIX)
-
-class PosixConsole : public SimpleConsole {
- public:
-  PosixConsole() : use_color_(false) { }
-
-  virtual bool Init() OVERRIDE {
-    // Technically, we should also check the terminal capabilities before using
-    // color, but in practice this is unlikely to be an issue.
-    use_color_ = isatty(STDOUT_FILENO);
-    return true;
-  }
-
-  virtual bool Write(const std::wstring& text) OVERRIDE {
-    printf("%s", base::SysWideToNativeMB(text).c_str());
-    return true;
-  }
-
-  virtual void OnQuit() OVERRIDE {
-    // The "press enter to continue" prompt isn't very unixy, so only do that on
-    // Windows.
-  }
-
-  virtual bool SetColor(Color color) OVERRIDE {
-    if (!use_color_)
-      return false;
-
-    const char* code = "\033[m";
-    switch (color) {
-      case RED:
-        code = "\033[1;31m";
-        break;
-      case GREEN:
-        code = "\033[1;32m";
-        break;
-      case DEFAULT:
-        break;
-      default:
-        NOTREACHED();
-    }
-    printf("%s", code);
-    return true;
-  }
-
- private:
-  bool use_color_;
-
-  DISALLOW_COPY_AND_ASSIGN(PosixConsole);
-};
-
-SimpleConsole* SimpleConsole::Create() {
-  return new PosixConsole();
-}
-
-#else  // !defined(OS_WIN) && !defined(OS_POSIX)
-
-SimpleConsole* SimpleConsole::Create() {
-  return NULL;
-}
-#endif
-
-// This class wraps a SimpleConsole for the specific use case of
-// writing the results of the diagnostic tests.
-// TODO(cpu) figure out the localization strategy.
-class TestWriter {
- public:
-  // The |console| must be valid and properly initialized. This
-  // class does not own it.
-  explicit TestWriter(SimpleConsole* console)
-      : console_(console),
-        failures_(0) {
-  }
-
-  // How many tests reported failure.
-  int failures() { return failures_; }
-
-  // Write an informational line of text in white over black.
-  bool WriteInfoText(const std::wstring& txt) {
-    console_->SetColor(SimpleConsole::DEFAULT);
-    return console_->Write(txt);
-  }
-
-  bool WriteInfoText(const std::string& txt) {
-    return WriteInfoText(UTF8ToWide(txt));
-  }
-
-  // Write a result block. It consist of two lines. The first line
-  // has [PASS] or [FAIL] with |name| and the second line has
-  // the text in |extra|.
-  bool WriteResult(bool success, const std::wstring& name,
-                   const std::wstring& extra) {
-    if (success) {
-      console_->SetColor(SimpleConsole::GREEN);
-      console_->Write(L"[PASS] ");
-    } else {
-      console_->SetColor(SimpleConsole::RED);
-      console_->Write(L"[FAIL] ");
-      failures_++;
-    }
-    WriteInfoText(name + L"\n");
-    std::wstring second_line(L"   ");
-    second_line.append(extra);
-    return WriteInfoText(second_line + L"\n\n");
-  }
-
- private:
-  SimpleConsole* console_;
-
-  // Keeps track of how many tests reported failure.
-  int failures_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestWriter);
-};
-
-std::string PrintableUSCurrentTime() {
-  base::Time::Exploded exploded = {0};
-  base::Time::Now().UTCExplode(&exploded);
-  return base::StringPrintf("%d:%d:%d.%d:%d:%d",
-                            exploded.year,
-                            exploded.month,
-                            exploded.day_of_month,
-                            exploded.hour,
-                            exploded.minute,
-                            exploded.second);
-}
-
-// This class is a basic test controller. In this design the view (TestWriter)
-// and the model (DiagnosticsModel) do not talk to each other directly but they
-// are mediated by the controller. This has a name: 'passive view'.
-// More info at http://martinfowler.com/eaaDev/PassiveScreen.html
-class TestController : public DiagnosticsModel::Observer {
- public:
-  explicit TestController(TestWriter* writer)
-      : model_(NULL),
-        writer_(writer) {
-  }
-
-  // Run all the diagnostics of |model| and invoke the view as the model
-  // callbacks arrive.
-  void Run(DiagnosticsModel* model) {
-    writer_->WriteInfoText(L"Chrome Diagnostics Mode (");
-    writer_->WriteInfoText(PrintableUSCurrentTime() + ")\n");
-    if (!model) {
-      writer_->WriteResult(false, L"Diagnostics start", L"model is null");
-      return;
-    }
-    bool icu_result = icu_util::Initialize();
-    if (!icu_result) {
-      writer_->WriteResult(false, L"Diagnostics start", L"ICU failure");
-      return;
-    }
-    ResourceBundle::InitSharedInstanceWithLocale(std::string(), NULL);
-    int count = model->GetTestAvailableCount();
-    writer_->WriteInfoText(base::StringPrintf(
-        "%d available test(s)\n\n", count));
-    model->RunAll(this);
-  }
-
-  // Next four are overridden from DiagnosticsModel::Observer.
-  virtual void OnProgress(int id,
-                          int percent,
-                          DiagnosticsModel* model) OVERRIDE {
-  }
-
-  virtual void OnSkipped(int id, DiagnosticsModel* model) OVERRIDE {
-    // TODO(cpu): display skipped tests.
-  }
-
-  virtual void OnFinished(int id, DiagnosticsModel* model) OVERRIDE {
-    // As each test completes we output the results.
-    ShowResult(&model->GetTest(id));
-  }
-
-  virtual void OnDoneAll(DiagnosticsModel* model) OVERRIDE {
-    if (writer_->failures() > 0) {
-      writer_->WriteInfoText(base::StringPrintf(
-          "DONE. %d failure(s)\n\n", writer_->failures()));
-    } else {
-      writer_->WriteInfoText(L"DONE\n\n");
-    }
-  }
-
- private:
-  void ShowResult(DiagnosticsModel::TestInfo* test_info) {
-    bool success = (DiagnosticsModel::TEST_OK == test_info->GetResult());
-    writer_->WriteResult(success, UTF16ToWide(test_info->GetTitle()),
-                         UTF16ToWide(test_info->GetAdditionalInfo()));
-  }
-
-  DiagnosticsModel* model_;
-  TestWriter* writer_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestController);
-};
-}  // namespace
-
-// This entry point is called from ChromeMain() when very few things
-// have been initialized. To wit:
-// -(win)   Breakpad
-// -(macOS) base::EnableTerminationOnHeapCorruption()
-// -(macOS) base::EnableTerminationOnOutOfMemory()
-// -(all)   RegisterInvalidParamHandler()
-// -(all)   base::AtExitManager::AtExitManager()
-// -(macOS) base::ScopedNSAutoreleasePool
-// -(posix) base::GlobalDescriptors::GetInstance()->Set(kPrimaryIPCChannel)
-// -(linux) base::GlobalDescriptors::GetInstance()->Set(kCrashDumpSignal)
-// -(posix) setlocale(LC_ALL,..)
-// -(all)   CommandLine::Init();
-
-int DiagnosticsMain(const CommandLine& command_line) {
-  // If we can't initialize the console exit right away.
-  SimpleConsole* console = SimpleConsole::Create();
-  if (!console || !console->Init())
-    return 1;
-
-  // We need to have the path providers registered. They both
-  // return void so there is no early error signal that we can use.
-  ui::RegisterPathProvider();
-  chrome::RegisterPathProvider();
-
-  TestWriter writer(console);
-  DiagnosticsModel* model = MakeDiagnosticsModel(command_line);
-  TestController controller(&writer);
-
-  // Run all the diagnostic tests.
-  controller.Run(model);
-  delete model;
-
-  console->OnQuit();
-  delete console;
-  return 0;
-}
diff --git a/chrome/browser/diagnostics/diagnostics_main.h b/chrome/browser/diagnostics/diagnostics_main.h
deleted file mode 100644
index 0ce1404..0000000
--- a/chrome/browser/diagnostics/diagnostics_main.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MAIN_H_
-#define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MAIN_H_
-
-class CommandLine;
-
-// Entry point for the diagnostics mode. Most of the initialization that you
-// can see in ChromeMain() will be repeated here or will be done differently.
-int DiagnosticsMain(const CommandLine& command_line);
-
-
-#endif  // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MAIN_H_
diff --git a/chrome/browser/diagnostics/diagnostics_model.cc b/chrome/browser/diagnostics/diagnostics_model.cc
index 6f96d06..b52e0a5 100644
--- a/chrome/browser/diagnostics/diagnostics_model.cc
+++ b/chrome/browser/diagnostics/diagnostics_model.cc
@@ -19,30 +19,31 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 
+namespace diagnostics {
+
 namespace {
 
 // Embodies the commonalities of the model across platforms. It manages the
 // list of tests and can loop over them. The main job of the platform specific
 // code becomes:
-// 1- Inserting the appropiate tests into |tests_|
-// 2- Overriding RunTest() to wrap it with the appropiate fatal exception
+// 1- Inserting the appropriate tests into |tests_|
+// 2- Overriding RunTest() to wrap it with the appropriate fatal exception
 //    handler for the OS.
 // This class owns the all the tests and will only delete them upon
 // destruction.
 class DiagnosticsModelImpl : public DiagnosticsModel {
  public:
-  DiagnosticsModelImpl() : tests_run_(0) {
-  }
+  DiagnosticsModelImpl() : tests_run_(0) {}
 
   virtual ~DiagnosticsModelImpl() {
     STLDeleteElements(&tests_);
   }
 
-  virtual int GetTestRunCount() OVERRIDE {
+  virtual int GetTestRunCount() const OVERRIDE {
     return tests_run_;
   }
 
-  virtual int GetTestAvailableCount() OVERRIDE {
+  virtual int GetTestAvailableCount() const OVERRIDE {
     return tests_.size();
   }
 
@@ -54,20 +55,23 @@
       if (!do_next)
         break;
     }
-    observer->OnDoneAll(this);
+    if (observer)
+      observer->OnDoneAll(this);
   }
 
-  virtual TestInfo& GetTest(size_t id) OVERRIDE {
-    return *tests_[id];
+  virtual const TestInfo& GetTest(size_t index) OVERRIDE {
+    return *tests_[index];
   }
 
  protected:
   // Run a particular test. Return false if no other tests should be run.
-  virtual bool RunTest(DiagnosticTest* test, Observer* observer, size_t index) {
+  virtual bool RunTest(DiagnosticsTest* test,
+                       Observer* observer,
+                       size_t index) {
     return test->Execute(observer, this, index);
   }
 
-  typedef std::vector<DiagnosticTest*> TestArray;
+  typedef std::vector<DiagnosticsTest*> TestArray;
   TestArray tests_;
   int tests_run_;
 
@@ -153,6 +157,10 @@
     tests_.push_back(MakeSqliteThumbnailsDbTest());
     tests_.push_back(MakeSqliteAppCacheDbTest());
     tests_.push_back(MakeSqliteWebDatabaseTrackerDbTest());
+#if defined(OS_CHROMEOS)
+    tests_.push_back(MakeSqliteNssCertDbTest());
+    tests_.push_back(MakeSqliteNssKeyDbTest());
+#endif
   }
 
  private:
@@ -176,3 +184,5 @@
   return new DiagnosticsModelPosix();
 #endif
 }
+
+}  // namespace diagnostics
diff --git a/chrome/browser/diagnostics/diagnostics_model.h b/chrome/browser/diagnostics/diagnostics_model.h
index 466020b..1af3ae3 100644
--- a/chrome/browser/diagnostics/diagnostics_model.h
+++ b/chrome/browser/diagnostics/diagnostics_model.h
@@ -5,14 +5,16 @@
 #ifndef CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MODEL_H_
 #define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MODEL_H_
 
-#include "base/strings/string16.h"
+#include <string>
+#include "base/time/time.h"
 
 class CommandLine;
 
+namespace diagnostics {
+
 // The chrome diagnostics system is a model-view-controller system. The Model
 // responsible for holding and running the individual tests and providing a
 // uniform interface for querying the outcome.
-// TODO(cpu): The view and the controller are not yet built.
 class DiagnosticsModel {
  public:
   // A particular test can be in one of the following states.
@@ -31,13 +33,8 @@
   class Observer {
    public:
     virtual ~Observer() {}
-    // Called once upon test start with |percent| = 0 and periodically as the
-    // test progresses. There is no cancellation method.
-    virtual void OnProgress(int id, int percent, DiagnosticsModel* model) = 0;
-    // Called if the test in question cannot be run.
-    virtual void OnSkipped(int id, DiagnosticsModel* model) = 0;
-    // Called when the test has finished regardless of outcome.
-    virtual void OnFinished(int id, DiagnosticsModel* model) = 0;
+    // Called when a test has finished regardless of outcome.
+    virtual void OnFinished(int index, DiagnosticsModel* model) = 0;
     // Called once all the test are run.
     virtual void OnDoneAll(DiagnosticsModel* model) = 0;
   };
@@ -46,32 +43,45 @@
   class TestInfo {
    public:
     virtual ~TestInfo() {}
-    // A human readable, localized string that tells you what is being tested.
-    virtual string16 GetTitle() = 0;
+    // A parse-able ASCII string that indicates what is being tested.
+    virtual std::string GetId() const = 0;
+    // A human readable string that tells you what is being tested.
+    // This is not localized: it is only meant for developer consumption.
+    virtual std::string GetTitle() const = 0;
     // The result of running the test. If called before the test is ran the
     // answer is TEST_NOT_RUN.
-    virtual TestResult GetResult() = 0;
-    // A human readable, localized string that tells you what happened. If
+    virtual TestResult GetResult() const = 0;
+    // A human readable string that tells you more about what happened. If
     // called before the test is run it returns the empty string.
-    virtual string16 GetAdditionalInfo() = 0;
+    // This is not localized: it is only meant for developer consumption.
+    virtual std::string GetAdditionalInfo() const = 0;
+    // A test-specific code representing what happened. If called before the
+    // test is run, it should return -1.
+    virtual int GetOutcomeCode() const = 0;
+    // Returns the system time when the test was performed.
+    virtual base::Time GetStartTime() const = 0;
+    // Returns the system time when the test was finished.
+    virtual base::Time GetEndTime() const = 0;
   };
 
   virtual ~DiagnosticsModel() {}
   // Returns how many tests have been run.
-  virtual int GetTestRunCount() = 0;
+  virtual int GetTestRunCount() const = 0;
   // Returns how many tests are available. This value never changes.
-  virtual int GetTestAvailableCount() =0;
+  virtual int GetTestAvailableCount() const = 0;
   // Runs all the available tests, the |observer| callbacks will be called as
-  // the test progress and thus cannot be null.
+  // the diagnostics progress. |observer| maybe NULL if no observation is
+  // needed.
   virtual void RunAll(DiagnosticsModel::Observer* observer) = 0;
-  // Get the information for a particular test. Do not keep a pointer to the
-  // returned object.
-  virtual TestInfo& GetTest(size_t id) = 0;
+  // Get the information for a particular test. Lifetime of returned object is
+  // limited to the lifetime of this model.
+  virtual const TestInfo& GetTest(size_t index) = 0;
 };
 
 // The factory for the model. The main purpose is to hide the creation of
 // different models for different platforms.
 DiagnosticsModel* MakeDiagnosticsModel(const CommandLine& cmdline);
 
+}  // namespace diagnostics
 
 #endif  // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_MODEL_H_
diff --git a/chrome/browser/diagnostics/diagnostics_model_unittest.cc b/chrome/browser/diagnostics/diagnostics_model_unittest.cc
index e362cd4..d70a299 100644
--- a/chrome/browser/diagnostics/diagnostics_model_unittest.cc
+++ b/chrome/browser/diagnostics/diagnostics_model_unittest.cc
@@ -8,7 +8,9 @@
 #include "base/compiler_specific.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-// Basic harness to adquire and release the Diagnostic model object.
+namespace diagnostics {
+
+// Basic harness to acquire and release the Diagnostic model object.
 class DiagnosticsModelTest : public testing::Test {
  protected:
   DiagnosticsModelTest()
@@ -36,27 +38,15 @@
  public:
   UTObserver()
       : done_(false),
-        progress_called_(0),
         finished_(0),
         id_of_failed_stop_test(-1) {
   }
 
-  virtual void OnProgress(int id,
-                          int percent,
-                          DiagnosticsModel* model) OVERRIDE {
-    EXPECT_TRUE(model != NULL);
-    ++progress_called_;
-  }
-
-  virtual void OnSkipped(int id, DiagnosticsModel* model) OVERRIDE {
-    EXPECT_TRUE(model != NULL);
-  }
-
-  virtual void OnFinished(int id, DiagnosticsModel* model) OVERRIDE {
+  virtual void OnFinished(int index, DiagnosticsModel* model) OVERRIDE {
     EXPECT_TRUE(model != NULL);
     ++finished_;
-    if (model->GetTest(id).GetResult() == DiagnosticsModel::TEST_FAIL_STOP) {
-      id_of_failed_stop_test = id;
+    if (model->GetTest(index).GetResult() == DiagnosticsModel::TEST_FAIL_STOP) {
+      id_of_failed_stop_test = index;
       ASSERT_TRUE(false);
     }
   }
@@ -68,25 +58,26 @@
 
   bool done() const { return done_; }
 
-  int progress_called() const { return progress_called_; }
-
   int finished() const { return finished_;}
 
  private:
   bool done_;
-  int progress_called_;
   int finished_;
   int id_of_failed_stop_test;
 };
 
-// We currently have more tests operational on windows.
+// This is the count of tests on each platform.
 #if defined(OS_WIN)
 const int kDiagnosticsTestCount = 19;
 #elif defined(OS_MACOSX)
 const int kDiagnosticsTestCount = 16;
 #elif defined(OS_POSIX)
+#if defined(OS_CHROMEOS)
+const int kDiagnosticsTestCount = 19;
+#else
 const int kDiagnosticsTestCount = 17;
 #endif
+#endif
 
 // Test that the initial state is correct.
 TEST_F(DiagnosticsModelTest, BeforeRun) {
@@ -103,7 +94,8 @@
   EXPECT_FALSE(observer.done());
   model_->RunAll(&observer);
   EXPECT_TRUE(observer.done());
-  EXPECT_GT(observer.progress_called(), 0);
   EXPECT_EQ(kDiagnosticsTestCount, model_->GetTestRunCount());
   EXPECT_EQ(kDiagnosticsTestCount, observer.finished());
 }
+
+}  // namespace diagnostics
diff --git a/chrome/browser/diagnostics/diagnostics_test.cc b/chrome/browser/diagnostics/diagnostics_test.cc
index 64d4797..fe08dd6 100644
--- a/chrome/browser/diagnostics/diagnostics_test.cc
+++ b/chrome/browser/diagnostics/diagnostics_test.cc
@@ -9,45 +9,61 @@
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths.h"
 
-DiagnosticTest::DiagnosticTest(const string16& title)
-    : title_(title), result_(DiagnosticsModel::TEST_NOT_RUN) {
-}
+namespace diagnostics {
 
-DiagnosticTest::~DiagnosticTest() {
-}
+DiagnosticsTest::DiagnosticsTest(const std::string& id,
+                                 const std::string& title)
+    : id_(id),
+      title_(title),
+      outcome_code_(-1),
+      result_(DiagnosticsModel::TEST_NOT_RUN) {}
 
-bool DiagnosticTest::Execute(DiagnosticsModel::Observer* observer,
-                             DiagnosticsModel* model,
-                             size_t index) {
+DiagnosticsTest::~DiagnosticsTest() {}
+
+bool DiagnosticsTest::Execute(DiagnosticsModel::Observer* observer,
+                              DiagnosticsModel* model,
+                              size_t index) {
+  start_time_ = base::Time::Now();
   result_ = DiagnosticsModel::TEST_RUNNING;
-  observer->OnProgress(index, 0, model);
   bool keep_going = ExecuteImpl(observer);
-  observer->OnFinished(index, model);
+  if (observer)
+    observer->OnFinished(index, model);
   return keep_going;
 }
 
-string16 DiagnosticTest::GetTitle() {
-  return title_;
-}
-
-DiagnosticsModel::TestResult DiagnosticTest::GetResult() {
-  return result_;
-}
-
-string16 DiagnosticTest::GetAdditionalInfo() {
-  return additional_info_;
-}
-
-void DiagnosticTest::RecordOutcome(const string16& additional_info,
-                                   DiagnosticsModel::TestResult result) {
+void DiagnosticsTest::RecordOutcome(int outcome_code,
+                                    const std::string& additional_info,
+                                    DiagnosticsModel::TestResult result) {
+  end_time_ = base::Time::Now();
+  outcome_code_ = outcome_code;
   additional_info_ = additional_info;
   result_ = result;
 }
 
 // static
-base::FilePath DiagnosticTest::GetUserDefaultProfileDir() {
+base::FilePath DiagnosticsTest::GetUserDefaultProfileDir() {
   base::FilePath path;
   if (!PathService::Get(chrome::DIR_USER_DATA, &path))
     return base::FilePath();
   return path.AppendASCII(chrome::kInitialProfile);
 }
+
+std::string DiagnosticsTest::GetId() const { return id_; }
+
+std::string DiagnosticsTest::GetTitle() const { return title_; }
+
+DiagnosticsModel::TestResult DiagnosticsTest::GetResult() const {
+  return result_;
+}
+
+int DiagnosticsTest::GetOutcomeCode() const { return outcome_code_; }
+
+std::string DiagnosticsTest::GetAdditionalInfo() const {
+  return additional_info_;
+}
+
+base::Time DiagnosticsTest::GetStartTime() const { return start_time_; }
+
+base::Time DiagnosticsTest::GetEndTime() const { return end_time_; }
+
+}  // namespace diagnostics
diff --git a/chrome/browser/diagnostics/diagnostics_test.h b/chrome/browser/diagnostics/diagnostics_test.h
index eed176d..20e44d9 100644
--- a/chrome/browser/diagnostics/diagnostics_test.h
+++ b/chrome/browser/diagnostics/diagnostics_test.h
@@ -6,16 +6,17 @@
 #define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_TEST_H_
 
 #include "base/compiler_specific.h"
-#include "base/strings/string16.h"
 #include "chrome/browser/diagnostics/diagnostics_model.h"
 
 namespace base {
 class FilePath;
 }
 
+namespace diagnostics {
+
 // Represents a single diagnostic test and encapsulates the common
 // functionality across platforms as well.
-// It also Implements the TestInfo interface providing the storage
+// It also implements the TestInfo interface providing the storage
 // for the outcome of the test.
 // Specific tests need (minimally) only to:
 // 1- override ExecuteImpl() to implement the test.
@@ -23,52 +24,61 @@
 //    at the end of the test.
 // 3- Optionally call observer->OnProgress() if the test is long.
 // 4- Optionally call observer->OnSkipped() if the test cannot be run.
-class DiagnosticTest : public DiagnosticsModel::TestInfo {
+class DiagnosticsTest : public DiagnosticsModel::TestInfo {
  public:
-  // |title| is the human readable, localized string that says that
-  // the objective of the test is.
-  explicit DiagnosticTest(const string16& title);
+  // |id| is a parse-able ASCII ID string that uniquely identifies the test. It
+  // should only have letters, numbers and underscores in it (and no spaces).
+  // |title| is the human readable string that says what the objective of the
+  // test is.
+  DiagnosticsTest(const std::string& id, const std::string& title);
 
-  virtual ~DiagnosticTest();
+  virtual ~DiagnosticsTest();
 
   // Runs the test. Returning false signals that no more tests should be run.
   // The actual outcome of the test should be set using the RecordXX functions.
   bool Execute(DiagnosticsModel::Observer* observer, DiagnosticsModel* model,
                size_t index);
 
-  virtual string16 GetTitle() OVERRIDE;
-
-  virtual DiagnosticsModel::TestResult GetResult() OVERRIDE;
-
-  virtual string16 GetAdditionalInfo() OVERRIDE;
-
-  void RecordStopFailure(const string16& additional_info) {
-    RecordOutcome(additional_info, DiagnosticsModel::TEST_FAIL_STOP);
+  void RecordStopFailure(int outcome_code, const std::string& additional_info) {
+    RecordOutcome(
+        outcome_code, additional_info, DiagnosticsModel::TEST_FAIL_STOP);
   }
 
-  void RecordFailure(const string16& additional_info) {
-    RecordOutcome(additional_info, DiagnosticsModel::TEST_FAIL_CONTINUE);
+  void RecordFailure(int outcome_code, const std::string& additional_info) {
+    RecordOutcome(
+        outcome_code, additional_info, DiagnosticsModel::TEST_FAIL_CONTINUE);
   }
 
-  void RecordSuccess(const string16& additional_info) {
-    RecordOutcome(additional_info, DiagnosticsModel::TEST_OK);
+  void RecordSuccess(const std::string& additional_info) {
+    RecordOutcome(0, additional_info, DiagnosticsModel::TEST_OK);
   }
 
-  void RecordOutcome(const string16& additional_info,
+  void RecordOutcome(int outcome_code,
+                     const std::string& additional_info,
                      DiagnosticsModel::TestResult result);
 
   static base::FilePath GetUserDefaultProfileDir();
 
+  // DiagnosticsModel::TestInfo overrides
+  virtual std::string GetId() const OVERRIDE;
+  virtual std::string GetTitle() const OVERRIDE;
+  virtual DiagnosticsModel::TestResult GetResult() const OVERRIDE;
+  virtual std::string GetAdditionalInfo() const OVERRIDE;
+  virtual int GetOutcomeCode() const OVERRIDE;
+  virtual base::Time GetStartTime() const OVERRIDE;
+  virtual base::Time GetEndTime() const OVERRIDE;
  protected:
-  // The id needs to be overridden by derived classes and must uniquely
-  // identify this test so other test can refer to it.
-  virtual int GetId() = 0;
   // Derived classes override this method do perform the actual test.
   virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) = 0;
 
-  string16 title_;
-  string16 additional_info_;
+  const std::string id_;
+  const std::string title_;
+  std::string additional_info_;
+  int outcome_code_;
   DiagnosticsModel::TestResult result_;
+  base::Time start_time_;
+  base::Time end_time_;
 };
 
+}  // namespace diagnostics
 #endif  // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_TEST_H_
diff --git a/chrome/browser/diagnostics/diagnostics_writer.cc b/chrome/browser/diagnostics/diagnostics_writer.cc
new file mode 100644
index 0000000..bf49e3e
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_writer.cc
@@ -0,0 +1,281 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/diagnostics/diagnostics_writer.h"
+
+#include "build/build_config.h"
+
+#if defined(OS_POSIX)
+#include <stdio.h>
+#include <unistd.h>
+#endif
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/logging.h"
+#include "base/strings/string16.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/common/chrome_switches.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/ui_base_paths.h"
+
+namespace diagnostics {
+
+// This is a minimalistic interface to wrap the platform console.
+class SimpleConsole {
+ public:
+  enum Color {
+    DEFAULT,
+    RED,
+    GREEN,
+  };
+
+  virtual ~SimpleConsole() {}
+
+  // Init must be called before using any other method. If it returns
+  // false there will be no console output.
+  virtual bool Init() = 0;
+
+  // Writes a string to the console with the current color.
+  virtual bool Write(const string16& text) = 0;
+
+  // Called when the program is about to exit.
+  virtual void OnQuit() = 0;
+
+  // Sets the foreground text color.
+  virtual bool SetColor(Color color) = 0;
+
+  // Create an appropriate SimpleConsole instance.  May return NULL if there is
+  // no implementation for the current platform.
+  static SimpleConsole* Create();
+};
+
+#if defined(OS_WIN)
+namespace {
+
+// Wrapper for the windows console operating in high-level IO mode.
+class WinConsole : public SimpleConsole {
+ public:
+  // The ctor allocates a console. This avoids having to ask the user to start
+  // chrome from a command prompt.
+  WinConsole()
+      : std_out_(INVALID_HANDLE_VALUE),
+        std_in_(INVALID_HANDLE_VALUE) {
+    ::AllocConsole();
+  }
+
+  virtual ~WinConsole() {
+    ::FreeConsole();
+  }
+
+  virtual bool Init() {
+    return SetIOHandles();
+  }
+
+  virtual bool Write(const string16& txt) {
+    DWORD sz = txt.size();
+    return (TRUE == ::WriteConsoleW(std_out_, txt.c_str(), sz, &sz, NULL));
+  }
+
+  // Reads a string from the console. Internally it is limited to 256
+  // characters.
+  virtual void OnQuit() {
+    // Block here so the user can see the results.
+    SetColor(SimpleConsole::DEFAULT);
+    Write(L"Press [enter] to continue\n");
+    wchar_t buf[256];
+    DWORD read = arraysize(buf);
+    ::ReadConsoleW(std_in_, buf, read, &read, NULL);
+  }
+
+  // Sets the foreground and background color.
+  virtual bool SetColor(Color color) {
+    uint16 color_combo = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
+                         FOREGROUND_INTENSITY;
+    switch (color) {
+      case RED:
+        color_combo = FOREGROUND_RED | FOREGROUND_INTENSITY;
+        break;
+      case GREEN:
+        color_combo = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+        break;
+      case DEFAULT:
+        break;
+      default:
+        NOTREACHED();
+    }
+    return (TRUE == ::SetConsoleTextAttribute(std_out_, color_combo));
+  }
+
+ private:
+  bool SetIOHandles() {
+    std_out_ = ::GetStdHandle(STD_OUTPUT_HANDLE);
+    std_in_ = ::GetStdHandle(STD_INPUT_HANDLE);
+    return ((std_out_ != INVALID_HANDLE_VALUE) &&
+            (std_in_ != INVALID_HANDLE_VALUE));
+  }
+
+  // The input and output handles to the screen. They seem to be
+  // implemented as pipes but they have non-documented protocol.
+  HANDLE std_out_;
+  HANDLE std_in_;
+
+  DISALLOW_COPY_AND_ASSIGN(WinConsole);
+};
+
+}  // namespace
+
+SimpleConsole* SimpleConsole::Create() { return new WinConsole(); }
+
+#elif defined(OS_POSIX)
+namespace {
+
+class PosixConsole : public SimpleConsole {
+ public:
+  PosixConsole() : use_color_(false) {}
+
+  virtual bool Init() OVERRIDE {
+    // Technically, we should also check the terminal capabilities before using
+    // color, but in practice this is unlikely to be an issue.
+    use_color_ = isatty(STDOUT_FILENO);
+    return true;
+  }
+
+  virtual bool Write(const string16& text) OVERRIDE {
+    // We're assuming that the terminal is using UTF-8 encoding.
+    printf("%s", UTF16ToUTF8(text).c_str());
+    return true;
+  }
+
+  virtual void OnQuit() OVERRIDE {
+    // The "press enter to continue" prompt isn't very unixy, so only do that on
+    // Windows.
+  }
+
+  virtual bool SetColor(Color color) OVERRIDE {
+    if (!use_color_)
+      return false;
+
+    const char* code = "\033[m";
+    switch (color) {
+      case RED:
+        code = "\033[1;31m";
+        break;
+      case GREEN:
+        code = "\033[1;32m";
+        break;
+      case DEFAULT:
+        break;
+      default:
+        NOTREACHED();
+    }
+    printf("%s", code);
+    return true;
+  }
+
+ private:
+  bool use_color_;
+
+  DISALLOW_COPY_AND_ASSIGN(PosixConsole);
+};
+
+}  // namespace
+
+SimpleConsole* SimpleConsole::Create() { return new PosixConsole(); }
+
+#else  // !defined(OS_WIN) && !defined(OS_POSIX)
+SimpleConsole* SimpleConsole::Create() { return NULL; }
+#endif
+
+///////////////////////////////////////////////////////////
+//  DiagnosticsWriter
+
+DiagnosticsWriter::DiagnosticsWriter(FormatType format)
+    : failures_(0), format_(format) {
+  // Only create consoles for non-log output.
+  if (format_ != LOG) {
+    console_.reset(SimpleConsole::Create());
+    console_->Init();
+  }
+}
+
+DiagnosticsWriter::~DiagnosticsWriter() {
+  if (console_.get())
+    console_->OnQuit();
+}
+
+bool DiagnosticsWriter::WriteInfoLine(const std::string& info_text) {
+  if (format_ == LOG) {
+    LOG(WARNING) << info_text;
+    return true;
+  } else {
+    if (console_.get()) {
+      console_->SetColor(SimpleConsole::DEFAULT);
+      console_->Write(UTF8ToUTF16(info_text + "\n"));
+    }
+  }
+  return true;
+}
+
+void DiagnosticsWriter::OnFinished(int index, DiagnosticsModel* model) {
+  const DiagnosticsModel::TestInfo& test_info = model->GetTest(index);
+  bool success = (DiagnosticsModel::TEST_OK == test_info.GetResult());
+  WriteResult(success,
+              test_info.GetId(),
+              test_info.GetTitle(),
+              test_info.GetOutcomeCode(),
+              test_info.GetAdditionalInfo());
+}
+
+void DiagnosticsWriter::OnDoneAll(DiagnosticsModel* model) {
+  WriteInfoLine(
+      base::StringPrintf("Finished %d tests.", model->GetTestRunCount()));
+}
+
+bool DiagnosticsWriter::WriteResult(bool success,
+                                    const std::string& id,
+                                    const std::string& name,
+                                    int outcome_code,
+                                    const std::string& extra) {
+  std::string result;
+  SimpleConsole::Color color;
+
+  if (success) {
+    result = "[PASS] ";
+    color = SimpleConsole::GREEN;
+  } else {
+    color = SimpleConsole::RED;
+    result = "[FAIL] ";
+    failures_++;
+  }
+
+  if (format_ != LOG) {
+    if (console_.get()) {
+      console_->SetColor(color);
+      console_->Write(ASCIIToUTF16(result));
+    }
+    if (format_ == MACHINE) {
+      return WriteInfoLine(base::StringPrintf(
+          "%03d %s (%s)", outcome_code, id.c_str(), extra.c_str()));
+    } else {
+      return WriteInfoLine(name + "\n       " + extra + "\n");
+    }
+  } else {
+    if (!success) {
+      // For log output, we only care about the tests that failed.
+      return WriteInfoLine(base::StringPrintf("%s%03d %s (%s)",
+                                              result.c_str(),
+                                              outcome_code,
+                                              id.c_str(),
+                                              extra.c_str()));
+    }
+  }
+  return true;
+}
+
+}  // namespace diagnostics
diff --git a/chrome/browser/diagnostics/diagnostics_writer.h b/chrome/browser/diagnostics/diagnostics_writer.h
new file mode 100644
index 0000000..1fad047
--- /dev/null
+++ b/chrome/browser/diagnostics/diagnostics_writer.h
@@ -0,0 +1,66 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_WRITER_H_
+#define CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_WRITER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/diagnostics/diagnostics_model.h"
+
+namespace diagnostics {
+
+// Console base class used internally.
+class SimpleConsole;
+
+class DiagnosticsWriter : public DiagnosticsModel::Observer {
+ public:
+  // The type of formatting done by this writer.
+  enum FormatType {
+    MACHINE,
+    LOG,
+    HUMAN
+  };
+
+  explicit DiagnosticsWriter(FormatType format);
+  virtual ~DiagnosticsWriter();
+
+  // How many tests reported failure.
+  int failures() { return failures_; }
+
+  // What format are we writing things in.
+  FormatType format() const { return format_; }
+
+  // Write an informational line of text in white over black. String must be
+  // UTF8 encoded. A newline will be added for non-LOG output formats.
+  bool WriteInfoLine(const std::string& info_text);
+
+  // DiagnosticsModel::Observer overrides
+  virtual void OnFinished(int id, DiagnosticsModel* model) OVERRIDE;
+  virtual void OnDoneAll(DiagnosticsModel* model) OVERRIDE;
+
+ private:
+  // Write a result block. For humans, it consists of two lines. The first line
+  // has [PASS] or [FAIL] with |name| and the second line has the text in
+  // |extra|. For machine and log formats, we just have [PASS] or [FAIL],
+  // followed by the exact error code and the id. Name and extra strings must be
+  // UTF8 encoded, as they are user-facing strings.
+  bool WriteResult(bool success,
+                   const std::string& id,
+                   const std::string& name,
+                   int outcome_code,
+                   const std::string& extra);
+
+  scoped_ptr<SimpleConsole> console_;
+
+  // Keeps track of how many tests reported failure.
+  int failures_;
+  FormatType format_;
+
+  DISALLOW_COPY_AND_ASSIGN(DiagnosticsWriter);
+};
+
+}  // namespace diagnostics
+
+#endif  // CHROME_BROWSER_DIAGNOSTICS_DIAGNOSTICS_WRITER_H_
diff --git a/chrome/browser/diagnostics/recon_diagnostics.cc b/chrome/browser/diagnostics/recon_diagnostics.cc
index b66fd03..059d6fc 100644
--- a/chrome/browser/diagnostics/recon_diagnostics.cc
+++ b/chrome/browser/diagnostics/recon_diagnostics.cc
@@ -19,7 +19,6 @@
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_version_info.h"
-#include "ui/base/text/bytes_formatting.h"
 
 #if defined(OS_WIN)
 #include "base/win/windows_version.h"
@@ -31,21 +30,35 @@
 // diagnostic tests. Here we check for the existence of critical files.
 // TODO(cpu): Define if it makes sense to localize strings.
 
-// TODO(cpu): There are a few maximum file sizes hardcoded in this file
+// TODO(cpu): There are a few maximum file sizes hard-coded in this file
 // that have little or no theoretical or experimental ground. Find a way
 // to justify them.
 
+namespace diagnostics {
+
+const char kConflictingDllsTest[] = "ConflictingDlls";
+const char kDiskSpaceTest[] = "DiskSpace";
+const char kInstallTypeTest[] = "InstallType";
+const char kJSONBookmarksTest[] = "JSONBookmarks";
+const char kJSONLocalStateTest[] = "JSONLocalState";
+const char kJSONProfileTest[] = "JSONProfile";
+const char kOperatingSystemTest[] = "OperatingSystem";
+const char kPathDictionariesTest[] = "PathDictionaries";
+const char kPathLocalStateTest[] = "PathLocalState";
+const char kPathResourcesTest[] = "PathResources";
+const char kPathUserDataTest[] = "PathUserData";
+const char kVersionTest[] = "Version";
+
 namespace {
 
 class InstallTypeTest;
 InstallTypeTest* g_install_type = 0;
 
 // Check that the flavor of the operating system is supported.
-class OperatingSystemTest : public DiagnosticTest {
+class OperatingSystemTest : public DiagnosticsTest {
  public:
-  OperatingSystemTest() : DiagnosticTest(ASCIIToUTF16("Operating System")) {}
-
-  virtual int GetId() OVERRIDE { return 0; }
+  OperatingSystemTest()
+      : DiagnosticsTest(kOperatingSystemTest, "Operating System") {}
 
   virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
 #if defined(OS_WIN)
@@ -53,16 +66,17 @@
     if ((version < base::win::VERSION_XP) ||
         ((version == base::win::VERSION_XP) &&
          (base::win::OSInfo::GetInstance()->service_pack().major < 2))) {
-      RecordFailure(ASCIIToUTF16("Must have Windows XP SP2 or later"));
+      RecordFailure(DIAG_RECON_PRE_WINDOW_XP_SP2,
+                    "Must have Windows XP SP2 or later");
       return false;
     }
 #else
-    // TODO(port): define the OS criteria for Linux and Mac.
+// TODO(port): define the OS criteria for Linux and Mac.
 #endif  // defined(OS_WIN)
-    RecordSuccess(ASCIIToUTF16(base::StringPrintf(
-        "%s %s",
-        base::SysInfo::OperatingSystemName().c_str(),
-        base::SysInfo::OperatingSystemVersion().c_str())));
+    RecordSuccess(
+        base::StringPrintf("%s %s",
+                           base::SysInfo::OperatingSystemName().c_str(),
+                           base::SysInfo::OperatingSystemVersion().c_str()));
     return true;
   }
 
@@ -71,11 +85,10 @@
 };
 
 // Check if any conflicting DLLs are loaded.
-class ConflictingDllsTest : public DiagnosticTest {
+class ConflictingDllsTest : public DiagnosticsTest {
  public:
-  ConflictingDllsTest() : DiagnosticTest(ASCIIToUTF16("Conflicting modules")) {}
-
-  virtual int GetId() OVERRIDE { return 0; }
+  ConflictingDllsTest()
+      : DiagnosticsTest(kConflictingDllsTest, "Conflicting modules") {}
 
   virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
 #if defined(OS_WIN)
@@ -85,38 +98,40 @@
     scoped_ptr<ListValue> list(model->GetModuleList());
     if (!model->confirmed_bad_modules_detected() &&
         !model->suspected_bad_modules_detected()) {
-      RecordSuccess(ASCIIToUTF16("No conflicting modules found"));
+      RecordSuccess("No conflicting modules found");
       return true;
     }
 
-    string16 failures = ASCIIToUTF16("Possibly conflicting modules:");
+    std::string failures = "Possibly conflicting modules:";
     DictionaryValue* dictionary;
     for (size_t i = 0; i < list->GetSize(); ++i) {
       if (!list->GetDictionary(i, &dictionary))
-        RecordFailure(ASCIIToUTF16("Dictionary lookup failed"));
+        RecordFailure(DIAG_RECON_DICTIONARY_LOOKUP_FAILED,
+                      "Dictionary lookup failed");
       int status;
-      string16 location;
-      string16 name;
+      std::string location;
+      std::string name;
       if (!dictionary->GetInteger("status", &status))
-        RecordFailure(ASCIIToUTF16("No 'status' field found"));
+        RecordFailure(DIAG_RECON_NO_STATUS_FIELD, "No 'status' field found");
       if (status < ModuleEnumerator::SUSPECTED_BAD)
         continue;
 
       if (!dictionary->GetString("location", &location)) {
-        RecordFailure(ASCIIToUTF16("No 'location' field found"));
+        RecordFailure(DIAG_RECON_NO_LOCATION_FIELD,
+                      "No 'location' field found");
         return true;
       }
       if (!dictionary->GetString("name", &name)) {
-        RecordFailure(ASCIIToUTF16("No 'name' field found"));
+        RecordFailure(DIAG_RECON_NO_NAME_FIELD, "No 'name' field found");
         return true;
       }
 
-      failures += ASCIIToUTF16("\n") + location + name;
+      failures += "\n" + location + name;
     }
-    RecordFailure(failures);
+    RecordFailure(DIAG_RECON_CONFLICTING_MODULES, failures);
     return true;
 #else
-    RecordFailure(ASCIIToUTF16("Not implemented"));
+    RecordFailure(DIAG_RECON_NOT_IMPLEMENTED, "Not implemented");
     return true;
 #endif  // defined(OS_WIN)
   }
@@ -126,25 +141,23 @@
 };
 
 // Check if it is system install or per-user install.
-class InstallTypeTest : public DiagnosticTest {
+class InstallTypeTest : public DiagnosticsTest {
  public:
-  InstallTypeTest() : DiagnosticTest(ASCIIToUTF16("Install Type")),
-                      user_level_(false) {}
-
-  virtual int GetId() OVERRIDE { return 0; }
+  InstallTypeTest()
+      : DiagnosticsTest(kInstallTypeTest, "Install Type"), user_level_(false) {}
 
   virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
 #if defined(OS_WIN)
     base::FilePath chrome_exe;
     if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
-      RecordFailure(ASCIIToUTF16("Path provider failure"));
+      RecordFailure(DIAG_RECON_INSTALL_PATH_PROVIDER, "Path provider failure");
       return false;
     }
     user_level_ = InstallUtil::IsPerUserInstall(chrome_exe.value().c_str());
     const char* type = user_level_ ? "User Level" : "System Level";
-    string16 install_type(ASCIIToUTF16(type));
+    std::string install_type(type);
 #else
-    string16 install_type(ASCIIToUTF16("System Level"));
+    std::string install_type("System Level");
 #endif  // defined(OS_WIN)
     RecordSuccess(install_type);
     g_install_type = this;
@@ -159,21 +172,19 @@
 };
 
 // Check the version of Chrome.
-class VersionTest : public DiagnosticTest {
+class VersionTest : public DiagnosticsTest {
  public:
-  VersionTest() : DiagnosticTest(ASCIIToUTF16("Browser Version")) {}
-
-  virtual int GetId() OVERRIDE { return 0; }
+  VersionTest() : DiagnosticsTest(kVersionTest, "Browser Version") {}
 
   virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
     chrome::VersionInfo version_info;
     if (!version_info.is_valid()) {
-      RecordFailure(ASCIIToUTF16("No Version"));
+      RecordFailure(DIAG_RECON_NO_VERSION, "No Version");
       return true;
     }
     std::string current_version = version_info.Version();
     if (current_version.empty()) {
-      RecordFailure(ASCIIToUTF16("Empty Version"));
+      RecordFailure(DIAG_RECON_EMPTY_VERSION, "Empty Version");
       return true;
     }
     std::string version_modifier =
@@ -183,7 +194,7 @@
 #if defined(GOOGLE_CHROME_BUILD)
     current_version += " GCB";
 #endif  // defined(GOOGLE_CHROME_BUILD)
-    RecordSuccess(ASCIIToUTF16(current_version));
+    RecordSuccess(current_version);
     return true;
   }
 
@@ -193,51 +204,51 @@
 
 struct TestPathInfo {
   const char* test_name;
-  int  path_id;
+  const char* test_id;
+  int path_id;
   bool is_directory;
   bool is_optional;
   bool test_writable;
   int64 max_size;
 };
 
-const int64 kOneKilo = 1024;
-const int64 kOneMeg = 1024 * kOneKilo;
+const int64 kOneKilobyte = 1024;
+const int64 kOneMegabyte = 1024 * kOneKilobyte;
 
 const TestPathInfo kPathsToTest[] = {
-  {"User data Directory", chrome::DIR_USER_DATA,
-      true, false, true, 850 * kOneMeg},
-  {"Local state file", chrome::FILE_LOCAL_STATE,
-      false, false, true, 500 * kOneKilo},
-  {"Dictionaries Directory", chrome::DIR_APP_DICTIONARIES,
-      true, true, false, 0},
-  {"Resources file", chrome::FILE_RESOURCES_PACK,
-      false, false, false, 0}
+  {"User data Directory", kPathUserDataTest, chrome::DIR_USER_DATA, true, false,
+   true, 850 * kOneMegabyte},
+  {"Local state file", kPathLocalStateTest, chrome::FILE_LOCAL_STATE, false,
+   false, true, 500 * kOneKilobyte},
+  {"Dictionaries Directory", kPathDictionariesTest,
+   chrome::DIR_APP_DICTIONARIES, true, true, false, 0},
+  {"Resources file", kPathResourcesTest, chrome::FILE_RESOURCES_PACK, false,
+   false, false, 0}
 };
 
 // Check that the user's data directory exists and the paths are writable.
-// If it is a systemwide install some paths are not expected to be writable.
+// If it is a system-wide install some paths are not expected to be writable.
 // This test depends on |InstallTypeTest| having run successfully.
-class PathTest : public DiagnosticTest {
+class PathTest : public DiagnosticsTest {
  public:
   explicit PathTest(const TestPathInfo& path_info)
-      : DiagnosticTest(ASCIIToUTF16(path_info.test_name)),
+      : DiagnosticsTest(path_info.test_id, path_info.test_name),
         path_info_(path_info) {}
 
-  virtual int GetId() OVERRIDE { return 0; }
-
   virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
     if (!g_install_type) {
-      RecordStopFailure(ASCIIToUTF16("dependency failure"));
+      RecordStopFailure(DIAG_RECON_DEPENDENCY, "Install dependency failure");
       return false;
     }
     base::FilePath dir_or_file;
     if (!PathService::Get(path_info_.path_id, &dir_or_file)) {
-      RecordStopFailure(ASCIIToUTF16("Path provider failure"));
+      RecordStopFailure(DIAG_RECON_PATH_PROVIDER, "Path provider failure");
       return false;
     }
-    if (!file_util::PathExists(dir_or_file)) {
-      RecordFailure(ASCIIToUTF16("Path not found: ") +
-                    dir_or_file.LossyDisplayName());
+    if (!base::PathExists(dir_or_file)) {
+      RecordFailure(
+          DIAG_RECON_PATH_NOT_FOUND,
+          "Path not found: " + UTF16ToUTF8(dir_or_file.LossyDisplayName()));
       return true;
     }
 
@@ -248,32 +259,32 @@
       file_util::GetFileSize(dir_or_file, &dir_or_file_size);
     }
     if (!dir_or_file_size && !path_info_.is_optional) {
-      RecordFailure(ASCIIToUTF16("Cannot obtain size for: ") +
-                    dir_or_file.LossyDisplayName());
+      RecordFailure(DIAG_RECON_CANNOT_OBTAIN_SIZE,
+                    "Cannot obtain size for: " +
+                        UTF16ToUTF8(dir_or_file.LossyDisplayName()));
       return true;
     }
-    string16 printable_size = ui::FormatBytes(dir_or_file_size);
+    std::string printable_size = base::Int64ToString(dir_or_file_size);
 
     if (path_info_.max_size > 0) {
       if (dir_or_file_size > path_info_.max_size) {
-        RecordFailure(ASCIIToUTF16("Path contents too large (") +
-                      printable_size +
-                      ASCIIToUTF16(") for: ") +
-                      dir_or_file.LossyDisplayName());
+        RecordFailure(DIAG_RECON_FILE_TOO_LARGE,
+                      "Path contents too large (" + printable_size + ") for: " +
+                          UTF16ToUTF8(dir_or_file.LossyDisplayName()));
         return true;
       }
     }
     if (g_install_type->system_level() && !path_info_.test_writable) {
-      RecordSuccess(ASCIIToUTF16("Path exists"));
+      RecordSuccess("Path exists");
       return true;
     }
-    if (!file_util::PathIsWritable(dir_or_file)) {
-      RecordFailure(ASCIIToUTF16("Path is not writable: ") +
-                    dir_or_file.LossyDisplayName());
+    if (!base::PathIsWritable(dir_or_file)) {
+      RecordFailure(DIAG_RECON_NOT_WRITABLE,
+                    "Path is not writable: " +
+                        UTF16ToUTF8(dir_or_file.LossyDisplayName()));
       return true;
     }
-    RecordSuccess(ASCIIToUTF16("Path exists and is writable: ")
-                  + printable_size);
+    RecordSuccess("Path exists and is writable: " + printable_size);
     return true;
   }
 
@@ -282,13 +293,11 @@
   DISALLOW_COPY_AND_ASSIGN(PathTest);
 };
 
-// Check that the disk space in the volume where the user data dir normally
-// lives is not dangerously low.
-class DiskSpaceTest : public DiagnosticTest {
+// Check that the disk space in the volume where the user data directory
+// normally lives is not dangerously low.
+class DiskSpaceTest : public DiagnosticsTest {
  public:
-  DiskSpaceTest() : DiagnosticTest(ASCIIToUTF16("Disk Space")) {}
-
-  virtual int GetId() OVERRIDE { return 0; }
+  DiskSpaceTest() : DiagnosticsTest(kDiskSpaceTest, "Disk Space") {}
 
   virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
     base::FilePath data_dir;
@@ -296,15 +305,16 @@
       return false;
     int64 disk_space = base::SysInfo::AmountOfFreeDiskSpace(data_dir);
     if (disk_space < 0) {
-      RecordFailure(ASCIIToUTF16("Unable to query free space"));
+      RecordFailure(DIAG_RECON_UNABLE_TO_QUERY, "Unable to query free space");
       return true;
     }
-    string16 printable_size = ui::FormatBytes(disk_space);
-    if (disk_space < 80 * kOneMeg) {
-      RecordFailure(ASCIIToUTF16("Low disk space : ") + printable_size);
+    std::string printable_size = base::Int64ToString(disk_space);
+    if (disk_space < 80 * kOneMegabyte) {
+      RecordFailure(DIAG_RECON_LOW_DISK_SPACE,
+                    "Low disk space: " + printable_size);
       return true;
     }
-    RecordSuccess(ASCIIToUTF16("Free space : ") + printable_size);
+    RecordSuccess("Free space: " + printable_size);
     return true;
   }
 
@@ -313,36 +323,35 @@
 };
 
 // Checks that a given json file can be correctly parsed.
-class JSONTest : public DiagnosticTest {
+class JSONTest : public DiagnosticsTest {
  public:
   JSONTest(const base::FilePath& path,
-           const string16& name,
+           const std::string& id,
+           const std::string& name,
            int64 max_file_size)
-      : DiagnosticTest(name), path_(path), max_file_size_(max_file_size) {
-  }
-
-  virtual int GetId() OVERRIDE { return 0; }
+      : DiagnosticsTest(id, name), path_(path), max_file_size_(max_file_size) {}
 
   virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
-    if (!file_util::PathExists(path_)) {
-      RecordFailure(ASCIIToUTF16("File not found"));
+    if (!base::PathExists(path_)) {
+      RecordFailure(DIAG_RECON_FILE_NOT_FOUND, "File not found");
       return true;
     }
     int64 file_size;
     if (!file_util::GetFileSize(path_, &file_size)) {
-      RecordFailure(ASCIIToUTF16("Cannot obtain file size"));
+      RecordFailure(DIAG_RECON_CANNOT_OBTAIN_FILE_SIZE,
+                    "Cannot obtain file size");
       return true;
     }
 
     if (file_size > max_file_size_) {
-      RecordFailure(ASCIIToUTF16("File too big"));
+      RecordFailure(DIAG_RECON_FILE_TOO_BIG, "File too big");
       return true;
     }
     // Being small enough, we can process it in-memory.
     std::string json_data;
     if (!file_util::ReadFileToString(path_, &json_data)) {
-      RecordFailure(ASCIIToUTF16(
-          "Could not open file. Possibly locked by other process"));
+      RecordFailure(DIAG_RECON_UNABLE_TO_OPEN_FILE,
+                    "Could not open file. Possibly locked by another process");
       return true;
     }
 
@@ -354,11 +363,11 @@
       if (error_message.empty()) {
         error_message = "Parse error " + base::IntToString(error_code);
       }
-      RecordFailure(UTF8ToUTF16(error_message));
+      RecordFailure(DIAG_RECON_PARSE_ERROR, error_message);
       return true;
     }
 
-    RecordSuccess(ASCIIToUTF16("File parsed OK"));
+    RecordSuccess("File parsed OK");
     return true;
   }
 
@@ -370,57 +379,50 @@
 
 }  // namespace
 
-DiagnosticTest* MakeUserDirTest() {
-  return new PathTest(kPathsToTest[0]);
-}
+DiagnosticsTest* MakeUserDirTest() { return new PathTest(kPathsToTest[0]); }
 
-DiagnosticTest* MakeLocalStateFileTest() {
+DiagnosticsTest* MakeLocalStateFileTest() {
   return new PathTest(kPathsToTest[1]);
 }
 
-DiagnosticTest* MakeDictonaryDirTest() {
+DiagnosticsTest* MakeDictonaryDirTest() {
   return new PathTest(kPathsToTest[2]);
 }
 
-DiagnosticTest* MakeResourcesFileTest() {
+DiagnosticsTest* MakeResourcesFileTest() {
   return new PathTest(kPathsToTest[3]);
 }
 
-DiagnosticTest* MakeVersionTest() {
-  return new VersionTest();
-}
+DiagnosticsTest* MakeVersionTest() { return new VersionTest(); }
 
-DiagnosticTest* MakeDiskSpaceTest() {
-  return new DiskSpaceTest();
-}
+DiagnosticsTest* MakeDiskSpaceTest() { return new DiskSpaceTest(); }
 
-DiagnosticTest* MakeOperatingSystemTest() {
-  return new OperatingSystemTest();
-}
+DiagnosticsTest* MakeOperatingSystemTest() { return new OperatingSystemTest(); }
 
-DiagnosticTest* MakeConflictingDllsTest() {
-  return new ConflictingDllsTest();
-}
+DiagnosticsTest* MakeConflictingDllsTest() { return new ConflictingDllsTest(); }
 
-DiagnosticTest* MakeInstallTypeTest() {
-  return new InstallTypeTest();
-}
+DiagnosticsTest* MakeInstallTypeTest() { return new InstallTypeTest(); }
 
-DiagnosticTest* MakePreferencesTest() {
-  base::FilePath path = DiagnosticTest::GetUserDefaultProfileDir();
+DiagnosticsTest* MakePreferencesTest() {
+  base::FilePath path = DiagnosticsTest::GetUserDefaultProfileDir();
   path = path.Append(chrome::kPreferencesFilename);
-  return new JSONTest(path, ASCIIToUTF16("Profile JSON"), 100 * kOneKilo);
+  return new JSONTest(
+      path, kJSONProfileTest, "Profile JSON", 100 * kOneKilobyte);
 }
 
-DiagnosticTest* MakeBookMarksTest() {
-  base::FilePath path = DiagnosticTest::GetUserDefaultProfileDir();
+DiagnosticsTest* MakeBookMarksTest() {
+  base::FilePath path = DiagnosticsTest::GetUserDefaultProfileDir();
   path = path.Append(chrome::kBookmarksFileName);
-  return new JSONTest(path, ASCIIToUTF16("BookMarks JSON"), 2 * kOneMeg);
+  return new JSONTest(
+      path, kJSONBookmarksTest, "Bookmarks JSON", 2 * kOneMegabyte);
 }
 
-DiagnosticTest* MakeLocalStateTest() {
+DiagnosticsTest* MakeLocalStateTest() {
   base::FilePath path;
   PathService::Get(chrome::DIR_USER_DATA, &path);
   path = path.Append(chrome::kLocalStateFilename);
-  return new JSONTest(path, ASCIIToUTF16("Local State JSON"), 50 * kOneKilo);
+  return new JSONTest(
+      path, kJSONLocalStateTest, "Local State JSON", 50 * kOneKilobyte);
 }
+
+}  // namespace diagnostics
diff --git a/chrome/browser/diagnostics/recon_diagnostics.h b/chrome/browser/diagnostics/recon_diagnostics.h
index 3e04601..ac23e55 100644
--- a/chrome/browser/diagnostics/recon_diagnostics.h
+++ b/chrome/browser/diagnostics/recon_diagnostics.h
@@ -7,17 +7,76 @@
 
 #include "chrome/browser/diagnostics/diagnostics_test.h"
 
-DiagnosticTest* MakeOperatingSystemTest();
-DiagnosticTest* MakeConflictingDllsTest();
-DiagnosticTest* MakeInstallTypeTest();
-DiagnosticTest* MakeVersionTest();
-DiagnosticTest* MakeUserDirTest();
-DiagnosticTest* MakeLocalStateFileTest();
-DiagnosticTest* MakeDictonaryDirTest();
-DiagnosticTest* MakeResourcesFileTest();
-DiagnosticTest* MakeDiskSpaceTest();
-DiagnosticTest* MakePreferencesTest();
-DiagnosticTest* MakeBookMarksTest();
-DiagnosticTest* MakeLocalStateTest();
+namespace diagnostics {
+
+enum OutcomeCodes {
+  DIAG_RECON_SUCCESS,
+
+  // OperatingSystemTest
+  DIAG_RECON_PRE_WINDOW_XP_SP2,
+
+  // ConflictingDllsTest
+  DIAG_RECON_DICTIONARY_LOOKUP_FAILED,
+  DIAG_RECON_NO_STATUS_FIELD,
+  DIAG_RECON_NO_NAME_FIELD,
+  DIAG_RECON_NO_LOCATION_FIELD,
+  DIAG_RECON_CONFLICTING_MODULES,
+  DIAG_RECON_NOT_IMPLEMENTED,
+
+  // InstallTypeTest
+  DIAG_RECON_INSTALL_PATH_PROVIDER,
+
+  // VersionTest
+  DIAG_RECON_NO_VERSION,
+  DIAG_RECON_EMPTY_VERSION,
+
+  // PathTest
+  DIAG_RECON_DEPENDENCY,
+  DIAG_RECON_PATH_PROVIDER,
+  DIAG_RECON_PATH_NOT_FOUND,
+  DIAG_RECON_CANNOT_OBTAIN_SIZE,
+  DIAG_RECON_FILE_TOO_LARGE,
+  DIAG_RECON_NOT_WRITABLE,
+
+  // DiskSpaceTest
+  DIAG_RECON_UNABLE_TO_QUERY,
+  DIAG_RECON_LOW_DISK_SPACE,
+
+  // JSONTest
+  DIAG_RECON_FILE_NOT_FOUND,
+  DIAG_RECON_CANNOT_OBTAIN_FILE_SIZE,
+  DIAG_RECON_FILE_TOO_BIG,
+  DIAG_RECON_UNABLE_TO_OPEN_FILE,
+  DIAG_RECON_PARSE_ERROR,
+};
+
+// Identifiers for the tests.
+extern const char kConflictingDllsTest[];
+extern const char kDiskSpaceTest[];
+extern const char kInstallTypeTest[];
+extern const char kJSONBookmarksTest[];
+extern const char kJSONLocalStateTest[];
+extern const char kJSONProfileTest[];
+extern const char kOperatingSystemTest[];
+extern const char kPathDictionariesTest[];
+extern const char kPathLocalStateTest[];
+extern const char kPathResourcesTest[];
+extern const char kPathUserDataTest[];
+extern const char kVersionTest[];
+
+DiagnosticsTest* MakeOperatingSystemTest();
+DiagnosticsTest* MakeConflictingDllsTest();
+DiagnosticsTest* MakeInstallTypeTest();
+DiagnosticsTest* MakeVersionTest();
+DiagnosticsTest* MakeUserDirTest();
+DiagnosticsTest* MakeLocalStateFileTest();
+DiagnosticsTest* MakeDictonaryDirTest();
+DiagnosticsTest* MakeResourcesFileTest();
+DiagnosticsTest* MakeDiskSpaceTest();
+DiagnosticsTest* MakePreferencesTest();
+DiagnosticsTest* MakeBookMarksTest();
+DiagnosticsTest* MakeLocalStateTest();
+
+}  // namespace diagnostics
 
 #endif  // CHROME_BROWSER_DIAGNOSTICS_RECON_DIAGNOSTICS_H_
diff --git a/chrome/browser/diagnostics/sqlite_diagnostics.cc b/chrome/browser/diagnostics/sqlite_diagnostics.cc
index e808c5e..81753a8 100644
--- a/chrome/browser/diagnostics/sqlite_diagnostics.cc
+++ b/chrome/browser/diagnostics/sqlite_diagnostics.cc
@@ -6,13 +6,17 @@
 
 #include "base/file_util.h"
 #include "base/logging.h"
+#include "base/memory/ref_counted.h"
 #include "base/memory/singleton.h"
+#include "base/memory/weak_ptr.h"
 #include "base/metrics/histogram.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths.h"
+#include "chromeos/chromeos_constants.h"
 #include "components/webdata/common/webdata_constants.h"
 #include "content/public/common/content_constants.h"
 #include "sql/connection.h"
@@ -21,68 +25,159 @@
 #include "webkit/browser/database/database_tracker.h"
 #include "webkit/common/appcache/appcache_interfaces.h"
 
+namespace diagnostics {
+
+const char kSQLiteIntegrityAppCacheTest[] = "SQLiteIntegrityAppCache";
+const char kSQLiteIntegrityArchivedHistoryTest[] =
+    "SQLiteIntegrityArchivedHistory";
+const char kSQLiteIntegrityCookieTest[] = "SQLiteIntegrityCookie";
+const char kSQLiteIntegrityDatabaseTrackerTest[] =
+    "SQLiteIntegrityDatabaseTracker";
+const char kSQLiteIntegrityHistoryTest[] = "SQLiteIntegrityHistory";
+const char kSQLiteIntegrityThumbnailsTest[] = "SQLiteIntegrityThumbnails";
+const char kSQLiteIntegrityWebTest[] = "SQLiteIntegrityWeb";
+
+#if defined(OS_CHROMEOS)
+const char kSQLiteIntegrityNSSCertTest[] = "SQLiteIntegrityNSSCert";
+const char kSQLiteIntegrityNSSKeyTest[] = "SQLiteIntegrityNSSKey";
+#endif
+
 namespace {
 
-// Generic diagnostic test class for checking sqlite db integrity.
-class SqliteIntegrityTest : public DiagnosticTest {
+// Generic diagnostic test class for checking SQLite database integrity.
+class SqliteIntegrityTest : public DiagnosticsTest {
  public:
-  SqliteIntegrityTest(bool critical, const string16& title,
-                      const base::FilePath& profile_relative_db_path)
-      : DiagnosticTest(title),
-        critical_(critical),
-        db_path_(profile_relative_db_path) {
-  }
 
-  virtual int GetId() OVERRIDE { return 0; }
+  SqliteIntegrityTest(bool critical,
+                      const std::string& id,
+                      const std::string& title,
+                      const base::FilePath& db_path)
+      : DiagnosticsTest(id, title), critical_(critical), db_path_(db_path) {}
 
   virtual bool ExecuteImpl(DiagnosticsModel::Observer* observer) OVERRIDE {
-    base::FilePath path = GetUserDefaultProfileDir();
-    path = path.Append(db_path_);
-    if (!file_util::PathExists(path)) {
-      RecordOutcome(ASCIIToUTF16("File not found"),
-                    critical_ ? DiagnosticsModel::TEST_FAIL_CONTINUE :
-                                DiagnosticsModel::TEST_OK);
+    // If we're given an absolute path, use it. If not, then assume it's under
+    // the profile directory.
+    base::FilePath path;
+    if (!db_path_.IsAbsolute())
+      path = GetUserDefaultProfileDir().Append(db_path_);
+    else
+      path = db_path_;
+
+    if (!base::PathExists(path)) {
+      if (critical_) {
+        RecordOutcome(DIAG_SQLITE_FILE_NOT_FOUND,
+                      "File not found",
+                      DiagnosticsModel::TEST_FAIL_CONTINUE);
+      } else {
+        RecordOutcome(DIAG_SQLITE_FILE_NOT_FOUND_OK,
+                      "File not found (but that is OK)",
+                      DiagnosticsModel::TEST_OK);
+      }
       return true;
     }
 
     int errors = 0;
-    { // This block scopes the lifetime of the db objects.
-      sql::Connection db;
-      db.set_exclusive_locking();
-      if (!db.Open(path)) {
-        RecordFailure(ASCIIToUTF16("Cannot open DB. Possibly corrupted"));
+    {  // Scope the statement and database so they close properly.
+      sql::Connection database;
+      database.set_exclusive_locking();
+      scoped_refptr<ErrorRecorder> recorder(new ErrorRecorder);
+
+      // Set the error callback so that we can get useful results in a debug
+      // build for a corrupted database. Without setting the error callback,
+      // sql::Connection will just DCHECK.
+      database.set_error_callback(
+          base::Bind(&SqliteIntegrityTest::ErrorRecorder::RecordSqliteError,
+                     recorder->AsWeakPtr(),
+                     &database));
+      if (!database.Open(path)) {
+        RecordFailure(DIAG_SQLITE_CANNOT_OPEN_DB,
+                      "Cannot open DB. Possibly corrupted");
         return true;
       }
-      sql::Statement s(db.GetUniqueStatement("PRAGMA integrity_check;"));
-      if (!s.is_valid()) {
-        int error = db.GetErrorCode();
+      if (recorder->has_error()) {
+        RecordFailure(DIAG_SQLITE_ERROR_HANDLER_CALLED,
+                      recorder->FormatError());
+        return true;
+      }
+      sql::Statement statement(
+          database.GetUniqueStatement("PRAGMA integrity_check;"));
+      if (recorder->has_error()) {
+        RecordFailure(DIAG_SQLITE_ERROR_HANDLER_CALLED,
+                      recorder->FormatError());
+        return true;
+      }
+      if (!statement.is_valid()) {
+        int error = database.GetErrorCode();
         if (SQLITE_BUSY == error) {
-          RecordFailure(ASCIIToUTF16("DB locked by another process"));
+          RecordFailure(DIAG_SQLITE_DB_LOCKED,
+                        "Database locked by another process");
         } else {
-          string16 str(ASCIIToUTF16("Pragma failed. Error: "));
-          str += base::IntToString16(error);
-          RecordFailure(str);
+          std::string str("Pragma failed. Error: ");
+          str += base::IntToString(error);
+          RecordFailure(DIAG_SQLITE_PRAGMA_FAILED, str);
         }
         return false;
       }
-      while (s.Step()) {
-        std::string result(s.ColumnString(0));
+
+      while (statement.Step()) {
+        std::string result(statement.ColumnString(0));
         if ("ok" != result)
           ++errors;
       }
+      if (recorder->has_error()) {
+        RecordFailure(DIAG_SQLITE_ERROR_HANDLER_CALLED,
+                      recorder->FormatError());
+        return true;
+      }
     }
+
     // All done. Report to the user.
     if (errors != 0) {
-      string16 str(ASCIIToUTF16("Database corruption detected :"));
-      str += base::IntToString16(errors) + ASCIIToUTF16(" errors");
-      RecordFailure(str);
+      std::string str("Database corruption detected: ");
+      str += base::IntToString(errors) + " errors";
+      RecordFailure(DIAG_SQLITE_DB_CORRUPTED, str);
       return true;
     }
-    RecordSuccess(ASCIIToUTF16("no corruption detected"));
+    RecordSuccess("No corruption detected");
     return true;
   }
 
  private:
+  class ErrorRecorder : public base::RefCounted<ErrorRecorder>,
+                        public base::SupportsWeakPtr<ErrorRecorder> {
+   public:
+    ErrorRecorder() : has_error_(false), sqlite_error_(0), last_errno_(0) {}
+
+    void RecordSqliteError(sql::Connection* connection,
+                           int sqlite_error,
+                           sql::Statement* statement) {
+      has_error_ = true;
+      sqlite_error_ = sqlite_error;
+      last_errno_ = connection->GetLastErrno();
+      message_ = connection->GetErrorMessage();
+    }
+
+    bool has_error() const { return has_error_; }
+
+    std::string FormatError() {
+      return base::StringPrintf("SQLite error: %d, Last Errno: %d: %s",
+                                sqlite_error_,
+                                last_errno_,
+                                message_.c_str());
+    }
+
+   private:
+    friend class base::RefCounted<ErrorRecorder>;
+    ~ErrorRecorder() {}
+
+    bool has_error_;
+    int sqlite_error_;
+    int last_errno_;
+    std::string message_;
+
+    DISALLOW_COPY_AND_ASSIGN(ErrorRecorder);
+  };
+
   bool critical_;
   base::FilePath db_path_;
   DISALLOW_COPY_AND_ASSIGN(SqliteIntegrityTest);
@@ -90,44 +185,77 @@
 
 }  // namespace
 
-DiagnosticTest* MakeSqliteWebDbTest() {
-  return new SqliteIntegrityTest(true, ASCIIToUTF16("Web DB"),
+DiagnosticsTest* MakeSqliteWebDbTest() {
+  return new SqliteIntegrityTest(true,
+                                 kSQLiteIntegrityWebTest,
+                                 "Web Database",
                                  base::FilePath(kWebDataFilename));
 }
 
-DiagnosticTest* MakeSqliteCookiesDbTest() {
-  return new SqliteIntegrityTest(true, ASCIIToUTF16("Cookies DB"),
+DiagnosticsTest* MakeSqliteCookiesDbTest() {
+  return new SqliteIntegrityTest(true,
+                                 kSQLiteIntegrityCookieTest,
+                                 "Cookies Database",
                                  base::FilePath(chrome::kCookieFilename));
 }
 
-DiagnosticTest* MakeSqliteHistoryDbTest() {
-  return new SqliteIntegrityTest(true, ASCIIToUTF16("History DB"),
+DiagnosticsTest* MakeSqliteHistoryDbTest() {
+  return new SqliteIntegrityTest(true,
+                                 kSQLiteIntegrityHistoryTest,
+                                 "History Database",
                                  base::FilePath(chrome::kHistoryFilename));
 }
 
-DiagnosticTest* MakeSqliteArchivedHistoryDbTest() {
+DiagnosticsTest* MakeSqliteArchivedHistoryDbTest() {
   return new SqliteIntegrityTest(
-      false, ASCIIToUTF16("Archived History DB"),
+      false,
+      kSQLiteIntegrityArchivedHistoryTest,
+      "Archived History Database",
       base::FilePath(chrome::kArchivedHistoryFilename));
 }
 
-DiagnosticTest* MakeSqliteThumbnailsDbTest() {
-  return new SqliteIntegrityTest(false, ASCIIToUTF16("Thumbnails DB"),
+DiagnosticsTest* MakeSqliteThumbnailsDbTest() {
+  return new SqliteIntegrityTest(false,
+                                 kSQLiteIntegrityThumbnailsTest,
+                                 "Thumbnails Database",
                                  base::FilePath(chrome::kThumbnailsFilename));
 }
 
-DiagnosticTest* MakeSqliteAppCacheDbTest() {
+DiagnosticsTest* MakeSqliteAppCacheDbTest() {
   base::FilePath appcache_dir(content::kAppCacheDirname);
   base::FilePath appcache_db =
       appcache_dir.Append(appcache::kAppCacheDatabaseName);
-  return new SqliteIntegrityTest(false, ASCIIToUTF16("AppCache DB"),
+  return new SqliteIntegrityTest(false,
+                                 kSQLiteIntegrityAppCacheTest,
+                                 "Application Cache Database",
                                  appcache_db);
 }
 
-DiagnosticTest* MakeSqliteWebDatabaseTrackerDbTest() {
+DiagnosticsTest* MakeSqliteWebDatabaseTrackerDbTest() {
   base::FilePath databases_dir(webkit_database::kDatabaseDirectoryName);
   base::FilePath tracker_db =
       databases_dir.Append(webkit_database::kTrackerDatabaseFileName);
-  return new SqliteIntegrityTest(false, ASCIIToUTF16("DatabaseTracker DB"),
+  return new SqliteIntegrityTest(false,
+                                 kSQLiteIntegrityDatabaseTrackerTest,
+                                 "Database Tracker Database",
                                  tracker_db);
 }
+
+#if defined(OS_CHROMEOS)
+DiagnosticsTest* MakeSqliteNssCertDbTest() {
+  base::FilePath home_dir = file_util::GetHomeDir();
+  return new SqliteIntegrityTest(false,
+                                 kSQLiteIntegrityNSSCertTest,
+                                 "NSS Certificate Database",
+                                 home_dir.Append(chromeos::kNssCertDbPath));
+}
+
+DiagnosticsTest* MakeSqliteNssKeyDbTest() {
+  base::FilePath home_dir = file_util::GetHomeDir();
+  return new SqliteIntegrityTest(false,
+                                 kSQLiteIntegrityNSSKeyTest,
+                                 "NSS Key Database",
+                                 home_dir.Append(chromeos::kNssKeyDbPath));
+}
+#endif  // defined(OS_CHROMEOS)
+}       // namespace diagnostics
diff --git a/chrome/browser/diagnostics/sqlite_diagnostics.h b/chrome/browser/diagnostics/sqlite_diagnostics.h
index 2017c4b..279dd5b 100644
--- a/chrome/browser/diagnostics/sqlite_diagnostics.h
+++ b/chrome/browser/diagnostics/sqlite_diagnostics.h
@@ -7,13 +7,46 @@
 
 #include "chrome/browser/diagnostics/diagnostics_test.h"
 
-// Factories for the db integrity tests we run in diagnostic mode.
-DiagnosticTest* MakeSqliteWebDbTest();
-DiagnosticTest* MakeSqliteCookiesDbTest();
-DiagnosticTest* MakeSqliteHistoryDbTest();
-DiagnosticTest* MakeSqliteArchivedHistoryDbTest();
-DiagnosticTest* MakeSqliteThumbnailsDbTest();
-DiagnosticTest* MakeSqliteAppCacheDbTest();
-DiagnosticTest* MakeSqliteWebDatabaseTrackerDbTest();
+namespace diagnostics {
+
+enum SQLiteIntegrityOutcomeCode {
+  DIAG_SQLITE_SUCCESS,
+  DIAG_SQLITE_FILE_NOT_FOUND_OK,
+  DIAG_SQLITE_FILE_NOT_FOUND,
+  DIAG_SQLITE_ERROR_HANDLER_CALLED,
+  DIAG_SQLITE_CANNOT_OPEN_DB,
+  DIAG_SQLITE_DB_LOCKED,
+  DIAG_SQLITE_PRAGMA_FAILED,
+  DIAG_SQLITE_DB_CORRUPTED
+};
+
+extern const char kSQLiteIntegrityAppCacheTest[];
+extern const char kSQLiteIntegrityArchivedHistoryTest[];
+extern const char kSQLiteIntegrityCookieTest[];
+extern const char kSQLiteIntegrityDatabaseTrackerTest[];
+extern const char kSQLiteIntegrityHistoryTest[];
+extern const char kSQLiteIntegrityThumbnailsTest[];
+extern const char kSQLiteIntegrityWebTest[];
+
+#if defined(OS_CHROMEOS)
+extern const char kSQLiteIntegrityNSSCertTest[];
+extern const char kSQLiteIntegrityNSSKeyTest[];
+#endif
+
+// Factories for the database integrity tests we run in diagnostic mode.
+DiagnosticsTest* MakeSqliteWebDbTest();
+DiagnosticsTest* MakeSqliteCookiesDbTest();
+DiagnosticsTest* MakeSqliteHistoryDbTest();
+DiagnosticsTest* MakeSqliteArchivedHistoryDbTest();
+DiagnosticsTest* MakeSqliteThumbnailsDbTest();
+DiagnosticsTest* MakeSqliteAppCacheDbTest();
+DiagnosticsTest* MakeSqliteWebDatabaseTrackerDbTest();
+
+#if defined(OS_CHROMEOS)
+DiagnosticsTest* MakeSqliteNssCertDbTest();
+DiagnosticsTest* MakeSqliteNssKeyDbTest();
+#endif  // defined(OS_CHROMEOS)
+
+}  // namespace diagnostics
 
 #endif  // CHROME_BROWSER_DIAGNOSTICS_SQLITE_DIAGNOSTICS_H_
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc
index 2274fb7..7331349 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.cc
+++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -17,6 +17,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_completion_blocker.h"
 #include "chrome/browser/download/download_crx_util.h"
 #include "chrome/browser/download/download_file_picker.h"
@@ -33,7 +34,6 @@
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -47,7 +47,6 @@
 #endif
 
 using content::BrowserThread;
-using content::DownloadId;
 using content::DownloadItem;
 using content::DownloadManager;
 using safe_browsing::DownloadProtectionService;
@@ -159,7 +158,7 @@
 
 ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile)
     : profile_(profile),
-      next_download_id_(0),
+      next_download_id_(content::DownloadItem::kInvalidId),
       download_prefs_(new DownloadPrefs(profile)) {
 }
 
@@ -174,12 +173,41 @@
   download_prefs_.reset();
 }
 
-DownloadId ChromeDownloadManagerDelegate::GetNextId() {
-  if (!profile_->IsOffTheRecord())
-    return DownloadId(this, next_download_id_++);
+void ChromeDownloadManagerDelegate::SetNextId(uint32 next_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!profile_->IsOffTheRecord());
+  DCHECK_NE(content::DownloadItem::kInvalidId, next_id);
+  next_download_id_ = next_id;
 
-  return content::BrowserContext::GetDownloadManager(
-      profile_->GetOriginalProfile())->GetDelegate()->GetNextId();
+  IdCallbackVector callbacks;
+  id_callbacks_.swap(callbacks);
+  for (IdCallbackVector::const_iterator it = callbacks.begin();
+       it != callbacks.end(); ++it) {
+    ReturnNextId(*it);
+  }
+}
+
+void ChromeDownloadManagerDelegate::GetNextId(
+    const content::DownloadIdCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  if (profile_->IsOffTheRecord()) {
+    content::BrowserContext::GetDownloadManager(
+        profile_->GetOriginalProfile())->GetDelegate()->GetNextId(callback);
+    return;
+  }
+  if (next_download_id_ == content::DownloadItem::kInvalidId) {
+    id_callbacks_.push_back(callback);
+    return;
+  }
+  ReturnNextId(callback);
+}
+
+void ChromeDownloadManagerDelegate::ReturnNextId(
+    const content::DownloadIdCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!profile_->IsOffTheRecord());
+  DCHECK_NE(content::DownloadItem::kInvalidId, next_download_id_);
+  callback.Run(next_download_id_++);
 }
 
 bool ChromeDownloadManagerDelegate::DetermineDownloadTarget(
@@ -256,7 +284,7 @@
 }
 
 void ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal(
-    int download_id,
+    uint32 download_id,
     const base::Closure& user_complete_callback) {
   DownloadItem* item = download_manager_->GetDownload(download_id);
   if (!item)
@@ -370,7 +398,7 @@
 #endif
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::FILE, FROM_HERE,
-      base::Bind(&file_util::PathExists, download->GetTargetFilePath()),
+      base::Bind(&base::PathExists, download->GetTargetFilePath()),
       callback);
 }
 
@@ -426,8 +454,12 @@
   }
 #endif
   DownloadPathReservationTracker::GetReservedPath(
-      download, virtual_path, download_prefs_->DownloadPath(),
-      create_directory, conflict_action, callback);
+      download,
+      virtual_path,
+      download_prefs_->DownloadPath(),
+      create_directory,
+      conflict_action,
+      callback);
 }
 
 void ChromeDownloadManagerDelegate::PromptUserForDownloadPath(
@@ -480,7 +512,7 @@
 }
 
 void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
-    int32 download_id,
+    uint32 download_id,
     DownloadProtectionService::DownloadCheckResult result) {
   DownloadItem* item = download_manager_->GetDownload(download_id);
   if (!item || (item->GetState() != DownloadItem::IN_PROGRESS))
diff --git a/chrome/browser/download/chrome_download_manager_delegate.h b/chrome/browser/download/chrome_download_manager_delegate.h
index f1aa32d..e2c13ad 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.h
+++ b/chrome/browser/download/chrome_download_manager_delegate.h
@@ -59,9 +59,13 @@
 
   void SetDownloadManager(content::DownloadManager* dm);
 
+  // Callbacks passed to GetNextId() will not be called until SetNextId() is
+  // called.
+  void SetNextId(uint32 next_id);
+
   // content::DownloadManagerDelegate
   virtual void Shutdown() OVERRIDE;
-  virtual content::DownloadId GetNextId() OVERRIDE;
+  virtual void GetNextId(const content::DownloadIdCallback& callback) OVERRIDE;
   virtual bool DetermineDownloadTarget(
       content::DownloadItem* item,
       const content::DownloadTargetCallback& callback) OVERRIDE;
@@ -130,6 +134,8 @@
  private:
   friend class base::RefCountedThreadSafe<ChromeDownloadManagerDelegate>;
 
+  typedef std::vector<content::DownloadIdCallback> IdCallbackVector;
+
   // content::NotificationObserver implementation.
   virtual void Observe(int type,
                        const content::NotificationSource& source,
@@ -137,7 +143,7 @@
 
   // Callback function after the DownloadProtectionService completes.
   void CheckClientDownloadDone(
-      int32 download_id,
+      uint32 download_id,
       safe_browsing::DownloadProtectionService::DownloadCheckResult result);
 
   // Internal gateways for ShouldCompleteDownload().
@@ -145,11 +151,14 @@
       content::DownloadItem* item,
       const base::Closure& internal_complete_callback);
   void ShouldCompleteDownloadInternal(
-    int download_id,
+    uint32 download_id,
     const base::Closure& user_complete_callback);
 
+  void ReturnNextId(const content::DownloadIdCallback& callback);
+
   Profile* profile_;
-  int next_download_id_;
+  uint32 next_download_id_;
+  IdCallbackVector id_callbacks_;
   scoped_ptr<DownloadPrefs> download_prefs_;
 
   // Maps from pending extension installations to DownloadItem IDs.
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index 505c42a..6125d22 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/command_line.h"
 #include "base/file_util.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
@@ -20,6 +21,7 @@
 #include "base/test/test_file_util.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/common/cancelable_request.h"
 #include "chrome/browser/download/chrome_download_manager_delegate.h"
 #include "chrome/browser/download/download_crx_util.h"
@@ -52,7 +54,6 @@
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/feature_switch.h"
 #include "chrome/common/pref_names.h"
@@ -68,6 +69,7 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/resource_context.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/common/context_menu_params.h"
 #include "content/public/common/page_transition_types.h"
 #include "content/public/test/browser_test_utils.h"
@@ -185,6 +187,64 @@
   DISALLOW_COPY_AND_ASSIGN(PercentWaiter);
 };
 
+// DownloadTestObserver subclass that observes one download until it transitions
+// from a non-resumable state to a resumable state a specified number of
+// times. Note that this observer can only observe a single download.
+class DownloadTestObserverResumable : public content::DownloadTestObserver {
+ public:
+  // Construct a new observer. |transition_count| is the number of times the
+  // download should transition from a non-resumable state to a resumable state.
+  DownloadTestObserverResumable(DownloadManager* download_manager,
+                                size_t transition_count)
+      : DownloadTestObserver(download_manager, 1,
+                             ON_DANGEROUS_DOWNLOAD_FAIL),
+        was_previously_resumable_(false),
+        transitions_left_(transition_count) {
+    Init();
+  }
+  virtual ~DownloadTestObserverResumable() {}
+
+ private:
+  virtual bool IsDownloadInFinalState(DownloadItem* download) OVERRIDE {
+    bool is_resumable_now = download->CanResume();
+    if (!was_previously_resumable_ && is_resumable_now)
+      --transitions_left_;
+    was_previously_resumable_ = is_resumable_now;
+    return transitions_left_ == 0;
+  }
+
+  bool was_previously_resumable_;
+  size_t transitions_left_;
+
+  DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverResumable);
+};
+
+// DownloadTestObserver subclass that observes a download until it transitions
+// from IN_PROGRESS to another state, but only after StartObserving() is called.
+class DownloadTestObserverNotInProgress : public content::DownloadTestObserver {
+ public:
+  DownloadTestObserverNotInProgress(DownloadManager* download_manager,
+                                    size_t count)
+      : DownloadTestObserver(download_manager, count,
+                             ON_DANGEROUS_DOWNLOAD_FAIL),
+        started_observing_(false) {
+    Init();
+  }
+  virtual ~DownloadTestObserverNotInProgress() {}
+
+  void StartObserving() {
+    started_observing_ = true;
+  }
+
+ private:
+  virtual bool IsDownloadInFinalState(DownloadItem* download) OVERRIDE {
+    return started_observing_ &&
+        download->GetState() != DownloadItem::IN_PROGRESS;
+  }
+
+  bool started_observing_;
+};
+
 // IDs and paths of CRX files used in tests.
 const char kGoodCrxId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
 const base::FilePath kGoodCrxPath(FILE_PATH_LITERAL("extensions/good.crx"));
@@ -600,13 +660,13 @@
   bool CheckDownloadFullPaths(Browser* browser,
                               const base::FilePath& downloaded_file,
                               const base::FilePath& origin_file) {
-    bool origin_file_exists = file_util::PathExists(origin_file);
+    bool origin_file_exists = base::PathExists(origin_file);
     EXPECT_TRUE(origin_file_exists) << origin_file.value();
     if (!origin_file_exists)
       return false;
 
     // Confirm the downloaded data file exists.
-    bool downloaded_file_exists = file_util::PathExists(downloaded_file);
+    bool downloaded_file_exists = base::PathExists(downloaded_file);
     EXPECT_TRUE(downloaded_file_exists) << downloaded_file.value();
     if (!downloaded_file_exists)
       return false;
@@ -723,7 +783,7 @@
         downloads_directory_.path().Append(basefilename);
     EXPECT_TRUE(browser->window()->IsDownloadShelfVisible());
 
-    bool downloaded_path_exists = file_util::PathExists(download_path);
+    bool downloaded_path_exists = base::PathExists(download_path);
     EXPECT_TRUE(downloaded_path_exists);
     if (!downloaded_path_exists)
       return false;
@@ -736,7 +796,7 @@
 
     // Delete the file we just downloaded.
     EXPECT_TRUE(file_util::DieFileDie(download_path, true));
-    EXPECT_FALSE(file_util::PathExists(download_path));
+    EXPECT_FALSE(base::PathExists(download_path));
 
     return true;
   }
@@ -846,15 +906,16 @@
       // won't be.
       creation_observer->WaitForDownloadItemCreation();
 
-      int32 invalid_id = content::DownloadId::Invalid().local();
       EXPECT_EQ(download_info.show_download_item,
                 creation_observer->succeeded());
       if (download_info.show_download_item) {
         EXPECT_EQ(net::OK, creation_observer->error());
-        EXPECT_NE(invalid_id, creation_observer->download_id());
+        EXPECT_NE(content::DownloadItem::kInvalidId,
+                  creation_observer->download_id());
       } else {
         EXPECT_NE(net::OK, creation_observer->error());
-        EXPECT_EQ(invalid_id, creation_observer->download_id());
+        EXPECT_EQ(content::DownloadItem::kInvalidId,
+                  creation_observer->download_id());
       }
     } else {
       // Navigate to URL normally, wait until done.
@@ -898,8 +959,8 @@
         // Clean up the file, in case it ended up in the My Documents folder.
         base::FilePath destination_folder = GetDownloadDirectory(browser());
         base::FilePath my_downloaded_file = item->GetTargetFilePath();
-        EXPECT_TRUE(file_util::PathExists(my_downloaded_file));
-        EXPECT_TRUE(base::Delete(my_downloaded_file, false));
+        EXPECT_TRUE(base::PathExists(my_downloaded_file));
+        EXPECT_TRUE(base::DeleteFile(my_downloaded_file, false));
 
         EXPECT_EQ(download_info.should_redirect_to_documents ?
                       std::string::npos :
@@ -1005,6 +1066,49 @@
             browser()->tab_strip_model()->GetActiveWebContents()));
   }
 
+  // This method:
+  // * Starts a mock download by navigating browser() to a URLRequestMockHTTPJob
+  //   mock URL.
+  // * Injects |error| on the first write using |error_injector|.
+  // * Waits for the download to be interrupted.
+  // * Clears the errors on |error_injector|.
+  // * Returns the resulting interrupted download.
+  DownloadItem* StartMockDownloadAndInjectError(
+      content::TestFileErrorInjector* error_injector,
+      content::DownloadInterruptReason error) {
+    base::FilePath file_path(FILE_PATH_LITERAL("download-test1.lib"));
+    GURL url = URLRequestMockHTTPJob::GetMockUrl(file_path);
+
+    content::TestFileErrorInjector::FileErrorInfo error_info;
+    error_info.url = url.spec();
+    error_info.code = content::TestFileErrorInjector::FILE_OPERATION_WRITE;
+    error_info.operation_instance = 0;
+    error_info.error = error;
+    error_injector->ClearErrors();
+    error_injector->AddError(error_info);
+    error_injector->InjectErrors();
+
+    scoped_ptr<content::DownloadTestObserver> observer(
+        new DownloadTestObserverResumable(
+            DownloadManagerForBrowser(browser()), 1));
+    ui_test_utils::NavigateToURL(browser(), url);
+    observer->WaitForFinished();
+
+    content::DownloadManager::DownloadVector downloads;
+    DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
+    EXPECT_EQ(1u, downloads.size());
+
+    if (downloads.size() != 1)
+      return NULL;
+
+    error_injector->ClearErrors();
+    error_injector->InjectErrors();
+    DownloadItem* download = downloads[0];
+    EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
+    EXPECT_EQ(error, download->GetLastReason());
+    return download;
+  }
+
  private:
   static void EnsureNoPendingDownloadJobsOnIO(bool* result) {
     if (URLRequestSlowDownloadJob::NumberOutstandingRequests())
@@ -1106,7 +1210,7 @@
   ui_test_utils::NavigateToURL(browser(), url);
 
   // Check that we did not download the web page.
-  EXPECT_FALSE(file_util::PathExists(file_path));
+  EXPECT_FALSE(base::PathExists(file_path));
 
   // Check state.
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
@@ -1192,7 +1296,7 @@
   // Check that we did not download the file.
   base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
   base::FilePath file_path(DestinationFile(browser(), file));
-  EXPECT_FALSE(file_util::PathExists(file_path));
+  EXPECT_FALSE(base::PathExists(file_path));
 
   // Check state.
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
@@ -1361,7 +1465,7 @@
   // later.
   base::FilePath origin(OriginFile(base::FilePath(FILE_PATH_LITERAL(
       "downloads/a_zip_file.zip"))));
-  ASSERT_TRUE(file_util::PathExists(origin));
+  ASSERT_TRUE(base::PathExists(origin));
   int64 origin_file_size = 0;
   EXPECT_TRUE(file_util::GetFileSize(origin, &origin_file_size));
   std::string original_contents;
@@ -1382,7 +1486,7 @@
   ASSERT_EQ(1UL, download_items.size());
   ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("a_zip_file.zip")),
             download_items[0]->GetTargetFilePath().BaseName());
-  ASSERT_TRUE(file_util::PathExists(download_items[0]->GetTargetFilePath()));
+  ASSERT_TRUE(base::PathExists(download_items[0]->GetTargetFilePath()));
   EXPECT_TRUE(VerifyFile(download_items[0]->GetTargetFilePath(),
                          original_contents, origin_file_size));
 
@@ -1414,7 +1518,7 @@
   ASSERT_EQ(1UL, download_items.size());
   ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("a_zip_file (1).zip")),
             download_items[0]->GetTargetFilePath().BaseName());
-  ASSERT_TRUE(file_util::PathExists(download_items[0]->GetTargetFilePath()));
+  ASSERT_TRUE(base::PathExists(download_items[0]->GetTargetFilePath()));
   EXPECT_TRUE(VerifyFile(download_items[0]->GetTargetFilePath(),
                          original_contents, origin_file_size));
 }
@@ -1813,6 +1917,11 @@
   HistoryObserver observer(browser()->profile());
   DownloadAndWait(browser(), download_url);
   observer.WaitForStored();
+  HistoryServiceFactory::GetForProfile(
+      browser()->profile(), Profile::IMPLICIT_ACCESS)->FlushForTest(
+      base::Bind(&base::MessageLoop::Quit,
+                  base::Unretained(base::MessageLoop::current()->current())));
+  content::RunMessageLoop();
 }
 
 #if defined(OS_CHROMEOS)
@@ -1907,7 +2016,7 @@
   // Confirm the downloaded data exists.
   base::FilePath downloaded_file = GetDownloadDirectory(browser());
   downloaded_file = downloaded_file.Append(FILE_PATH_LITERAL("a_red_dot.png"));
-  EXPECT_TRUE(file_util::PathExists(downloaded_file));
+  EXPECT_TRUE(base::PathExists(downloaded_file));
 }
 
 // Test to make sure auto-open works.
@@ -2716,7 +2825,7 @@
   content::DownloadManager* manager = DownloadManagerForBrowser(browser());
   base::FilePath origin_file(OriginFile(base::FilePath(FILE_PATH_LITERAL(
       "downloads/a_zip_file.zip"))));
-  ASSERT_TRUE(file_util::PathExists(origin_file));
+  ASSERT_TRUE(base::PathExists(origin_file));
   std::string origin_contents;
   ASSERT_TRUE(file_util::ReadFileToString(origin_file, &origin_contents));
 
@@ -2725,7 +2834,8 @@
   for (int index = 0; index < 5; ++index) {
     DownloadAndWait(browser(), url);
     EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
-    content::DownloadItem* item = manager->GetDownload(index);
+    content::DownloadItem* item = manager->GetDownload(
+        content::DownloadItem::kInvalidId + 1 + index);
     ASSERT_TRUE(item);
     ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
     base::FilePath target_path(item->GetTargetFilePath());
@@ -2733,7 +2843,7 @@
         (index == 0 ? std::string(".zip") :
                       base::StringPrintf(" (%d).zip", index)),
               target_path.BaseName().AsUTF8Unsafe());
-    ASSERT_TRUE(file_util::PathExists(target_path));
+    ASSERT_TRUE(base::PathExists(target_path));
     ASSERT_TRUE(VerifyFile(target_path, origin_contents,
                            origin_contents.size()));
   }
@@ -2918,7 +3028,7 @@
   EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
 
   // Check that the file downloaded correctly.
-  ASSERT_TRUE(file_util::PathExists(download_items[0]->GetTargetFilePath()));
+  ASSERT_TRUE(base::PathExists(download_items[0]->GetTargetFilePath()));
   int64 downloaded_size = 0;
   ASSERT_TRUE(file_util::GetFileSize(
       download_items[0]->GetTargetFilePath(), &downloaded_size));
@@ -2971,3 +3081,156 @@
   EXPECT_EQ(dir.AppendASCII("on").value(), on_prefs->SaveFilePath().value());
   EXPECT_EQ(dir.AppendASCII("off").value(), off_prefs->SaveFilePath().value());
 }
+
+// A download that is interrupted due to a file error should be able to be
+// resumed.
+IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_NoPrompt) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableDownloadResumption);
+  scoped_refptr<content::TestFileErrorInjector> error_injector(
+      content::TestFileErrorInjector::Create(
+          DownloadManagerForBrowser(browser())));
+  scoped_ptr<content::DownloadTestObserver> completion_observer(
+      CreateWaiter(browser(), 1));
+  EnableFileChooser(true);
+
+  DownloadItem* download = StartMockDownloadAndInjectError(
+      error_injector,
+      content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
+  ASSERT_TRUE(download);
+
+  download->Resume();
+  completion_observer->WaitForFinished();
+
+  EXPECT_EQ(
+      1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
+  EXPECT_FALSE(DidShowFileChooser());
+}
+
+// A download that's interrupted due to a reason that indicates that the target
+// path is invalid or unusable should cause a prompt to be displayed on
+// resumption.
+IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_WithPrompt) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableDownloadResumption);
+  scoped_refptr<content::TestFileErrorInjector> error_injector(
+      content::TestFileErrorInjector::Create(
+          DownloadManagerForBrowser(browser())));
+  scoped_ptr<content::DownloadTestObserver> completion_observer(
+      CreateWaiter(browser(), 1));
+  EnableFileChooser(true);
+
+  DownloadItem* download = StartMockDownloadAndInjectError(
+      error_injector,
+      content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE);
+  ASSERT_TRUE(download);
+
+  download->Resume();
+  completion_observer->WaitForFinished();
+
+  EXPECT_EQ(
+      1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
+  EXPECT_TRUE(DidShowFileChooser());
+}
+
+// The user shouldn't be prompted on a resumed download unless a prompt is
+// necessary due to the interrupt reason.
+IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_WithPromptAlways) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableDownloadResumption);
+  browser()->profile()->GetPrefs()->SetBoolean(
+      prefs::kPromptForDownload, true);
+  scoped_refptr<content::TestFileErrorInjector> error_injector(
+      content::TestFileErrorInjector::Create(
+          DownloadManagerForBrowser(browser())));
+  scoped_ptr<content::DownloadTestObserver> completion_observer(
+      CreateWaiter(browser(), 1));
+  EnableFileChooser(true);
+
+  DownloadItem* download = StartMockDownloadAndInjectError(
+      error_injector,
+      content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
+  ASSERT_TRUE(download);
+
+  // Prompts the user initially because of the kPromptForDownload preference.
+  EXPECT_TRUE(DidShowFileChooser());
+
+  download->Resume();
+  completion_observer->WaitForFinished();
+
+  EXPECT_EQ(
+      1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
+  // Shouldn't prompt for resumption.
+  EXPECT_FALSE(DidShowFileChooser());
+}
+
+// A download that is interrupted due to a transient error should be resumed
+// automatically.
+IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_Automatic) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableDownloadResumption);
+  scoped_refptr<content::TestFileErrorInjector> error_injector(
+      content::TestFileErrorInjector::Create(
+          DownloadManagerForBrowser(browser())));
+
+  DownloadItem* download = StartMockDownloadAndInjectError(
+      error_injector,
+      content::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
+  ASSERT_TRUE(download);
+
+  // The number of times this the download is resumed automatically is defined
+  // in DownloadItemImpl::kMaxAutoResumeAttempts. The number of DownloadFiles
+  // created should be that number + 1 (for the original download request). We
+  // only care that it is greater than 1.
+  EXPECT_GT(1u, error_injector->TotalFileCount());
+}
+
+// An interrupting download should be resumable multiple times.
+IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_MultipleAttempts) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableDownloadResumption);
+  scoped_refptr<content::TestFileErrorInjector> error_injector(
+      content::TestFileErrorInjector::Create(
+          DownloadManagerForBrowser(browser())));
+  scoped_ptr<DownloadTestObserverNotInProgress> completion_observer(
+      new DownloadTestObserverNotInProgress(
+          DownloadManagerForBrowser(browser()), 1));
+  // Wait for two transitions to a resumable state
+  scoped_ptr<content::DownloadTestObserver> resumable_observer(
+      new DownloadTestObserverResumable(
+          DownloadManagerForBrowser(browser()), 2));
+
+  EnableFileChooser(true);
+  DownloadItem* download = StartMockDownloadAndInjectError(
+      error_injector,
+      content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
+  ASSERT_TRUE(download);
+
+  content::TestFileErrorInjector::FileErrorInfo error_info;
+  error_info.url = download->GetOriginalUrl().spec();
+  error_info.code = content::TestFileErrorInjector::FILE_OPERATION_WRITE;
+  error_info.operation_instance = 0;
+  error_info.error = content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
+  error_injector->AddError(error_info);
+  error_injector->InjectErrors();
+
+  // Resuming should cause the download to be interrupted again due to the
+  // errors we are injecting.
+  download->Resume();
+  resumable_observer->WaitForFinished();
+  ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
+  ASSERT_EQ(content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
+            download->GetLastReason());
+
+  error_injector->ClearErrors();
+  error_injector->InjectErrors();
+
+  // No errors this time. The download should complete successfully.
+  EXPECT_FALSE(completion_observer->IsFinished());
+  completion_observer->StartObserving();
+  download->Resume();
+  completion_observer->WaitForFinished();
+  EXPECT_EQ(DownloadItem::COMPLETE, download->GetState());
+
+  EXPECT_FALSE(DidShowFileChooser());
+}
diff --git a/chrome/browser/download/download_crx_util.cc b/chrome/browser/download/download_crx_util.cc
index 043f990..1f71a88 100644
--- a/chrome/browser/download/download_crx_util.cc
+++ b/chrome/browser/download/download_crx_util.cc
@@ -6,6 +6,7 @@
 
 #include "chrome/browser/download/download_crx_util.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_install_prompt.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/user_script.h"
 #include "content/public/browser/download_item.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/download/download_history.cc b/chrome/browser/download/download_history.cc
index 7cc7f74..758dc86 100644
--- a/chrome/browser/download/download_history.cc
+++ b/chrome/browser/download/download_history.cc
@@ -8,21 +8,20 @@
 //
 // DownloadHistory decides whether and when to add items to, remove items from,
 // and update items in the database. DownloadHistory uses DownloadHistoryData to
-// store per-DownloadItem data such as its db_handle, whether the item is being
-// added and waiting for its db_handle, and the last history::DownloadRow
-// that was passed to the database.  When the DownloadManager and its delegate
-// (ChromeDownloadManagerDelegate) are initialized, DownloadHistory is created
-// and queries the HistoryService. When the HistoryService calls back from
-// QueryDownloads() to QueryCallback(), DownloadHistory uses
-// DownloadManager::CreateDownloadItem() to inform DownloadManager of these
-// persisted DownloadItems. CreateDownloadItem() internally calls
-// OnDownloadCreated(), which normally adds items to the database, so
-// QueryCallback() uses |loading_db_handle_| to disable adding these items to
-// the database as it matches them up with their db_handles.  If a download is
-// removed via OnDownloadRemoved() while the item is still being added to the
-// database, DownloadHistory uses |removed_while_adding_| to remember to remove
-// the item when its ItemAdded() callback is called.  All callbacks are bound
-// with a weak pointer to DownloadHistory to prevent use-after-free bugs.
+// store per-DownloadItem data such as whether the item is persisted or being
+// persisted, and the last history::DownloadRow that was passed to the database.
+// When the DownloadManager and its delegate (ChromeDownloadManagerDelegate) are
+// initialized, DownloadHistory is created and queries the HistoryService. When
+// the HistoryService calls back from QueryDownloads() to QueryCallback(),
+// DownloadHistory uses DownloadManager::CreateDownloadItem() to inform
+// DownloadManager of these persisted DownloadItems. CreateDownloadItem()
+// internally calls OnDownloadCreated(), which normally adds items to the
+// database, so QueryCallback() uses |loading_id_| to disable adding these items
+// to the database.  If a download is removed via OnDownloadRemoved() while the
+// item is still being added to the database, DownloadHistory uses
+// |removed_while_adding_| to remember to remove the item when its ItemAdded()
+// callback is called.  All callbacks are bound with a weak pointer to
+// DownloadHistory to prevent use-after-free bugs.
 // ChromeDownloadManagerDelegate owns DownloadHistory, and deletes it in
 // Shutdown(), which is called by DownloadManagerImpl::Shutdown() after all
 // DownloadItems are destroyed.
@@ -48,31 +47,28 @@
 // have no control over when DownloadItems are destroyed.
 class DownloadHistoryData : public base::SupportsUserData::Data {
  public:
+  enum PersistenceState {
+    NOT_PERSISTED,
+    PERSISTING,
+    PERSISTED,
+  };
+
   static DownloadHistoryData* Get(content::DownloadItem* item) {
     base::SupportsUserData::Data* data = item->GetUserData(kKey);
     return (data == NULL) ? NULL :
       static_cast<DownloadHistoryData*>(data);
   }
 
-  DownloadHistoryData(content::DownloadItem* item, int64 handle)
-      : is_adding_(false), db_handle_(handle) {
+  explicit DownloadHistoryData(content::DownloadItem* item)
+    : state_(NOT_PERSISTED) {
     item->SetUserData(kKey, this);
   }
 
   virtual ~DownloadHistoryData() {
   }
 
-  // Whether this item is currently being added to the database.
-  bool is_adding() const { return is_adding_; }
-  void set_is_adding(bool a) { is_adding_ = a; }
-
-  // Whether this item is already persisted in the database.
-  bool is_persisted() const {
-    return db_handle_ != history::DownloadDatabase::kUninitializedHandle;
-  }
-
-  int64 db_handle() const { return db_handle_; }
-  void set_db_handle(int64 h) { db_handle_ = h; }
+  PersistenceState state() const { return state_; }
+  void SetState(PersistenceState s) { state_ = s; }
 
   // This allows DownloadHistory::OnDownloadUpdated() to see what changed in a
   // DownloadItem if anything, in order to prevent writing to the database
@@ -89,8 +85,7 @@
  private:
   static const char kKey[];
 
-  bool is_adding_;
-  int64 db_handle_;
+  PersistenceState state_;
   scoped_ptr<history::DownloadRow> info_;
 
   DISALLOW_COPY_AND_ASSIGN(DownloadHistoryData);
@@ -101,8 +96,6 @@
 
 history::DownloadRow GetDownloadRow(
     content::DownloadItem* item) {
-  // TODO(asanka): Persist GetTargetFilePath() as well.
-  DownloadHistoryData* data = DownloadHistoryData::Get(item);
   return history::DownloadRow(
       item->GetFullPath(),
       item->GetTargetFilePath(),
@@ -115,14 +108,13 @@
       item->GetState(),
       item->GetDangerType(),
       item->GetLastReason(),
-      ((data != NULL) ? data->db_handle()
-       : history::DownloadDatabase::kUninitializedHandle),
+      item->GetId(),
       item->GetOpened());
 }
 
 bool ShouldUpdateHistory(const history::DownloadRow* previous,
                          const history::DownloadRow& current) {
-  // Ignore url, referrer, start_time, db_handle, which don't change.
+  // Ignore url, referrer, start_time, id, which don't change.
   return ((previous == NULL) ||
           (previous->current_path != current.current_path) ||
           (previous->target_path != current.target_path) ||
@@ -161,8 +153,8 @@
 }
 
 void DownloadHistory::HistoryAdapter::RemoveDownloads(
-    const std::set<int64>& db_handles) {
-  history_->RemoveDownloads(db_handles);
+    const std::set<uint32>& ids) {
+  history_->RemoveDownloads(ids);
 }
 
 
@@ -171,14 +163,14 @@
 
 bool DownloadHistory::IsPersisted(content::DownloadItem* item) {
   DownloadHistoryData* data = DownloadHistoryData::Get(item);
-  return data && data->is_persisted();
+  return data && (data->state() == DownloadHistoryData::PERSISTED);
 }
 
 DownloadHistory::DownloadHistory(content::DownloadManager* manager,
                                  scoped_ptr<HistoryAdapter> history)
   : notifier_(manager, this),
     history_(history.Pass()),
-    loading_db_handle_(history::DownloadDatabase::kUninitializedHandle),
+    loading_id_(content::DownloadItem::kInvalidId),
     history_size_(0),
     weak_ptr_factory_(this) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
@@ -215,12 +207,9 @@
     return;
   for (InfoVector::const_iterator it = infos->begin();
        it != infos->end(); ++it) {
-    // OnDownloadCreated() is called inside DM::CreateDownloadItem(), so set
-    // loading_db_handle_ to match up the created item with its db_handle.  All
-    // methods run on the UI thread and CreateDownloadItem() is synchronous.
-    loading_db_handle_ = it->db_handle;
-    content::DownloadItem* download_item =
-      notifier_.GetManager()->CreateDownloadItem(
+    loading_id_ = it->id;
+    content::DownloadItem* item = notifier_.GetManager()->CreateDownloadItem(
+        loading_id_,
         it->current_path,
         it->target_path,
         it->url_chain,
@@ -233,15 +222,8 @@
         it->danger_type,
         it->interrupt_reason,
         it->opened);
-    DownloadHistoryData* data = DownloadHistoryData::Get(download_item);
-
-    // If this DCHECK fails, then you probably added an Observer that
-    // synchronously creates a DownloadItem in response to
-    // DownloadManager::OnDownloadCreated(), and your observer runs before
-    // DownloadHistory, and DownloadManager creates items synchronously. Just
-    // bounce your DownloadItem creation off the message loop to flush
-    // DownloadHistory::OnDownloadCreated.
-    DCHECK_EQ(it->db_handle, data->db_handle());
+    DCHECK_EQ(DownloadHistoryData::Get(item)->state(),
+              DownloadHistoryData::PERSISTED);
     ++history_size_;
   }
   notifier_.GetManager()->CheckForHistoryFilesRemoval();
@@ -250,20 +232,18 @@
 void DownloadHistory::MaybeAddToHistory(content::DownloadItem* item) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 
-  int32 download_id = item->GetId();
+  uint32 download_id = item->GetId();
   DownloadHistoryData* data = DownloadHistoryData::Get(item);
-  bool removing = (removing_handles_.find(data->db_handle()) !=
-                   removing_handles_.end());
+  bool removing = removing_ids_.find(download_id) != removing_ids_.end();
 
   // TODO(benjhayden): Remove IsTemporary().
   if (download_crx_util::IsExtensionDownload(*item) ||
       item->IsTemporary() ||
-      data->is_adding() ||
-      data->is_persisted() ||
+      (data->state() != DownloadHistoryData::NOT_PERSISTED) ||
       removing)
     return;
 
-  data->set_is_adding(true);
+  data->SetState(DownloadHistoryData::PERSISTING);
   if (data->info() == NULL) {
     // Keep the info here regardless of whether the item is in progress so that,
     // when ItemAdded() calls OnDownloadUpdated(), it can decide whether to
@@ -274,13 +254,16 @@
   history_->CreateDownload(*data->info(), base::Bind(
       &DownloadHistory::ItemAdded, weak_ptr_factory_.GetWeakPtr(),
       download_id));
+  FOR_EACH_OBSERVER(Observer, observers_, OnDownloadStored(
+      item, *data->info()));
 }
 
-void DownloadHistory::ItemAdded(int32 download_id, int64 db_handle) {
+void DownloadHistory::ItemAdded(uint32 download_id, bool success) {
   if (removed_while_adding_.find(download_id) !=
       removed_while_adding_.end()) {
     removed_while_adding_.erase(download_id);
-    ScheduleRemoveDownload(download_id, db_handle);
+    if (success)
+      ScheduleRemoveDownload(download_id);
     return;
   }
 
@@ -298,25 +281,16 @@
   }
 
   DownloadHistoryData* data = DownloadHistoryData::Get(item);
-  data->set_is_adding(false);
 
   // The sql INSERT statement failed. Avoid an infinite loop: don't
   // automatically retry. Retry adding the next time the item is updated by
-  // unsetting is_adding.
-  if (db_handle == history::DownloadDatabase::kUninitializedHandle) {
+  // resetting the state to NOT_PERSISTED.
+  if (!success) {
     DVLOG(20) << __FUNCTION__ << " INSERT failed id=" << download_id;
+    data->SetState(DownloadHistoryData::NOT_PERSISTED);
     return;
   }
-
-  data->set_db_handle(db_handle);
-
-  // Send to observers the actual history::DownloadRow that was sent to
-  // the db, plus the db_handle, instead of completely regenerating the
-  // history::DownloadRow, in order to accurately reflect the contents of
-  // the database.
-  data->info()->db_handle = db_handle;
-  FOR_EACH_OBSERVER(Observer, observers_, OnDownloadStored(
-      item, *data->info()));
+  data->SetState(DownloadHistoryData::PERSISTED);
 
   UMA_HISTOGRAM_CUSTOM_COUNTS("Download.HistorySize2",
                               history_size_,
@@ -327,8 +301,8 @@
 
   // In case the item changed or became temporary while it was being added.
   // Don't just update all of the item's observers because we're the only
-  // observer that can also see db_handle, which is the only thing that
-  // ItemAdded changed.
+  // observer that can also see data->state(), which is the only thing that
+  // ItemAdded() changed.
   OnDownloadUpdated(notifier_.GetManager(), item);
 }
 
@@ -338,8 +312,11 @@
 
   // All downloads should pass through OnDownloadCreated exactly once.
   CHECK(!DownloadHistoryData::Get(item));
-  DownloadHistoryData* data = new DownloadHistoryData(item, loading_db_handle_);
-  loading_db_handle_ = history::DownloadDatabase::kUninitializedHandle;
+  DownloadHistoryData* data = new DownloadHistoryData(item);
+  if (item->GetId() == loading_id_) {
+    data->SetState(DownloadHistoryData::PERSISTED);
+    loading_id_ = content::DownloadItem::kInvalidId;
+  }
   if (item->GetState() == content::DownloadItem::IN_PROGRESS) {
     data->set_info(GetDownloadRow(item));
   }
@@ -351,7 +328,7 @@
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 
   DownloadHistoryData* data = DownloadHistoryData::Get(item);
-  if (!data->is_persisted()) {
+  if (data->state() == DownloadHistoryData::NOT_PERSISTED) {
     MaybeAddToHistory(item);
     return;
   }
@@ -386,44 +363,40 @@
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 
   DownloadHistoryData* data = DownloadHistoryData::Get(item);
-  if (!data->is_persisted()) {
-    if (data->is_adding()) {
+  if (data->state() != DownloadHistoryData::PERSISTED) {
+    if (data->state() == DownloadHistoryData::PERSISTING) {
       // ScheduleRemoveDownload will be called when history_ calls ItemAdded().
       removed_while_adding_.insert(item->GetId());
     }
     return;
   }
-  ScheduleRemoveDownload(item->GetId(), data->db_handle());
-  data->set_db_handle(history::DownloadDatabase::kUninitializedHandle);
+  ScheduleRemoveDownload(item->GetId());
+  // This is important: another OnDownloadRemoved() handler could do something
+  // that synchronously fires an OnDownloadUpdated().
+  data->SetState(DownloadHistoryData::NOT_PERSISTED);
   // ItemAdded increments history_size_ only if the item wasn't
   // removed_while_adding_, so the next line does not belong in
   // ScheduleRemoveDownload().
   --history_size_;
 }
 
-void DownloadHistory::ScheduleRemoveDownload(
-    int32 download_id, int64 db_handle) {
+void DownloadHistory::ScheduleRemoveDownload(uint32 download_id) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-  if (db_handle == history::DownloadDatabase::kUninitializedHandle)
-    return;
 
   // For database efficiency, batch removals together if they happen all at
   // once.
-  if (removing_handles_.empty()) {
+  if (removing_ids_.empty()) {
     content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
         base::Bind(&DownloadHistory::RemoveDownloadsBatch,
                    weak_ptr_factory_.GetWeakPtr()));
   }
-  removing_handles_.insert(db_handle);
   removing_ids_.insert(download_id);
 }
 
 void DownloadHistory::RemoveDownloadsBatch() {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-  HandleSet remove_handles;
   IdSet remove_ids;
-  removing_handles_.swap(remove_handles);
   removing_ids_.swap(remove_ids);
-  history_->RemoveDownloads(remove_handles);
+  history_->RemoveDownloads(remove_ids);
   FOR_EACH_OBSERVER(Observer, observers_, OnDownloadsRemoved(remove_ids));
 }
diff --git a/chrome/browser/download/download_history.h b/chrome/browser/download/download_history.h
index be34c9f..e983c90 100644
--- a/chrome/browser/download/download_history.h
+++ b/chrome/browser/download/download_history.h
@@ -25,7 +25,7 @@
 // DownloadDatabase up to date.
 class DownloadHistory : public AllDownloadItemNotifier::Observer {
  public:
-  typedef std::set<int32> IdSet;
+  typedef std::set<uint32> IdSet;
 
   // Caller must guarantee that HistoryService outlives HistoryAdapter.
   class HistoryAdapter {
@@ -42,7 +42,7 @@
 
     virtual void UpdateDownload(const history::DownloadRow& data);
 
-    virtual void RemoveDownloads(const std::set<int64>& db_handles);
+    virtual void RemoveDownloads(const std::set<uint32>& ids);
 
    private:
     HistoryService* history_;
@@ -54,14 +54,10 @@
     Observer();
     virtual ~Observer();
 
-    // Fires when a download is added to or updated in the database. When
-    // downloads are first added, this fires after the callback from the
-    // database so that |info| includes the |db_handle|. When downloads are
-    // updated, this fires right after the message is sent to the database.
-    // |info| always includes the |db_handle|.
+    // Fires when a download is added to or updated in the database, just after
+    // the task is posted to the history thread.
     virtual void OnDownloadStored(content::DownloadItem* item,
-                                  const history::DownloadRow& info) {
-    }
+                                  const history::DownloadRow& info) {}
 
     // Fires when RemoveDownloads messages are sent to the DB thread.
     virtual void OnDownloadsRemoved(const IdSet& ids) {}
@@ -87,7 +83,6 @@
   void RemoveObserver(Observer* observer);
 
  private:
-  typedef std::set<int64> HandleSet;
   typedef std::set<content::DownloadItem*> ItemSet;
 
   // Callback from |history_| containing all entries in the downloads database
@@ -100,7 +95,7 @@
 
   // Callback from |history_| when an item was successfully inserted into the
   // database.
-  void ItemAdded(int32 id, int64 db_handle);
+  void ItemAdded(uint32 id, bool success);
 
   // AllDownloadItemNotifier::Observer
   virtual void OnDownloadCreated(
@@ -115,29 +110,28 @@
   // Schedule a record to be removed from |history_| the next time
   // RemoveDownloadsBatch() runs. Schedule RemoveDownloadsBatch() to be run soon
   // if it isn't already scheduled.
-  void ScheduleRemoveDownload(int32 download_id, int64 db_handle);
+  void ScheduleRemoveDownload(uint32 download_id);
 
-  // Removes all |removing_handles_| from |history_|.
+  // Removes all |removing_ids_| from |history_|.
   void RemoveDownloadsBatch();
 
-
   AllDownloadItemNotifier notifier_;
 
   scoped_ptr<HistoryAdapter> history_;
 
-  // |db_handle| of the item being created in response to QueryCallback(),
-  // matched up with created items in OnDownloadCreated() so that the item is
-  // not re-added to the database. For items not created by QueryCallback(),
-  // this is DownloadDatabase::kUninitializedHandle.
-  int64 loading_db_handle_;
+  // Identifier of the item being created in QueryCallback(), matched up with
+  // created items in OnDownloadCreated() so that the item is not re-added to
+  // the database.
+  uint32 loading_id_;
 
-  // |db_handles| and |ids| of items that are scheduled for removal from
-  // history, to facilitate batching removals together for database efficiency.
-  HandleSet removing_handles_;
+  // Identifiers of items that are scheduled for removal from history, to
+  // facilitate batching removals together for database efficiency.
   IdSet removing_ids_;
 
   // |GetId()|s of items that were removed while they were being added, so that
-  // they can be removed when their db_handles are received from the database.
+  // they can be removed when the database finishes adding them.
+  // TODO(benjhayden) Can this be removed now that it doesn't need to wait for
+  // the db_handle, and can rely on PostTask sequentiality?
   IdSet removed_while_adding_;
 
   // Count the number of items in the history for UMA.
diff --git a/chrome/browser/download/download_history_unittest.cc b/chrome/browser/download/download_history_unittest.cc
index 39129df..8ec764b 100644
--- a/chrome/browser/download/download_history_unittest.cc
+++ b/chrome/browser/download/download_history_unittest.cc
@@ -44,11 +44,11 @@
   EXPECT_EQ(left.total_bytes, right.total_bytes);
   EXPECT_EQ(left.state, right.state);
   EXPECT_EQ(left.danger_type, right.danger_type);
-  EXPECT_EQ(left.db_handle, right.db_handle);
+  EXPECT_EQ(left.id, right.id);
   EXPECT_EQ(left.opened, right.opened);
 }
 
-typedef std::set<int64> HandleSet;
+typedef DownloadHistory::IdSet IdSet;
 typedef std::vector<history::DownloadRow> InfoVector;
 typedef testing::NiceMock<content::MockDownloadItem> NiceMockDownloadItem;
 
@@ -57,8 +57,7 @@
   FakeHistoryAdapter()
     : DownloadHistory::HistoryAdapter(NULL),
       slow_create_download_(false),
-      fail_create_download_(false),
-      handle_counter_(0) {
+      fail_create_download_(false) {
   }
 
   virtual ~FakeHistoryAdapter() {}
@@ -87,11 +86,7 @@
     create_download_info_ = info;
     // Must not call CreateDownload() again before FinishCreateDownload()!
     DCHECK(create_download_callback_.is_null());
-    create_download_callback_ = base::Bind(
-        callback,
-        (fail_create_download_ ?
-          history::DownloadDatabase::kUninitializedHandle :
-          handle_counter_++));
+    create_download_callback_ = base::Bind(callback, !fail_create_download_);
     fail_create_download_ = false;
     if (!slow_create_download_)
       FinishCreateDownload();
@@ -109,10 +104,10 @@
     update_download_ = info;
   }
 
-  virtual void RemoveDownloads(const HandleSet& handles) OVERRIDE {
+  virtual void RemoveDownloads(const IdSet& ids) OVERRIDE {
     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-    for (HandleSet::const_iterator it = handles.begin();
-         it != handles.end(); ++it) {
+    for (IdSet::const_iterator it = ids.begin();
+         it != ids.end(); ++it) {
       remove_downloads_.insert(*it);
     }
   }
@@ -165,17 +160,17 @@
     EXPECT_EQ(0, static_cast<int>(remove_downloads_.size()));
   }
 
-  void ExpectDownloadsRemoved(const HandleSet& handles) {
+  void ExpectDownloadsRemoved(const IdSet& ids) {
     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
-    HandleSet differences;
-    std::insert_iterator<HandleSet> differences_iter(
+    IdSet differences;
+    std::insert_iterator<IdSet> differences_iter(
         differences, differences.begin());
-    std::set_difference(handles.begin(), handles.end(),
+    std::set_difference(ids.begin(), ids.end(),
                         remove_downloads_.begin(),
                         remove_downloads_.end(),
                         differences_iter);
-    for (HandleSet::const_iterator different = differences.begin();
+    for (IdSet::const_iterator different = differences.begin();
          different != differences.end(); ++different) {
       EXPECT_TRUE(false) << *different;
     }
@@ -186,10 +181,9 @@
   bool slow_create_download_;
   bool fail_create_download_;
   base::Closure create_download_callback_;
-  int handle_counter_;
   history::DownloadRow update_download_;
   scoped_ptr<InfoVector> expect_query_downloads_;
-  HandleSet remove_downloads_;
+  IdSet remove_downloads_;
   history::DownloadRow create_download_info_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeHistoryAdapter);
@@ -242,6 +236,7 @@
     download_created_index_ = 0;
     for (size_t index = 0; index < infos->size(); ++index) {
       content::MockDownloadManager::CreateDownloadItemAdapter adapter(
+          infos->at(index).id,
           infos->at(index).current_path,
           infos->at(index).target_path,
           infos->at(index).url_chain,
@@ -323,16 +318,16 @@
     history_->ExpectNoDownloadsRemoved();
   }
 
-  void ExpectDownloadsRemoved(const HandleSet& handles) {
+  void ExpectDownloadsRemoved(const IdSet& ids) {
     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-    history_->ExpectDownloadsRemoved(handles);
+    history_->ExpectDownloadsRemoved(ids);
   }
 
   // Caller is responsibile for making sure reference arguments lifetime is
   // greater than the lifetime of the NiceMockDownloadItem() created by this
   // routine.
   void InitItem(
-      int32 id,
+      uint32 id,
       const base::FilePath& current_path,
       const base::FilePath& target_path,
       const std::vector<GURL>& url_chain,
@@ -344,11 +339,10 @@
       content::DownloadItem::DownloadState state,
       content::DownloadDangerType danger_type,
       content::DownloadInterruptReason interrupt_reason,
-      int64 db_handle,
       bool opened,
       history::DownloadRow* info) {
     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-    int32 index = items_.size();
+    size_t index = items_.size();
     NiceMockDownloadItem* mock_item = new NiceMockDownloadItem();
     items_.push_back(mock_item);
 
@@ -363,7 +357,7 @@
     info->state = state;
     info->danger_type = danger_type;
     info->interrupt_reason = interrupt_reason;
-    info->db_handle = db_handle;
+    info->id = id;
     info->opened = opened;
 
     EXPECT_CALL(item(index), GetId()).WillRepeatedly(Return(id));
@@ -446,7 +440,6 @@
            content::DownloadItem::COMPLETE,
            content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
            content::DOWNLOAD_INTERRUPT_REASON_NONE,
-           base::RandInt(0, 1 << 20),
            false,
            &info);
   {
@@ -464,10 +457,10 @@
   ExpectDownloadUpdated(info);
 
   // Pretend that the user removed the item.
-  HandleSet handles;
-  handles.insert(info.db_handle);
+  IdSet ids;
+  ids.insert(info.id);
   item_observer()->OnDownloadRemoved(&item(0));
-  ExpectDownloadsRemoved(handles);
+  ExpectDownloadsRemoved(ids);
 }
 
 // Test creating an item, saving it to the database, changing it, saving it
@@ -477,7 +470,6 @@
   // OnDownloadRemoved.
   ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
 
-  // Note that db_handle must be -1 at first because it isn't in the db yet.
   history::DownloadRow info;
   base::FilePath path(FILE_PATH_LITERAL("/foo/bar.pdf"));
   GURL url("http://example.com/bar.pdf");
@@ -496,15 +488,12 @@
            content::DownloadItem::COMPLETE,
            content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
            content::DOWNLOAD_INTERRUPT_REASON_NONE,
-           -1,
            false,
            &info);
 
   // Pretend the manager just created |item|.
   CallOnDownloadCreated(0);
-  // CreateDownload() always gets db_handle=-1.
   ExpectDownloadCreated(info);
-  info.db_handle = 0;
   EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
 
   // Pretend that something changed on the item.
@@ -514,10 +503,10 @@
   ExpectDownloadUpdated(info);
 
   // Pretend that the user removed the item.
-  HandleSet handles;
-  handles.insert(info.db_handle);
+  IdSet ids;
+  ids.insert(info.id);
   item_observer()->OnDownloadRemoved(&item(0));
-  ExpectDownloadsRemoved(handles);
+  ExpectDownloadsRemoved(ids);
 }
 
 // Test creating a new item, saving it, removing it by setting it Temporary,
@@ -529,7 +518,6 @@
   // OnDownloadRemoved.
   ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
 
-  // Note that db_handle must be -1 at first because it isn't in the db yet.
   history::DownloadRow info;
   base::FilePath path(FILE_PATH_LITERAL("/foo/bar.pdf"));
   GURL url("http://example.com/bar.pdf");
@@ -548,24 +536,21 @@
            content::DownloadItem::COMPLETE,
            content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
            content::DOWNLOAD_INTERRUPT_REASON_NONE,
-           -1,
            false,
            &info);
 
   // Pretend the manager just created |item|.
   CallOnDownloadCreated(0);
-  // CreateDownload() always gets db_handle=-1.
   ExpectDownloadCreated(info);
-  info.db_handle = 0;
   EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
 
   // Pretend the item was marked temporary. DownloadHistory should remove it
   // from history and start ignoring it.
   EXPECT_CALL(item(0), IsTemporary()).WillRepeatedly(Return(true));
   item_observer()->OnDownloadUpdated(&item(0));
-  HandleSet handles;
-  handles.insert(info.db_handle);
-  ExpectDownloadsRemoved(handles);
+  IdSet ids;
+  ids.insert(info.id);
+  ExpectDownloadsRemoved(ids);
 
   // Change something that would make DownloadHistory call UpdateDownload if the
   // item weren't temporary.
@@ -578,10 +563,7 @@
   EXPECT_CALL(item(0), IsTemporary()).WillRepeatedly(Return(false));
   item_observer()->OnDownloadUpdated(&item(0));
   info.received_bytes = 4200;
-  info.db_handle = -1;
-  // CreateDownload() always gets db_handle=-1.
   ExpectDownloadCreated(info);
-  info.db_handle = 1;
   EXPECT_TRUE(DownloadHistory::IsPersisted(&item(0)));
 
   EXPECT_CALL(item(0), GetReceivedBytes()).WillRepeatedly(Return(100));
@@ -595,7 +577,6 @@
     DownloadHistoryTest_RemoveWhileAdding) {
   ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
 
-  // Note that db_handle must be -1 at first because it isn't in the db yet.
   history::DownloadRow info;
   base::FilePath path(FILE_PATH_LITERAL("/foo/bar.pdf"));
   GURL url("http://example.com/bar.pdf");
@@ -614,7 +595,6 @@
            content::DownloadItem::COMPLETE,
            content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
            content::DOWNLOAD_INTERRUPT_REASON_NONE,
-           -1,
            false,
            &info);
 
@@ -624,9 +604,7 @@
 
   // Pretend the manager just created |item|.
   CallOnDownloadCreated(0);
-  // CreateDownload() always gets db_handle=-1.
   ExpectDownloadCreated(info);
-  info.db_handle = 0;
   EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
 
   // Call OnDownloadRemoved before calling back to DownloadHistory::ItemAdded().
@@ -642,9 +620,9 @@
   // Now callback to DownloadHistory::ItemAdded(), and expect a call to
   // RemoveDownloads() for the item that was removed while it was being added.
   FinishCreateDownload();
-  HandleSet handles;
-  handles.insert(info.db_handle);
-  ExpectDownloadsRemoved(handles);
+  IdSet ids;
+  ids.insert(info.id);
+  ExpectDownloadsRemoved(ids);
   EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
 }
 
@@ -670,7 +648,6 @@
            content::DownloadItem::COMPLETE,
            content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
            content::DOWNLOAD_INTERRUPT_REASON_NONE,
-           base::RandInt(0, 1 << 10),
            false,
            &info0);
   base::FilePath path1(FILE_PATH_LITERAL("/foo/qux.pdf"));
@@ -690,7 +667,6 @@
            content::DownloadItem::COMPLETE,
            content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
            content::DOWNLOAD_INTERRUPT_REASON_NONE,
-           info0.db_handle + base::RandInt(1, 1 << 10),
            false,
            &info1);
   {
@@ -705,12 +681,12 @@
   EXPECT_TRUE(DownloadHistory::IsPersisted(&item(1)));
 
   // Pretend that the user removed both items.
-  HandleSet handles;
-  handles.insert(info0.db_handle);
-  handles.insert(info1.db_handle);
+  IdSet ids;
+  ids.insert(info0.id);
+  ids.insert(info1.id);
   item_observer()->OnDownloadRemoved(&item(0));
   item_observer()->OnDownloadRemoved(&item(1));
-  ExpectDownloadsRemoved(handles);
+  ExpectDownloadsRemoved(ids);
 }
 
 // Test what happens when HistoryService/CreateDownload::CreateDownload() fails.
@@ -719,7 +695,6 @@
   // OnDownloadRemoved.
   ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
 
-  // Note that db_handle must be -1 at first because it isn't in the db yet.
   history::DownloadRow info;
   base::FilePath path(FILE_PATH_LITERAL("/foo/bar.pdf"));
   GURL url("http://example.com/bar.pdf");
@@ -738,14 +713,12 @@
            content::DownloadItem::COMPLETE,
            content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
            content::DOWNLOAD_INTERRUPT_REASON_NONE,
-           -1,
            false,
            &info);
 
   FailCreateDownload();
   // Pretend the manager just created |item|.
   CallOnDownloadCreated(0);
-  // CreateDownload() always gets db_handle=-1.
   ExpectDownloadCreated(info);
   EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
 
@@ -762,7 +735,6 @@
   // OnDownloadRemoved.
   ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
 
-  // Note that db_handle must be -1 at first because it isn't in the db yet.
   history::DownloadRow info;
   base::FilePath path(FILE_PATH_LITERAL("/foo/bar.pdf"));
   GURL url("http://example.com/bar.pdf");
@@ -781,7 +753,6 @@
            content::DownloadItem::COMPLETE,
            content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
            content::DOWNLOAD_INTERRUPT_REASON_NONE,
-           -1,
            false,
            &info);
 
@@ -791,9 +762,7 @@
 
   // Pretend the manager just created |item|.
   CallOnDownloadCreated(0);
-  // CreateDownload() always gets db_handle=-1.
   ExpectDownloadCreated(info);
-  info.db_handle = 0;
   EXPECT_FALSE(DownloadHistory::IsPersisted(&item(0)));
 
   // Pretend that something changed on the item.
diff --git a/chrome/browser/download/download_path_reservation_tracker.cc b/chrome/browser/download/download_path_reservation_tracker.cc
index 554cc12..37954a3 100644
--- a/chrome/browser/download/download_path_reservation_tracker.cc
+++ b/chrome/browser/download/download_path_reservation_tracker.cc
@@ -96,7 +96,7 @@
     return true;
 
   // If the path exists in the file system, then the path is in use.
-  if (file_util::PathExists(path))
+  if (base::PathExists(path))
     return true;
 
   return false;
@@ -180,7 +180,7 @@
   // since been removed, do NOT automatically re-create it. Only automatically
   // create the directory if it is the default Downloads directory or if the
   // caller explicitly requested automatic directory creation.
-  if (!file_util::DirectoryExists(target_dir) &&
+  if (!base::DirectoryExists(target_dir) &&
       (create_directory ||
        (!default_download_path.empty() &&
         (default_download_path == target_dir)))) {
@@ -189,7 +189,7 @@
 
   // Check writability of the suggested path. If we can't write to it, default
   // to the user's "My Documents" directory. We'll prompt them in this case.
-  if (!file_util::PathIsWritable(target_dir)) {
+  if (!base::PathIsWritable(target_dir)) {
     DVLOG(1) << "Unable to write to directory \"" << target_dir.value() << "\"";
     is_path_writeable = false;
     PathService::Get(chrome::DIR_USER_DOCUMENTS, &target_dir);
diff --git a/chrome/browser/download/download_path_reservation_tracker_unittest.cc b/chrome/browser/download/download_path_reservation_tracker_unittest.cc
index 67a3dfb..6ac7b45 100644
--- a/chrome/browser/download/download_path_reservation_tracker_unittest.cc
+++ b/chrome/browser/download/download_path_reservation_tracker_unittest.cc
@@ -500,7 +500,7 @@
   base::FilePath path(
       GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo/foo.txt")));
   base::FilePath dir(path.DirName());
-  ASSERT_FALSE(file_util::DirectoryExists(dir));
+  ASSERT_FALSE(base::DirectoryExists(dir));
   DownloadPathReservationTracker::FilenameConflictAction conflict_action =
     DownloadPathReservationTracker::OVERWRITE;
   bool create_directory = false;
@@ -535,7 +535,7 @@
         &verified);
     // Verification succeeds because the directory is created.
     EXPECT_TRUE(verified);
-    EXPECT_TRUE(file_util::DirectoryExists(dir));
+    EXPECT_TRUE(base::DirectoryExists(dir));
     item->SetState(DownloadItem::COMPLETE);
   }
 }
diff --git a/chrome/browser/download/download_prefs.cc b/chrome/browser/download/download_prefs.cc
index 33ac703..130807a 100644
--- a/chrome/browser/download/download_prefs.cc
+++ b/chrome/browser/download/download_prefs.cc
@@ -82,7 +82,7 @@
 }
 
 // static
-void DownloadPrefs::RegisterUserPrefs(
+void DownloadPrefs::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kPromptForDownload,
diff --git a/chrome/browser/download/download_prefs.h b/chrome/browser/download/download_prefs.h
index ca70b6c..d186f8d 100644
--- a/chrome/browser/download/download_prefs.h
+++ b/chrome/browser/download/download_prefs.h
@@ -28,7 +28,7 @@
   explicit DownloadPrefs(Profile* profile);
   ~DownloadPrefs();
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Returns the DownloadPrefs corresponding to the given DownloadManager
   // or BrowserContext.
diff --git a/chrome/browser/download/download_query_unittest.cc b/chrome/browser/download/download_query_unittest.cc
index e86e40e..00b36ad 100644
--- a/chrome/browser/download/download_query_unittest.cc
+++ b/chrome/browser/download/download_query_unittest.cc
@@ -31,7 +31,7 @@
 static const char kSomeKnownTime8601[] = "2012-12-18T20:56:0";
 static const char k8601Suffix[] = ".000Z";
 
-bool IdNotEqual(int not_id, const DownloadItem& item) {
+bool IdNotEqual(uint32 not_id, const DownloadItem& item) {
   return item.GetId() != not_id;
 }
 
@@ -77,7 +77,7 @@
   void ExpectStandardFilterResults() {
     Search();
     ASSERT_EQ(1U, results()->size());
-    ASSERT_EQ(0, results()->at(0)->GetId());
+    ASSERT_EQ(0U, results()->at(0)->GetId());
   }
 
   // If no sorters distinguish between two items, then DownloadQuery sorts by ID
@@ -86,8 +86,8 @@
   void ExpectSortInverted() {
     Search();
     ASSERT_EQ(2U, results()->size());
-    ASSERT_EQ(1, results()->at(0)->GetId());
-    ASSERT_EQ(0, results()->at(1)->GetId());
+    ASSERT_EQ(1U, results()->at(0)->GetId());
+    ASSERT_EQ(0U, results()->at(1)->GetId());
   }
 
  private:
@@ -152,8 +152,8 @@
   CreateMocks(2);
   Search();
   ASSERT_EQ(2U, results()->size());
-  ASSERT_EQ(0, results()->at(0)->GetId());
-  ASSERT_EQ(1, results()->at(1)->GetId());
+  ASSERT_EQ(0U, results()->at(0)->GetId());
+  ASSERT_EQ(1U, results()->at(1)->GetId());
 }
 
 TEST_F(DownloadQueryTest, DownloadQueryTest_Limit) {
@@ -556,8 +556,8 @@
                      DownloadQuery::ASCENDING);
   Search();
   ASSERT_EQ(2U, results()->size());
-  EXPECT_EQ(0, results()->at(0)->GetId());
-  EXPECT_EQ(1, results()->at(1)->GetId());
+  EXPECT_EQ(0U, results()->at(0)->GetId());
+  EXPECT_EQ(1U, results()->at(1)->GetId());
 }
 
 TEST_F(DownloadQueryTest, DownloadQueryTest_DefaultSortById2) {
@@ -568,8 +568,8 @@
                      DownloadQuery::DESCENDING);
   Search();
   ASSERT_EQ(2U, results()->size());
-  EXPECT_EQ(0, results()->at(0)->GetId());
-  EXPECT_EQ(1, results()->at(1)->GetId());
+  EXPECT_EQ(0U, results()->at(0)->GetId());
+  EXPECT_EQ(1U, results()->at(1)->GetId());
 }
 
 TEST_F(DownloadQueryTest, DownloadQueryFilterPerformance) {
diff --git a/chrome/browser/download/download_request_infobar_delegate.cc b/chrome/browser/download/download_request_infobar_delegate.cc
index 408c186..bdd827c 100644
--- a/chrome/browser/download/download_request_infobar_delegate.cc
+++ b/chrome/browser/download/download_request_infobar_delegate.cc
@@ -13,8 +13,8 @@
   DownloadRequestInfoBarDelegate::callback_ = NULL;
 
 DownloadRequestInfoBarDelegate::~DownloadRequestInfoBarDelegate() {
-  if (host_.get())
-    host_->Cancel();
+  if (!responded_ && host_)
+    host_->CancelOnce();
 }
 
 // static
@@ -45,11 +45,12 @@
     FakeCreateCallback* callback) {
   DownloadRequestInfoBarDelegate::callback_ = callback;
 }
-
+#
 DownloadRequestInfoBarDelegate::DownloadRequestInfoBarDelegate(
     InfoBarService* infobar_service,
     base::WeakPtr<DownloadRequestLimiter::TabDownloadState> host)
     : ConfirmInfoBarDelegate(infobar_service),
+      responded_(false),
       host_(host) {
 }
 
@@ -68,11 +69,21 @@
 }
 
 bool DownloadRequestInfoBarDelegate::Accept() {
-  if (host_.get()) {
-    // Accept() call will invalidate host_ weak pointer if no further
-    // prompts are required.
+  DCHECK(!responded_);
+  responded_ = true;
+  if (host_) {
+    // This may invalidate |host_|.
     host_->Accept();
   }
+  return !host_;
+}
 
-  return !host_.get();
+bool DownloadRequestInfoBarDelegate::Cancel() {
+  DCHECK(!responded_);
+  responded_ = true;
+  if (host_) {
+    // This may invalidate |host_|.
+    host_->Cancel();
+  }
+  return !host_;
 }
diff --git a/chrome/browser/download/download_request_infobar_delegate.h b/chrome/browser/download/download_request_infobar_delegate.h
index 5368c43..815e3ca 100644
--- a/chrome/browser/download/download_request_infobar_delegate.h
+++ b/chrome/browser/download/download_request_infobar_delegate.h
@@ -52,7 +52,9 @@
   virtual string16 GetMessageText() const OVERRIDE;
   virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
   virtual bool Accept() OVERRIDE;
+  virtual bool Cancel() OVERRIDE;
 
+  bool responded_;
   base::WeakPtr<DownloadRequestLimiter::TabDownloadState> host_;
 
   DISALLOW_COPY_AND_ASSIGN(DownloadRequestInfoBarDelegate);
diff --git a/chrome/browser/download/download_request_infobar_delegate_unittest.cc b/chrome/browser/download/download_request_infobar_delegate_unittest.cc
index ff1479d..c45dd69 100644
--- a/chrome/browser/download/download_request_infobar_delegate_unittest.cc
+++ b/chrome/browser/download/download_request_infobar_delegate_unittest.cc
@@ -18,9 +18,10 @@
   // DownloadRequestLimiter::TabDownloadState
   virtual void Cancel() OVERRIDE;
   virtual void Accept() OVERRIDE;
+  virtual void CancelOnce() OVERRIDE { Cancel(); }
 
-  ConfirmInfoBarDelegate* infobar() { return infobar_.get(); }
-  void delete_infobar_delegate() { infobar_.reset(); }
+  ConfirmInfoBarDelegate* infobar_delegate() { return infobar_delegate_.get(); }
+  void delete_infobar_delegate() { infobar_delegate_.reset(); }
   bool responded() const { return responded_; }
   bool accepted() const { return accepted_; }
 
@@ -29,7 +30,7 @@
   base::WeakPtrFactory<DownloadRequestLimiter::TabDownloadState> factory_;
 
   // The actual infobar delegate we're listening to.
-  scoped_ptr<DownloadRequestInfoBarDelegate> infobar_;
+  scoped_ptr<DownloadRequestInfoBarDelegate> infobar_delegate_;
 
   // True if we have gotten some sort of response.
   bool responded_;
@@ -42,9 +43,11 @@
 
 MockTabDownloadState::MockTabDownloadState()
     : factory_(this),
-      infobar_(DownloadRequestInfoBarDelegate::Create(factory_.GetWeakPtr())),
+      infobar_delegate_(
+          DownloadRequestInfoBarDelegate::Create(factory_.GetWeakPtr())),
       responded_(false),
-      accepted_(false) {}
+      accepted_(false) {
+}
 
 MockTabDownloadState::~MockTabDownloadState() {
   EXPECT_TRUE(responded_);
@@ -66,21 +69,21 @@
 
 // Tests ----------------------------------------------------------------------
 
-TEST(DownloadRequestInfobarDelegate, AcceptTest) {
+TEST(DownloadRequestInfoBarDelegate, AcceptTest) {
   MockTabDownloadState state;
-  if (state.infobar()->Accept())
+  if (state.infobar_delegate()->Accept())
     state.delete_infobar_delegate();
   EXPECT_TRUE(state.accepted());
 }
 
-TEST(DownloadRequestInfobarDelegate, CancelTest) {
+TEST(DownloadRequestInfoBarDelegate, CancelTest) {
   MockTabDownloadState state;
-  if (state.infobar()->Cancel())
+  if (state.infobar_delegate()->Cancel())
     state.delete_infobar_delegate();
   EXPECT_FALSE(state.accepted());
 }
 
-TEST(DownloadRequestInfobarDelegate, CloseTest) {
+TEST(DownloadRequestInfoBarDelegate, CloseTest) {
   MockTabDownloadState state;
   state.delete_infobar_delegate();
   EXPECT_FALSE(state.accepted());
diff --git a/chrome/browser/download/download_request_limiter.cc b/chrome/browser/download/download_request_limiter.cc
index eced59c..c99e029 100644
--- a/chrome/browser/download/download_request_limiter.cc
+++ b/chrome/browser/download/download_request_limiter.cc
@@ -6,32 +6,38 @@
 
 #include "base/bind.h"
 #include "base/stl_util.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/download/download_request_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar_service.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/tab_contents/tab_util.h"
 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper_delegate.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_process_host.h"
+#include "content/public/browser/resource_dispatcher_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 using content::NavigationController;
 using content::NavigationEntry;
-using content::WebContents;
 
 // TabDownloadState ------------------------------------------------------------
 
 DownloadRequestLimiter::TabDownloadState::TabDownloadState(
     DownloadRequestLimiter* host,
-    WebContents* contents,
-    WebContents* originating_web_contents)
+    content::WebContents* contents,
+    content::WebContents* originating_web_contents)
     : content::WebContentsObserver(contents),
+      web_contents_(contents),
       host_(host),
       status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD),
       download_count_(0),
@@ -65,15 +71,11 @@
     return;
   }
 
-  InfoBarService* infobar_service =
-      InfoBarService::FromWebContents(web_contents());
   // See PromptUserForDownload(): if there's no InfoBarService, then
   // DOWNLOADS_NOT_ALLOWED is functionally equivalent to PROMPT_BEFORE_DOWNLOAD.
-  if ((infobar_service &&
-       status_ != DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS &&
-       status_ != DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED) ||
-      (!infobar_service &&
-       status_ != DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS)) {
+  if ((status_ != DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS) &&
+      (!InfoBarService::FromWebContents(web_contents()) ||
+       (status_ != DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED))) {
     // Revert to default status.
     host_->Remove(this);
     // WARNING: We've been deleted.
@@ -107,27 +109,50 @@
 }
 
 void DownloadRequestLimiter::TabDownloadState::PromptUserForDownload(
-    WebContents* web_contents,
     const DownloadRequestLimiter::Callback& callback) {
   callbacks_.push_back(callback);
-
+  DCHECK(web_contents_);
   if (is_showing_prompt())
-    return;  // Already showing prompt.
-
+    return;
   DownloadRequestInfoBarDelegate::Create(
-      InfoBarService::FromWebContents(web_contents), factory_.GetWeakPtr());
+      InfoBarService::FromWebContents(web_contents_), factory_.GetWeakPtr());
+}
+
+void DownloadRequestLimiter::TabDownloadState::SetContentSetting(
+    ContentSetting setting) {
+  if (!web_contents_)
+    return;
+  HostContentSettingsMap* settings =
+    DownloadRequestLimiter::GetContentSettings(web_contents_);
+  ContentSettingsPattern pattern(
+      ContentSettingsPattern::FromURL(web_contents_->GetURL()));
+  if (!settings || !pattern.IsValid())
+    return;
+  settings->SetContentSetting(
+      pattern,
+      ContentSettingsPattern::Wildcard(),
+      CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
+      std::string(),
+      setting);
 }
 
 void DownloadRequestLimiter::TabDownloadState::Cancel() {
+  SetContentSetting(CONTENT_SETTING_BLOCK);
+  NotifyCallbacks(false);
+}
+
+void DownloadRequestLimiter::TabDownloadState::CancelOnce() {
   NotifyCallbacks(false);
 }
 
 void DownloadRequestLimiter::TabDownloadState::Accept() {
+  SetContentSetting(CONTENT_SETTING_ALLOW);
   NotifyCallbacks(true);
 }
 
 DownloadRequestLimiter::TabDownloadState::TabDownloadState()
-    : host_(NULL),
+    : web_contents_(NULL),
+      host_(NULL),
       status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD),
       download_count_(0),
       factory_(this) {
@@ -209,6 +234,13 @@
 
 // DownloadRequestLimiter ------------------------------------------------------
 
+HostContentSettingsMap* DownloadRequestLimiter::content_settings_ = NULL;
+
+void DownloadRequestLimiter::SetContentSettingsForTesting(
+    HostContentSettingsMap* content_settings) {
+  content_settings_ = content_settings;
+}
+
 DownloadRequestLimiter::DownloadRequestLimiter()
     : factory_(this) {
 }
@@ -220,7 +252,7 @@
 }
 
 DownloadRequestLimiter::DownloadStatus
-    DownloadRequestLimiter::GetDownloadStatus(WebContents* web_contents) {
+DownloadRequestLimiter::GetDownloadStatus(content::WebContents* web_contents) {
   TabDownloadState* state = GetDownloadState(web_contents, NULL, false);
   return state ? state->download_status() : ALLOW_ONE_DOWNLOAD;
 }
@@ -243,8 +275,8 @@
 
 DownloadRequestLimiter::TabDownloadState*
 DownloadRequestLimiter::GetDownloadState(
-    WebContents* web_contents,
-    WebContents* originating_web_contents,
+    content::WebContents* web_contents,
+    content::WebContents* originating_web_contents,
     bool create) {
   DCHECK(web_contents);
   StateMap::iterator i = state_map_.find(web_contents);
@@ -267,7 +299,7 @@
                                          const Callback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  WebContents* originating_contents =
+  content::WebContents* originating_contents =
       tab_util::GetWebContentsByID(render_process_host_id, render_view_id);
   if (!originating_contents) {
     // The WebContents was closed, don't allow the download.
@@ -306,7 +338,7 @@
     const std::string& request_method,
     const Callback& orig_callback, bool allow) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  WebContents* originating_contents =
+  content::WebContents* originating_contents =
       tab_util::GetWebContentsByID(render_process_host_id, render_view_id);
   if (!originating_contents || !allow) {
     ScheduleNotification(orig_callback, false);
@@ -319,15 +351,22 @@
                   orig_callback);
 }
 
-void DownloadRequestLimiter::CanDownloadImpl(WebContents* originating_contents,
-                                             int request_id,
-                                             const std::string& request_method,
-                                             const Callback& callback) {
+HostContentSettingsMap* DownloadRequestLimiter::GetContentSettings(
+    content::WebContents* contents) {
+  return content_settings_ ? content_settings_ : Profile::FromBrowserContext(
+      contents->GetBrowserContext())->GetHostContentSettingsMap();
+}
+
+void DownloadRequestLimiter::CanDownloadImpl(
+    content::WebContents* originating_contents,
+    int request_id,
+    const std::string& request_method,
+    const Callback& callback) {
   DCHECK(originating_contents);
 
   // If the tab requesting the download is a constrained popup that is not
   // shown, treat the request as if it came from the parent.
-  WebContents* effective_contents = originating_contents;
+  content::WebContents* effective_contents = originating_contents;
   BlockedContentTabHelper* blocked_content_tab_helper =
       BlockedContentTabHelper::FromWebContents(originating_contents);
   if (blocked_content_tab_helper &&
@@ -350,16 +389,48 @@
     case ALLOW_ONE_DOWNLOAD:
       state->set_download_status(PROMPT_BEFORE_DOWNLOAD);
       ScheduleNotification(callback, true);
+      state->increment_download_count();
       break;
 
     case DOWNLOADS_NOT_ALLOWED:
       ScheduleNotification(callback, false);
       break;
 
-    case PROMPT_BEFORE_DOWNLOAD:
-      state->PromptUserForDownload(effective_contents, callback);
-      state->increment_download_count();
+    case PROMPT_BEFORE_DOWNLOAD: {
+      HostContentSettingsMap* content_settings = GetContentSettings(
+          effective_contents);
+      ContentSetting setting = CONTENT_SETTING_ASK;
+      if (content_settings)
+        setting = content_settings->GetContentSetting(
+            effective_contents->GetURL(),
+            effective_contents->GetURL(),
+            CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
+            std::string());
+      switch (setting) {
+        case CONTENT_SETTING_ALLOW:
+          TabSpecificContentSettings::FromWebContents(
+              effective_contents)->SetDownloadsBlocked(false);
+          ScheduleNotification(callback, true);
+          state->increment_download_count();
+          return;
+        case CONTENT_SETTING_BLOCK:
+          TabSpecificContentSettings::FromWebContents(
+              effective_contents)->SetDownloadsBlocked(true);
+          ScheduleNotification(callback, false);
+          return;
+        case CONTENT_SETTING_DEFAULT:
+        case CONTENT_SETTING_ASK:
+        case CONTENT_SETTING_SESSION_ONLY:
+          state->PromptUserForDownload(callback);
+          state->increment_download_count();
+          break;
+        case CONTENT_SETTING_NUM_SETTINGS:
+        default:
+          NOTREACHED();
+          return;
+      }
       break;
+    }
 
     default:
       NOTREACHED();
diff --git a/chrome/browser/download/download_request_limiter.h b/chrome/browser/download/download_request_limiter.h
index 05b3b73..23165ff 100644
--- a/chrome/browser/download/download_request_limiter.h
+++ b/chrome/browser/download/download_request_limiter.h
@@ -13,10 +13,12 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "chrome/common/content_settings.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_contents_observer.h"
 
+class HostContentSettingsMap;
 class DownloadRequestInfoBarDelegate;
 
 namespace content {
@@ -115,12 +117,12 @@
     // See description above CanDownloadOnIOThread for details on lifetime of
     // callback.
     void PromptUserForDownload(
-        content::WebContents* tab,
         const DownloadRequestLimiter::Callback& callback);
 
     // Invoked from DownloadRequestDialogDelegate. Notifies the delegates and
     // changes the status appropriately. Virtual for testing.
     virtual void Cancel();
+    virtual void CancelOnce();
     virtual void Accept();
 
    protected:
@@ -138,10 +140,15 @@
                          const content::NotificationSource& source,
                          const content::NotificationDetails& details) OVERRIDE;
 
+    // Remember to either block or allow automatic downloads from this origin.
+    void SetContentSetting(ContentSetting setting);
+
     // Notifies the callbacks as to whether the download is allowed or not.
     // Updates status_ appropriately.
     void NotifyCallbacks(bool allow);
 
+    content::WebContents* web_contents_;
+
     DownloadRequestLimiter* host_;
 
     // Host of the first page the download started on. This may be empty.
@@ -169,6 +176,8 @@
     DISALLOW_COPY_AND_ASSIGN(TabDownloadState);
   };
 
+  static void SetContentSettingsForTesting(HostContentSettingsMap* settings);
+
   DownloadRequestLimiter();
 
   // Returns the download status for a page. This does not change the state in
@@ -235,6 +244,10 @@
   // ALLOW_ONE_DOWNLOAD.
   void Remove(TabDownloadState* state);
 
+  static HostContentSettingsMap* content_settings_;
+  static HostContentSettingsMap* GetContentSettings(
+      content::WebContents* contents);
+
   // Maps from tab to download state. The download state for a tab only exists
   // if the state is other than ALLOW_ONE_DOWNLOAD. Similarly once the state
   // transitions from anything but ALLOW_ONE_DOWNLOAD back to ALLOW_ONE_DOWNLOAD
diff --git a/chrome/browser/download/download_request_limiter_unittest.cc b/chrome/browser/download/download_request_limiter_unittest.cc
index ca6a9ef..06cd852 100644
--- a/chrome/browser/download/download_request_limiter_unittest.cc
+++ b/chrome/browser/download/download_request_limiter_unittest.cc
@@ -2,10 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/download/download_request_limiter.h"
+
 #include "base/bind.h"
 #include "base/run_loop.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/download/download_request_infobar_delegate.h"
-#include "chrome/browser/download/download_request_limiter.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
@@ -35,6 +37,9 @@
         &DownloadRequestLimiterTest::FakeCreate, base::Unretained(this));
     DownloadRequestInfoBarDelegate::SetCallbackForTesting(
         &fake_create_callback_);
+    content_settings_ = new HostContentSettingsMap(profile_.GetPrefs(), false);
+    DownloadRequestLimiter::SetContentSettingsForTesting(
+        content_settings_.get());
   }
 
   void FakeCreate(
@@ -54,6 +59,8 @@
   }
 
   virtual void TearDown() {
+    content_settings_->ShutdownOnUIThread();
+    content_settings_ = NULL;
     UnsetDelegate();
     ChromeRenderViewHostTestHarness::TearDown();
   }
@@ -128,8 +135,11 @@
   // Number of times ShouldAllowDownload was invoked.
   int ask_allow_count_;
 
+  scoped_refptr<HostContentSettingsMap> content_settings_;
+
  private:
   DownloadRequestInfoBarDelegate::FakeCreateCallback fake_create_callback_;
+  TestingProfile profile_;
 };
 
 TEST_F(DownloadRequestLimiterTest,
@@ -217,7 +227,6 @@
   ExpectAndResetCounts(0, 1, 0, __LINE__);
   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
             download_request_limiter_->GetDownloadStatus(web_contents()));
-
 }
 
 TEST_F(DownloadRequestLimiterTest,
@@ -311,7 +320,7 @@
 TEST_F(DownloadRequestLimiterTest,
        DownloadRequestLimiter_RawWebContents) {
   scoped_ptr<WebContents> web_contents(CreateTestWebContents());
-  // DownloadRequestLimiter won't try to make an infobar if it doesn't have a
+  // DownloadRequestLimiter won't try to make an infobar if it doesn't have an
   // InfoBarService, and we want to test that it will Cancel() instead of
   // prompting when it doesn't have a InfoBarService, so unset the delegate.
   UnsetDelegate();
diff --git a/chrome/browser/download/download_service.cc b/chrome/browser/download/download_service.cc
index 7838e2d..34e5c49 100644
--- a/chrome/browser/download/download_service.cc
+++ b/chrome/browser/download/download_service.cc
@@ -53,13 +53,14 @@
 #endif
 
   if (!profile_->IsOffTheRecord()) {
-    HistoryService* hs = HistoryServiceFactory::GetForProfile(
+    HistoryService* history = HistoryServiceFactory::GetForProfile(
         profile_, Profile::EXPLICIT_ACCESS);
-    if (hs)
-      download_history_.reset(new DownloadHistory(
-          manager,
-          scoped_ptr<DownloadHistory::HistoryAdapter>(
-            new DownloadHistory::HistoryAdapter(hs))));
+    history->GetNextDownloadId(base::Bind(
+        &ChromeDownloadManagerDelegate::SetNextId, manager_delegate_));
+    download_history_.reset(new DownloadHistory(
+        manager,
+        scoped_ptr<DownloadHistory::HistoryAdapter>(
+            new DownloadHistory::HistoryAdapter(history))));
   }
 
   // Pass an empty delegate when constructing the DownloadUIController. The
diff --git a/chrome/browser/download/download_status_updater_mac.mm b/chrome/browser/download/download_status_updater_mac.mm
index 4e80610..dedb3a0 100644
--- a/chrome/browser/download/download_status_updater_mac.mm
+++ b/chrome/browser/download/download_status_updater_mac.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2012 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.
 
@@ -12,55 +12,71 @@
 #include "content/public/browser/download_item.h"
 #include "url/gurl.h"
 
-// --- Private 10.8 API for showing progress ---
-// rdar://12058866 http://www.openradar.me/12058866
+// NSProgress is public API in 10.9, but a version of it exists and is usable
+// in 10.8.
+
+#if !defined(MAC_OS_X_VERSION_10_9) || \
+    MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9
+
+@interface NSProgress : NSObject
+
+- (instancetype)initWithParent:(NSProgress*)parentProgressOrNil
+                      userInfo:(NSDictionary*)userInfoOrNil;
+@property (copy) NSString* kind;
+
+@property int64_t totalUnitCount;
+@property int64_t completedUnitCount;
+
+@property (getter=isCancellable) BOOL cancellable;
+@property (getter=isPausable) BOOL pausable;
+@property (readonly, getter=isCancelled) BOOL cancelled;
+@property (readonly, getter=isPaused) BOOL paused;
+@property (copy) void (^cancellationHandler)(void);
+@property (copy) void (^pausingHandler)(void);
+- (void)cancel;
+- (void)pause;
+
+- (void)setUserInfoObject:(id)objectOrNil forKey:(NSString*)key;
+- (NSDictionary*)userInfo;
+
+@property (readonly, getter=isIndeterminate) BOOL indeterminate;
+@property (readonly) double fractionCompleted;
+
+- (void)publish;
+- (void)unpublish;
+
+@end
+
+#endif  // MAC_OS_X_VERSION_10_9
 
 namespace {
 
-NSString* const kNSProgressAppBundleIdentifierKey =
-    @"NSProgressAppBundleIdentifierKey";
-NSString* const kNSProgressEstimatedTimeRemainingKey =
-    @"NSProgressEstimatedTimeRemainingKey";
+// These are not the keys themselves; they are the names for dynamic lookup via
+// the ProgressString() function.
 
-// NSProgressEstimatedTimeKey is 10.8 SPI only; it became
-// NSProgressEstimatedTimeRemainingKey when NSProgress became API in 10.9.
-NSString* const kNSProgressEstimatedTimeKey =
-    @"NSProgressEstimatedTimeKey";
-NSString* const kNSProgressFileCompletedCountKey =
-    @"NSProgressFileCompletedCountKey";
-NSString* const kNSProgressFileContainerURLKey =
-    @"NSProgressFileContainerURLKey";
-NSString* const kNSProgressFileDownloadingSourceURLKey =
-    @"NSProgressFileDownloadingSourceURLKey";
-NSString* const kNSProgressFileIconKey =
-    @"NSProgressFileIconKey";
-NSString* const kNSProgressFileIconOriginalRectKey =
-    @"NSProgressFileIconOriginalRectKey";
-NSString* const kNSProgressFileLocationCanChangeKey =
-    @"NSProgressFileLocationCanChangeKey";
-NSString* const kNSProgressFileOperationKindAirDropping =
-    @"NSProgressFileOperationKindAirDropping";
-NSString* const kNSProgressFileOperationKindCopying =
-    @"NSProgressFileOperationKindCopying";
-NSString* const kNSProgressFileOperationKindDecompressingAfterDownloading =
-    @"NSProgressFileOperationKindDecompressingAfterDownloading";
-NSString* const kNSProgressFileOperationKindDownloading =
+// Public keys, SPI in 10.8, API in 10.9:
+NSString* const kNSProgressEstimatedTimeRemainingKeyName =
+    @"NSProgressEstimatedTimeRemainingKey";
+NSString* const kNSProgressFileOperationKindDownloadingName =
     @"NSProgressFileOperationKindDownloading";
-NSString* const kNSProgressFileOperationKindEncrypting =
-    @"NSProgressFileOperationKindEncrypting";
-NSString* const kNSProgressFileOperationKindKey =
+NSString* const kNSProgressFileOperationKindKeyName =
     @"NSProgressFileOperationKindKey";
-NSString* const kNSProgressFileTotalCountKey =
-    @"NSProgressFileTotalCountKey";
-NSString* const kNSProgressFileURLKey =
+NSString* const kNSProgressFileURLKeyName =
     @"NSProgressFileURLKey";
-NSString* const kNSProgressIsWaitingKey =
-    @"NSProgressIsWaitingKey";
-NSString* const kNSProgressKindFile =
+NSString* const kNSProgressKindFileName =
     @"NSProgressKindFile";
-NSString* const kNSProgressThroughputKey =
+NSString* const kNSProgressThroughputKeyName =
     @"NSProgressThroughputKey";
 
+// Private keys, SPI in 10.8 and 10.9:
+// TODO(avi): Are any of these actually needed for the NSProgress integration?
+NSString* const kNSProgressFileDownloadingSourceURLKeyName =
+    @"NSProgressFileDownloadingSourceURLKey";
+NSString* const kNSProgressFileLocationCanChangeKeyName =
+    @"NSProgressFileLocationCanChangeKey";
+
+// Given an NSProgress string name (kNSProgress[...]Name above), looks up the
+// real symbol of that name from Foundation and returns it.
 NSString* ProgressString(NSString* string) {
   static NSMutableDictionary* cache;
   static CFBundleRef foundation;
@@ -72,19 +88,19 @@
   NSString* result = [cache objectForKey:string];
   if (!result) {
     NSString** ref = static_cast<NSString**>(
-        CFBundleGetDataPointerForName(
-            foundation, base::mac::NSToCFCast(string)));
+        CFBundleGetDataPointerForName(foundation,
+                                      base::mac::NSToCFCast(string)));
     if (ref) {
       result = *ref;
       [cache setObject:result forKey:string];
     }
   }
 
-  if (!result && string == kNSProgressEstimatedTimeRemainingKey) {
+  if (!result && string == kNSProgressEstimatedTimeRemainingKeyName) {
     // Perhaps this is 10.8; try the old name of this key.
     NSString** ref = static_cast<NSString**>(
-        CFBundleGetDataPointerForName(
-            foundation, base::mac::NSToCFCast(kNSProgressEstimatedTimeKey)));
+        CFBundleGetDataPointerForName(foundation,
+                                      CFSTR("NSProgressEstimatedTimeKey")));
     if (ref) {
       result = *ref;
       [cache setObject:result forKey:string];
@@ -102,61 +118,6 @@
   return result;
 }
 
-}  // namespace
-
-@interface NSProgress : NSObject
-
-- (id)initWithParent:(id)parent userInfo:(NSDictionary*)info;
-@property(copy) NSString* kind;
-
-- (void)unpublish;
-- (void)publish;
-
-- (void)setUserInfoObject:(id)object forKey:(NSString*)key;
-- (NSDictionary*)userInfo;
-
-@property(readonly) double fractionCompleted;
-// Set the totalUnitCount to -1 to indicate an indeterminate download. The dock
-// shows a non-filling progress bar; the Finder is lame and draws its progress
-// bar off the right side.
-@property(readonly, getter=isIndeterminate) BOOL indeterminate;
-@property long long completedUnitCount;
-@property long long totalUnitCount;
-
-// Pausing appears to be unimplemented in 10.8.0.
-- (void)pause;
-@property(readonly, getter=isPaused) BOOL paused;
-@property(getter=isPausable) BOOL pausable;
-- (void)setPausingHandler:(id)blockOfUnknownSignature;
-
-- (void)cancel;
-@property(readonly, getter=isCancelled) BOOL cancelled;
-@property(getter=isCancellable) BOOL cancellable;
-// Note that the cancellation handler block will be called on a random thread.
-- (void)setCancellationHandler:(void (^)())block;
-
-// Allows other applications to provide feedback as to whether the progress is
-// visible in that app. Note that the acknowledgement handler block will be
-// called on a random thread.
-// com.apple.dock => BOOL indicating whether the download target folder was
-//                   successfully "flown to" at the beginning of the download.
-//                   This primarily depends on whether the download target
-//                   folder is in the dock. Note that if the download target
-//                   folder is added or removed from the dock during the
-//                   duration of the download, it will not trigger a callback.
-//                   Note that if the "fly to the dock" keys were not set, the
-//                   callback's parameter will always be NO.
-// com.apple.Finder => always YES, no matter whether the download target
-//                     folder's window is open.
-- (void)handleAcknowledgementByAppWithBundleIdentifier:(NSString*)bundle
-                                       usingBlock:(void (^)(BOOL success))block;
-
-@end
-
-// --- Private 10.8 API for showing progress ---
-
-namespace {
-
 bool NSProgressSupported() {
   static bool supported;
   static bool valid;
@@ -206,16 +167,11 @@
   NSURL* destination_url = [NSURL fileURLWithPath:
       base::mac::FilePathToNSString(destination_path)];
 
-  // If there were an image to fly to the download folder in the dock, then
-  // the keys in the userInfo to set would be:
-  // - @"NSProgressFlyToImageKey" : NSImage
-  // - kNSProgressFileIconOriginalRectKey : NSValue of NSRect in global coords
-
   NSDictionary* user_info = @{
-    ProgressString(kNSProgressFileLocationCanChangeKey) : @true,
-    ProgressString(kNSProgressFileOperationKindKey) :
-        ProgressString(kNSProgressFileOperationKindDownloading),
-    ProgressString(kNSProgressFileURLKey) : destination_url
+    ProgressString(kNSProgressFileLocationCanChangeKeyName) : @true,
+    ProgressString(kNSProgressFileOperationKindKeyName) :
+        ProgressString(kNSProgressFileOperationKindDownloadingName),
+    ProgressString(kNSProgressFileURLKeyName) : destination_url
   };
 
   Class progress_class = NSClassFromString(@"NSProgress");
@@ -223,11 +179,11 @@
   progress = [progress performSelector:@selector(initWithParent:userInfo:)
                             withObject:nil
                             withObject:user_info];
-  progress.kind = ProgressString(kNSProgressKindFile);
+  progress.kind = ProgressString(kNSProgressKindFileName);
 
   if (source_url) {
     [progress setUserInfoObject:source_url forKey:
-        ProgressString(kNSProgressFileDownloadingSourceURLKey)];
+        ProgressString(kNSProgressFileDownloadingSourceURLKeyName)];
   }
 
   progress.pausable = NO;
@@ -253,14 +209,14 @@
   progress.totalUnitCount = download->GetTotalBytes();
   progress.completedUnitCount = download->GetReceivedBytes();
   [progress setUserInfoObject:@(download->CurrentSpeed())
-                       forKey:ProgressString(kNSProgressThroughputKey)];
+                       forKey:ProgressString(kNSProgressThroughputKeyName)];
 
   base::TimeDelta time_remaining;
   NSNumber* time_remaining_ns = nil;
   if (download->TimeRemaining(&time_remaining))
     time_remaining_ns = @(time_remaining.InSeconds());
   [progress setUserInfoObject:time_remaining_ns
-                   forKey:ProgressString(kNSProgressEstimatedTimeRemainingKey)];
+               forKey:ProgressString(kNSProgressEstimatedTimeRemainingKeyName)];
 
   base::FilePath download_path = download->GetFullPath();
   if (progress_data->target() != download_path) {
@@ -268,7 +224,7 @@
     NSURL* download_url = [NSURL fileURLWithPath:
         base::mac::FilePathToNSString(download_path)];
     [progress setUserInfoObject:download_url
-                         forKey:ProgressString(kNSProgressFileURLKey)];
+                         forKey:ProgressString(kNSProgressFileURLKeyName)];
   }
 }
 
diff --git a/chrome/browser/download/download_test_file_activity_observer.cc b/chrome/browser/download/download_test_file_activity_observer.cc
index 0a0835a..83b46c3 100644
--- a/chrome/browser/download/download_test_file_activity_observer.cc
+++ b/chrome/browser/download/download_test_file_activity_observer.cc
@@ -24,7 +24,10 @@
   explicit MockDownloadManagerDelegate(Profile* profile)
       : ChromeDownloadManagerDelegate(profile),
         file_chooser_enabled_(false),
-        file_chooser_displayed_(false) {}
+        file_chooser_displayed_(false) {
+    if (!profile->IsOffTheRecord())
+      SetNextId(content::DownloadItem::kInvalidId + 1);
+  }
 
   void EnableFileChooser(bool enable) {
     file_chooser_enabled_ = enable;
diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc
index 5c2467a..2a7a91f 100644
--- a/chrome/browser/download/download_util.cc
+++ b/chrome/browser/download/download_util.cc
@@ -24,10 +24,10 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/value_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_extensions.h"
 #include "chrome/browser/download/download_item_model.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/time_format.h"
 #include "content/public/browser/download_item.h"
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc
index 33d1de6..afaef69 100644
--- a/chrome/browser/download/save_page_browsertest.cc
+++ b/chrome/browser/download/save_page_browsertest.cc
@@ -401,20 +401,15 @@
   ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
   persisted.WaitForPersisted();
   EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
-  EXPECT_TRUE(file_util::PathExists(full_file_name));
-  EXPECT_FALSE(file_util::PathExists(dir));
-  EXPECT_TRUE(file_util::ContentsEqual(test_dir_.Append(base::FilePath(
+  EXPECT_TRUE(base::PathExists(full_file_name));
+  EXPECT_FALSE(base::PathExists(dir));
+  EXPECT_TRUE(base::ContentsEqual(test_dir_.Append(base::FilePath(
       kTestDir)).Append(FILE_PATH_LITERAL("a.htm")), full_file_name));
 }
 
-// Disabled on Windows due to flakiness. http://crbug.com/162323
-// TODO(linux_aura) http://crbug.com/163931
-#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
-#define MAYBE_SaveHTMLOnlyCancel DISABLED_SaveHTMLOnlyCancel
-#else
-#define MAYBE_SaveHTMLOnlyCancel SaveHTMLOnlyCancel
-#endif
-IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveHTMLOnlyCancel) {
+// http://crbug.com/162323
+// http://crbug.com/163931
+IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, DISABLED_SaveHTMLOnlyCancel) {
   GURL url = NavigateToMockURL("a");
   DownloadManager* manager(GetDownloadManager());
   std::vector<DownloadItem*> downloads;
@@ -449,9 +444,31 @@
   // notification, then expect the contents of the downloaded file.
 }
 
+class DelayingDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
+ public:
+  explicit DelayingDownloadManagerDelegate(Profile* profile)
+    : ChromeDownloadManagerDelegate(profile) {
+  }
+  virtual bool ShouldCompleteDownload(
+      content::DownloadItem* item,
+      const base::Closure& user_complete_callback) OVERRIDE {
+    return false;
+  }
+
+ protected:
+  virtual ~DelayingDownloadManagerDelegate() {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DelayingDownloadManagerDelegate);
+};
+
 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveHTMLOnlyTabDestroy) {
   GURL url = NavigateToMockURL("a");
   DownloadManager* manager(GetDownloadManager());
+  scoped_refptr<DelayingDownloadManagerDelegate> delaying_delegate(
+      new DelayingDownloadManagerDelegate(browser()->profile()));
+  delaying_delegate->SetNextId(content::DownloadItem::kInvalidId + 1);
+  manager->SetDelegate(delaying_delegate.get());
   std::vector<DownloadItem*> downloads;
   manager->GetAllDownloads(&downloads);
   ASSERT_EQ(0u, downloads.size());
@@ -469,8 +486,10 @@
   GetCurrentTab(browser())->Close();
   EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());
 
-  EXPECT_FALSE(file_util::PathExists(full_file_name));
-  EXPECT_FALSE(file_util::PathExists(dir));
+  EXPECT_FALSE(base::PathExists(full_file_name));
+  EXPECT_FALSE(base::PathExists(dir));
+
+  manager->SetDelegate(NULL);
 }
 
 // Disabled on Windows due to flakiness. http://crbug.com/162323
@@ -506,9 +525,9 @@
 
   EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
 
-  EXPECT_TRUE(file_util::PathExists(full_file_name));
-  EXPECT_FALSE(file_util::PathExists(dir));
-  EXPECT_TRUE(file_util::ContentsEqual(
+  EXPECT_TRUE(base::PathExists(full_file_name));
+  EXPECT_FALSE(base::PathExists(dir));
+  EXPECT_TRUE(base::ContentsEqual(
       test_dir_.Append(base::FilePath(kTestDir)).Append(file_name),
       full_file_name));
 }
@@ -541,15 +560,15 @@
 
   EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
 
-  EXPECT_TRUE(file_util::PathExists(full_file_name));
-  EXPECT_TRUE(file_util::PathExists(dir));
-  EXPECT_TRUE(file_util::TextContentsEqual(
+  EXPECT_TRUE(base::PathExists(full_file_name));
+  EXPECT_TRUE(base::PathExists(dir));
+  EXPECT_TRUE(base::TextContentsEqual(
       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved1.htm"),
       full_file_name));
-  EXPECT_TRUE(file_util::ContentsEqual(
+  EXPECT_TRUE(base::ContentsEqual(
       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
       dir.AppendASCII("1.png")));
-  EXPECT_TRUE(file_util::ContentsEqual(
+  EXPECT_TRUE(base::ContentsEqual(
       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.css"),
       dir.AppendASCII("1.css")));
 }
@@ -639,15 +658,15 @@
 
   EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
 
-  EXPECT_TRUE(file_util::PathExists(full_file_name));
-  EXPECT_TRUE(file_util::PathExists(dir));
-  EXPECT_TRUE(file_util::TextContentsEqual(
+  EXPECT_TRUE(base::PathExists(full_file_name));
+  EXPECT_TRUE(base::PathExists(dir));
+  EXPECT_TRUE(base::TextContentsEqual(
       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved2.htm"),
       full_file_name));
-  EXPECT_TRUE(file_util::ContentsEqual(
+  EXPECT_TRUE(base::ContentsEqual(
       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
       dir.AppendASCII("1.png")));
-  EXPECT_TRUE(file_util::ContentsEqual(
+  EXPECT_TRUE(base::ContentsEqual(
       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.css"),
       dir.AppendASCII("1.css")));
 }
@@ -691,9 +710,9 @@
 
   removed.WaitForRemoved();
 
-  EXPECT_TRUE(file_util::PathExists(full_file_name));
-  EXPECT_FALSE(file_util::PathExists(dir));
-  EXPECT_TRUE(file_util::ContentsEqual(test_dir_.Append(base::FilePath(
+  EXPECT_TRUE(base::PathExists(full_file_name));
+  EXPECT_FALSE(base::PathExists(dir));
+  EXPECT_TRUE(base::ContentsEqual(test_dir_.Append(base::FilePath(
       kTestDir)).Append(FILE_PATH_LITERAL("a.htm")), full_file_name));
 }
 
@@ -710,7 +729,7 @@
       download_dir.AppendASCII(std::string("test.exe") + kAppendedExtension);
   base::FilePath dir = download_dir.AppendASCII("test.exe_files");
 
-  EXPECT_FALSE(file_util::PathExists(full_file_name));
+  EXPECT_FALSE(base::PathExists(full_file_name));
   GURL url = URLRequestMockHTTPJob::GetMockUrl(
       base::FilePath(kTestDir).Append(file_name));
   ui_test_utils::NavigateToURL(browser(), url);
@@ -724,7 +743,7 @@
   chrome::SavePage(browser());
   loop_runner->Run();
 
-  EXPECT_TRUE(file_util::PathExists(full_file_name));
+  EXPECT_TRUE(base::PathExists(full_file_name));
 
   EXPECT_TRUE(file_util::DieFileDie(full_file_name, false));
   EXPECT_TRUE(file_util::DieFileDie(dir, true));
@@ -767,7 +786,7 @@
   ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
   persisted.WaitForPersisted();
 
-  ASSERT_TRUE(file_util::PathExists(full_file_name));
+  ASSERT_TRUE(base::PathExists(full_file_name));
   int64 actual_file_size = -1;
   EXPECT_TRUE(file_util::GetFileSize(full_file_name, &actual_file_size));
   EXPECT_LE(kFileSizeMin, actual_file_size);
@@ -787,7 +806,7 @@
   base::FilePath download_dir = DownloadPrefs::FromDownloadManager(
       GetDownloadManager())->DownloadPath();
   base::FilePath filename = download_dir.AppendASCII("dataurl.txt");
-  ASSERT_TRUE(file_util::PathExists(filename));
+  ASSERT_TRUE(base::PathExists(filename));
   std::string contents;
   EXPECT_TRUE(file_util::ReadFileToString(filename, &contents));
   EXPECT_EQ("foo", contents);
diff --git a/chrome/browser/drive/DEPS b/chrome/browser/drive/DEPS
new file mode 100644
index 0000000..498b0d4
--- /dev/null
+++ b/chrome/browser/drive/DEPS
@@ -0,0 +1,26 @@
+include_rules = [
+  "-chrome",
+  "-content",
+  "+chrome/browser/drive",
+  "+content/public/browser",
+  "+content/public/test",
+  # This should be changed to "+google_apis" once
+  # //chrome/browser/google_apis is moved to //google_apis. crbug.com/146989
+  "!chrome/browser/google_apis",
+]
+
+# The following dependencies should be removed to componentize this
+# directory. crbug.com/257943
+specific_include_rules = {
+  "drive_notification_manager_factory\.cc": [
+    "!chrome/browser/invalidation/invalidation_service_factory.h",
+    "!chrome/browser/profiles/profile.h",
+    "!chrome/browser/sync/profile_sync_service.h",
+    "!chrome/browser/sync/profile_sync_service_factory.h",
+  ],
+  "drive_notification_manager\.cc": [
+    "!chrome/browser/invalidation/invalidation_service.h",
+    "!chrome/browser/invalidation/invalidation_service_factory.h",
+    "!chrome/browser/profiles/profile.h",
+  ],
+}
diff --git a/chrome/browser/drive/drive_api_service.cc b/chrome/browser/drive/drive_api_service.cc
index 4ad4732..c2a5e34 100644
--- a/chrome/browser/drive/drive_api_service.cc
+++ b/chrome/browser/drive/drive_api_service.cc
@@ -15,12 +15,14 @@
 #include "chrome/browser/google_apis/auth_service.h"
 #include "chrome/browser/google_apis/drive_api_parser.h"
 #include "chrome/browser/google_apis/drive_api_requests.h"
+#include "chrome/browser/google_apis/gdata_errorcode.h"
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
 #include "chrome/browser/google_apis/request_sender.h"
 #include "content/public/browser/browser_thread.h"
 
 using content::BrowserThread;
 using google_apis::AppList;
+using google_apis::AuthStatusCallback;
 using google_apis::AuthorizeAppCallback;
 using google_apis::CancelCallback;
 using google_apis::ChangeList;
@@ -287,6 +289,7 @@
   scopes.push_back(kDriveAppsReadonlyScope);
   sender_.reset(new RequestSender(profile,
                                   url_request_context_getter_,
+                                  blocking_task_runner_.get(),
                                   scopes,
                                   custom_user_agent_));
   sender_->Initialize();
@@ -517,7 +520,7 @@
 
 CancelCallback DriveAPIService::AddNewDirectory(
     const std::string& parent_resource_id,
-    const std::string& directory_name,
+    const std::string& directory_title,
     const GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -527,14 +530,14 @@
           sender_.get(),
           url_generator_,
           parent_resource_id,
-          directory_name,
+          directory_title,
           base::Bind(&ParseResourceEntryAndRun, callback)));
 }
 
 CancelCallback DriveAPIService::CopyResource(
     const std::string& resource_id,
     const std::string& parent_resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -545,13 +548,13 @@
           url_generator_,
           resource_id,
           parent_resource_id,
-          new_name,
+          new_title,
           base::Bind(&ParseResourceEntryAndRun, callback)));
 }
 
 CancelCallback DriveAPIService::CopyHostedDocument(
     const std::string& resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -562,13 +565,13 @@
           url_generator_,
           resource_id,
           std::string(),  // parent_resource_id.
-          new_name,
+          new_title,
           base::Bind(&ParseResourceEntryAndRun, callback)));
 }
 
 CancelCallback DriveAPIService::RenameResource(
     const std::string& resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const EntryActionCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -578,7 +581,7 @@
           sender_.get(),
           url_generator_,
           resource_id,
-          new_name,
+          new_title,
           callback));
 }
 
@@ -729,24 +732,36 @@
 
 bool DriveAPIService::HasAccessToken() const {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
   return sender_->auth_service()->HasAccessToken();
 }
 
+void DriveAPIService::RequestAccessToken(const AuthStatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+
+  const std::string access_token = sender_->auth_service()->access_token();
+  if (!access_token.empty()) {
+    callback.Run(google_apis::HTTP_NOT_MODIFIED, access_token);
+    return;
+  }
+
+  // Retrieve the new auth token.
+  sender_->auth_service()->StartAuthentication(callback);
+}
+
 bool DriveAPIService::HasRefreshToken() const {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
   return sender_->auth_service()->HasRefreshToken();
 }
 
 void DriveAPIService::ClearAccessToken() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  return sender_->auth_service()->ClearAccessToken();
+  sender_->auth_service()->ClearAccessToken();
 }
 
 void DriveAPIService::ClearRefreshToken() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  return sender_->auth_service()->ClearRefreshToken();
+  sender_->auth_service()->ClearRefreshToken();
 }
 
 void DriveAPIService::OnOAuth2RefreshTokenChanged() {
diff --git a/chrome/browser/drive/drive_api_service.h b/chrome/browser/drive/drive_api_service.h
index 3a330d6..f2b2957 100644
--- a/chrome/browser/drive/drive_api_service.h
+++ b/chrome/browser/drive/drive_api_service.h
@@ -11,6 +11,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/observer_list.h"
 #include "chrome/browser/drive/drive_service_interface.h"
+#include "chrome/browser/google_apis/auth_service_interface.h"
 #include "chrome/browser/google_apis/auth_service_observer.h"
 #include "chrome/browser/google_apis/drive_api_url_generator.h"
 
@@ -61,6 +62,8 @@
   virtual std::string CanonicalizeResourceId(
       const std::string& resource_id) const OVERRIDE;
   virtual bool HasAccessToken() const OVERRIDE;
+  virtual void RequestAccessToken(
+      const google_apis::AuthStatusCallback& callback) OVERRIDE;
   virtual bool HasRefreshToken() const OVERRIDE;
   virtual void ClearAccessToken() OVERRIDE;
   virtual void ClearRefreshToken() OVERRIDE;
@@ -103,15 +106,15 @@
   virtual google_apis::CancelCallback CopyResource(
       const std::string& resource_id,
       const std::string& parent_resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback CopyHostedDocument(
       const std::string& resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback RenameResource(
       const std::string& resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::EntryActionCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback TouchResource(
       const std::string& resource_id,
@@ -128,7 +131,7 @@
       const google_apis::EntryActionCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback AddNewDirectory(
       const std::string& parent_resource_id,
-      const std::string& directory_name,
+      const std::string& directory_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback InitiateUploadNewFile(
       const std::string& content_type,
diff --git a/chrome/browser/drive/drive_service_interface.h b/chrome/browser/drive/drive_service_interface.h
index f792d24..7774727 100644
--- a/chrome/browser/drive/drive_service_interface.h
+++ b/chrome/browser/drive/drive_service_interface.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "chrome/browser/google_apis/auth_service_interface.h"
 #include "chrome/browser/google_apis/base_requests.h"
 #include "chrome/browser/google_apis/drive_common_callbacks.h"
 
@@ -59,6 +60,10 @@
   // True if OAuth2 access token is retrieved and believed to be fresh.
   virtual bool HasAccessToken() const = 0;
 
+  // Gets the cached OAuth2 access token or if empty, then fetches a new one.
+  virtual void RequestAccessToken(
+      const google_apis::AuthStatusCallback& callback) = 0;
+
   // True if OAuth2 refresh token is present.
   virtual bool HasRefreshToken() const = 0;
 
@@ -174,7 +179,7 @@
 
   // Makes a copy of a resource with |resource_id|.
   // The new resource will be put under a directory with |parent_resource_id|,
-  // and it'll be named |new_name|.
+  // and it'll be named |new_title|.
   // This request is supported only on DriveAPIService, because GData WAPI
   // doesn't support the function unfortunately.
   // Upon completion, invokes |callback| with results on the calling thread.
@@ -182,11 +187,11 @@
   virtual google_apis::CancelCallback CopyResource(
       const std::string& resource_id,
       const std::string& parent_resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback) = 0;
 
   // Makes a copy of a hosted document identified by its |resource_id|.
-  // The copy is named as the UTF-8 encoded |new_name| and is not added to any
+  // The copy is named as the UTF-8 encoded |new_title| and is not added to any
   // collection. Use AddResourceToDirectory() to add the copy to a collection
   // when needed. Upon completion, invokes |callback| with results on the
   // calling thread.
@@ -195,16 +200,16 @@
   // because we can use CopyResource instead.
   virtual google_apis::CancelCallback CopyHostedDocument(
       const std::string& resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback) = 0;
 
   // Renames a document or collection identified by its |resource_id|
-  // to the UTF-8 encoded |new_name|. Upon completion,
+  // to the UTF-8 encoded |new_title|. Upon completion,
   // invokes |callback| with results on the calling thread.
   // |callback| must not be null.
   virtual google_apis::CancelCallback RenameResource(
       const std::string& resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::EntryActionCallback& callback) = 0;
 
   // Touches the resource with |resource_id|.
@@ -236,7 +241,7 @@
       const std::string& resource_id,
       const google_apis::EntryActionCallback& callback) = 0;
 
-  // Adds new collection with |directory_name| under parent directory
+  // Adds new collection with |directory_title| under parent directory
   // identified with |parent_resource_id|. |parent_resource_id| can be the
   // value returned by GetRootResourceId to represent the root directory.
   // Upon completion, invokes |callback| and passes newly created entry on
@@ -246,7 +251,7 @@
   // |callback| must not be null.
   virtual google_apis::CancelCallback AddNewDirectory(
       const std::string& parent_resource_id,
-      const std::string& directory_name,
+      const std::string& directory_title,
       const google_apis::GetResourceEntryCallback& callback) = 0;
 
   // Downloads a file with |resourced_id|. The downloaded file will
diff --git a/chrome/browser/drive/dummy_drive_service.cc b/chrome/browser/drive/dummy_drive_service.cc
index 24da00a..6d3d241 100644
--- a/chrome/browser/drive/dummy_drive_service.cc
+++ b/chrome/browser/drive/dummy_drive_service.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/drive/dummy_drive_service.h"
 
+using google_apis::AuthStatusCallback;
 using google_apis::AuthorizeAppCallback;
 using google_apis::CancelCallback;
 using google_apis::DownloadActionCallback;
@@ -38,6 +39,10 @@
 
 bool DummyDriveService::HasAccessToken() const { return true; }
 
+void DummyDriveService::RequestAccessToken(const AuthStatusCallback& callback) {
+  callback.Run(google_apis::HTTP_NOT_MODIFIED, "fake_access_token");
+}
+
 bool DummyDriveService::HasRefreshToken() const { return true; }
 
 void DummyDriveService::ClearAccessToken() { }
@@ -97,17 +102,17 @@
 CancelCallback DummyDriveService::CopyResource(
     const std::string& resource_id,
     const std::string& parent_resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const GetResourceEntryCallback& callback) { return CancelCallback(); }
 
 CancelCallback DummyDriveService::CopyHostedDocument(
     const std::string& resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const GetResourceEntryCallback& callback) { return CancelCallback(); }
 
 CancelCallback DummyDriveService::RenameResource(
     const std::string& resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const EntryActionCallback& callback) { return CancelCallback(); }
 
 CancelCallback DummyDriveService::TouchResource(
@@ -128,7 +133,7 @@
 
 CancelCallback DummyDriveService::AddNewDirectory(
     const std::string& parent_resource_id,
-    const std::string& directory_name,
+    const std::string& directory_title,
     const GetResourceEntryCallback& callback) { return CancelCallback(); }
 
 CancelCallback DummyDriveService::InitiateUploadNewFile(
diff --git a/chrome/browser/drive/dummy_drive_service.h b/chrome/browser/drive/dummy_drive_service.h
index bcb89bf..8ebc922 100644
--- a/chrome/browser/drive/dummy_drive_service.h
+++ b/chrome/browser/drive/dummy_drive_service.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_DRIVE_DUMMY_DRIVE_SERVICE_H_
 
 #include "chrome/browser/drive/drive_service_interface.h"
+#include "chrome/browser/google_apis/auth_service_interface.h"
 
 namespace drive {
 
@@ -24,6 +25,8 @@
   virtual std::string CanonicalizeResourceId(
       const std::string& resource_id) const OVERRIDE;
   virtual bool HasAccessToken() const OVERRIDE;
+  virtual void RequestAccessToken(
+      const google_apis::AuthStatusCallback& callback) OVERRIDE;
   virtual bool HasRefreshToken() const OVERRIDE;
   virtual void ClearAccessToken() OVERRIDE;
   virtual void ClearRefreshToken() OVERRIDE;
@@ -66,15 +69,15 @@
   virtual google_apis::CancelCallback CopyResource(
       const std::string& resource_id,
       const std::string& parent_resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback CopyHostedDocument(
       const std::string& resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback RenameResource(
       const std::string& resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::EntryActionCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback TouchResource(
       const std::string& resource_id,
@@ -91,7 +94,7 @@
       const google_apis::EntryActionCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback AddNewDirectory(
       const std::string& parent_resource_id,
-      const std::string& directory_name,
+      const std::string& directory_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback InitiateUploadNewFile(
       const std::string& content_type,
diff --git a/chrome/browser/drive/fake_drive_service.cc b/chrome/browser/drive/fake_drive_service.cc
index 28899cf..40f8ddf 100644
--- a/chrome/browser/drive/fake_drive_service.cc
+++ b/chrome/browser/drive/fake_drive_service.cc
@@ -28,6 +28,7 @@
 using google_apis::AboutResource;
 using google_apis::AccountMetadata;
 using google_apis::AppList;
+using google_apis::AuthStatusCallback;
 using google_apis::AuthorizeAppCallback;
 using google_apis::CancelCallback;
 using google_apis::DownloadActionCallback;
@@ -270,6 +271,12 @@
   return true;
 }
 
+void FakeDriveService::RequestAccessToken(const AuthStatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+  callback.Run(google_apis::HTTP_NOT_MODIFIED, "fake_access_token");
+}
+
 bool FakeDriveService::HasRefreshToken() const {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   return true;
@@ -633,7 +640,7 @@
 CancelCallback FakeDriveService::CopyResource(
     const std::string& resource_id,
     const std::string& in_parent_resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -664,7 +671,7 @@
         scoped_ptr<DictionaryValue> copied_entry(entry->DeepCopy());
         copied_entry->SetString("gd$resourceId.$t",
                                 resource_id + "_copied");
-        copied_entry->SetString("title.$t", new_name);
+        copied_entry->SetString("title.$t", new_title);
 
         // Reset parent directory.
         base::ListValue* links = NULL;
@@ -707,17 +714,17 @@
 
 CancelCallback FakeDriveService::CopyHostedDocument(
     const std::string& resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
-  return CopyResource(resource_id, std::string(), new_name, callback);
+  return CopyResource(resource_id, std::string(), new_title, callback);
 }
 
 CancelCallback FakeDriveService::RenameResource(
     const std::string& resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const EntryActionCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -730,7 +737,7 @@
 
   base::DictionaryValue* entry = FindEntryByResourceId(resource_id);
   if (entry) {
-    entry->SetString("title.$t", new_name);
+    entry->SetString("title.$t", new_title);
     AddNewChangestampAndETag(entry);
     base::MessageLoop::current()->PostTask(
         FROM_HERE, base::Bind(callback, HTTP_SUCCESS));
@@ -868,7 +875,7 @@
 
 CancelCallback FakeDriveService::AddNewDirectory(
     const std::string& parent_resource_id,
-    const std::string& directory_name,
+    const std::string& directory_title,
     const GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -887,7 +894,7 @@
   const base::DictionaryValue* new_entry = AddNewEntry(kContentType,
                                                        "",  // content_data
                                                        parent_resource_id,
-                                                       directory_name,
+                                                       directory_title,
                                                        false,  // shared_with_me
                                                        "folder");
   if (!new_entry) {
@@ -1368,18 +1375,22 @@
     int* load_counter,
     const GetResourceListCallback& callback) {
   if (offline_) {
-    scoped_ptr<ResourceList> null;
     base::MessageLoop::current()->PostTask(
         FROM_HERE,
         base::Bind(callback,
                    GDATA_NO_CONNECTION,
-                   base::Passed(&null)));
+                   base::Passed(scoped_ptr<ResourceList>())));
     return;
   }
 
   scoped_ptr<ResourceList> resource_list =
       ResourceList::CreateFrom(*resource_list_value_);
 
+  // TODO(hashimoto): Drive API always provides largest changestamp. Remove this
+  // if-statement after API switch.
+  if (start_changestamp > 0 && start_offset == 0)
+    resource_list->set_largest_changestamp(largest_changestamp_);
+
   // Filter out entries per parameters like |directory_resource_id| and
   // |search_query|.
   ScopedVector<ResourceEntry>* entries = resource_list->mutable_entries();
@@ -1476,9 +1487,7 @@
     *load_counter += 1;
   base::MessageLoop::current()->PostTask(
       FROM_HERE,
-      base::Bind(callback,
-                 HTTP_SUCCESS,
-                 base::Passed(&resource_list)));
+      base::Bind(callback, HTTP_SUCCESS, base::Passed(&resource_list)));
 }
 
 GURL FakeDriveService::GetNewUploadSessionUrl() {
diff --git a/chrome/browser/drive/fake_drive_service.h b/chrome/browser/drive/fake_drive_service.h
index 9b59e0c..369eaa0 100644
--- a/chrome/browser/drive/fake_drive_service.h
+++ b/chrome/browser/drive/fake_drive_service.h
@@ -8,6 +8,7 @@
 #include "base/files/file_path.h"
 #include "base/values.h"
 #include "chrome/browser/drive/drive_service_interface.h"
+#include "chrome/browser/google_apis/auth_service_interface.h"
 
 namespace drive {
 
@@ -85,6 +86,8 @@
       const std::string& resource_id) const OVERRIDE;
   virtual std::string GetRootResourceId() const OVERRIDE;
   virtual bool HasAccessToken() const OVERRIDE;
+  virtual void RequestAccessToken(
+      const google_apis::AuthStatusCallback& callback) OVERRIDE;
   virtual bool HasRefreshToken() const OVERRIDE;
   virtual void ClearAccessToken() OVERRIDE;
   virtual void ClearRefreshToken() OVERRIDE;
@@ -128,17 +131,17 @@
   virtual google_apis::CancelCallback CopyResource(
       const std::string& resource_id,
       const std::string& parent_resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   // The new resource ID for the copied document will look like
   // |resource_id| + "_copied".
   virtual google_apis::CancelCallback CopyHostedDocument(
       const std::string& resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback RenameResource(
       const std::string& resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::EntryActionCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback TouchResource(
       const std::string& resource_id,
@@ -155,7 +158,7 @@
       const google_apis::EntryActionCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback AddNewDirectory(
       const std::string& parent_resource_id,
-      const std::string& directory_name,
+      const std::string& directory_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback InitiateUploadNewFile(
       const std::string& content_type,
diff --git a/chrome/browser/drive/fake_drive_service_unittest.cc b/chrome/browser/drive/fake_drive_service_unittest.cc
index 26334d5..7104094 100644
--- a/chrome/browser/drive/fake_drive_service_unittest.cc
+++ b/chrome/browser/drive/fake_drive_service_unittest.cc
@@ -65,12 +65,12 @@
   // Adds a new directory at |parent_resource_id| with the given name.
   // Returns true on success.
   bool AddNewDirectory(const std::string& parent_resource_id,
-                       const std::string& directory_name) {
+                       const std::string& directory_title) {
     GDataErrorCode error = GDATA_OTHER_ERROR;
     scoped_ptr<ResourceEntry> resource_entry;
     fake_service_.AddNewDirectory(
         parent_resource_id,
-        directory_name,
+        directory_title,
         test_util::CreateCopyResultCallback(&error, &resource_entry));
     base::RunLoop().RunUntilIdle();
     return error == HTTP_CREATED;
@@ -369,6 +369,8 @@
 
   EXPECT_EQ(HTTP_SUCCESS, error);
   ASSERT_TRUE(resource_list);
+  EXPECT_EQ(fake_service_.largest_changestamp(),
+            resource_list->largest_changestamp());
   // This should be empty as the latest changestamp was passed to
   // GetResourceList(), hence there should be no new entries.
   EXPECT_EQ(0U, resource_list->entries().size());
@@ -398,6 +400,8 @@
 
   EXPECT_EQ(HTTP_SUCCESS, error);
   ASSERT_TRUE(resource_list);
+  EXPECT_EQ(fake_service_.largest_changestamp(),
+            resource_list->largest_changestamp());
   // The result should only contain the newly created directory.
   ASSERT_EQ(1U, resource_list->entries().size());
   EXPECT_EQ("new directory", resource_list->entries()[0]->title());
@@ -449,6 +453,8 @@
 
   EXPECT_EQ(HTTP_SUCCESS, error);
   ASSERT_TRUE(resource_list);
+  EXPECT_EQ(fake_service_.largest_changestamp(),
+            resource_list->largest_changestamp());
   // The result should only contain the newly created directory.
   ASSERT_EQ(1U, resource_list->entries().size());
   const ResourceEntry& entry = *resource_list->entries()[0];
@@ -949,7 +955,7 @@
   fake_service_.CopyResource(
       kResourceId,
       kParentResourceId,
-      "new name",
+      "new title",
       test_util::CreateCopyResultCallback(&error, &resource_entry));
   base::RunLoop().RunUntilIdle();
 
@@ -957,7 +963,7 @@
   ASSERT_TRUE(resource_entry);
   // The copied entry should have the new resource ID and the title.
   EXPECT_EQ(kResourceId + "_copied", resource_entry->resource_id());
-  EXPECT_EQ("new name", resource_entry->title());
+  EXPECT_EQ("new title", resource_entry->title());
   EXPECT_TRUE(HasParent(kResourceId, kParentResourceId));
   // Should be incremented as a new hosted document was created.
   EXPECT_EQ(old_largest_change_id + 1, fake_service_.largest_changestamp());
@@ -974,7 +980,7 @@
   fake_service_.CopyResource(
       kResourceId,
       "folder:1_folder_resource_id",
-      "new name",
+      "new title",
       test_util::CreateCopyResultCallback(&error, &resource_entry));
   base::RunLoop().RunUntilIdle();
 
@@ -995,7 +1001,7 @@
   fake_service_.CopyResource(
       kResourceId,
       std::string(),
-      "new name",
+      "new title",
       test_util::CreateCopyResultCallback(&error, &resource_entry));
   base::RunLoop().RunUntilIdle();
 
@@ -1003,7 +1009,7 @@
   ASSERT_TRUE(resource_entry);
   // The copied entry should have the new resource ID and the title.
   EXPECT_EQ(kResourceId + "_copied", resource_entry->resource_id());
-  EXPECT_EQ("new name", resource_entry->title());
+  EXPECT_EQ("new title", resource_entry->title());
   EXPECT_TRUE(HasParent(kResourceId, fake_service_.GetRootResourceId()));
   // Should be incremented as a new hosted document was created.
   EXPECT_EQ(old_largest_change_id + 1, fake_service_.largest_changestamp());
@@ -1021,7 +1027,7 @@
   fake_service_.CopyResource(
       kResourceId,
       "folder:1_folder_resource_id",
-      "new name",
+      "new title",
       test_util::CreateCopyResultCallback(&error, &resource_entry));
   base::RunLoop().RunUntilIdle();
 
@@ -1042,7 +1048,7 @@
   scoped_ptr<ResourceEntry> resource_entry;
   fake_service_.CopyHostedDocument(
       kResourceId,
-      "new name",
+      "new title",
       test_util::CreateCopyResultCallback(&error, &resource_entry));
   base::RunLoop().RunUntilIdle();
 
@@ -1050,7 +1056,7 @@
   ASSERT_TRUE(resource_entry);
   // The copied entry should have the new resource ID and the title.
   EXPECT_EQ(kResourceId + "_copied", resource_entry->resource_id());
-  EXPECT_EQ("new name", resource_entry->title());
+  EXPECT_EQ("new title", resource_entry->title());
   // Should be incremented as a new hosted document was created.
   EXPECT_EQ(old_largest_change_id + 1, fake_service_.largest_changestamp());
   EXPECT_EQ(old_largest_change_id + 1, GetLargestChangeByAboutResource());
@@ -1065,7 +1071,7 @@
   scoped_ptr<ResourceEntry> resource_entry;
   fake_service_.CopyHostedDocument(
       kResourceId,
-      "new name",
+      "new title",
       test_util::CreateCopyResultCallback(&error, &resource_entry));
   base::RunLoop().RunUntilIdle();
 
@@ -1082,7 +1088,7 @@
   scoped_ptr<ResourceEntry> resource_entry;
   fake_service_.CopyHostedDocument(
       kResourceId,
-      "new name",
+      "new title",
       test_util::CreateCopyResultCallback(&error, &resource_entry));
   base::RunLoop().RunUntilIdle();
 
@@ -1102,7 +1108,7 @@
 
   GDataErrorCode error = GDATA_OTHER_ERROR;
   fake_service_.RenameResource(kResourceId,
-                               "new name",
+                               "new title",
                                test_util::CreateCopyResultCallback(&error));
   base::RunLoop().RunUntilIdle();
 
@@ -1110,7 +1116,7 @@
 
   scoped_ptr<ResourceEntry> resource_entry = FindEntry(kResourceId);
   ASSERT_TRUE(resource_entry);
-  EXPECT_EQ("new name", resource_entry->title());
+  EXPECT_EQ("new title", resource_entry->title());
   // Should be incremented as a file was renamed.
   EXPECT_EQ(old_largest_change_id + 1, fake_service_.largest_changestamp());
   EXPECT_EQ(old_largest_change_id + 1, GetLargestChangeByAboutResource());
@@ -1124,7 +1130,7 @@
 
   GDataErrorCode error = GDATA_OTHER_ERROR;
   fake_service_.RenameResource(kResourceId,
-                               "new name",
+                               "new title",
                                test_util::CreateCopyResultCallback(&error));
   base::RunLoop().RunUntilIdle();
 
@@ -1140,7 +1146,7 @@
 
   GDataErrorCode error = GDATA_OTHER_ERROR;
   fake_service_.RenameResource(kResourceId,
-                               "new name",
+                               "new title",
                                test_util::CreateCopyResultCallback(&error));
   base::RunLoop().RunUntilIdle();
 
diff --git a/chrome/browser/drive/gdata_wapi_service.cc b/chrome/browser/drive/gdata_wapi_service.cc
index 689726b..1081538 100644
--- a/chrome/browser/drive/gdata_wapi_service.cc
+++ b/chrome/browser/drive/gdata_wapi_service.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/drive/drive_api_util.h"
 #include "chrome/browser/google_apis/auth_service.h"
 #include "chrome/browser/google_apis/drive_api_parser.h"
+#include "chrome/browser/google_apis/gdata_errorcode.h"
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
 #include "chrome/browser/google_apis/gdata_wapi_requests.h"
 #include "chrome/browser/google_apis/gdata_wapi_url_generator.h"
@@ -24,6 +25,7 @@
 using google_apis::AccountMetadata;
 using google_apis::AddResourceToDirectoryRequest;
 using google_apis::AppList;
+using google_apis::AuthStatusCallback;
 using google_apis::AuthorizeAppCallback;
 using google_apis::AuthorizeAppRequest;
 using google_apis::AuthService;
@@ -161,6 +163,7 @@
   scopes.push_back(kDriveAppsScope);
   sender_.reset(new RequestSender(profile,
                                   url_request_context_getter_,
+                                  blocking_task_runner_.get(),
                                   scopes,
                                   custom_user_agent_));
   sender_->Initialize();
@@ -369,7 +372,7 @@
 
 CancelCallback GDataWapiService::AddNewDirectory(
     const std::string& parent_resource_id,
-    const std::string& directory_name,
+    const std::string& directory_title,
     const GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -380,13 +383,13 @@
                                  base::Bind(&ParseResourceEntryAndRun,
                                             callback),
                                  parent_resource_id,
-                                 directory_name));
+                                 directory_title));
 }
 
 CancelCallback GDataWapiService::CopyResource(
     const std::string& resource_id,
     const std::string& parent_resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -400,7 +403,7 @@
 
 CancelCallback GDataWapiService::CopyHostedDocument(
     const std::string& resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const GetResourceEntryCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -411,12 +414,12 @@
                                     base::Bind(&ParseResourceEntryAndRun,
                                                callback),
                                     resource_id,
-                                    new_name));
+                                    new_title));
 }
 
 CancelCallback GDataWapiService::RenameResource(
     const std::string& resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const EntryActionCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
@@ -426,7 +429,7 @@
                                 url_generator_,
                                 callback,
                                 resource_id,
-                                new_name));
+                                new_title));
 }
 
 CancelCallback GDataWapiService::TouchResource(
@@ -577,20 +580,33 @@
   return sender_->auth_service()->HasAccessToken();
 }
 
+void GDataWapiService::RequestAccessToken(const AuthStatusCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+
+  const std::string access_token = sender_->auth_service()->access_token();
+  if (!access_token.empty()) {
+    callback.Run(google_apis::HTTP_NOT_MODIFIED, access_token);
+    return;
+  }
+
+  // Retrieve the new auth token.
+  sender_->auth_service()->StartAuthentication(callback);
+}
+
 bool GDataWapiService::HasRefreshToken() const {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
   return sender_->auth_service()->HasRefreshToken();
 }
 
 void GDataWapiService::ClearAccessToken() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  return sender_->auth_service()->ClearAccessToken();
+  sender_->auth_service()->ClearAccessToken();
 }
 
 void GDataWapiService::ClearRefreshToken() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  return sender_->auth_service()->ClearRefreshToken();
+  sender_->auth_service()->ClearRefreshToken();
 }
 
 void GDataWapiService::OnOAuth2RefreshTokenChanged() {
diff --git a/chrome/browser/drive/gdata_wapi_service.h b/chrome/browser/drive/gdata_wapi_service.h
index 72e6c6c..5674cbc 100644
--- a/chrome/browser/drive/gdata_wapi_service.h
+++ b/chrome/browser/drive/gdata_wapi_service.h
@@ -12,6 +12,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "chrome/browser/drive/drive_service_interface.h"
+#include "chrome/browser/google_apis/auth_service_interface.h"
 #include "chrome/browser/google_apis/auth_service_observer.h"
 #include "chrome/browser/google_apis/gdata_wapi_requests.h"
 #include "chrome/browser/google_apis/gdata_wapi_url_generator.h"
@@ -65,6 +66,8 @@
   virtual std::string CanonicalizeResourceId(
       const std::string& resource_id) const OVERRIDE;
   virtual bool HasAccessToken() const OVERRIDE;
+  virtual void RequestAccessToken(
+      const google_apis::AuthStatusCallback& callback) OVERRIDE;
   virtual bool HasRefreshToken() const OVERRIDE;
   virtual void ClearAccessToken() OVERRIDE;
   virtual void ClearRefreshToken() OVERRIDE;
@@ -107,15 +110,15 @@
   virtual google_apis::CancelCallback CopyResource(
       const std::string& resource_id,
       const std::string& parent_resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback CopyHostedDocument(
       const std::string& resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback RenameResource(
       const std::string& resource_id,
-      const std::string& new_name,
+      const std::string& new_title,
       const google_apis::EntryActionCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback TouchResource(
       const std::string& resource_id,
@@ -132,7 +135,7 @@
       const google_apis::EntryActionCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback AddNewDirectory(
       const std::string& parent_resource_id,
-      const std::string& directory_name,
+      const std::string& directory_title,
       const google_apis::GetResourceEntryCallback& callback) OVERRIDE;
   virtual google_apis::CancelCallback InitiateUploadNewFile(
       const std::string& content_type,
diff --git a/chrome/browser/enumerate_modules_model_win.cc b/chrome/browser/enumerate_modules_model_win.cc
index 279cbd2..a22f358 100644
--- a/chrome/browser/enumerate_modules_model_win.cc
+++ b/chrome/browser/enumerate_modules_model_win.cc
@@ -24,9 +24,9 @@
 #include "base/win/registry.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/windows_version.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/net/service_providers_win.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/notification_service.h"
 #include "crypto/sha2.h"
diff --git a/chrome/browser/extensions/DEPS b/chrome/browser/extensions/DEPS
index 05df41b..890d2ba 100644
--- a/chrome/browser/extensions/DEPS
+++ b/chrome/browser/extensions/DEPS
@@ -4,6 +4,7 @@
   # chrome/browser/extensions, the restriction of not being able
   # to depend on apps will be lifted.
   "-apps",
+  "+apps/app_window_contents.h",
   "+apps/shell_window.h",
 
   # TODO(tfarina): Remove all these. crbug.com/125846.
diff --git a/chrome/browser/extensions/OWNERS b/chrome/browser/extensions/OWNERS
index bb8432e..2ffbdc3 100644
--- a/chrome/browser/extensions/OWNERS
+++ b/chrome/browser/extensions/OWNERS
@@ -10,7 +10,6 @@
 # extensions/OWNERS
 asargent@chromium.org
 benwells@chromium.org
-erikkay@chromium.org
 finnur@chromium.org
 jyasskin@chromium.org
 kalman@chromium.org
@@ -19,5 +18,7 @@
 mpcomplete@chromium.org
 yoz@chromium.org
 
-per-file web_view_browsertest.cc=fsamuel@chromium.org
-per-file web_view_interactive_browsertest.cc=fsamuel@chromium.org
+per-file web_view_*.cc=fsamuel@chromium.org
+per-file web_view_*.cc=lazyboy@chromium.org
+per-file ad_view_*.cc=fsamuel@chromium.org
+per-file ad_view_*.cc=lazyboy@chromium.org
diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc
index 8a766d7..97440e2 100644
--- a/chrome/browser/extensions/active_tab_permission_granter.cc
+++ b/chrome/browser/extensions/active_tab_permission_granter.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/extensions/active_tab_permission_granter.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_id.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_messages.h"
 #include "chrome/common/extensions/permissions/permission_set.h"
diff --git a/chrome/browser/extensions/active_tab_unittest.cc b/chrome/browser/extensions/active_tab_unittest.cc
index 505ce28..7349c72 100644
--- a/chrome/browser/extensions/active_tab_unittest.cc
+++ b/chrome/browser/extensions/active_tab_unittest.cc
@@ -8,11 +8,11 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/active_tab_permission_granter.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_id.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_builder.h"
 #include "chrome/common/extensions/features/feature.h"
diff --git a/chrome/browser/extensions/activity_log/activity_database.cc b/chrome/browser/extensions/activity_log/activity_database.cc
index 20f4b98..9770937 100644
--- a/chrome/browser/extensions/activity_log/activity_database.cc
+++ b/chrome/browser/extensions/activity_log/activity_database.cc
@@ -34,8 +34,9 @@
 
 namespace extensions {
 
-ActivityDatabase::ActivityDatabase()
-    : testing_clock_(NULL),
+ActivityDatabase::ActivityDatabase(ActivityDatabase::Delegate* delegate)
+    : delegate_(delegate),
+      testing_clock_(NULL),
       valid_db_(false),
       already_closed_(false),
       did_init_(false) {
@@ -74,24 +75,17 @@
   base::mac::SetFileBackupExclusion(db_name);
 #endif
 
-  db_.Preload();
-
-  // Create the DOMAction database.
-  if (!DOMAction::InitializeTable(&db_))
-    return LogInitFailure();
-
-  // Create the APIAction database.
-  if (!APIAction::InitializeTable(&db_))
-    return LogInitFailure();
-
-  // Create the BlockedAction database.
-  if (!BlockedAction::InitializeTable(&db_))
+  if (!delegate_->OnDatabaseInit(&db_))
     return LogInitFailure();
 
   sql::InitStatus stat = committer.Commit() ? sql::INIT_OK : sql::INIT_FAILURE;
   if (stat != sql::INIT_OK)
     return LogInitFailure();
 
+  // Pre-loads the first <cache-size> pages into the cache.
+  // Doesn't do anything if the database is new.
+  db_.Preload();
+
   valid_db_ = true;
   timer_.Start(FROM_HERE,
                base::TimeDelta::FromMinutes(2),
@@ -140,13 +134,13 @@
   batch_mode_ = batch_mode;
 }
 
-scoped_ptr<std::vector<scoped_refptr<Action> > > ActivityDatabase::GetActions(
+scoped_ptr<ActivityDatabase::ActionVector> ActivityDatabase::GetActions(
     const std::string& extension_id, const int days_ago) {
   if (BrowserThread::IsMessageLoopValid(BrowserThread::DB))
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
   DCHECK_GE(days_ago, 0);
-  scoped_ptr<std::vector<scoped_refptr<Action> > >
-      actions(new std::vector<scoped_refptr<Action> >());
+
+  scoped_ptr<ActionVector> actions(new ActionVector());
   if (!valid_db_)
     return actions.Pass();
   // Compute the time bounds for that day.
@@ -177,8 +171,7 @@
   dom_statement.BindInt64(1, early_bound);
   dom_statement.BindInt64(2, late_bound);
   while (dom_statement.is_valid() && dom_statement.Step()) {
-    scoped_refptr<DOMAction> action = new DOMAction(dom_statement);
-    actions->push_back(action);
+    actions->push_back(new DOMAction(dom_statement));
   }
   // Get the APIActions.
   std::string api_str = base::StringPrintf("SELECT * FROM %s "
@@ -191,8 +184,7 @@
   api_statement.BindInt64(1, early_bound);
   api_statement.BindInt64(2, late_bound);
   while (api_statement.is_valid() && api_statement.Step()) {
-    scoped_refptr<APIAction> action = new APIAction(api_statement);
-    actions->push_back(action);
+    actions->push_back(new APIAction(api_statement));
   }
   // Get the BlockedActions.
   std::string blocked_str = base::StringPrintf("SELECT * FROM %s "
@@ -205,8 +197,7 @@
   blocked_statement.BindInt64(1, early_bound);
   blocked_statement.BindInt64(2, late_bound);
   while (blocked_statement.is_valid() && blocked_statement.Step()) {
-    scoped_refptr<BlockedAction> action = new BlockedAction(blocked_statement);
-    actions->push_back(action);
+    actions->push_back(new BlockedAction(blocked_statement));
   }
   // Sort by time (from newest to oldest).
   std::sort(actions->begin(), actions->end(), SortActionsByTime);
@@ -221,6 +212,9 @@
   }
   valid_db_ = false;
   already_closed_ = true;
+  // Call DatabaseCloseCallback() just before deleting the ActivityDatabase
+  // itself--these two objects should have the same lifetime.
+  delegate_->OnDatabaseClose();
   delete this;
 }
 
diff --git a/chrome/browser/extensions/activity_log/activity_database.h b/chrome/browser/extensions/activity_log/activity_database.h
index 8c3c42f..e646840 100644
--- a/chrome/browser/extensions/activity_log/activity_database.h
+++ b/chrome/browser/extensions/activity_log/activity_database.h
@@ -9,6 +9,7 @@
 #include <vector>
 #include "base/basictypes.h"
 #include "base/files/file_path.h"
+#include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/synchronization/lock.h"
 #include "base/timer/timer.h"
@@ -27,28 +28,82 @@
 
 namespace extensions {
 
-// Encapsulates the SQL connection for the activity log database.
-// This class holds the database connection and has methods for writing.
-// All of the methods except constructor need to be
-// called on the DB thread. For this reason, the ActivityLog calls Close from
-// its destructor instead of destructing its ActivityDatabase object.
+// Encapsulates the SQL connection for the activity log database.  This class
+// holds the database connection and has methods for writing.  All of the
+// methods except the constructor need to be called on the DB thread.
+//
+// Object ownership and lifetime is a bit complicated for ActivityLog,
+// ActivityLogPolicy, and ActivityDatabase:
+//
+//    ActivityLog ----> ActivityLogPolicy ----> ActivityDatabase
+//                         ^                               |
+//                         |                               |
+//                         \--(ActivityDatabase::Delegate)-/
+//
+// The ActivityLogPolicy object contains a pointer to the ActivityDatabase, and
+// the ActivityDatabase contains a pointer back to the ActivityLogPolicy object
+// (as an instance of ActivityDatabase::Delegate).
+//
+// Since some cleanup must happen on the database thread, deletion should occur
+// as follows:
+//   1. ActivityLog calls ActivityLogPolicy::Close()
+//   2. ActivityLogPolicy should call ActivityDatabase::Close() on the database
+//      thread.
+//   3. ActivityDatabase::Close() shuts down the database, then calls
+//      ActivityDatabase::Delegate::OnDatabaseClose().
+//   4. ActivityDatabase::Delegate::OnDatabaseClose() should delete the
+//      ActivityLogPolicy object.
+//   5. ActivityDatabase::Close() finishes running by deleting the
+//      ActivityDatabase object.
+//
+// (This assumes the common case that the ActivityLogPolicy uses an
+// ActivityDatabase and implements the ActivityDatabase::Delegate interface.
+// It is also possible for an ActivityLogPolicy to not use a database at all,
+// in which case ActivityLogPolicy::Close() should directly delete itself.)
 class ActivityDatabase {
  public:
-  // Need to call Init to actually use the ActivityDatabase.
-  ActivityDatabase();
+  // Interface defining calls that the ActivityDatabase can make into a
+  // ActivityLogPolicy instance to implement policy-specific behavior.  Methods
+  // are always invoked on the database thread.  Classes other than
+  // ActivityDatabase should not call these methods.
+  class Delegate {
+   protected:
+    friend class ActivityDatabase;
 
-  // Opens the DB and creates tables as necessary.
+    // A Delegate is never directly deleted; it should instead delete itself
+    // after any final cleanup when OnDatabaseClose() is invoked.
+    virtual ~Delegate() {}
+
+    // Initializes the database schema; this gives a policy a chance to create
+    // or update database tables as needed.  Should return true on success.
+    virtual bool OnDatabaseInit(sql::Connection* db) = 0;
+
+    // Called by ActivityDatabase just before the ActivityDatabase object is
+    // deleted.  The database will make no further callbacks after invoking
+    // this method, so it is an appropriate time for the policy to delete
+    // itself.
+    virtual void OnDatabaseClose() = 0;
+  };
+
+  // Used to simplify the return type of GetActions.
+  typedef std::vector<scoped_refptr<Action> > ActionVector;
+
+  // Need to call Init to actually use the ActivityDatabase.  The Delegate
+  // provides hooks for an ActivityLogPolicy to control the database schema and
+  // reads/writes.
+  explicit ActivityDatabase(Delegate* delegate);
+
+  // Opens the DB.  This invokes OnDatabaseInit in the delegate to create or
+  // update the database schema if needed.
   void Init(const base::FilePath& db_name);
 
   // The ActivityLog should call this to kill the ActivityDatabase.
   void Close();
 
-  void LogInitFailure();
-
-  // Record a DOMction in the database.
+  // Record a DOMAction in the database.
   void RecordDOMAction(scoped_refptr<DOMAction> action);
 
-  // Record a APIAction in the database.
+  // Record an APIAction in the database.
   void RecordAPIAction(scoped_refptr<APIAction> action);
 
   // Record a BlockedAction in the database.
@@ -57,34 +112,35 @@
   // Record an Action in the database.
   void RecordAction(scoped_refptr<Action> action);
 
+  // Turns off batch I/O writing mode. This should only be used in unit tests,
+  // browser tests, or in our special --enable-extension-activity-log-testing
+  // policy state.
+  void SetBatchModeForTesting(bool batch_mode);
+
   // Gets all actions for a given extension for the specified day. 0 = today,
   // 1 = yesterday, etc. Only returns 1 day at a time. Actions are sorted from
   // newest to oldest.
-  scoped_ptr<std::vector<scoped_refptr<Action> > > GetActions(
-      const std::string& extension_id, const int days_ago);
-
-  // Handle errors in database writes.
-  void DatabaseErrorCallback(int error, sql::Statement* stmt);
+  scoped_ptr<ActionVector> GetActions(const std::string& extension_id,
+                                      const int days_ago);
 
   bool is_db_valid() const { return valid_db_; }
 
-  // For unit testing only.
-  void SetBatchModeForTesting(bool batch_mode);
-  void SetClockForTesting(base::Clock* clock);
-  void SetTimerForTesting(int milliseconds);
-
  private:
   // This should never be invoked by another class. Use Close() to order a
   // suicide.
   virtual ~ActivityDatabase();
 
+  // Used by the Init() method as a convenience for handling a failied
+  // database initialization attempt. Prints an error and puts us in the soft
+  // failure state.
+  void LogInitFailure();
+
   sql::InitStatus InitializeTable(const char* table_name,
                                   const char* table_structure);
 
   // When we're in batched mode (which is on by default), we write to the db
   // every X minutes instead of on every API call. This prevents the annoyance
   // of writing to disk multiple times a second.
-  void StartTimer();
   void RecordBatchedActions();
 
   // If an error is unrecoverable or occurred while we were trying to close
@@ -97,8 +153,19 @@
   // or changes to it.
   void SoftFailureClose();
 
+  // Handle errors in database writes. For a serious & permanent error, it
+  // invokes HardFailureClose(); for a less serious/permanent error, it invokes
+  // SoftFailureClose().
+  void DatabaseErrorCallback(int error, sql::Statement* stmt);
+
   // For unit testing only.
   void RecordBatchedActionsWhileTesting();
+  void SetClockForTesting(base::Clock* clock);
+  void SetTimerForTesting(int milliseconds);
+
+  // A reference a Delegate for policy-specific database behavior.  See the
+  // top-level comment for ActivityDatabase for comments on cleanup.
+  Delegate* delegate_;
 
   base::Clock* testing_clock_;
   sql::Connection db_;
@@ -109,6 +176,8 @@
   bool already_closed_;
   bool did_init_;
 
+  FRIEND_TEST_ALL_PREFIXES(ActivityDatabaseTest, BatchModeOff);
+  FRIEND_TEST_ALL_PREFIXES(ActivityDatabaseTest, BatchModeOn);
   DISALLOW_COPY_AND_ASSIGN(ActivityDatabase);
 };
 
diff --git a/chrome/browser/extensions/activity_log/activity_database_unittest.cc b/chrome/browser/extensions/activity_log/activity_database_unittest.cc
index 56ac824..3fd040bf 100644
--- a/chrome/browser/extensions/activity_log/activity_database_unittest.cc
+++ b/chrome/browser/extensions/activity_log/activity_database_unittest.cc
@@ -27,7 +27,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/mock_user_manager.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
@@ -39,6 +39,28 @@
 
 namespace extensions {
 
+// A dummy implementation of ActivityDatabase::Delegate, sufficient for
+// the unit tests.
+class ActivityDatabaseTestPolicy : public ActivityDatabase::Delegate {
+ public:
+  ActivityDatabaseTestPolicy() {};
+
+ protected:
+  virtual bool OnDatabaseInit(sql::Connection* db) OVERRIDE {
+    if (!DOMAction::InitializeTable(db)) return false;
+    if (!APIAction::InitializeTable(db)) return false;
+    if (!BlockedAction::InitializeTable(db)) return false;
+    return true;
+  }
+
+  // Called by ActivityDatabase just before the ActivityDatabase object is
+  // deleted.  The database will make no further callbacks after invoking this
+  // method, so it is an appropriate time for the policy to delete itself.
+  virtual void OnDatabaseClose() OVERRIDE {
+    delete this;
+  }
+};
+
 class ActivityDatabaseTest : public ChromeRenderViewHostTestHarness {
  protected:
   virtual void SetUp() OVERRIDE {
@@ -58,9 +80,18 @@
     ChromeRenderViewHostTestHarness::TearDown();
   }
 
+  // Creates a test database and initializes the table schema.
+  ActivityDatabase* OpenDatabase(const base::FilePath& db_file) const {
+    ActivityDatabase* activity_db =
+        new ActivityDatabase(new ActivityDatabaseTestPolicy());
+    activity_db->Init(db_file);
+    CHECK(activity_db->is_db_valid());
+    return activity_db;
+  }
+
  private:
 #if defined OS_CHROMEOS
-  chromeos::ScopedStubCrosEnabler stub_cros_enabler_;
+  chromeos::ScopedStubNetworkLibraryEnabler stub_network_library_enabler_;
   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
   chromeos::ScopedTestCrosSettings test_cros_settings_;
   scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
@@ -68,18 +99,15 @@
 
 };
 
-
 // Check that the database is initialized properly.
 TEST_F(ActivityDatabaseTest, Init) {
   base::ScopedTempDir temp_dir;
   base::FilePath db_file;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   db_file = temp_dir.path().AppendASCII("ActivityInit.db");
-  base::Delete(db_file, false);
+  base::DeleteFile(db_file, false);
 
-  ActivityDatabase* activity_db = new ActivityDatabase();
-  activity_db->Init(db_file);
-  ASSERT_TRUE(activity_db->is_db_valid());
+  ActivityDatabase* activity_db = OpenDatabase(db_file);
   activity_db->Close();
 
   sql::Connection db;
@@ -96,12 +124,10 @@
   base::FilePath db_file;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   db_file = temp_dir.path().AppendASCII("ActivityRecord.db");
-  base::Delete(db_file, false);
+  base::DeleteFile(db_file, false);
 
-  ActivityDatabase* activity_db = new ActivityDatabase();
-  activity_db->Init(db_file);
+  ActivityDatabase* activity_db = OpenDatabase(db_file);
   activity_db->SetBatchModeForTesting(false);
-  ASSERT_TRUE(activity_db->is_db_valid());
   scoped_refptr<APIAction> action = new APIAction(
       "punky",
       base::Time::Now(),
@@ -132,12 +158,10 @@
   base::FilePath db_file;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   db_file = temp_dir.path().AppendASCII("ActivityRecord.db");
-  base::Delete(db_file, false);
+  base::DeleteFile(db_file, false);
 
-  ActivityDatabase* activity_db = new ActivityDatabase();
-  activity_db->Init(db_file);
+  ActivityDatabase* activity_db = OpenDatabase(db_file);
   activity_db->SetBatchModeForTesting(false);
-  ASSERT_TRUE(activity_db->is_db_valid());
   scoped_refptr<DOMAction> action = new DOMAction(
       "punky",
       base::Time::Now(),
@@ -177,11 +201,9 @@
   base::FilePath db_file;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   db_file = temp_dir.path().AppendASCII("ActivityRecord.db");
-  base::Delete(db_file, false);
+  base::DeleteFile(db_file, false);
 
-  ActivityDatabase* activity_db = new ActivityDatabase();
-  activity_db->Init(db_file);
-  ASSERT_TRUE(activity_db->is_db_valid());
+  ActivityDatabase* activity_db = OpenDatabase(db_file);
   scoped_refptr<BlockedAction> action = new BlockedAction(
       "punky",
       base::Time::Now(),
@@ -213,7 +235,7 @@
   base::FilePath db_file;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   db_file = temp_dir.path().AppendASCII("ActivityRecord.db");
-  base::Delete(db_file, false);
+  base::DeleteFile(db_file, false);
 
   // Use a mock clock to ensure that events are not recorded on the wrong day
   // when the test is run close to local midnight.
@@ -222,9 +244,7 @@
                     base::TimeDelta::FromHours(12));
 
   // Record some actions
-  ActivityDatabase* activity_db = new ActivityDatabase();
-  activity_db->Init(db_file);
-  ASSERT_TRUE(activity_db->is_db_valid());
+  ActivityDatabase* activity_db = OpenDatabase(db_file);
   scoped_refptr<APIAction> api_action = new APIAction(
       "punky",
       mock_clock.Now() - base::TimeDelta::FromMinutes(40),
@@ -273,7 +293,7 @@
   base::FilePath db_file;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   db_file = temp_dir.path().AppendASCII("ActivityRecord.db");
-  base::Delete(db_file, false);
+  base::DeleteFile(db_file, false);
 
   // Use a mock clock to ensure that events are not recorded on the wrong day
   // when the test is run close to local midnight.
@@ -282,9 +302,7 @@
                     base::TimeDelta::FromHours(12));
 
   // Record some actions
-  ActivityDatabase* activity_db = new ActivityDatabase();
-  activity_db->Init(db_file);
-  ASSERT_TRUE(activity_db->is_db_valid());
+  ActivityDatabase* activity_db = OpenDatabase(db_file);
   scoped_refptr<APIAction> api_action = new APIAction(
       "punky",
       mock_clock.Now() - base::TimeDelta::FromDays(3)
@@ -343,7 +361,7 @@
   base::FilePath db_file;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   db_file = temp_dir.path().AppendASCII("ActivityRecord.db");
-  base::Delete(db_file, false);
+  base::DeleteFile(db_file, false);
 
   // Use a mock clock to ensure that events are not recorded on the wrong day
   // when the test is run close to local midnight.
@@ -352,11 +370,9 @@
                     base::TimeDelta::FromHours(12));
 
   // Record some actions
-  ActivityDatabase* activity_db = new ActivityDatabase();
-  activity_db->Init(db_file);
+  ActivityDatabase* activity_db = OpenDatabase(db_file);
   activity_db->SetBatchModeForTesting(false);
   activity_db->SetClockForTesting(&mock_clock);
-  ASSERT_TRUE(activity_db->is_db_valid());
   scoped_refptr<APIAction> api_action = new APIAction(
       "punky",
       mock_clock.Now() - base::TimeDelta::FromMinutes(40),
@@ -377,7 +393,7 @@
   base::FilePath db_file;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   db_file = temp_dir.path().AppendASCII("ActivityRecord.db");
-  base::Delete(db_file, false);
+  base::DeleteFile(db_file, false);
 
   // Use a mock clock to set the time, and a special timer to control the
   // timing and skip ahead in time.
@@ -386,11 +402,9 @@
                     base::TimeDelta::FromHours(11));
 
   // Record some actions
-  ActivityDatabase* activity_db = new ActivityDatabase();
-  activity_db->Init(db_file);
+  ActivityDatabase* activity_db = OpenDatabase(db_file);
   activity_db->SetBatchModeForTesting(true);
   activity_db->SetClockForTesting(&mock_clock);
-  ASSERT_TRUE(activity_db->is_db_valid());
   scoped_refptr<APIAction> api_action = new APIAction(
       "punky",
       mock_clock.Now() - base::TimeDelta::FromMinutes(40),
@@ -421,9 +435,10 @@
   base::FilePath db_file;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   db_file = temp_dir.path().AppendASCII("ActivityRecord.db");
-  base::Delete(db_file, false);
+  base::DeleteFile(db_file, false);
 
-  ActivityDatabase* activity_db = new ActivityDatabase();
+  ActivityDatabase* activity_db =
+      new ActivityDatabase(new ActivityDatabaseTestPolicy());
   scoped_refptr<APIAction> action = new APIAction(
       "punky",
       base::Time::Now(),
@@ -436,4 +451,3 @@
 }
 
 }  // namespace extensions
-
diff --git a/chrome/browser/extensions/activity_log/activity_log.cc b/chrome/browser/extensions/activity_log/activity_log.cc
index 278a157..7eac24f 100644
--- a/chrome/browser/extensions/activity_log/activity_log.cc
+++ b/chrome/browser/extensions/activity_log/activity_log.cc
@@ -26,8 +26,8 @@
 #include "chrome/common/extensions/extension.h"
 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
 #include "third_party/re2/re2/re2.h"
+#include "url/gurl.h"
 
 namespace {
 
@@ -130,8 +130,19 @@
 // ActivityLog
 
 void ActivityLog::SetDefaultPolicy(ActivityLogPolicy::PolicyType policy_type) {
-  if (policy_type != policy_type_ && IsLogEnabled()) {
-    delete policy_;
+  // Can't use IsLogEnabled() here because this is called from inside Init.
+  if (policy_type != policy_type_ && enabled_) {
+    // Deleting the old policy takes place asynchronously, on the database
+    // thread.  Initializing a new policy below similarly happens
+    // asynchronously.  Since the two operations are both queued for the
+    // database, the queue ordering should ensure that the deletion completes
+    // before database initialization occurs.
+    //
+    // However, changing policies at runtime is still not recommended, and
+    // likely only should be done for unit tests.
+    if (policy_)
+      policy_->Close();
+
     switch (policy_type) {
       case ActivityLogPolicy::POLICY_FULLSTREAM:
         policy_ = new FullStreamUIPolicy(profile_);
@@ -140,8 +151,7 @@
         policy_ = new StreamWithoutArgsUIPolicy(profile_);
         break;
       default:
-        if (testing_mode_)
-          LOG(INFO) << "Calling SetDefaultPolicy with invalid policy type?";
+        NOTREACHED();
     }
     policy_type_ = policy_type;
   }
@@ -152,11 +162,16 @@
     : policy_(NULL),
       policy_type_(ActivityLogPolicy::POLICY_INVALID),
       profile_(profile),
-      first_time_checking_(true),
+      enabled_(false),
+      initialized_(false),
+      policy_chosen_(false),
       testing_mode_(false),
       has_threads_(true),
       tracker_(NULL) {
-  enabled_ = IsLogEnabledOnAnyProfile();
+  // This controls whether logging statements are printed, which policy is set,
+  // etc.
+  testing_mode_ = CommandLine::ForCurrentProcess()->HasSwitch(
+    switches::kEnableExtensionActivityLogTesting);
 
   // Check that the right threads exist. If not, we shouldn't try to do things
   // that require them.
@@ -165,63 +180,66 @@
       !BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
     LOG(ERROR) << "Missing threads, disabling Activity Logging!";
     has_threads_ = false;
+  } else {
+    enabled_ = IsLogEnabledOnAnyProfile();
+    ExtensionSystem::Get(profile_)->ready().Post(
+      FROM_HERE, base::Bind(&ActivityLog::Init, base::Unretained(this)));
   }
 
   observers_ = new ObserverListThreadSafe<Observer>;
 }
 
-void ActivityLog::Shutdown() {
-  if (!first_time_checking_ && tracker_) tracker_->RemoveObserver(this);
-}
-
-ActivityLog::~ActivityLog() {
-  delete policy_;
-}
-
-// We can't register for the InstallTrackerFactory events or talk to the
-// extension service in the constructor, so we do that here the first time
-// this is called (as identified by first_time_checking_).
-bool ActivityLog::IsLogEnabled() {
-  if (!first_time_checking_) return enabled_;
-  if (!has_threads_) return false;
-  tracker_ = InstallTrackerFactory::GetForProfile(profile_);
-  tracker_->AddObserver(this);
+void ActivityLog::Init() {
+  DCHECK(has_threads_);
+  DCHECK(!initialized_);
   const Extension* whitelisted_extension = ExtensionSystem::Get(profile_)->
       extension_service()->GetExtensionById(kActivityLogExtensionId, false);
   if (whitelisted_extension) {
     enabled_ = true;
     LogIsEnabled::GetInstance()->SetProfileEnabled(true);
   }
-  first_time_checking_ = false;
+  tracker_ = InstallTrackerFactory::GetForProfile(profile_);
+  tracker_->AddObserver(this);
+  ChooseDefaultPolicy();
+  initialized_ = true;
+}
+
+void ActivityLog::ChooseDefaultPolicy() {
+  if (policy_chosen_ || !enabled_) return;
+  if (testing_mode_)
+    SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM);
+  else
+    SetDefaultPolicy(ActivityLogPolicy::POLICY_NOARGS);
+}
+
+void ActivityLog::Shutdown() {
+  if (tracker_) tracker_->RemoveObserver(this);
+}
+
+ActivityLog::~ActivityLog() {
+  if (policy_)
+    policy_->Close();
+}
+
+bool ActivityLog::IsLogEnabled() {
+  if (!has_threads_ || !initialized_) return false;
   return enabled_;
 }
 
-void ActivityLog::OnExtensionInstalled(const Extension* extension) {
+void ActivityLog::OnExtensionLoaded(const Extension* extension) {
   if (extension->id() != kActivityLogExtensionId) return;
   enabled_ = true;
   LogIsEnabled::GetInstance()->SetProfileEnabled(true);
+  ChooseDefaultPolicy();
 }
 
-void ActivityLog::OnExtensionUninstalled(const Extension* extension) {
+void ActivityLog::OnExtensionUnloaded(const Extension* extension) {
   if (extension->id() != kActivityLogExtensionId) return;
   if (!CommandLine::ForCurrentProcess()->HasSwitch(
       switches::kEnableExtensionActivityLogging))
     enabled_ = false;
 }
 
-// Counter-intuitively, OnExtensionInstalled is also called when an extension
-// is reenabled.
-void ActivityLog::OnExtensionDisabled(const Extension* extension) {
-  if (extension->id() != kActivityLogExtensionId) return;
-  if (!CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kEnableExtensionActivityLogging))
-    enabled_ = false;
-}
-
-void ActivityLog::SetArgumentLoggingForTesting(bool log_arguments) {
-  testing_mode_ = log_arguments;
-}
-
 // static
 ActivityLog* ActivityLog::GetInstance(Profile* profile) {
   return ActivityLogFactory::GetForProfile(profile);
diff --git a/chrome/browser/extensions/activity_log/activity_log.h b/chrome/browser/extensions/activity_log/activity_log.h
index fd9b6e2..2a4e491 100644
--- a/chrome/browser/extensions/activity_log/activity_log.h
+++ b/chrome/browser/extensions/activity_log/activity_log.h
@@ -121,11 +121,13 @@
   // We keep track of whether the whitelisted extension is installed; if it is,
   // we want to recompute whether to have logging enabled.
   virtual void OnExtensionInstalled(
+      const extensions::Extension* extension) OVERRIDE {}
+  virtual void OnExtensionLoaded(
+      const extensions::Extension* extension) OVERRIDE;
+  virtual void OnExtensionUnloaded(
       const extensions::Extension* extension) OVERRIDE;
   virtual void OnExtensionUninstalled(
-      const extensions::Extension* extension) OVERRIDE;
-  virtual void OnExtensionDisabled(
-      const extensions::Extension* extension) OVERRIDE;
+      const extensions::Extension* extension) OVERRIDE {}
   // We also have to list the following from InstallObserver.
   virtual void OnBeginExtensionInstall(const std::string& extension_id,
                                        const std::string& extension_name,
@@ -140,29 +142,21 @@
       const std::string& extension_id) OVERRIDE {}
   virtual void OnShutdown() OVERRIDE {}
 
-  // For unit tests only.
-  // TODO(felt) In the future, when we'll have multiple policies, it might
-  // be needed to rename the argument.
-  void SetArgumentLoggingForTesting(bool log_arguments);
-  static void RecomputeLoggingIsEnabled(bool profile_enabled);
-
   // BrowserContextKeyedService
   virtual void Shutdown() OVERRIDE;
 
-  // At the moment, ActivityLog will use only one policy for summarization
-  // (POLICY_NOARGS by default).  This static member function can be used
-  // to change the default type, but has to be called before the first
-  // GetInstance call.
-  // TODO(dbabic,felt) ActivityLog should support multiple policies at the
-  // same time, so this will need to be changed later.
-  void SetDefaultPolicy(ActivityLogPolicy::PolicyType policy_type);
-
  private:
   friend class ActivityLogFactory;
+  friend class ActivityLogTest;
+  friend class RenderViewActivityLogTest;
 
   explicit ActivityLog(Profile* profile);
   virtual ~ActivityLog();
 
+  // Some setup needs to wait until after the ExtensionSystem/ExtensionService
+  // are done with their own setup.
+  void Init();
+
   // We log callbacks and API calls very similarly, so we handle them the same
   // way internally.
   void LogAPIActionInternal(
@@ -180,20 +174,32 @@
       int32 page_id,
       const GURL& on_url) OVERRIDE;
 
+  // For unit tests only. Does not call Init again!
+  // Sets whether logging should be enabled for the whole current profile.
+  static void RecomputeLoggingIsEnabled(bool profile_enabled);
+
+  // At the moment, ActivityLog will use only one policy for summarization.
+  // These methods are used to choose and set the most appropriate policy.
+  void ChooseDefaultPolicy();
+  void SetDefaultPolicy(ActivityLogPolicy::PolicyType policy_type);
+
   typedef ObserverListThreadSafe<Observer> ObserverList;
   scoped_refptr<ObserverList> observers_;
 
   // The policy object takes care of data summarization, compression, and
-  // logging
+  // logging.  The policy object is owned by the ActivityLog, but this cannot
+  // be a scoped_ptr since some cleanup work must happen on the database
+  // thread.  Calling policy_->Close() will free the object; see the comments
+  // on the ActivityDatabase class for full details.
   extensions::ActivityLogPolicy* policy_;
 
   // TODO(dbabic,felt) change this into a list of policy types later.
   ActivityLogPolicy::PolicyType policy_type_;
 
   Profile* profile_;
-  // TODO(felt) These two flags could use a comment.
-  bool enabled_;
-  bool first_time_checking_;
+  bool enabled_;  // Whether logging is currently enabled.
+  bool initialized_;  // Whether Init() has already been called.
+  bool policy_chosen_;  // Whether we've already set the default policy.
   // testing_mode_ controls whether to log API call arguments. By default, we
   // don't log most arguments to avoid saving too much data. In testing mode,
   // argument collection is enabled. We also whitelist some arguments for
@@ -205,6 +211,8 @@
   // ActivityDatabase to prevent things from exploding.
   bool has_threads_;
 
+  // Used to track whether the whitelisted extension is installed. If it's
+  // added or removed, enabled_ may change.
   InstallTracker* tracker_;
 
   DISALLOW_COPY_AND_ASSIGN(ActivityLog);
diff --git a/chrome/browser/extensions/activity_log/activity_log_browsertest.cc b/chrome/browser/extensions/activity_log/activity_log_browsertest.cc
index 3368730..481e5cb 100644
--- a/chrome/browser/extensions/activity_log/activity_log_browsertest.cc
+++ b/chrome/browser/extensions/activity_log/activity_log_browsertest.cc
@@ -19,14 +19,11 @@
 
 namespace extensions {
 
-// Used to fire all of the listeners on the test buttons.
-static const char kScriptBeginClickingTestButtons[] =
-    "(function() {"
-    "  setRunningAsRobot();"
-    "  beginClickingTestButtons();"
-    "})();";
+// Only the prerender tests are in this file. To add tests for activity
+// logging please see:
+//    chrome/test/data/extensions/api_test/activity_log_private/README
 
-class ActivityLogExtensionTest : public ExtensionApiTest {
+class ActivityLogPrerenderTest : public ExtensionApiTest {
  protected:
   // Make sure the activity log is turned on.
   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
@@ -36,24 +33,6 @@
     command_line->AppendSwitchASCII(switches::kPrerenderMode,
                                     switches::kPrerenderModeSwitchValueEnabled);
   }
-  // Start the test server, load the activity log extension, and navigate
-  // the browser to the options page of the extension.
-  TabStripModel* StartEmbeddedTestServerAndInitialize() {
-    host_resolver()->AddRule("*", "127.0.0.1");
-    StartEmbeddedTestServer();
-
-    // Get the extension (chrome/test/data/extensions/activity_log)
-    const extensions::Extension* ext =
-        LoadExtension(test_data_dir_.AppendASCII("activity_log"));
-    CHECK(ext);
-
-    // Open up the Options page.
-    ui_test_utils::NavigateToURL(
-        browser(),
-        GURL("chrome-extension://" + ext->id() + "/options.html"));
-    TabStripModel* tab_strip = browser()->tab_strip_model();
-    return tab_strip;
-  }
 
   static void Prerender_Arguments(int port,
       scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
@@ -74,61 +53,7 @@
   }
 };
 
-#if defined(OS_WIN)
-// TODO(ataly): test flaky on windows. See Bug: crbug.com/245594
-#define MAYBE_ChromeEndToEnd DISABLED_ChromeEndToEnd
-#else
-#define MAYBE_ChromeEndToEnd ChromeEndToEnd
-#endif
-
-IN_PROC_BROWSER_TEST_F(ActivityLogExtensionTest, MAYBE_ChromeEndToEnd) {
-  TabStripModel* tab_strip = StartEmbeddedTestServerAndInitialize();
-  ResultCatcher catcher;
-  // Set the default URL so that is has the correct port number.
-  std::string url_setting_script = base::StringPrintf(
-      "defaultUrl = \'http://www.google.com:%d\';",
-      embedded_test_server()->port());
-  ASSERT_TRUE(content::ExecuteScript(tab_strip->GetActiveWebContents(),
-                                     url_setting_script));
-  // Set the test buttons array
-  std::string test_buttons_setting_script =
-      "setTestButtons(document.getElementsByName('chromeButton'))";
-  ASSERT_TRUE(content::ExecuteScript(tab_strip->GetActiveWebContents(),
-                                     test_buttons_setting_script));
-  // Run the test by firing all the buttons.  Wait until completion.
-  ASSERT_TRUE(content::ExecuteScript(tab_strip->GetActiveWebContents(),
-                                     kScriptBeginClickingTestButtons));
-  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
-}
-
-#if defined(OS_WIN) || defined(OS_MACOSX)
-// TODO(ataly): test flaky on windows and Mac. See Bug: crbug.com/245594
-#define MAYBE_DOMEndToEnd DISABLED_DOMEndToEnd
-#else
-#define MAYBE_DOMEndToEnd DOMEndToEnd
-#endif
-
-IN_PROC_BROWSER_TEST_F(ActivityLogExtensionTest, MAYBE_DOMEndToEnd) {
-  TabStripModel* tab_strip = StartEmbeddedTestServerAndInitialize();
-  ResultCatcher catcher;
-  // Set the default URL so that is has the correct port number.
-  std::string url_setting_script = base::StringPrintf(
-      "defaultUrl = \'http://www.google.com:%d\';",
-      embedded_test_server()->port());
-  ASSERT_TRUE(content::ExecuteScript(tab_strip->GetActiveWebContents(),
-                                     url_setting_script));
-  // Set the test buttons array
-  std::string test_buttons_setting_script =
-      "setTestButtons(document.getElementsByName('domButton'))";
-  ASSERT_TRUE(content::ExecuteScript(tab_strip->GetActiveWebContents(),
-                                     test_buttons_setting_script));
-  // Run the test by firing all the buttons.  Wait until completion.
-  ASSERT_TRUE(content::ExecuteScript(tab_strip->GetActiveWebContents(),
-                                     kScriptBeginClickingTestButtons));
-  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
-}
-
-IN_PROC_BROWSER_TEST_F(ActivityLogExtensionTest, ExtensionPrerender) {
+IN_PROC_BROWSER_TEST_F(ActivityLogPrerenderTest, TestScriptInjected) {
   host_resolver()->AddRule("*", "127.0.0.1");
   StartEmbeddedTestServer();
   int port = embedded_test_server()->port();
@@ -139,7 +64,6 @@
   ASSERT_TRUE(ext);
 
   ActivityLog* activity_log = ActivityLog::GetInstance(profile());
-  activity_log->SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM);
   ASSERT_TRUE(activity_log);
 
   //Disable rate limiting in PrerenderManager
@@ -174,7 +98,7 @@
 
   activity_log->GetActions(
       ext->id(), 0, base::Bind(
-          ActivityLogExtensionTest::Prerender_Arguments, port));
+          ActivityLogPrerenderTest::Prerender_Arguments, port));
 
   // Allow invocation of Prerender_Arguments
   base::MessageLoop::current()->Run();
diff --git a/chrome/browser/extensions/activity_log/activity_log_policy.cc b/chrome/browser/extensions/activity_log/activity_log_policy.cc
index 528f260..157a9ea 100644
--- a/chrome/browser/extensions/activity_log/activity_log_policy.cc
+++ b/chrome/browser/extensions/activity_log/activity_log_policy.cc
@@ -9,25 +9,16 @@
 #include "chrome/browser/extensions/activity_log/activity_log_policy.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/extensions/extension.h"
-#include "googleurl/src/gurl.h"
-
-using base::TimeDelta;
+#include "url/gurl.h"
 
 namespace extensions {
 
 ActivityLogPolicy::ActivityLogPolicy(Profile* profile) {
   CHECK(profile && "Null ptr dereference");
   profile_base_path_ = profile->GetPath();
-  timer_.Start(FROM_HERE, TimeDelta::FromMinutes(2), this,
-               &ActivityLogPolicy::SaveState);
 }
 
 ActivityLogPolicy::~ActivityLogPolicy() {
-  timer_.Stop();
-}
-
-void ActivityLogPolicy::SetSaveStateOnRequestOnly() {
-  timer_.Stop();
 }
 
 std::string ActivityLogPolicy::GetKey(KeyType) const {
diff --git a/chrome/browser/extensions/activity_log/activity_log_policy.h b/chrome/browser/extensions/activity_log/activity_log_policy.h
index 797cba5..98bc4ba 100644
--- a/chrome/browser/extensions/activity_log/activity_log_policy.h
+++ b/chrome/browser/extensions/activity_log/activity_log_policy.h
@@ -13,11 +13,10 @@
 #include "base/callback.h"
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/timer/timer.h"
 #include "base/values.h"
 #include "chrome/browser/extensions/activity_log/activity_actions.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Profile;
 class GURL;
@@ -72,7 +71,11 @@
   // TODO(felt,dbabic)  Since only ReadData uses thread_id, it would be
   // cleaner to pass thread_id as a param of ReadData directly.
   explicit ActivityLogPolicy(Profile* profile);
-  virtual ~ActivityLogPolicy();
+
+  // Instead of a public destructor, ActivityLogPolicy objects have a Close()
+  // method which will cause the object to be deleted (but may do so on another
+  // thread or in a deferred fashion).
+  virtual void Close() = 0;
 
   // Updates the internal state of the model summarizing actions and possibly
   // writes to the database.  Implements the default policy storing internal
@@ -85,11 +88,6 @@
       const base::ListValue* args,                // arguments
       const base::DictionaryValue* details) = 0;  // details
 
-  // Saves the internal state in the memory into the database.  Must be
-  // written so as to be thread-safe, as it can be called from a timer that
-  // saves state periodically and explicitly.
-  virtual void SaveState() { }
-
   // Pass the parameters as a set of key-value pairs and return data back via
   // a callback passing results as a set of key-value pairs.  The keys are
   // policy-specific.
@@ -108,13 +106,13 @@
           <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback)
       const {}
 
-  // For testing purposes --- disables periodic state saving, making the
-  // behavior reproducible.
-  virtual void SetSaveStateOnRequestOnly();
-
   virtual std::string GetKey(KeyType key_id) const;
 
  protected:
+  // An ActivityLogPolicy is not directly destroyed.  Instead, call Close()
+  // which will cause the object to be deleted when it is safe.
+  virtual ~ActivityLogPolicy();
+
   // The Schedule methods dispatch the calls to the database on a
   // separate thread. We dispatch to the UI thread if the DB thread doesn't
   // exist, which should only happen in tests where there is no DB thread.
@@ -144,7 +142,9 @@
   }
 
   base::FilePath profile_base_path_;
-  base::RepeatingTimer<ActivityLogPolicy> timer_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ActivityLogPolicy);
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/activity_log/activity_log_unittest.cc b/chrome/browser/extensions/activity_log/activity_log_unittest.cc
index 01bdcd1..a35ae26 100644
--- a/chrome/browser/extensions/activity_log/activity_log_unittest.cc
+++ b/chrome/browser/extensions/activity_log/activity_log_unittest.cc
@@ -38,37 +38,38 @@
 
 namespace extensions {
 
-class ActivityLogTest : public testing::Test {
+class ActivityLogTest : public ChromeRenderViewHostTestHarness {
  protected:
-  ActivityLogTest()
-      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
-        saved_cmdline_(CommandLine::NO_PROGRAM) {
+  ActivityLogTest() : saved_cmdline_(CommandLine::NO_PROGRAM) {}
+
+  virtual void SetUp() OVERRIDE {
+    ChromeRenderViewHostTestHarness::SetUp();
 #if defined OS_CHROMEOS
     test_user_manager_.reset(new chromeos::ScopedTestUserManager());
 #endif
     CommandLine command_line(CommandLine::NO_PROGRAM);
     saved_cmdline_ = *CommandLine::ForCurrentProcess();
-    profile_.reset(new TestingProfile());
     CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kEnableExtensionActivityLogging);
     CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kEnableExtensionActivityLogTesting);
+    ActivityLog::RecomputeLoggingIsEnabled(true);  // Logging now enabled.
     extension_service_ = static_cast<TestExtensionSystem*>(
-        ExtensionSystem::Get(profile_.get()))->CreateExtensionService
+        ExtensionSystem::Get(profile()))->CreateExtensionService
             (&command_line, base::FilePath(), false);
-    ActivityLog::RecomputeLoggingIsEnabled(false);
+    ActivityLog::GetInstance(profile())->Init();
+    base::RunLoop().RunUntilIdle();
   }
 
-  virtual ~ActivityLogTest() {
+  virtual void TearDown() OVERRIDE {
 #if defined OS_CHROMEOS
     test_user_manager_.reset();
 #endif
     base::RunLoop().RunUntilIdle();
-    profile_.reset(NULL);
-    base::RunLoop().RunUntilIdle();
     // Restore the original command line and undo the affects of SetUp().
     *CommandLine::ForCurrentProcess() = saved_cmdline_;
-    ActivityLog::RecomputeLoggingIsEnabled(false);
+    ActivityLog::RecomputeLoggingIsEnabled(false);  // Logging now disabled.
+    ChromeRenderViewHostTestHarness::TearDown();
   }
 
   static void RetrieveActions_LogAndFetchActions(
@@ -109,53 +110,12 @@
     ASSERT_EQ(args, last->PrintForDebug());
   }
 
- protected:
-  scoped_ptr<TestingProfile> profile_;
-  ExtensionService* extension_service_;
-
-  content::TestBrowserThreadBundle thread_bundle_;
-
-  // Used to preserve a copy of the original command line.
-  // The test framework will do this itself as well. However, by then,
-  // it is too late to call ActivityLog::RecomputeLoggingIsEnabled() in
-  // TearDown().
-  CommandLine saved_cmdline_;
-
-#if defined OS_CHROMEOS
-  chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
-  chromeos::ScopedTestCrosSettings test_cros_settings_;
-  scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
-#endif
-};
-
-class RenderViewActivityLogTest : public ChromeRenderViewHostTestHarness {
- protected:
-  RenderViewActivityLogTest() : saved_cmdline_(CommandLine::NO_PROGRAM) {}
-
-  virtual void SetUp() OVERRIDE {
-    ChromeRenderViewHostTestHarness::SetUp();
-#if defined OS_CHROMEOS
-    test_user_manager_.reset(new chromeos::ScopedTestUserManager());
-#endif
-    CommandLine command_line(CommandLine::NO_PROGRAM);
-    saved_cmdline_ = *CommandLine::ForCurrentProcess();
-    CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kEnableExtensionActivityLogging);
-    CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kEnableExtensionActivityLogTesting);
-    ActivityLog::RecomputeLoggingIsEnabled(false);
-    extension_service_ = static_cast<TestExtensionSystem*>(
-        ExtensionSystem::Get(profile()))->CreateExtensionService(
-            &command_line, base::FilePath(), false);
-  }
-
-  virtual void TearDown() OVERRIDE {
-#if defined OS_CHROMEOS
-    test_user_manager_.reset();
-#endif
-    ChromeRenderViewHostTestHarness::TearDown();
-    *CommandLine::ForCurrentProcess() = saved_cmdline_;
-    ActivityLog::RecomputeLoggingIsEnabled(false);
+  void SetPolicy(bool log_arguments) {
+    ActivityLog* activity_log = ActivityLog::GetInstance(profile());
+    if (log_arguments)
+      activity_log->SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM);
+    else
+      activity_log->SetDefaultPolicy(ActivityLogPolicy::POLICY_NOARGS);
   }
 
   static void Arguments_Prerender(
@@ -174,7 +134,6 @@
   // TearDown().
   CommandLine saved_cmdline_;
 
- private:
 #if defined OS_CHROMEOS
   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
   chromeos::ScopedTestCrosSettings test_cros_settings_;
@@ -187,7 +146,7 @@
 }
 
 TEST_F(ActivityLogTest, Construct) {
-  ActivityLog* activity_log = ActivityLog::GetInstance(profile_.get());
+  ActivityLog* activity_log = ActivityLog::GetInstance(profile());
   scoped_ptr<base::ListValue> args(new base::ListValue());
   ASSERT_TRUE(activity_log->IsLogEnabled());
   activity_log->LogAPIAction(
@@ -195,7 +154,7 @@
 }
 
 TEST_F(ActivityLogTest, LogAndFetchActions) {
-  ActivityLog* activity_log = ActivityLog::GetInstance(profile_.get());
+  ActivityLog* activity_log = ActivityLog::GetInstance(profile());
   scoped_ptr<base::ListValue> args(new base::ListValue());
   ASSERT_TRUE(activity_log->IsLogEnabled());
 
@@ -216,7 +175,7 @@
 }
 
 TEST_F(ActivityLogTest, LogAndFetchPathActions) {
-  ActivityLog* activity_log = ActivityLog::GetInstance(profile_.get());
+  ActivityLog* activity_log = ActivityLog::GetInstance(profile());
   scoped_ptr<base::ListValue> args(new base::ListValue());
   ASSERT_TRUE(activity_log->IsLogEnabled());
 
@@ -234,10 +193,9 @@
 }
 
 TEST_F(ActivityLogTest, LogWithoutArguments) {
-  ActivityLog* activity_log = ActivityLog::GetInstance(profile_.get());
-  activity_log->SetArgumentLoggingForTesting(false);
+  ActivityLog* activity_log = ActivityLog::GetInstance(profile());
   ASSERT_TRUE(activity_log->IsLogEnabled());
-  activity_log->SetDefaultPolicy(ActivityLogPolicy::POLICY_NOARGS);
+  SetPolicy(false);
   scoped_ptr<base::ListValue> args(new base::ListValue());
   args->Set(0, new base::StringValue("hello"));
   args->Set(1, new base::StringValue("world"));
@@ -245,11 +203,11 @@
       kExtensionId, std::string("tabs.testMethod"), args.get(), std::string());
   activity_log->GetActions(
       kExtensionId, 0, base::Bind(ActivityLogTest::Arguments_Missing));
+  SetPolicy(true);
 }
 
 TEST_F(ActivityLogTest, LogWithArguments) {
-  ActivityLog* activity_log = ActivityLog::GetInstance(profile_.get());
-  activity_log->SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM);
+  ActivityLog* activity_log = ActivityLog::GetInstance(profile());
   ASSERT_TRUE(activity_log->IsLogEnabled());
 
   scoped_ptr<base::ListValue> args(new base::ListValue());
@@ -263,7 +221,7 @@
       kExtensionId, 0, base::Bind(ActivityLogTest::Arguments_Present));
 }
 
-TEST_F(RenderViewActivityLogTest, LogPrerender) {
+TEST_F(ActivityLogTest, LogPrerender) {
   scoped_refptr<const Extension> extension =
       ExtensionBuilder()
           .SetManifest(DictionaryBuilder()
@@ -273,7 +231,6 @@
           .Build();
   extension_service_->AddExtension(extension.get());
   ActivityLog* activity_log = ActivityLog::GetInstance(profile());
-  activity_log->SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM);
   ASSERT_TRUE(activity_log->IsLogEnabled());
   GURL url("http://www.google.com");
 
@@ -301,8 +258,7 @@
       OnScriptsExecuted(contents, executing_scripts, 0, url);
 
   activity_log->GetActions(
-      extension->id(), 0, base::Bind(
-          RenderViewActivityLogTest::Arguments_Prerender));
+      extension->id(), 0, base::Bind(ActivityLogTest::Arguments_Prerender));
 
   prerender_manager->CancelAllPrerenders();
 }
diff --git a/chrome/browser/extensions/activity_log/api_actions.cc b/chrome/browser/extensions/activity_log/api_actions.cc
index 483d394..39ec099 100644
--- a/chrome/browser/extensions/activity_log/api_actions.cc
+++ b/chrome/browser/extensions/activity_log/api_actions.cc
@@ -9,9 +9,10 @@
 #include "chrome/browser/extensions/activity_log/api_actions.h"
 #include "chrome/browser/extensions/activity_log/api_name_constants.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
+#include "chrome/browser/ui/browser.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
@@ -20,16 +21,23 @@
 // Gets the URL for a given tab ID. Helper method for APIAction::LookupTabId.
 std::string GetURLForTabId(const int tab_id, Profile* profile) {
   content::WebContents* contents = NULL;
+  Browser* browser = NULL;
   bool found = ExtensionTabUtil::GetTabById(tab_id,
                                             profile,
-                                            false,  // no incognito URLs
-                                            NULL,
+                                            true,  // search incognito tabs too
+                                            &browser,
                                             NULL,
                                             &contents,
                                             NULL);
   if (found) {
-    GURL url = contents->GetURL();
-    return std::string(url.spec());
+    // Check whether the profile the tab was found in is a normal or incognito
+    // profile.
+    if (!browser->profile()->IsOffTheRecord()) {
+      GURL url = contents->GetURL();
+      return std::string(url.spec());
+    } else {
+      return std::string(extensions::APIAction::kIncognitoUrl);
+    }
   } else {
     return std::string();
   }
@@ -114,6 +122,12 @@
      "tabs.executeScript", "tabs.insertCSS" };
 const int APIAction::kSizeAlwaysLog = arraysize(kAlwaysLog);
 
+// A string used in place of the real URL when the URL is hidden because it is
+// in an incognito window.  Extension activity logs mentioning kIncognitoUrl
+// let the user know that an extension is manipulating incognito tabs without
+// recording specific data about the pages.
+const char* APIAction::kIncognitoUrl = "http://incognito/";
+
 APIAction::APIAction(const std::string& extension_id,
                      const base::Time& time,
                      const Type type,
diff --git a/chrome/browser/extensions/activity_log/api_actions.h b/chrome/browser/extensions/activity_log/api_actions.h
index 70a16a7..4cd3cb0 100644
--- a/chrome/browser/extensions/activity_log/api_actions.h
+++ b/chrome/browser/extensions/activity_log/api_actions.h
@@ -28,6 +28,8 @@
   static const char* kAlwaysLog[];
   static const int kSizeAlwaysLog;
 
+  static const char* kIncognitoUrl;
+
   // Create the database table for storing APIActions, or update the schema if
   // it is out of date.  Any existing data is preserved.
   static bool InitializeTable(sql::Connection* db);
diff --git a/chrome/browser/extensions/activity_log/dom_actions.h b/chrome/browser/extensions/activity_log/dom_actions.h
index 904def8..1eff74b 100644
--- a/chrome/browser/extensions/activity_log/dom_actions.h
+++ b/chrome/browser/extensions/activity_log/dom_actions.h
@@ -8,7 +8,7 @@
 #include "base/strings/string16.h"
 #include "chrome/browser/extensions/activity_log/activity_actions.h"
 #include "chrome/common/extensions/dom_action_types.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc b/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
index ddf56c7..554d201 100644
--- a/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
+++ b/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
@@ -15,8 +15,8 @@
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/extensions/dom_action_types.h"
 #include "chrome/common/extensions/extension.h"
-#include "googleurl/src/gurl.h"
 #include "sql/error_delegate_util.h"
+#include "url/gurl.h"
 
 using base::Callback;
 using base::FilePath;
@@ -43,13 +43,28 @@
 
 FullStreamUIPolicy::FullStreamUIPolicy(Profile* profile)
     : ActivityLogPolicy(profile) {
-  db_ = new ActivityDatabase();
+  db_ = new ActivityDatabase(this);
   FilePath database_name = profile_base_path_.Append(
       chrome::kExtensionActivityLogFilename);
   ScheduleAndForget(db_, &ActivityDatabase::Init, database_name);
 }
 
-FullStreamUIPolicy::~FullStreamUIPolicy() {
+bool FullStreamUIPolicy::OnDatabaseInit(sql::Connection* db) {
+  if (!DOMAction::InitializeTable(db))
+    return false;
+  if (!APIAction::InitializeTable(db))
+    return false;
+  if (!BlockedAction::InitializeTable(db))
+    return false;
+
+  return true;
+}
+
+void FullStreamUIPolicy::OnDatabaseClose() {
+  delete this;
+}
+
+void FullStreamUIPolicy::Close() {
   // The policy object should have never been created if there's no DB thread.
   DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB));
   ScheduleAndForget(db_, &ActivityDatabase::Close);
@@ -70,11 +85,6 @@
       callback);
 }
 
-void FullStreamUIPolicy::SetSaveStateOnRequestOnly() {
-  ScheduleAndForget(db_, &ActivityDatabase::SetBatchModeForTesting, false);
-  ActivityLogPolicy::SetSaveStateOnRequestOnly();
-}
-
 std::string FullStreamUIPolicy::GetKey(ActivityLogPolicy::KeyType key_ty) const
 {
   switch (key_ty) {
diff --git a/chrome/browser/extensions/activity_log/fullstream_ui_policy.h b/chrome/browser/extensions/activity_log/fullstream_ui_policy.h
index 88bb029..3b33963 100644
--- a/chrome/browser/extensions/activity_log/fullstream_ui_policy.h
+++ b/chrome/browser/extensions/activity_log/fullstream_ui_policy.h
@@ -7,31 +7,27 @@
 
 #include <string>
 #include <vector>
+#include "chrome/browser/extensions/activity_log/activity_database.h"
 #include "chrome/browser/extensions/activity_log/activity_log_policy.h"
 
 class GURL;
 
 namespace extensions {
 
-class ActivityDatabase;
-
 // A policy for logging the full stream of actions, including all arguments.
 // It's mostly intended to be used in testing and analysis.
-class FullStreamUIPolicy : public ActivityLogPolicy {
+class FullStreamUIPolicy : public ActivityLogPolicy,
+                           public ActivityDatabase::Delegate {
  public:
   // For more info about these member functions, see the super class.
   explicit FullStreamUIPolicy(Profile* profile);
 
-  virtual ~FullStreamUIPolicy();
-
   virtual void ProcessAction(ActionType action_type,
                              const std::string& extension_id,
                              const std::string& name, const GURL& gurl,
                              const base::ListValue* args,
                              const base::DictionaryValue* details) OVERRIDE;
 
-  virtual void SaveState() OVERRIDE {}
-
   // TODO(felt,dbabic) This is overly specific to FullStreamUIPolicy.
   // It assumes that the callback can return a sorted vector of actions.  Some
   // policies might not do that.  For instance, imagine a trivial policy that
@@ -44,12 +40,21 @@
           <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback)
       const OVERRIDE;
 
-  virtual void SetSaveStateOnRequestOnly() OVERRIDE;
-
   // Returns the actual key for a given key type
   virtual std::string GetKey(ActivityLogPolicy::KeyType key_id) const OVERRIDE;
 
+  virtual void Close() OVERRIDE;
+
  protected:
+  // Only ever run by OnDatabaseClose() below; see the comments on the
+  // ActivityDatabase class for an overall discussion of how cleanup works.
+  virtual ~FullStreamUIPolicy() {}
+
+  // The ActivityDatabase::PolicyDelegate interface.  These are always called
+  // from the database thread.
+  virtual bool OnDatabaseInit(sql::Connection* db) OVERRIDE;
+  virtual void OnDatabaseClose() OVERRIDE;
+
   // Concatenates arguments
   virtual std::string ProcessArguments(ActionType action_type,
                                        const std::string& name,
@@ -59,10 +64,8 @@
       base::DictionaryValue& details,
       std::string& details_string) const;
 
-  // We initialize this on the same thread as the ActivityLog and policy, but
-  // then subsequent operations occur on the DB thread. Instead of destructing
-  // the ActivityDatabase, we call its Close() method on the DB thread and it
-  // commits suicide.
+  // See the comments for the ActivityDatabase class for a discussion of how
+  // cleanup runs.
   ActivityDatabase* db_;
 };
 
diff --git a/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc b/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
index 19db206..0028eaa 100644
--- a/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
+++ b/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
@@ -89,7 +89,7 @@
 };
 
 TEST_F(FullStreamUIPolicyTest, Construct) {
-  scoped_ptr<ActivityLogPolicy> policy(new FullStreamUIPolicy(profile_.get()));
+  ActivityLogPolicy* policy = new FullStreamUIPolicy(profile_.get());
   scoped_refptr<const Extension> extension =
       ExtensionBuilder()
           .SetManifest(DictionaryBuilder()
@@ -101,10 +101,11 @@
   scoped_ptr<base::ListValue> args(new base::ListValue());
   policy->ProcessAction(ActivityLogPolicy::ACTION_API, extension->id(),
       std::string("tabs.testMethod"), GURL(), args.get(), NULL);
+  policy->Close();
 }
 
 TEST_F(FullStreamUIPolicyTest, LogAndFetchActions) {
-  scoped_ptr<ActivityLogPolicy> policy(new FullStreamUIPolicy(profile_.get()));
+  ActivityLogPolicy* policy = new FullStreamUIPolicy(profile_.get());
   scoped_refptr<const Extension> extension =
       ExtensionBuilder()
           .SetManifest(DictionaryBuilder()
@@ -124,10 +125,12 @@
                         gurl, args.get(), NULL);
   policy->ReadData(extension->id(), 0,
       base::Bind(FullStreamUIPolicyTest::RetrieveActions_LogAndFetchActions));
+
+  policy->Close();
 }
 
 TEST_F(FullStreamUIPolicyTest, LogWithArguments) {
-  scoped_ptr<ActivityLogPolicy> policy(new FullStreamUIPolicy(profile_.get()));
+  ActivityLogPolicy* policy = new FullStreamUIPolicy(profile_.get());
   scoped_refptr<const Extension> extension =
       ExtensionBuilder()
           .SetManifest(DictionaryBuilder()
@@ -143,6 +146,7 @@
       std::string("extension.connect"), GURL(), args.get(), NULL);
   policy->ReadData(extension->id(), 0,
       base::Bind(FullStreamUIPolicyTest::Arguments_Present));
+  policy->Close();
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc
index df279d1..a1c806d 100644
--- a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc
+++ b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc
@@ -89,8 +89,7 @@
 };
 
 TEST_F(StreamWithoutArgsUIPolicyTest, Construct) {
-  scoped_ptr<ActivityLogPolicy> policy(
-      new StreamWithoutArgsUIPolicy(profile_.get()));
+  ActivityLogPolicy* policy = new StreamWithoutArgsUIPolicy(profile_.get());
   scoped_refptr<const Extension> extension =
       ExtensionBuilder()
           .SetManifest(DictionaryBuilder()
@@ -102,11 +101,11 @@
   scoped_ptr<base::ListValue> args(new base::ListValue());
   policy->ProcessAction(ActivityLogPolicy::ACTION_API, extension->id(),
       std::string("tabs.testMethod"), GURL(), args.get(), NULL);
+  policy->Close();
 }
 
 TEST_F(StreamWithoutArgsUIPolicyTest, LogAndFetchActions) {
-  scoped_ptr<ActivityLogPolicy> policy(
-      new StreamWithoutArgsUIPolicy(profile_.get()));
+  ActivityLogPolicy* policy = new StreamWithoutArgsUIPolicy(profile_.get());
   scoped_refptr<const Extension> extension =
       ExtensionBuilder()
           .SetManifest(DictionaryBuilder()
@@ -127,11 +126,12 @@
   policy->ReadData(extension->id(), 0,
       base::Bind(
           StreamWithoutArgsUIPolicyTest::RetrieveActions_LogAndFetchActions));
+
+  policy->Close();
 }
 
 TEST_F(StreamWithoutArgsUIPolicyTest, LogWithoutArguments) {
-  scoped_ptr<ActivityLogPolicy> policy(
-      new StreamWithoutArgsUIPolicy(profile_.get()));
+  ActivityLogPolicy* policy = new StreamWithoutArgsUIPolicy(profile_.get());
   scoped_refptr<const Extension> extension =
       ExtensionBuilder()
           .SetManifest(DictionaryBuilder()
@@ -147,6 +147,7 @@
       std::string("tabs.testMethod"), GURL(), args.get(), NULL);
   policy->ReadData(extension->id(), 0,
       base::Bind(StreamWithoutArgsUIPolicyTest::Arguments_Missing));
+  policy->Close();
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/ad_view_browsertest.cc b/chrome/browser/extensions/ad_view_browsertest.cc
index 494ab6b..045293e 100644
--- a/chrome/browser/extensions/ad_view_browsertest.cc
+++ b/chrome/browser/extensions/ad_view_browsertest.cc
@@ -84,13 +84,8 @@
 // This test checks that 1) it is possible change the value of the "ad-network"
 // attribute of an <adview> element and 2) changing the value will reset the
 // "src" attribute.
-#if defined(OS_MACOSX)
-// Very flaky on MacOS 10.8 - crbug.com/253644.
-#define MAYBE_ChangeAdNetworkValue DISABLED_ChangeAdNetworkValue
-#else
-#define MAYBE_ChangeAdNetworkValue ChangeAdNetworkValue
-#endif
-IN_PROC_BROWSER_TEST_F(AdViewTest, MAYBE_ChangeAdNetworkValue) {
+// Broken test: http://crbug.com/257465.
+IN_PROC_BROWSER_TEST_F(AdViewTest, DISABLED_ChangeAdNetworkValue) {
   ASSERT_TRUE(StartEmbeddedTestServer());
 
   ASSERT_TRUE(RunPlatformAppTest(
diff --git a/chrome/browser/extensions/api/activity_log_private/activity_log_private_apitest.cc b/chrome/browser/extensions/api/activity_log_private/activity_log_private_apitest.cc
index 8930200..f6bf48e 100644
--- a/chrome/browser/extensions/api/activity_log_private/activity_log_private_apitest.cc
+++ b/chrome/browser/extensions/api/activity_log_private/activity_log_private_apitest.cc
@@ -8,6 +8,7 @@
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_builder.h"
+#include "net/dns/mock_host_resolver.h"
 
 namespace extensions {
 
@@ -31,11 +32,19 @@
   CommandLine saved_cmdline_;
 };
 
+#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
+// TODO(karenlees): test flaky on windows. See Bug: crbug.com/245594
+#define MAYBE_TriggerEvent DISABLED_TriggerEvent
+#else
+#define MAYBE_TriggerEvent TriggerEvent
+#endif
+
 // The test extension sends a message to its 'friend'. The test completes
 // if it successfully sees the 'friend' receive the message.
-IN_PROC_BROWSER_TEST_F(ActivityLogApiTest, TriggerEvent) {
-  const Extension* friend_extension =
-      LoadExtension(test_data_dir_.AppendASCII("activity_log_private/friend"));
+IN_PROC_BROWSER_TEST_F(ActivityLogApiTest, MAYBE_TriggerEvent) {
+  host_resolver()->AddRule("*", "127.0.0.1");
+  const Extension* friend_extension = LoadExtensionIncognito(
+      test_data_dir_.AppendASCII("activity_log_private/friend"));
   ASSERT_TRUE(friend_extension);
   ASSERT_TRUE(RunExtensionTest("activity_log_private/test"));
 }
diff --git a/chrome/browser/extensions/api/alarms/alarm_manager.cc b/chrome/browser/extensions/api/alarms/alarm_manager.cc
index 74b1e03..25fd9b4 100644
--- a/chrome/browser/extensions/api/alarms/alarm_manager.cc
+++ b/chrome/browser/extensions/api/alarms/alarm_manager.cc
@@ -13,12 +13,12 @@
 #include "base/time/time.h"
 #include "base/value_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/state_store.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 
 namespace extensions {
@@ -97,6 +97,8 @@
       delegate_(new DefaultAlarmDelegate(profile)) {
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
                  content::Source<Profile>(profile_));
+  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
+                 content::Source<Profile>(profile_));
 
   StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
   if (storage)
@@ -344,6 +346,12 @@
       }
       break;
     }
+    case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
+      const Extension* extension =
+          content::Details<const Extension>(details).ptr();
+      RemoveAllAlarms(extension->id());
+      break;
+    }
     default:
       NOTREACHED();
       break;
diff --git a/chrome/browser/extensions/api/api_resource_manager.h b/chrome/browser/extensions/api/api_resource_manager.h
index 814fc9b..d357ebe 100644
--- a/chrome/browser/extensions/api/api_resource_manager.h
+++ b/chrome/browser/extensions/api/api_resource_manager.h
@@ -10,8 +10,8 @@
 #include "base/lazy_instance.h"
 #include "base/memory/linked_ptr.h"
 #include "base/threading/non_thread_safe.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/extensions/api/api_resource_manager_unittest.cc b/chrome/browser/extensions/api/api_resource_manager_unittest.cc
index c3218a2..725d8fe 100644
--- a/chrome/browser/extensions/api/api_resource_manager_unittest.cc
+++ b/chrome/browser/extensions/api/api_resource_manager_unittest.cc
@@ -12,8 +12,8 @@
 #include "chrome/common/extensions/extension_test_util.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace utils = extension_function_test_utils;
 
diff --git a/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc b/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc
index d4af336..81f5975 100644
--- a/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc
+++ b/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc
@@ -16,7 +16,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/api/app_window/app_window_api.cc b/chrome/browser/extensions/api/app_window/app_window_api.cc
index 1c0a0e5..96306e3 100644
--- a/chrome/browser/extensions/api/app_window/app_window_api.cc
+++ b/chrome/browser/extensions/api/app_window/app_window_api.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/extensions/api/app_window/app_window_api.h"
 
+#include "apps/app_window_contents.h"
 #include "apps/shell_window.h"
 #include "base/command_line.h"
 #include "base/time/time.h"
@@ -23,9 +24,9 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/gfx/rect.h"
+#include "url/gurl.h"
 
 #if defined(USE_ASH)
 #include "ash/shell.h"
@@ -292,14 +293,15 @@
   if (force_maximize)
     create_params.state = ui::SHOW_STATE_MAXIMIZED;
 
-  ShellWindow* shell_window = ShellWindow::Create(
+  ShellWindow* shell_window = new ShellWindow(
       profile(),
       new chrome::ChromeShellWindowDelegate(),
-      GetExtension(),
-      url,
-      create_params);
+      GetExtension());
+  shell_window->Init(url,
+                     new apps::AppWindowContents(shell_window),
+                     create_params);
 
-  if (chrome::ShouldForceFullscreenApp())
+  if (chrome::IsRunningInForcedAppMode())
     shell_window->Fullscreen();
 
   content::RenderViewHost* created_view =
diff --git a/chrome/browser/extensions/api/audio/audio_service_chromeos.cc b/chrome/browser/extensions/api/audio/audio_service_chromeos.cc
index 388546f..7485b19 100644
--- a/chrome/browser/extensions/api/audio/audio_service_chromeos.cc
+++ b/chrome/browser/extensions/api/audio/audio_service_chromeos.cc
@@ -22,7 +22,7 @@
 using api::audio::InputDeviceInfo;
 
 class AudioServiceImpl : public AudioService,
-                         public chromeos::CrasAudioHandler::Observer {
+                         public chromeos::CrasAudioHandler::AudioObserver {
  public:
   AudioServiceImpl();
   virtual ~AudioServiceImpl();
@@ -40,14 +40,14 @@
                                    int gain) OVERRIDE;
 
  protected:
-  // chromeos::CrasAudioClient::Observer overrides.
-  virtual void OutputVolumeChanged(int volume) OVERRIDE;
-  virtual void OutputMuteChanged(bool mute_on) OVERRIDE;
-  virtual void InputGainChanged(int gain) OVERRIDE;
-  virtual void InputMuteChanged(bool mute_on) OVERRIDE;
-  virtual void NodesChanged() OVERRIDE;
-  virtual void ActiveOutputNodeChanged(uint64 node_id) OVERRIDE;
-  virtual void ActiveInputNodeChanged(uint64 node_id) OVERRIDE;
+  // chromeos::CrasAudioHandler::AudioObserver overrides.
+  virtual void OnOutputVolumeChanged() OVERRIDE;
+  virtual void OnInputGainChanged() OVERRIDE;
+  virtual void OnOutputMuteChanged() OVERRIDE;
+  virtual void OnInputMuteChanged() OVERRIDE;
+  virtual void OnAudioNodesChanged() OVERRIDE;
+  virtual void OnActiveOutputNodeChanged() OVERRIDE;
+  virtual void OnActiveInputNodeChanged() OVERRIDE;
 
  private:
   void NotifyDeviceChanged();
@@ -81,16 +81,17 @@
       chromeos::DBusThreadManager::Get()) {
     cras_audio_client_ =
         chromeos::DBusThreadManager::Get()->GetCrasAudioClient();
-    if (cras_audio_client_)
-      cras_audio_client_->AddObserver(this);
-    if (chromeos::CrasAudioHandler::IsInitialized())
+    if (chromeos::CrasAudioHandler::IsInitialized()) {
       cras_audio_handler_ = chromeos::CrasAudioHandler::Get();
+      cras_audio_handler_->AddAudioObserver(this);
+    }
   }
 }
 
 AudioServiceImpl::~AudioServiceImpl() {
-  if (cras_audio_client_)
-    cras_audio_client_->RemoveObserver(this);
+  if (cras_audio_handler_ && chromeos::CrasAudioHandler::IsInitialized()) {
+    cras_audio_handler_->RemoveAudioObserver(this);
+  }
 }
 
 void AudioServiceImpl::AddObserver(AudioService::Observer* observer) {
@@ -123,10 +124,10 @@
     bool found = FindDevice(GetIdFromStr(device_list[i]), &device);
     if (found) {
       if (device.is_input && !input_device_set) {
-        cras_audio_handler_->SetActiveInputNode(device.id);
+        cras_audio_handler_->SwitchToDevice(device);
         input_device_set = true;
       } else if (!device.is_input && !output_device_set) {
-        cras_audio_handler_->SetActiveOutputNode(device.id);
+        cras_audio_handler_->SwitchToDevice(device);
         output_device_set = true;
       }
     }
@@ -170,7 +171,7 @@
       if (!iter->is_input) {
         linked_ptr<OutputDeviceInfo> info(new OutputDeviceInfo());
         info->id = base::Uint64ToString(iter->id);
-        info->name = iter->name;
+        info->name = iter->device_name + ": " + iter->name;
         info->is_active = iter->active;
         info->volume = cras_audio_handler_->GetOutputVolumePercentForDevice(
             iter->id);
@@ -179,7 +180,7 @@
       } else {
         linked_ptr<InputDeviceInfo> info(new InputDeviceInfo());
         info->id = base::Uint64ToString(iter->id);
-        info->name = iter->name;
+        info->name = iter->device_name + ": " + iter->name;
         info->is_active = iter->active;
         info->gain = cras_audio_handler_->GetInputGainPercentForDevice(
             iter->id);
@@ -215,31 +216,31 @@
     return device_id;
 }
 
-void AudioServiceImpl::OutputVolumeChanged(int volume) {
+void AudioServiceImpl::OnOutputVolumeChanged() {
   NotifyDeviceChanged();
 }
 
-void AudioServiceImpl::OutputMuteChanged(bool mute_on) {
+void AudioServiceImpl::OnOutputMuteChanged() {
   NotifyDeviceChanged();
 }
 
-void AudioServiceImpl::InputGainChanged(int gain) {
+void AudioServiceImpl::OnInputGainChanged() {
   NotifyDeviceChanged();
 }
 
-void AudioServiceImpl::InputMuteChanged(bool mute_on) {
+void AudioServiceImpl::OnInputMuteChanged() {
   NotifyDeviceChanged();
 }
 
-void AudioServiceImpl::NodesChanged() {
+void AudioServiceImpl::OnAudioNodesChanged() {
   NotifyDeviceChanged();
 }
 
-void AudioServiceImpl::ActiveOutputNodeChanged(uint64 node_id) {
+void AudioServiceImpl::OnActiveOutputNodeChanged() {
   NotifyDeviceChanged();
 }
 
-void AudioServiceImpl::ActiveInputNodeChanged(uint64 node_id) {
+void AudioServiceImpl::OnActiveInputNodeChanged() {
   NotifyDeviceChanged();
 }
 
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
index 553a13f..592fced 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
+++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
@@ -24,6 +24,7 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_constants.h"
 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h"
 #include "chrome/browser/extensions/event_router.h"
@@ -31,19 +32,26 @@
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/extensions_quota_service.h"
 #include "chrome/browser/importer/external_process_importer_host.h"
-#include "chrome/browser/importer/importer_creator.h"
+#include "chrome/browser/importer/importer_uma.h"
+#include "chrome/browser/platform_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/chrome_select_file_policy.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/ui/host_desktop.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/api/bookmarks.h"
 #include "chrome/common/importer/importer_data_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/user_prefs.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
+#if defined(OS_WIN) && defined(USE_AURA)
+#include "ui/aura/remote_root_window_host_win.h"
+#endif
+
 namespace extensions {
 
 namespace keys = bookmark_api_constants;
@@ -319,13 +327,13 @@
 
   std::vector<linked_ptr<BookmarkTreeNode> > nodes;
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
-  if (params->id_or_id_list.as_array) {
-    std::vector<std::string>* ids = params->id_or_id_list.as_array.get();
-    size_t count = ids->size();
+  if (params->id_or_id_list.as_strings) {
+    std::vector<std::string>& ids = *params->id_or_id_list.as_strings;
+    size_t count = ids.size();
     EXTENSION_FUNCTION_VALIDATE(count > 0);
     for (size_t i = 0; i < count; ++i) {
       int64 id;
-      if (!GetBookmarkIdAsInt64(ids->at(i), &id))
+      if (!GetBookmarkIdAsInt64(ids[i], &id))
         return false;
       const BookmarkNode* node = model->GetNodeByID(id);
       if (!node) {
@@ -939,6 +947,14 @@
   file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html"));
   // TODO(kinaba): http://crbug.com/140425. Turn file_type_info.support_drive
   // on for saving once Google Drive client on ChromeOS supports it.
+  gfx::NativeWindow owning_window = web_contents ?
+      platform_util::GetTopLevel(web_contents->GetView()->GetNativeView())
+          : NULL;
+#if defined(OS_WIN) && defined(USE_AURA)
+  if (!owning_window &&
+      chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH)
+    owning_window = aura::RemoteRootWindowHostWin::Instance()->GetAshWindow();
+#endif
   if (type == ui::SelectFileDialog::SELECT_OPEN_FILE)
     file_type_info.support_drive = true;
   // |web_contents| can be NULL (for background pages), which is fine. In such
@@ -950,7 +966,7 @@
                                   &file_type_info,
                                   0,
                                   base::FilePath::StringType(),
-                                  NULL,
+                                  owning_window,
                                   NULL);
 }
 
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc
index 376a3f1..4bd65cf 100644
--- a/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc
+++ b/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc
@@ -13,11 +13,11 @@
 #include "base/values.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_remover.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/browsing_data/browsing_data_api.h"
 #include "chrome/browser/extensions/extension_function_test_utils.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/extensions/api/commands/command_service.cc b/chrome/browser/extensions/api/commands/command_service.cc
index d5d75f3..13c70e1 100644
--- a/chrome/browser/extensions/api/commands/command_service.cc
+++ b/chrome/browser/extensions/api/commands/command_service.cc
@@ -7,6 +7,7 @@
 #include "base/lazy_instance.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/commands/commands.h"
 #include "chrome/browser/extensions/extension_function_registry.h"
 #include "chrome/browser/extensions/extension_keybinding_registry.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/accelerator_utils.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/commands/commands_handler.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -62,7 +62,7 @@
 namespace extensions {
 
 // static
-void CommandService::RegisterUserPrefs(
+void CommandService::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterDictionaryPref(
       prefs::kExtensionCommands,
diff --git a/chrome/browser/extensions/api/commands/command_service.h b/chrome/browser/extensions/api/commands/command_service.h
index bdaa46f..d857eb7 100644
--- a/chrome/browser/extensions/api/commands/command_service.h
+++ b/chrome/browser/extensions/api/commands/command_service.h
@@ -46,7 +46,7 @@
   };
 
   // Register prefs for keybinding.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Constructs a CommandService object for the given profile.
   explicit CommandService(Profile* profile);
diff --git a/chrome/browser/extensions/api/commands/command_service_new.cc b/chrome/browser/extensions/api/commands/command_service_new.cc
index 4143d6a..296180f 100644
--- a/chrome/browser/extensions/api/commands/command_service_new.cc
+++ b/chrome/browser/extensions/api/commands/command_service_new.cc
@@ -7,6 +7,7 @@
 #include "base/lazy_instance.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/commands/commands.h"
 #include "chrome/browser/extensions/extension_function_registry.h"
 #include "chrome/browser/extensions/extension_keybinding_registry.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/notification_details.h"
@@ -38,7 +38,7 @@
 namespace extensions {
 
 // static
-void CommandService::RegisterUserPrefs(
+void CommandService::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterDictionaryPref(
       prefs::kExtensionCommands,
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_store.h b/chrome/browser/extensions/api/content_settings/content_settings_store.h
index f3e9912..9cd21d3 100644
--- a/chrome/browser/extensions/api/content_settings/content_settings_store.h
+++ b/chrome/browser/extensions/api/content_settings/content_settings_store.h
@@ -18,7 +18,7 @@
 #include "chrome/common/content_settings.h"
 #include "chrome/common/content_settings_pattern.h"
 #include "extensions/browser/extension_prefs_scope.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace base {
 class ListValue;
diff --git a/chrome/browser/extensions/api/cookies/cookies_api.cc b/chrome/browser/extensions/api/cookies/cookies_api.cc
index c2cd6de..afeaf8e 100644
--- a/chrome/browser/extensions/api/cookies/cookies_api.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_api.cc
@@ -15,6 +15,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/cookies/cookies_api_constants.h"
 #include "chrome/browser/extensions/api/cookies/cookies_helpers.h"
 #include "chrome/browser/extensions/event_router.h"
@@ -22,7 +23,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_iterator.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/cookies.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/permissions/permissions_data.h"
diff --git a/chrome/browser/extensions/api/cookies/cookies_api.h b/chrome/browser/extensions/api/cookies/cookies_api.h
index ef6ae38..8dbc0a4 100644
--- a/chrome/browser/extensions/api/cookies/cookies_api.h
+++ b/chrome/browser/extensions/api/cookies/cookies_api.h
@@ -20,8 +20,8 @@
 #include "chrome/common/extensions/api/cookies.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
 #include "net/cookies/canonical_cookie.h"
+#include "url/gurl.h"
 
 namespace net {
 class URLRequestContextGetter;
diff --git a/chrome/browser/extensions/api/cookies/cookies_helpers.cc b/chrome/browser/extensions/api/cookies/cookies_helpers.cc
index c151c92..fc578e8 100644
--- a/chrome/browser/extensions/api/cookies/cookies_helpers.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_helpers.cc
@@ -24,9 +24,9 @@
 #include "chrome/common/extensions/permissions/permissions_data.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
 #include "net/cookies/canonical_cookie.h"
 #include "net/cookies/cookie_util.h"
+#include "url/gurl.h"
 
 using extensions::api::cookies::Cookie;
 using extensions::api::cookies::CookieStore;
diff --git a/chrome/browser/extensions/api/cookies/cookies_unittest.cc b/chrome/browser/extensions/api/cookies/cookies_unittest.cc
index f5f1523..764e028 100644
--- a/chrome/browser/extensions/api/cookies/cookies_unittest.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_unittest.cc
@@ -12,9 +12,9 @@
 #include "chrome/browser/extensions/api/cookies/cookies_helpers.h"
 #include "chrome/common/extensions/api/cookies.h"
 #include "chrome/test/base/testing_profile.h"
-#include "googleurl/src/gurl.h"
 #include "net/cookies/canonical_cookie.h"
 #include "net/cookies/cookie_constants.h"
+#include "url/gurl.h"
 
 using extensions::api::cookies::Cookie;
 using extensions::api::cookies::CookieStore;
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc
index 6ad5f83..b6648ef 100644
--- a/chrome/browser/extensions/api/debugger/debugger_api.cc
+++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -17,6 +17,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/debugger/debugger_api_constants.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_host.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/devtools_agent_host.h"
@@ -134,12 +134,9 @@
       RenderViewHost* rvh,
       const std::string& client_name);
 
-  // Associates DevToolsClientHost with this infobar delegate.
-  void AttachClientHost(ExtensionDevToolsClientHost* client_host);
-
-  // Notifies infobar delegate that associated DevToolsClientHost will be
-  // destroyed.
-  void DiscardClientHost();
+  void set_client_host(ExtensionDevToolsClientHost* client_host) {
+    client_host_ = client_host;
+  }
 
  private:
   ExtensionDevToolsInfoBarDelegate(InfoBarService* infobar_service,
@@ -182,15 +179,6 @@
           new ExtensionDevToolsInfoBarDelegate(infobar_service, client_name))));
 }
 
-void ExtensionDevToolsInfoBarDelegate::AttachClientHost(
-    ExtensionDevToolsClientHost* client_host) {
-  client_host_ = client_host;
-}
-
-void ExtensionDevToolsInfoBarDelegate::DiscardClientHost() {
-  client_host_ = NULL;
-}
-
 ExtensionDevToolsInfoBarDelegate::ExtensionDevToolsInfoBarDelegate(
     InfoBarService* infobar_service,
     const std::string& client_name)
@@ -236,91 +224,13 @@
 
 // Helpers --------------------------------------------------------------------
 
-void CopyDebuggee(Debuggee & dst, const Debuggee& src) {
+void CopyDebuggee(Debuggee* dst, const Debuggee& src) {
   if (src.tab_id)
-    dst.tab_id.reset(new int(*src.tab_id));
+    dst->tab_id.reset(new int(*src.tab_id));
   if (src.extension_id)
-    dst.extension_id.reset(new std::string(*src.extension_id));
+    dst->extension_id.reset(new std::string(*src.extension_id));
   if (src.target_id)
-    dst.target_id.reset(new std::string(*src.target_id));
-}
-
-extensions::ExtensionHost* GetExtensionBackgroundHost(
-    WebContents* web_contents) {
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents->GetBrowserContext());
-  if (!profile)
-    return NULL;
-
-  extensions::ExtensionHost* extension_host =
-      extensions::ExtensionSystem::Get(profile)->process_manager()->
-          GetBackgroundHostForExtension(web_contents->GetURL().host());
-
-  if (extension_host && extension_host->host_contents() == web_contents)
-    return extension_host;
-
-  return NULL;
-}
-
-const char kTargetIdField[]  = "id";
-const char kTargetTypeField[]  = "type";
-const char kTargetTitleField[]  = "title";
-const char kTargetAttachedField[]  = "attached";
-const char kTargetUrlField[]  = "url";
-const char kTargetFaviconUrlField[] = "faviconUrl";
-
-const char kTargetTypePage[]  = "page";
-const char kTargetTypeBackgroundPage[]  = "background_page";
-const char kTargetTypeWorker[]  = "worker";
-
-base::Value* SerializePageInfo(RenderViewHost* rvh) {
-  WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
-  if (!web_contents)
-    return NULL;
-
-  DevToolsAgentHost* agent_host = DevToolsAgentHost::GetOrCreateFor(rvh).get();
-
-  base::DictionaryValue* dictionary = new base::DictionaryValue();
-
-  dictionary->SetString(kTargetIdField, agent_host->GetId());
-  dictionary->SetBoolean(kTargetAttachedField, agent_host->IsAttached());
-  dictionary->SetString(kTargetUrlField, web_contents->GetURL().spec());
-
-  extensions::ExtensionHost* extension_host =
-      GetExtensionBackgroundHost(web_contents);
-  if (extension_host) {
-    // This RenderViewHost belongs to a background page.
-    dictionary->SetString(kTargetTypeField, kTargetTypeBackgroundPage);
-    dictionary->SetString(kTargetTitleField,
-        extension_host->extension()->name());
-  } else {
-    // This RenderViewHost belongs to a regular page.
-    dictionary->SetString(kTargetTypeField, kTargetTypePage);
-    dictionary->SetString(kTargetTitleField, web_contents->GetTitle());
-
-    content::NavigationController& controller = web_contents->GetController();
-    content::NavigationEntry* entry = controller.GetActiveEntry();
-    if (entry != NULL && entry->GetURL().is_valid()) {
-      dictionary->SetString(kTargetFaviconUrlField,
-          entry->GetFavicon().url.spec());
-    }
-  }
-
-  return dictionary;
-}
-
-base::Value* SerializeWorkerInfo(const WorkerService::WorkerInfo& worker) {
-  base::DictionaryValue* dictionary = new base::DictionaryValue;
-
-  scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetForWorker(
-      worker.process_id, worker.route_id));
-  dictionary->SetString(kTargetIdField, agent->GetId());
-  dictionary->SetString(kTargetTypeField, kTargetTypeWorker);
-  dictionary->SetString(kTargetTitleField, worker.name);
-  dictionary->SetString(kTargetUrlField, worker.url.spec());
-  dictionary->SetBoolean(kTargetAttachedField, agent->IsAttached());
-
-  return dictionary;
+    dst->target_id.reset(new std::string(*src.target_id));
 }
 
 
@@ -329,8 +239,9 @@
 class AttachedClientHosts {
  public:
   AttachedClientHosts();
+  ~AttachedClientHosts();
 
-  // Returns the singleton instance of this class
+  // Returns the singleton instance of this class.
   static AttachedClientHosts* GetInstance();
 
   void Add(ExtensionDevToolsClientHost* client_host);
@@ -339,8 +250,8 @@
                                       const std::string& extension_id);
 
  private:
-  typedef std::set<ExtensionDevToolsClientHost*> ClientHostSet;
-  ClientHostSet client_hosts_;
+  typedef std::set<ExtensionDevToolsClientHost*> ClientHosts;
+  ClientHosts client_hosts_;
 
   DISALLOW_COPY_AND_ASSIGN(AttachedClientHosts);
 };
@@ -348,6 +259,8 @@
 AttachedClientHosts::AttachedClientHosts() {
 }
 
+AttachedClientHosts::~AttachedClientHosts() {
+}
 // static
 AttachedClientHosts* AttachedClientHosts::GetInstance() {
   return Singleton<AttachedClientHosts>::get();
@@ -365,7 +278,7 @@
     DevToolsAgentHost* agent_host,
     const std::string& extension_id) {
   DevToolsManager* manager = DevToolsManager::GetInstance();
-  for (ClientHostSet::iterator it = client_hosts_.begin();
+  for (ClientHosts::iterator it = client_hosts_.begin();
        it != client_hosts_.end(); ++it) {
     ExtensionDevToolsClientHost* client_host = *it;
     if (manager->GetDevToolsAgentHostFor(client_host) == agent_host &&
@@ -393,7 +306,7 @@
       last_request_id_(0),
       infobar_delegate_(infobar_delegate),
       detach_reason_(OnDetach::REASON_TARGET_CLOSED) {
-  CopyDebuggee(debuggee_, debuggee);
+  CopyDebuggee(&debuggee_, debuggee);
 
   AttachedClientHosts::GetInstance()->Add(this);
 
@@ -412,7 +325,7 @@
       agent_host_.get(), this);
 
   if (infobar_delegate_) {
-    infobar_delegate_->AttachClientHost(this);
+    infobar_delegate_->set_client_host(this);
     registrar_.Add(
         this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
         content::Source<InfoBarService>(InfoBarService::FromWebContents(
@@ -427,7 +340,7 @@
   registrar_.RemoveAll();
 
   if (infobar_delegate_) {
-    infobar_delegate_->DiscardClientHost();
+    infobar_delegate_->set_client_host(NULL);
     InfoBarService* infobar_service = InfoBarService::FromWebContents(
         WebContents::FromRenderViewHost(agent_host_->GetRenderViewHost()));
     if (infobar_service)
@@ -492,10 +405,8 @@
     const content::NotificationSource& source,
     const content::NotificationDetails& details) {
   if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) {
-    std::string id =
-        content::Details<extensions::UnloadedExtensionInfo>(details)->
-            extension->id();
-    if (id == extension_id_)
+    if (content::Details<extensions::UnloadedExtensionInfo>(details)->
+        extension->id() == extension_id_)
       Close();
   } else if (type == chrome::NOTIFICATION_APP_TERMINATING) {
     Close();
@@ -625,15 +536,17 @@
 
 // DebuggerAttachFunction -----------------------------------------------------
 
-DebuggerAttachFunction::DebuggerAttachFunction() {}
+DebuggerAttachFunction::DebuggerAttachFunction() {
+}
 
-DebuggerAttachFunction::~DebuggerAttachFunction() {}
+DebuggerAttachFunction::~DebuggerAttachFunction() {
+}
 
 bool DebuggerAttachFunction::RunImpl() {
   scoped_ptr<Attach::Params> params(Attach::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
-  CopyDebuggee(debuggee_, params->target);
+  CopyDebuggee(&debuggee_, params->target);
   if (!InitAgentHost())
     return false;
 
@@ -679,15 +592,17 @@
 
 // DebuggerDetachFunction -----------------------------------------------------
 
-DebuggerDetachFunction::DebuggerDetachFunction() {}
+DebuggerDetachFunction::DebuggerDetachFunction() {
+}
 
-DebuggerDetachFunction::~DebuggerDetachFunction() {}
+DebuggerDetachFunction::~DebuggerDetachFunction() {
+}
 
 bool DebuggerDetachFunction::RunImpl() {
   scoped_ptr<Detach::Params> params(Detach::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
-  CopyDebuggee(debuggee_, params->target);
+  CopyDebuggee(&debuggee_, params->target);
   if (!InitClientHost())
     return false;
 
@@ -699,15 +614,17 @@
 
 // DebuggerSendCommandFunction ------------------------------------------------
 
-DebuggerSendCommandFunction::DebuggerSendCommandFunction() {}
+DebuggerSendCommandFunction::DebuggerSendCommandFunction() {
+}
 
-DebuggerSendCommandFunction::~DebuggerSendCommandFunction() {}
+DebuggerSendCommandFunction::~DebuggerSendCommandFunction() {
+}
 
 bool DebuggerSendCommandFunction::RunImpl() {
   scoped_ptr<SendCommand::Params> params(SendCommand::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
-  CopyDebuggee(debuggee_, params->target);
+  CopyDebuggee(&debuggee_, params->target);
   if (!InitClientHost())
     return false;
 
@@ -737,9 +654,90 @@
 
 // DebuggerGetTargetsFunction -------------------------------------------------
 
-DebuggerGetTargetsFunction::DebuggerGetTargetsFunction() {}
+namespace {
 
-DebuggerGetTargetsFunction::~DebuggerGetTargetsFunction() {}
+const char kTargetIdField[] = "id";
+const char kTargetTypeField[] = "type";
+const char kTargetTitleField[] = "title";
+const char kTargetAttachedField[] = "attached";
+const char kTargetUrlField[] = "url";
+const char kTargetFaviconUrlField[] = "faviconUrl";
+const char kTargetTypePage[] = "page";
+const char kTargetTypeBackgroundPage[] = "background_page";
+const char kTargetTypeWorker[] = "worker";
+
+extensions::ExtensionHost*
+    GetExtensionBackgroundHost(WebContents* web_contents) {
+  Profile* profile =
+      Profile::FromBrowserContext(web_contents->GetBrowserContext());
+  if (!profile)
+    return NULL;
+
+  extensions::ExtensionHost* extension_host =
+      extensions::ExtensionSystem::Get(profile)->process_manager()->
+          GetBackgroundHostForExtension(web_contents->GetURL().host());
+
+  return (extension_host && extension_host->host_contents() == web_contents) ?
+      extension_host : NULL;
+}
+
+base::Value* SerializePageInfo(RenderViewHost* rvh) {
+  WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
+  if (!web_contents)
+    return NULL;
+
+  DevToolsAgentHost* agent_host = DevToolsAgentHost::GetOrCreateFor(rvh);
+
+  base::DictionaryValue* dictionary = new base::DictionaryValue();
+
+  dictionary->SetString(kTargetIdField, agent_host->GetId());
+  dictionary->SetBoolean(kTargetAttachedField, agent_host->IsAttached());
+  dictionary->SetString(kTargetUrlField, web_contents->GetURL().spec());
+
+  extensions::ExtensionHost* extension_host =
+      GetExtensionBackgroundHost(web_contents);
+  if (extension_host) {
+    // This RenderViewHost belongs to a background page.
+    dictionary->SetString(kTargetTypeField, kTargetTypeBackgroundPage);
+    dictionary->SetString(kTargetTitleField,
+                          extension_host->extension()->name());
+  } else {
+    // This RenderViewHost belongs to a regular page.
+    dictionary->SetString(kTargetTypeField, kTargetTypePage);
+    dictionary->SetString(kTargetTitleField, web_contents->GetTitle());
+
+    content::NavigationController& controller = web_contents->GetController();
+    content::NavigationEntry* entry = controller.GetActiveEntry();
+    if (entry != NULL && entry->GetURL().is_valid()) {
+      dictionary->SetString(kTargetFaviconUrlField,
+                            entry->GetFavicon().url.spec());
+    }
+  }
+
+  return dictionary;
+}
+
+base::Value* SerializeWorkerInfo(const WorkerService::WorkerInfo& worker) {
+  base::DictionaryValue* dictionary = new base::DictionaryValue;
+
+  scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetForWorker(
+      worker.process_id, worker.route_id));
+  dictionary->SetString(kTargetIdField, agent->GetId());
+  dictionary->SetString(kTargetTypeField, kTargetTypeWorker);
+  dictionary->SetString(kTargetTitleField, worker.name);
+  dictionary->SetString(kTargetUrlField, worker.url.spec());
+  dictionary->SetBoolean(kTargetAttachedField, agent->IsAttached());
+
+  return dictionary;
+}
+
+} // namespace
+
+DebuggerGetTargetsFunction::DebuggerGetTargetsFunction() {
+}
+
+DebuggerGetTargetsFunction::~DebuggerGetTargetsFunction() {
+}
 
 bool DebuggerGetTargetsFunction::RunImpl() {
   base::ListValue* results_list = new base::ListValue();
@@ -756,11 +754,9 @@
   content::BrowserThread::PostTaskAndReply(
       content::BrowserThread::IO,
       FROM_HERE,
-      base::Bind(&DebuggerGetTargetsFunction::CollectWorkerInfo,
-                 this,
+      base::Bind(&DebuggerGetTargetsFunction::CollectWorkerInfo, this,
                  results_list),
-      base::Bind(&DebuggerGetTargetsFunction::SendTargetList,
-                 this,
+      base::Bind(&DebuggerGetTargetsFunction::SendTargetList, this,
                  results_list));
   return true;
 }
@@ -768,7 +764,6 @@
 void DebuggerGetTargetsFunction::CollectWorkerInfo(base::ListValue* list) {
   std::vector<WorkerService::WorkerInfo> worker_info =
       WorkerService::GetInstance()->GetWorkers();
-
   for (size_t i = 0; i < worker_info.size(); ++i)
     list->Append(SerializeWorkerInfo(worker_info[i]));
 }
diff --git a/chrome/browser/extensions/api/declarative/rules_registry_service.cc b/chrome/browser/extensions/api/declarative/rules_registry_service.cc
index 67a45c4..0803631 100644
--- a/chrome/browser/extensions/api/declarative/rules_registry_service.cc
+++ b/chrome/browser/extensions/api/declarative/rules_registry_service.cc
@@ -8,11 +8,11 @@
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/declarative/initializing_rules_registry.h"
 #include "chrome/browser/extensions/api/declarative_content/content_rules_registry.h"
 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h"
 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/extensions/api/declarative/rules_registry_with_cache.cc b/chrome/browser/extensions/api/declarative/rules_registry_with_cache.cc
index 059e7ba..09b1ab5 100644
--- a/chrome/browser/extensions/api/declarative/rules_registry_with_cache.cc
+++ b/chrome/browser/extensions/api/declarative/rules_registry_with_cache.cc
@@ -11,13 +11,13 @@
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_info_map.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/state_store.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/extensions/api/declarative_content/content_condition.h b/chrome/browser/extensions/api/declarative_content/content_condition.h
index 351aa43..abb86d6 100644
--- a/chrome/browser/extensions/api/declarative_content/content_condition.h
+++ b/chrome/browser/extensions/api/declarative_content/content_condition.h
@@ -16,7 +16,7 @@
 #include "base/values.h"
 #include "chrome/browser/extensions/api/declarative/declarative_rule.h"
 #include "extensions/common/matcher/url_matcher.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/api/declarative_content/content_rules_registry.cc b/chrome/browser/extensions/api/declarative_content/content_rules_registry.cc
index 9ac23db..cff0379 100644
--- a/chrome/browser/extensions/api/declarative_content/content_rules_registry.cc
+++ b/chrome/browser/extensions/api/declarative_content/content_rules_registry.cc
@@ -4,13 +4,13 @@
 
 #include "chrome/browser/extensions/api/declarative_content/content_rules_registry.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/declarative_content/content_action.h"
 #include "chrome/browser/extensions/api/declarative_content/content_condition.h"
 #include "chrome/browser/extensions/api/declarative_content/content_constants.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_messages.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h
index 4dcc74b..faa70cf 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h
@@ -16,7 +16,7 @@
 #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
 #include "chrome/common/extensions/api/events.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class ExtensionInfoMap;
 class WebRequestPermission;
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
index 54d4db5..6da6d0e 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -16,6 +16,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/api/developer_private/developer_private_api_factory.h"
 #include "chrome/browser/extensions/api/developer_private/entry_picker.h"
@@ -31,10 +32,9 @@
 #include "chrome/browser/extensions/updater/extension_updater.h"
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
 #include "chrome/browser/ui/chrome_select_file_policy.h"
 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/api/developer_private.h"
 #include "chrome/common/extensions/background_info.h"
@@ -920,7 +920,7 @@
 
 void DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
     ClearPrexistingDirectoryContent(const base::FilePath& project_path) {
-  if (!base::Delete(project_path, true/*recursive*/)) {
+  if (!base::DeleteFile(project_path, true/*recursive*/)) {
     SetError("Error in copying files from sync filesystem.");
     content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
         base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
@@ -1040,7 +1040,7 @@
   }
 
   if (success_)
-    file_util::CopyFile(src_path, target_path);
+    base::CopyFile(src_path, target_path);
 
   CHECK(pendingCopyOperationsCount_ > 0);
   pendingCopyOperationsCount_--;
diff --git a/chrome/browser/extensions/api/dial/dial_apitest.cc b/chrome/browser/extensions/api/dial/dial_apitest.cc
index dd83e35..56b4746 100644
--- a/chrome/browser/extensions/api/dial/dial_apitest.cc
+++ b/chrome/browser/extensions/api/dial/dial_apitest.cc
@@ -10,8 +10,8 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_test_message_listener.h"
 #include "chrome/common/chrome_switches.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "url/gurl.h"
 
 using extensions::DialDeviceData;
 using extensions::Extension;
diff --git a/chrome/browser/extensions/api/dial/dial_device_data.h b/chrome/browser/extensions/api/dial/dial_device_data.h
index ddda6b7..a59900c 100644
--- a/chrome/browser/extensions/api/dial/dial_device_data.h
+++ b/chrome/browser/extensions/api/dial/dial_device_data.h
@@ -10,7 +10,7 @@
 
 #include "base/time/time.h"
 #include "base/values.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/api/dial/dial_registry_unittest.cc b/chrome/browser/extensions/api/dial/dial_registry_unittest.cc
index 3e1b034..dd5c023 100644
--- a/chrome/browser/extensions/api/dial/dial_registry_unittest.cc
+++ b/chrome/browser/extensions/api/dial/dial_registry_unittest.cc
@@ -8,9 +8,9 @@
 #include "chrome/browser/extensions/api/dial/dial_registry.h"
 #include "chrome/browser/extensions/api/dial/dial_service.h"
 #include "chrome/test/base/testing_profile.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 using base::Time;
 using base::TimeDelta;
diff --git a/chrome/browser/extensions/api/dial/dial_service.cc b/chrome/browser/extensions/api/dial/dial_service.cc
index b4bc70e..2a2b8c3 100644
--- a/chrome/browser/extensions/api/dial/dial_service.cc
+++ b/chrome/browser/extensions/api/dial/dial_service.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/extensions/api/dial/dial_device_data.h"
 #include "chrome/common/chrome_version_info.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/completion_callback.h"
 #include "net/base/io_buffer.h"
 #include "net/base/ip_endpoint.h"
@@ -24,6 +23,7 @@
 #include "net/base/net_util.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_util.h"
+#include "url/gurl.h"
 #if defined(OS_CHROMEOS)
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc
index b831d52..0ebe8c5 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api.cc
@@ -27,6 +27,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_danger_prompt.h"
 #include "chrome/browser/download/download_file_icon_extractor.h"
 #include "chrome/browser/download/download_query.h"
@@ -45,7 +46,6 @@
 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/cancelable_task_tracker.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/downloads.h"
 #include "chrome/common/extensions/permissions/permissions_data.h"
 #include "content/public/browser/download_interrupt_reasons.h"
@@ -70,7 +70,6 @@
 
 using content::BrowserContext;
 using content::BrowserThread;
-using content::DownloadId;
 using content::DownloadItem;
 using content::DownloadManager;
 
@@ -927,7 +926,7 @@
   for (DownloadManager::DownloadVector::const_iterator it = results.begin();
        it != results.end(); ++it) {
     DownloadItem* download_item = *it;
-    int32 download_id = download_item->GetId();
+    uint32 download_id = download_item->GetId();
     bool off_record = ((incognito_manager != NULL) &&
                        (incognito_manager->GetDownload(download_id) != NULL));
     scoped_ptr<base::DictionaryValue> json_item(DownloadItemToJSON(
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.h b/chrome/browser/extensions/api/downloads/downloads_api.h
index 59abe29..77b7777 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api.h
+++ b/chrome/browser/extensions/api/downloads/downloads_api.h
@@ -16,7 +16,6 @@
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_function.h"
 #include "chrome/common/extensions/api/downloads.h"
-#include "content/public/browser/download_id.h"
 #include "content/public/browser/download_item.h"
 #include "content/public/browser/download_manager.h"
 
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc b/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc
index b3f08d0..7cca9bc 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_file_icon_extractor.h"
 #include "chrome/browser/download/download_service.h"
 #include "chrome/browser/download/download_service_factory.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -417,6 +417,7 @@
     url_chain.push_back(GURL());
     for (size_t i = 0; i < count; ++i) {
       DownloadItem* item = GetOnRecordManager()->CreateDownloadItem(
+          content::DownloadItem::kInvalidId + 1 + i,
           downloads_directory().Append(history_info[i].filename),
           downloads_directory().Append(history_info[i].filename),
           url_chain, GURL(),    // URL Chain, referrer
@@ -1130,8 +1131,8 @@
   base::FilePath fake_path = all_downloads[1]->GetTargetFilePath();
 
   EXPECT_EQ(0, file_util::WriteFile(real_path, "", 0));
-  ASSERT_TRUE(file_util::PathExists(real_path));
-  ASSERT_FALSE(file_util::PathExists(fake_path));
+  ASSERT_TRUE(base::PathExists(real_path));
+  ASSERT_FALSE(base::PathExists(fake_path));
 
   for (DownloadManager::DownloadVector::iterator iter = all_downloads.begin();
        iter != all_downloads.end();
@@ -1188,7 +1189,7 @@
   ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
   int item_id = -1;
   ASSERT_TRUE(item_value->GetInteger("id", &item_id));
-  ASSERT_EQ(0, item_id);
+  ASSERT_EQ(all_downloads[0]->GetId(), static_cast<uint32>(item_id));
 }
 
 // Test the |id| parameter for search().
@@ -1198,7 +1199,8 @@
   ScopedItemVectorCanceller delete_items(&items);
 
   scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
-      new DownloadsSearchFunction(), "[{\"id\": 0}]"));
+      new DownloadsSearchFunction(), base::StringPrintf(
+          "[{\"id\": %u}]", items[0]->GetId())));
   ASSERT_TRUE(result.get());
   base::ListValue* result_list = NULL;
   ASSERT_TRUE(result->GetAsList(&result_list));
@@ -1207,7 +1209,7 @@
   ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
   int item_id = -1;
   ASSERT_TRUE(item_value->GetInteger("id", &item_id));
-  ASSERT_EQ(0, item_id);
+  ASSERT_EQ(items[0]->GetId(), static_cast<uint32>(item_id));
 }
 
 // Test specifying both the |id| and |filename| parameters for search().
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
index 308d636..e01140e 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
+++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
@@ -367,7 +367,7 @@
 EPKPChallengeUserKey::~EPKPChallengeUserKey() {
 }
 
-void EPKPChallengeUserKey::RegisterUserPrefs(
+void EPKPChallengeUserKey::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kAttestationEnabled,
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h
index f08d498..2619f60 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h
+++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h
@@ -169,7 +169,7 @@
       chromeos::attestation::AttestationFlow* attestation_flow,
       policy::EnterpriseInstallAttributes* install_attributes);
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  protected:
   virtual bool RunImpl() OVERRIDE;
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
index 07845e4..f9785f8 100644
--- a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
+++ b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
@@ -8,6 +8,7 @@
 #include <gtk/gtk.h>
 #endif
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/browser_action_test_util.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_icon_factory.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
index 5102b6e..a4c5a2c 100644
--- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc
+++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
@@ -11,6 +11,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_api_constants.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
@@ -22,7 +23,6 @@
 #include "chrome/browser/extensions/state_store.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
 #include "chrome/common/render_messages.h"
 #include "content/public/browser/navigation_entry.h"
diff --git a/chrome/browser/extensions/api/feedback_private/blob_reader.h b/chrome/browser/extensions/api/feedback_private/blob_reader.h
index c937b4d..6c05b20 100644
--- a/chrome/browser/extensions/api/feedback_private/blob_reader.h
+++ b/chrome/browser/extensions/api/feedback_private/blob_reader.h
@@ -9,10 +9,10 @@
 
 #include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/io_buffer.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "net/url_request/url_request.h"
+#include "url/gurl.h"
 
 class Profile;
 namespace net {
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc b/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc
index b8f107f..b24a308 100644
--- a/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc
+++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc
@@ -12,10 +12,10 @@
 #include "chrome/browser/extensions/event_names.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_system.h"
-#include "googleurl/src/url_util.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/url_util.h"
 
 
 namespace extensions {
@@ -101,8 +101,18 @@
   const FeedbackInfo &feedback_info = params->feedback;
 
   std::string description = feedback_info.description;
-  std::string attached_file_url = feedback_info.attached_file_blob_url;
-  std::string screenshot_url = feedback_info.screenshot_blob_url;
+  std::string attached_file_url, screenshot_url;
+  if (feedback_info.attached_file.get() &&
+      feedback_info.attached_file_blob_url.get() &&
+      !feedback_info.attached_file_blob_url->empty()) {
+    attached_file_url = *feedback_info.attached_file_blob_url;
+  }
+
+  if (feedback_info.screenshot.get() &&
+      feedback_info.screenshot_blob_url.get() &&
+      !feedback_info.screenshot_blob_url->empty()) {
+    screenshot_url = *feedback_info.screenshot_blob_url;
+  }
 
   // Populate feedback data.
   scoped_refptr<FeedbackData> feedback_data(new FeedbackData());
@@ -116,14 +126,14 @@
   if (feedback_info.email.get())
     feedback_data->set_user_email(*feedback_info.email.get());
 
-  if (feedback_info.attached_file.get() &&
-      !feedback_info.attached_file_blob_url.empty()) {
+  if (!attached_file_url.empty()) {
     feedback_data->set_attached_filename(
         (*feedback_info.attached_file.get()).name);
-    feedback_data->set_attached_file_url(
-        GURL(feedback_info.attached_file_blob_url));
+    feedback_data->set_attached_file_url(GURL(attached_file_url));
   }
-  feedback_data->set_screenshot_url(GURL(feedback_info.screenshot_blob_url));
+
+  if (!screenshot_url.empty())
+    feedback_data->set_screenshot_url(GURL(screenshot_url));
 
   // TODO(rkc): Take this out of OS_CHROMEOS once we have FeedbackData and
   // FeedbackUtil migrated to handle system logs for both Chrome and ChromeOS.
diff --git a/chrome/browser/extensions/api/file_handlers/app_file_handler_util.cc b/chrome/browser/extensions/api/file_handlers/app_file_handler_util.cc
index 19ac093..17888ef 100644
--- a/chrome/browser/extensions/api/file_handlers/app_file_handler_util.cc
+++ b/chrome/browser/extensions/api/file_handlers/app_file_handler_util.cc
@@ -143,12 +143,6 @@
     policy->GrantWriteFileSystem(renderer_id, result.filesystem_id);
 
   result.id = result.filesystem_id + ":" + result.registered_name;
-
-  // We only need file level access for reading FileEntries. Saving FileEntries
-  // just needs the file system to have read/write access, which is granted
-  // above if required.
-  if (!policy->CanReadFile(renderer_id, path))
-    policy->GrantReadFile(renderer_id, path);
   return result;
 }
 
diff --git a/chrome/browser/extensions/api/file_system/file_system_api.cc b/chrome/browser/extensions/api/file_system/file_system_api.cc
index a441157..c02d5e01 100644
--- a/chrome/browser/extensions/api/file_system/file_system_api.cc
+++ b/chrome/browser/extensions/api/file_system/file_system_api.cc
@@ -212,7 +212,7 @@
 bool DoCheckWritableFile(const base::FilePath& path,
                          const base::FilePath& extension_directory) {
   // Don't allow links.
-  if (file_util::PathExists(path) && file_util::IsLink(path))
+  if (base::PathExists(path) && file_util::IsLink(path))
     return false;
 
   if (extension_directory == path || extension_directory.IsParent(path))
@@ -658,7 +658,7 @@
     const base::FilePath& suggested_name,
     const base::FilePath& previous_path) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
-  if (!previous_path.empty() && file_util::DirectoryExists(previous_path)) {
+  if (!previous_path.empty() && base::DirectoryExists(previous_path)) {
     initial_path_ = previous_path.Append(suggested_name);
   } else {
     base::FilePath documents_dir;
diff --git a/chrome/browser/extensions/api/file_system/file_system_apitest.cc b/chrome/browser/extensions/api/file_system/file_system_apitest.cc
index ab7c4d5..a08faad 100644
--- a/chrome/browser/extensions/api/file_system/file_system_apitest.cc
+++ b/chrome/browser/extensions/api/file_system/file_system_apitest.cc
@@ -6,10 +6,10 @@
 #include "base/file_util.h"
 #include "base/path_service.h"
 #include "build/build_config.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/platform_app_browsertest_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_service.h"
@@ -92,7 +92,7 @@
     base::FilePath destination = temp_dir_.path().AppendASCII(destination_name);
     if (copy_gold) {
       base::FilePath source = test_root_folder_.AppendASCII("gold.txt");
-      EXPECT_TRUE(file_util::CopyFile(source, destination));
+      EXPECT_TRUE(base::CopyFile(source, destination));
     }
     return destination;
   }
@@ -153,7 +153,7 @@
 
   base::FilePath test_file = test_path.AppendASCII("gold.txt");
   base::FilePath source = test_root_folder_.AppendASCII("gold.txt");
-  EXPECT_TRUE(file_util::CopyFile(source, test_file));
+  EXPECT_TRUE(base::CopyFile(source, test_file));
 
   FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
       &test_file);
diff --git a/chrome/browser/extensions/api/font_settings/font_settings_api.cc b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
index 722172a..b5498a1 100644
--- a/chrome/browser/extensions/api/font_settings/font_settings_api.cc
+++ b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
@@ -14,12 +14,12 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/preference/preference_api.h"
 #include "chrome/browser/extensions/api/preference/preference_helpers.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/font_settings.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/pref_names_util.h"
diff --git a/chrome/browser/extensions/api/history/history_api.cc b/chrome/browser/extensions/api/history/history_api.cc
index e45e94b..53412af 100644
--- a/chrome/browser/extensions/api/history/history_api.cc
+++ b/chrome/browser/extensions/api/history/history_api.cc
@@ -16,6 +16,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/history/history_service.h"
@@ -24,7 +25,6 @@
 #include "chrome/browser/history/visit_filter.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/cancelable_task_tracker.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/experimental_history.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
@@ -489,8 +489,8 @@
                                            Profile::EXPLICIT_ACCESS);
   hs->ExpireHistoryBetween(
       restrict_urls,
-      base::Time::UnixEpoch(),     // From the beginning of the epoch.
-      base::Time::Now(),           // To the current time.
+      base::Time(),      // Unbounded beginning...
+      base::Time(),      // ...and the end.
       base::Bind(&HistoryDeleteAllFunction::DeleteComplete,
                  base::Unretained(this)),
       &task_tracker_);
diff --git a/chrome/browser/extensions/api/history/history_apitest.cc b/chrome/browser/extensions/api/history/history_apitest.cc
index f2394e0..2d8e5f0 100644
--- a/chrome/browser/extensions/api/history/history_apitest.cc
+++ b/chrome/browser/extensions/api/history/history_apitest.cc
@@ -14,8 +14,8 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
-#include "googleurl/src/gurl.h"
 #include "net/dns/mock_host_resolver.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/api/i18n/i18n_apitest.cc b/chrome/browser/extensions/api/i18n/i18n_apitest.cc
index 12c7142..e6863f6 100644
--- a/chrome/browser/extensions/api/i18n/i18n_apitest.cc
+++ b/chrome/browser/extensions/api/i18n/i18n_apitest.cc
@@ -22,15 +22,15 @@
   // Create an Extension whose messages.json file will be updated.
   base::ScopedTempDir extension_dir;
   ASSERT_TRUE(extension_dir.CreateUniqueTempDir());
-  file_util::CopyFile(
+  base::CopyFile(
       test_data_dir_.AppendASCII("i18nUpdate")
                     .AppendASCII("manifest.json"),
       extension_dir.path().AppendASCII("manifest.json"));
-  file_util::CopyFile(
+  base::CopyFile(
       test_data_dir_.AppendASCII("i18nUpdate")
                     .AppendASCII("contentscript.js"),
       extension_dir.path().AppendASCII("contentscript.js"));
-  file_util::CopyDirectory(
+  base::CopyDirectory(
       test_data_dir_.AppendASCII("i18nUpdate")
                     .AppendASCII("_locales"),
       extension_dir.path().AppendASCII("_locales"),
@@ -51,7 +51,7 @@
   EXPECT_EQ(std::string("FIRSTMESSAGE"), UTF16ToUTF8(title));
 
   // Change messages.json file and reload extension.
-  file_util::CopyFile(
+  base::CopyFile(
       test_data_dir_.AppendASCII("i18nUpdate")
                     .AppendASCII("messages2.json"),
       extension_dir.path().AppendASCII("_locales/en/messages.json"));
diff --git a/chrome/browser/extensions/api/identity/OWNERS b/chrome/browser/extensions/api/identity/OWNERS
new file mode 100644
index 0000000..bc8f8b8
--- /dev/null
+++ b/chrome/browser/extensions/api/identity/OWNERS
@@ -0,0 +1 @@
+courage@chromium.org
diff --git a/chrome/browser/extensions/api/identity/experimental_identity_api.cc b/chrome/browser/extensions/api/identity/experimental_identity_api.cc
index 1845aed..27c5051 100644
--- a/chrome/browser/extensions/api/identity/experimental_identity_api.cc
+++ b/chrome/browser/extensions/api/identity/experimental_identity_api.cc
@@ -14,10 +14,10 @@
 #include "chrome/browser/extensions/api/identity/identity_api.h"
 #include "chrome/browser/extensions/extension_install_prompt.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/profile_oauth2_token_service.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
-#include "chrome/browser/signin/token_service.h"
-#include "chrome/browser/signin/token_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/extensions/api/experimental_identity.h"
 #include "chrome/common/extensions/api/identity.h"
@@ -28,8 +28,8 @@
 #include "chrome/common/url_constants.h"
 #include "content/public/common/page_transition_types.h"
 #include "google_apis/gaia/gaia_constants.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/window_open_disposition.h"
+#include "url/gurl.h"
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/login/user_manager.h"
@@ -94,8 +94,6 @@
     // Display a login prompt.
     StartSigninFlow();
   } else {
-    TokenService* token_service = TokenServiceFactory::GetForProfile(profile());
-    refresh_token_ = token_service->GetOAuth2LoginRefreshToken();
     StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
   }
 
@@ -136,7 +134,8 @@
   }
 
   if (type == IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE) {
-    StartGaiaRequest(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE);
+    gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE;
+    StartLoginAccessTokenRequest();
   } else {
     DCHECK(type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
 
@@ -188,9 +187,7 @@
   StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
 }
 
-void ExperimentalIdentityGetAuthTokenFunction::SigninSuccess(
-    const std::string& token) {
-  refresh_token_ = token;
+void ExperimentalIdentityGetAuthTokenFunction::SigninSuccess() {
   StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
 }
 
@@ -201,7 +198,8 @@
 void ExperimentalIdentityGetAuthTokenFunction::InstallUIProceed() {
   // The user has accepted the scopes, so we may now force (recording a grant
   // and receiving a token).
-  StartGaiaRequest(OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE);
+  gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE;
+  StartLoginAccessTokenRequest();
 }
 
 void ExperimentalIdentityGetAuthTokenFunction::InstallUIAbort(
@@ -209,9 +207,35 @@
   CompleteFunctionWithError(identity_constants::kUserRejected);
 }
 
+void ExperimentalIdentityGetAuthTokenFunction::OnGetTokenSuccess(
+      const OAuth2TokenService::Request* request,
+      const std::string& access_token,
+      const base::Time& expiration_time) {
+  DCHECK_EQ(login_token_request_.get(), request);
+  login_token_request_.reset();
+  StartGaiaRequest(access_token);
+}
+
+void ExperimentalIdentityGetAuthTokenFunction::OnGetTokenFailure(
+      const OAuth2TokenService::Request* request,
+      const GoogleServiceAuthError& error) {
+  DCHECK_EQ(login_token_request_.get(), request);
+  login_token_request_.reset();
+
+  CompleteFunctionWithError(
+      std::string(identity_constants::kAuthFailure) + error.ToString());
+}
+
+void ExperimentalIdentityGetAuthTokenFunction::StartLoginAccessTokenRequest() {
+  login_token_request_ =
+      ProfileOAuth2TokenServiceFactory::GetForProfile(profile())->
+          StartRequest(OAuth2TokenService::ScopeSet(), this);
+}
+
 void ExperimentalIdentityGetAuthTokenFunction::StartGaiaRequest(
-    OAuth2MintTokenFlow::Mode mode) {
-  mint_token_flow_.reset(CreateMintTokenFlow(mode));
+    const std::string& login_access_token) {
+  DCHECK(!login_access_token.empty());
+  mint_token_flow_.reset(CreateMintTokenFlow(login_access_token));
   mint_token_flow_->Start();
 }
 
@@ -227,11 +251,11 @@
 
 OAuth2MintTokenFlow*
 ExperimentalIdentityGetAuthTokenFunction::CreateMintTokenFlow(
-    OAuth2MintTokenFlow::Mode mode) {
+    const std::string& login_access_token) {
 #if defined(OS_CHROMEOS)
   // Always force minting token for ChromeOS kiosk app.
   if (chrome::IsRunningInForcedAppMode())
-    mode = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE;
+    gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE;
 #endif
 
   const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
@@ -240,11 +264,11 @@
           profile()->GetRequestContext(),
           this,
           OAuth2MintTokenFlow::Parameters(
-              refresh_token_,
+              login_access_token,
               GetExtension()->id(),
               oauth2_info.client_id,
               oauth2_info.scopes,
-              mode));
+              gaia_mint_token_mode_));
 #if defined(OS_CHROMEOS)
   if (chrome::IsRunningInForcedAppMode()) {
     std::string chrome_client_id;
@@ -260,8 +284,8 @@
 }
 
 bool ExperimentalIdentityGetAuthTokenFunction::HasLoginToken() const {
-  TokenService* token_service = TokenServiceFactory::GetForProfile(profile());
-  return token_service->HasOAuthLoginToken();
+  return ProfileOAuth2TokenServiceFactory::GetForProfile(profile())->
+      RefreshTokenIsAvailable();
 }
 
 ExperimentalIdentityLaunchWebAuthFlowFunction::
diff --git a/chrome/browser/extensions/api/identity/experimental_identity_api.h b/chrome/browser/extensions/api/identity/experimental_identity_api.h
index cf165dc..3dec6a7 100644
--- a/chrome/browser/extensions/api/identity/experimental_identity_api.h
+++ b/chrome/browser/extensions/api/identity/experimental_identity_api.h
@@ -15,6 +15,7 @@
 #include "chrome/browser/extensions/api/identity/identity_signin_flow.h"
 #include "chrome/browser/extensions/extension_function.h"
 #include "chrome/browser/extensions/extension_install_prompt.h"
+#include "chrome/browser/signin/oauth2_token_service.h"
 #include "google_apis/gaia/oauth2_mint_token_flow.h"
 
 namespace extensions {
@@ -44,7 +45,8 @@
     : public AsyncExtensionFunction,
       public ExtensionInstallPrompt::Delegate,
       public OAuth2MintTokenFlow::Delegate,
-      public IdentitySigninFlow::Delegate {
+      public IdentitySigninFlow::Delegate,
+      public OAuth2TokenService::Consumer {
  public:
   DECLARE_EXTENSION_FUNCTION("experimental.identity.getAuthToken",
                              EXPERIMENTAL_IDENTITY_GETAUTHTOKEN);
@@ -76,29 +78,41 @@
       const IssueAdviceInfo& issue_advice) OVERRIDE;
 
   // IdentitySigninFlow::Delegate implementation:
-  virtual void SigninSuccess(const std::string& token) OVERRIDE;
+  virtual void SigninSuccess() OVERRIDE;
   virtual void SigninFailed() OVERRIDE;
 
   // ExtensionInstallPrompt::Delegate implementation:
   virtual void InstallUIProceed() OVERRIDE;
   virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
 
+  // OAuth2TokenService::Consumer implementation:
+  virtual void OnGetTokenSuccess(
+      const OAuth2TokenService::Request* request,
+      const std::string& access_token,
+      const base::Time& expiration_time) OVERRIDE;
+  virtual void OnGetTokenFailure(
+      const OAuth2TokenService::Request* request,
+      const GoogleServiceAuthError& error) OVERRIDE;
+
+  // Starts a login access token request.
+  virtual void StartLoginAccessTokenRequest();
+
   // Starts a mint token request to GAIA.
-  void StartGaiaRequest(OAuth2MintTokenFlow::Mode mode);
+  void StartGaiaRequest(const std::string& login_access_token);
 
   // Methods for invoking UI. Overridable for testing.
   virtual void ShowLoginPopup();
   virtual void ShowOAuthApprovalDialog(const IssueAdviceInfo& issue_advice);
   // Caller owns the returned instance.
   virtual OAuth2MintTokenFlow* CreateMintTokenFlow(
-      OAuth2MintTokenFlow::Mode mode);
+      const std::string& login_access_token);
 
   // Checks if there is a master login token to mint tokens for the extension.
   virtual bool HasLoginToken() const;
 
   bool should_prompt_for_scopes_;
   scoped_ptr<OAuth2MintTokenFlow> mint_token_flow_;
-  std::string refresh_token_;
+  OAuth2MintTokenFlow::Mode gaia_mint_token_mode_;
   bool should_prompt_for_signin_;
 
   // When launched in interactive mode, and if there is no existing grant,
@@ -106,6 +120,7 @@
   IssueAdviceInfo issue_advice_;
   scoped_ptr<ExtensionInstallPrompt> install_ui_;
   scoped_ptr<IdentitySigninFlow> signin_flow_;
+  scoped_ptr<OAuth2TokenService::Request> login_token_request_;
 };
 
 class ExperimentalIdentityLaunchWebAuthFlowFunction
diff --git a/chrome/browser/extensions/api/identity/experimental_identity_apitest.cc b/chrome/browser/extensions/api/identity/experimental_identity_apitest.cc
index 12afd78..7d5c0cb 100644
--- a/chrome/browser/extensions/api/identity/experimental_identity_apitest.cc
+++ b/chrome/browser/extensions/api/identity/experimental_identity_apitest.cc
@@ -5,6 +5,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/identity/experimental_identity_api.h"
 #include "chrome/browser/extensions/api/identity/identity_api.h"
 #include "chrome/browser/extensions/api/identity/web_auth_flow.h"
@@ -13,7 +14,6 @@
 #include "chrome/browser/extensions/extension_function_test_utils.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/notification_service.h"
@@ -22,9 +22,9 @@
 #include "extensions/common/id_util.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "google_apis/gaia/oauth2_mint_token_flow.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 using testing::_;
 using testing::Return;
@@ -187,11 +187,16 @@
     public ExperimentalIdentityGetAuthTokenFunction {
  public:
   ExperimentalMockGetAuthTokenFunction()
-      : login_ui_result_(true),
+      : login_access_token_result_(true),
+        login_ui_result_(true),
         install_ui_result_(false),
         login_ui_shown_(false),
         install_ui_shown_(false) {}
 
+  void set_login_access_token_result(bool result) {
+    login_access_token_result_ = result;
+  }
+
   void set_login_ui_result(bool result) { login_ui_result_ = result; }
 
   void set_install_ui_result(bool result) { install_ui_result_ = result; }
@@ -200,11 +205,22 @@
 
   bool install_ui_shown() const { return install_ui_shown_; }
 
+  virtual void StartLoginAccessTokenRequest() OVERRIDE {
+    if (login_access_token_result_) {
+      OnGetTokenSuccess(login_token_request_.get(), "access_token",
+          base::Time::Now() + base::TimeDelta::FromHours(1LL));
+    } else {
+      GoogleServiceAuthError error(
+          GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
+      OnGetTokenFailure(login_token_request_.get(), error);
+    }
+  }
+
   virtual void ShowLoginPopup() OVERRIDE {
     EXPECT_FALSE(login_ui_shown_);
     login_ui_shown_ = true;
     if (login_ui_result_)
-      SigninSuccess("fake_refresh_token");
+      SigninSuccess();
     else
       SigninFailed();
   }
@@ -221,10 +237,11 @@
 
   MOCK_CONST_METHOD0(HasLoginToken, bool());
   MOCK_METHOD1(CreateMintTokenFlow,
-               OAuth2MintTokenFlow*(OAuth2MintTokenFlow::Mode mode));
+               OAuth2MintTokenFlow*(const std::string& login_access_token));
 
  private:
   ~ExperimentalMockGetAuthTokenFunction() {}
+  bool login_access_token_result_;
   bool login_ui_result_;
   bool install_ui_result_;
   bool login_ui_shown_;
@@ -299,6 +316,18 @@
 }
 
 IN_PROC_BROWSER_TEST_F(ExperimentalGetAuthTokenFunctionTest,
+                       NonInteractiveLoginAccessTokenFailure) {
+  scoped_refptr<ExperimentalMockGetAuthTokenFunction> func(
+      new ExperimentalMockGetAuthTokenFunction());
+  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
+  func->set_login_access_token_result(false);
+  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
+  std::string error =
+      utils::RunFunctionAndReturnError(func.get(), "[{}]", browser());
+  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
+}
+
+IN_PROC_BROWSER_TEST_F(ExperimentalGetAuthTokenFunctionTest,
                        NonInteractiveMintFailure) {
   scoped_refptr<ExperimentalMockGetAuthTokenFunction> func(
       new ExperimentalMockGetAuthTokenFunction());
@@ -421,6 +450,19 @@
 }
 
 IN_PROC_BROWSER_TEST_F(ExperimentalGetAuthTokenFunctionTest,
+                       InteractiveLoginSuccessLoginAccessTokenFailure) {
+  scoped_refptr<ExperimentalMockGetAuthTokenFunction> func(
+      new ExperimentalMockGetAuthTokenFunction());
+  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
+  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
+  func->set_login_ui_result(true);
+  func->set_login_access_token_result(false);
+  std::string error = utils::RunFunctionAndReturnError(
+      func.get(), "[{\"interactive\": true}]", browser());
+  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
+}
+
+IN_PROC_BROWSER_TEST_F(ExperimentalGetAuthTokenFunctionTest,
                        InteractiveLoginSuccessMintFailure) {
   scoped_refptr<ExperimentalMockGetAuthTokenFunction> func(
       new ExperimentalMockGetAuthTokenFunction());
diff --git a/chrome/browser/extensions/api/identity/experimental_web_auth_flow.cc b/chrome/browser/extensions/api/identity/experimental_web_auth_flow.cc
index e06a3b9..e661a37 100644
--- a/chrome/browser/extensions/api/identity/experimental_web_auth_flow.cc
+++ b/chrome/browser/extensions/api/identity/experimental_web_auth_flow.cc
@@ -17,8 +17,8 @@
 #include "content/public/browser/resource_request_details.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/page_transition_types.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/window_open_disposition.h"
+#include "url/gurl.h"
 
 using content::LoadNotificationDetails;
 using content::NavigationController;
diff --git a/chrome/browser/extensions/api/identity/experimental_web_auth_flow.h b/chrome/browser/extensions/api/identity/experimental_web_auth_flow.h
index 0dc2654..483742e 100644
--- a/chrome/browser/extensions/api/identity/experimental_web_auth_flow.h
+++ b/chrome/browser/extensions/api/identity/experimental_web_auth_flow.h
@@ -9,8 +9,8 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/rect.h"
+#include "url/gurl.h"
 
 class Profile;
 class ExperimentalWebAuthFlowTest;
diff --git a/chrome/browser/extensions/api/identity/identity_api.cc b/chrome/browser/extensions/api/identity/identity_api.cc
index 3191610..75dcaba 100644
--- a/chrome/browser/extensions/api/identity/identity_api.cc
+++ b/chrome/browser/extensions/api/identity/identity_api.cc
@@ -16,24 +16,22 @@
 #include "base/values.h"
 #include "chrome/browser/app_mode/app_mode_utils.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_function_dispatcher.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/signin_manager.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
-#include "chrome/browser/signin/token_service.h"
-#include "chrome/browser/signin/token_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/signin/profile_oauth2_token_service.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/browser/signin/signin_global_error.h"
 #include "chrome/common/extensions/api/identity.h"
 #include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
-#include "google_apis/gaia/gaia_constants.h"
 #include "google_apis/gaia/gaia_urls.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/login/user_manager.h"
@@ -123,8 +121,6 @@
     // Display a login prompt.
     StartSigninFlow();
   } else {
-    TokenService* token_service = TokenServiceFactory::GetForProfile(profile());
-    refresh_token_ = token_service->GetOAuth2LoginRefreshToken();
     StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
   }
 
@@ -228,7 +224,8 @@
                 chromeos::DeviceOAuth2TokenServiceFactory::Get()->StartRequest(
                     scope_set, this);
           } else {
-            StartGaiaRequest(OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE);
+            gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE;
+            StartLoginAccessTokenRequest();
           }
           return;
         }
@@ -238,9 +235,10 @@
           // oauth2_info.auto_approve is protected by a whitelist in
           // _manifest_features.json hence only selected extensions take
           // advantage of forcefully minting the token.
-          StartGaiaRequest(OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE);
+          gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE;
         else
-          StartGaiaRequest(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE);
+          gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE;
+        StartLoginAccessTokenRequest();
         break;
 
       case IdentityTokenCacheValue::CACHE_STATUS_TOKEN:
@@ -319,8 +317,7 @@
   StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
 }
 
-void IdentityGetAuthTokenFunction::SigninSuccess(const std::string& token) {
-  refresh_token_ = token;
+void IdentityGetAuthTokenFunction::SigninSuccess() {
   StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
 }
 
@@ -387,31 +384,47 @@
     const OAuth2TokenService::Request* request,
     const std::string& access_token,
     const base::Time& expiration_time) {
-  DCHECK_EQ(device_token_request_.get(), request);
-  device_token_request_.reset();
+  if (login_token_request_.get() == request) {
+    login_token_request_.reset();
+    StartGaiaRequest(access_token);
+  } else {
+    DCHECK_EQ(device_token_request_.get(), request);
+    device_token_request_.reset();
 
-  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
-  IdentityTokenCacheValue token(access_token,
-                                expiration_time - base::Time::Now());
-  IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->SetCachedToken(
-      GetExtension()->id(), oauth2_info.scopes, token);
+    const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
+    IdentityTokenCacheValue token(access_token,
+                                  expiration_time - base::Time::Now());
+    IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->SetCachedToken(
+        GetExtension()->id(), oauth2_info.scopes, token);
 
-  CompleteMintTokenFlow();
-  CompleteFunctionWithResult(access_token);
+    CompleteMintTokenFlow();
+    CompleteFunctionWithResult(access_token);
+  }
 }
 
 void IdentityGetAuthTokenFunction::OnGetTokenFailure(
     const OAuth2TokenService::Request* request,
     const GoogleServiceAuthError& error) {
-  DCHECK_EQ(device_token_request_.get(), request);
-  device_token_request_.reset();
+  if (login_token_request_.get() == request) {
+    login_token_request_.reset();
+  } else {
+    DCHECK_EQ(device_token_request_.get(), request);
+    device_token_request_.reset();
+  }
 
   OnGaiaFlowFailure(GaiaWebAuthFlow::SERVICE_AUTH_ERROR, error, std::string());
 }
 
+void IdentityGetAuthTokenFunction::StartLoginAccessTokenRequest() {
+  login_token_request_ =
+      ProfileOAuth2TokenServiceFactory::GetForProfile(profile())->
+          StartRequest(OAuth2TokenService::ScopeSet(), this);
+}
+
 void IdentityGetAuthTokenFunction::StartGaiaRequest(
-    OAuth2MintTokenFlow::Mode mode) {
-  mint_token_flow_.reset(CreateMintTokenFlow(mode));
+    const std::string& login_access_token) {
+  DCHECK(!login_access_token.empty());
+  mint_token_flow_.reset(CreateMintTokenFlow(login_access_token));
   mint_token_flow_->Start();
 }
 
@@ -432,7 +445,7 @@
 }
 
 OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow(
-    OAuth2MintTokenFlow::Mode mode) {
+    const std::string& login_access_token) {
   const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
 
   OAuth2MintTokenFlow* mint_token_flow =
@@ -440,11 +453,11 @@
           profile()->GetRequestContext(),
           this,
           OAuth2MintTokenFlow::Parameters(
-              refresh_token_,
+              login_access_token,
               GetExtension()->id(),
               oauth2_client_id_,
               oauth2_info.scopes,
-              mode));
+              gaia_mint_token_mode_));
 #if defined(OS_CHROMEOS)
   if (chrome::IsRunningInForcedAppMode()) {
     std::string chrome_client_id;
@@ -460,8 +473,8 @@
 }
 
 bool IdentityGetAuthTokenFunction::HasLoginToken() const {
-  TokenService* token_service = TokenServiceFactory::GetForProfile(profile());
-  return token_service->HasOAuthLoginToken();
+  return ProfileOAuth2TokenServiceFactory::GetForProfile(profile())->
+      RefreshTokenIsAvailable();
 }
 
 std::string IdentityGetAuthTokenFunction::MapOAuth2ErrorToDescription(
@@ -639,21 +652,18 @@
 
 IdentityAPI::IdentityAPI(Profile* profile)
     : profile_(profile),
-      signin_manager_(NULL),
-      error_(GoogleServiceAuthError::NONE) {
+      error_(GoogleServiceAuthError::NONE),
+      initialized_(false) {
 }
 
 IdentityAPI::~IdentityAPI() {
 }
 
 void IdentityAPI::Initialize() {
-  signin_manager_ = SigninManagerFactory::GetForProfile(profile_);
-  signin_manager_->signin_global_error()->AddProvider(this);
+  SigninGlobalError::GetForProfile(profile_)->AddProvider(this);
+  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->AddObserver(this);
 
-  TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
-  registrar_.Add(this,
-                 chrome::NOTIFICATION_TOKEN_AVAILABLE,
-                 content::Source<TokenService>(token_service));
+  initialized_ = true;
 }
 
 IdentityMintRequestQueue* IdentityAPI::mint_queue() {
@@ -702,16 +712,19 @@
 }
 
 void IdentityAPI::ReportAuthError(const GoogleServiceAuthError& error) {
-  if (!signin_manager_)
-    Initialize();
-
   error_ = error;
-  signin_manager_->signin_global_error()->AuthStatusChanged();
+  SigninGlobalError::GetForProfile(profile_)->AuthStatusChanged();
 }
 
 void IdentityAPI::Shutdown() {
-  if (signin_manager_)
-    signin_manager_->signin_global_error()->RemoveProvider(this);
+  if (!initialized_)
+    return;
+
+  SigninGlobalError::GetForProfile(profile_)->RemoveProvider(this);
+  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->
+      RemoveObserver(this);
+
+  initialized_ = false;
 }
 
 static base::LazyInstance<ProfileKeyedAPIFactory<IdentityAPI> >
@@ -726,24 +739,16 @@
   return error_;
 }
 
-void IdentityAPI::Observe(int type,
-                          const content::NotificationSource& source,
-                          const content::NotificationDetails& details) {
-  CHECK(type == chrome::NOTIFICATION_TOKEN_AVAILABLE);
-  TokenService::TokenAvailableDetails* token_details =
-      content::Details<TokenService::TokenAvailableDetails>(details).ptr();
-  if (token_details->service() ==
-      GaiaConstants::kGaiaOAuth2LoginRefreshToken) {
-    error_ = GoogleServiceAuthError::AuthErrorNone();
-    signin_manager_->signin_global_error()->AuthStatusChanged();
-  }
+void IdentityAPI::OnRefreshTokenAvailable(const std::string& account_id) {
+  error_ = GoogleServiceAuthError::AuthErrorNone();
 }
 
 template <>
 void ProfileKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies() {
   DependsOn(ExtensionSystemFactory::GetInstance());
-  DependsOn(TokenServiceFactory::GetInstance());
-  DependsOn(SigninManagerFactory::GetInstance());
+  // Need dependency on ProfileOAuth2TokenServiceFactory because it owns
+  // the SigninGlobalError instance.
+  DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
 }
 
 IdentityAPI::TokenCacheKey::TokenCacheKey(const std::string& extension_id,
diff --git a/chrome/browser/extensions/api/identity/identity_api.h b/chrome/browser/extensions/api/identity/identity_api.h
index a04a01d..b46668d 100644
--- a/chrome/browser/extensions/api/identity/identity_api.h
+++ b/chrome/browser/extensions/api/identity/identity_api.h
@@ -26,7 +26,6 @@
 class GoogleServiceAuthError;
 class MockGetAuthTokenFunction;
 class Profile;
-class SigninManagerBase;
 
 namespace extensions {
 
@@ -109,7 +108,7 @@
       const IssueAdviceInfo& issue_advice) OVERRIDE;
 
   // IdentitySigninFlow::Delegate implementation:
-  virtual void SigninSuccess(const std::string& token) OVERRIDE;
+  virtual void SigninSuccess() OVERRIDE;
   virtual void SigninFailed() OVERRIDE;
 
   // GaiaWebAuthFlow::Delegate implementation:
@@ -126,15 +125,18 @@
   virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
                                  const GoogleServiceAuthError& error) OVERRIDE;
 
+  // Starts a login access token request.
+  virtual void StartLoginAccessTokenRequest();
+
   // Starts a mint token request to GAIA.
-  void StartGaiaRequest(OAuth2MintTokenFlow::Mode mode);
+  void StartGaiaRequest(const std::string& login_access_token);
 
   // Methods for invoking UI. Overridable for testing.
   virtual void ShowLoginPopup();
   virtual void ShowOAuthApprovalDialog(const IssueAdviceInfo& issue_advice);
   // Caller owns the returned instance.
   virtual OAuth2MintTokenFlow* CreateMintTokenFlow(
-      OAuth2MintTokenFlow::Mode mode);
+      const std::string& login_access_token);
 
   // Checks if there is a master login token to mint tokens for the extension.
   virtual bool HasLoginToken() const;
@@ -148,7 +150,7 @@
   bool should_prompt_for_scopes_;
   IdentityMintRequestQueue::MintType mint_token_flow_type_;
   scoped_ptr<OAuth2MintTokenFlow> mint_token_flow_;
-  std::string refresh_token_;
+  OAuth2MintTokenFlow::Mode gaia_mint_token_mode_;
   bool should_prompt_for_signin_;
 
   std::string oauth2_client_id_;
@@ -158,6 +160,7 @@
   scoped_ptr<GaiaWebAuthFlow> gaia_web_auth_flow_;
   scoped_ptr<IdentitySigninFlow> signin_flow_;
   scoped_ptr<OAuth2TokenService::Request> device_token_request_;
+  scoped_ptr<OAuth2TokenService::Request> login_token_request_;
 };
 
 class IdentityRemoveCachedAuthTokenFunction : public SyncExtensionFunction {
@@ -232,7 +235,7 @@
 
 class IdentityAPI : public ProfileKeyedAPI,
                     public SigninGlobalError::AuthStatusProvider,
-                    public content::NotificationObserver {
+                    public OAuth2TokenService::Observer {
  public:
   struct TokenCacheKey {
     TokenCacheKey(const std::string& extension_id,
@@ -273,10 +276,8 @@
   // AuthStatusProvider implementation.
   virtual GoogleServiceAuthError GetAuthStatus() const OVERRIDE;
 
-  // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) OVERRIDE;
+  // OAuth2TokenService::Observer implementation:
+  virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE;
 
  private:
   friend class ProfileKeyedAPIFactory<IdentityAPI>;
@@ -288,10 +289,8 @@
   static const bool kServiceIsNULLWhileTesting = true;
 
   Profile* profile_;
-  SigninManagerBase* signin_manager_;
   GoogleServiceAuthError error_;
-  // Used to listen to notifications from the TokenService.
-  content::NotificationRegistrar registrar_;
+  bool initialized_;
   IdentityMintRequestQueue mint_queue_;
   CachedTokens token_cache_;
 };
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc
index 8659114..bf5351f 100644
--- a/chrome/browser/extensions/api/identity/identity_apitest.cc
+++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -5,6 +5,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/identity/identity_api.h"
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/extensions/extension_apitest.h"
@@ -13,7 +14,6 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -23,11 +23,11 @@
 #include "extensions/common/id_util.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "google_apis/gaia/oauth2_mint_token_flow.h"
-#include "googleurl/src/gurl.h"
 #include "grit/browser_resources.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 using testing::_;
 using testing::Return;
@@ -238,12 +238,17 @@
 
 class MockGetAuthTokenFunction : public IdentityGetAuthTokenFunction {
  public:
-  MockGetAuthTokenFunction() : login_ui_result_(true),
+  MockGetAuthTokenFunction() : login_access_token_result_(true),
+                               login_ui_result_(true),
                                scope_ui_result_(true),
                                login_ui_shown_(false),
                                scope_ui_shown_(false) {
   }
 
+  void set_login_access_token_result(bool result) {
+    login_access_token_result_ = result;
+  }
+
   void set_login_ui_result(bool result) {
     login_ui_result_ = result;
   }
@@ -267,11 +272,22 @@
     return scope_ui_shown_;
   }
 
+  virtual void StartLoginAccessTokenRequest() OVERRIDE {
+    if (login_access_token_result_) {
+      OnGetTokenSuccess(login_token_request_.get(), "access_token",
+          base::Time::Now() + base::TimeDelta::FromHours(1LL));
+    } else {
+      GoogleServiceAuthError error(
+          GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
+      OnGetTokenFailure(login_token_request_.get(), error);
+    }
+  }
+
   virtual void ShowLoginPopup() OVERRIDE {
     EXPECT_FALSE(login_ui_shown_);
     login_ui_shown_ = true;
     if (login_ui_result_)
-      SigninSuccess("fake_refresh_token");
+      SigninSuccess();
     else
       SigninFailed();
   }
@@ -293,10 +309,11 @@
 
   MOCK_CONST_METHOD0(HasLoginToken, bool());
   MOCK_METHOD1(CreateMintTokenFlow,
-               OAuth2MintTokenFlow* (OAuth2MintTokenFlow::Mode mode));
+               OAuth2MintTokenFlow* (const std::string& login_access_token));
 
  private:
   ~MockGetAuthTokenFunction() {}
+  bool login_access_token_result_;
   bool login_ui_result_;
   bool scope_ui_result_;
   GaiaWebAuthFlow::Failure scope_ui_failure_;
@@ -401,6 +418,18 @@
 }
 
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
+                       NonInteractiveLoginAccessTokenFailure) {
+  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
+  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
+  EXPECT_CALL(*func.get(), HasLoginToken())
+      .WillOnce(Return(true));
+  func->set_login_access_token_result(false);
+  std::string error = utils::RunFunctionAndReturnError(
+      func.get(), "[{}]", browser());
+  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
+}
+
+IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
                        NonInteractiveMintAdviceSuccess) {
   scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
   scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
@@ -520,6 +549,20 @@
 }
 
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
+                       InteractiveLoginSuccessLoginAccessTokenFailure) {
+  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
+  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
+  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
+  func->set_login_ui_result(true);
+  func->set_login_access_token_result(false);
+  std::string error = utils::RunFunctionAndReturnError(
+      func.get(), "[{\"interactive\": true}]", browser());
+  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
+  EXPECT_TRUE(func->login_ui_shown());
+  EXPECT_FALSE(func->scope_ui_shown());
+}
+
+IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
                        InteractiveLoginSuccessMintSuccess) {
   scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
   func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
diff --git a/chrome/browser/extensions/api/identity/identity_signin_flow.cc b/chrome/browser/extensions/api/identity/identity_signin_flow.cc
index e002247..0367fc9 100644
--- a/chrome/browser/extensions/api/identity/identity_signin_flow.cc
+++ b/chrome/browser/extensions/api/identity/identity_signin_flow.cc
@@ -5,14 +5,10 @@
 #include "chrome/browser/extensions/api/identity/identity_signin_flow.h"
 
 #include "chrome/browser/app_mode/app_mode_utils.h"
-#include "chrome/browser/signin/token_service.h"
-#include "chrome/browser/signin/token_service_factory.h"
+#include "chrome/browser/signin/profile_oauth2_token_service.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
-#include "google_apis/gaia/gaia_constants.h"
 
 namespace extensions {
 
@@ -22,6 +18,8 @@
 }
 
 IdentitySigninFlow::~IdentitySigninFlow() {
+  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->
+      RemoveObserver(this);
 }
 
 void IdentitySigninFlow::Start() {
@@ -36,24 +34,16 @@
   }
 #endif
 
-  TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
-  registrar_.Add(this,
-                 chrome::NOTIFICATION_TOKEN_AVAILABLE,
-                 content::Source<TokenService>(token_service));
+  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->AddObserver(this);
 
   LoginUIService* login_ui_service =
       LoginUIServiceFactory::GetForProfile(profile_);
   login_ui_service->ShowLoginPopup();
 }
 
-void IdentitySigninFlow::Observe(int type,
-                                 const content::NotificationSource& source,
-                                 const content::NotificationDetails& details) {
-  CHECK(type == chrome::NOTIFICATION_TOKEN_AVAILABLE);
-  TokenService::TokenAvailableDetails* token_details =
-      content::Details<TokenService::TokenAvailableDetails>(details).ptr();
-  if (token_details->service() == GaiaConstants::kGaiaOAuth2LoginRefreshToken)
-    delegate_->SigninSuccess(token_details->token());
+void IdentitySigninFlow::OnRefreshTokenAvailable(
+    const std::string& account_id) {
+  delegate_->SigninSuccess();
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/identity/identity_signin_flow.h b/chrome/browser/extensions/api/identity/identity_signin_flow.h
index a1289f8..cb1eb74 100644
--- a/chrome/browser/extensions/api/identity/identity_signin_flow.h
+++ b/chrome/browser/extensions/api/identity/identity_signin_flow.h
@@ -8,8 +8,7 @@
 #include <string>
 
 #include "base/memory/scoped_ptr.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
+#include "chrome/browser/signin/oauth2_token_service.h"
 
 class Profile;
 
@@ -19,14 +18,14 @@
 // interactive Identity API call. The UI is launched through the LoginUIService.
 // When the flow completes, the delegate is notified, and on success will
 // be given an OAuth2 login refresh token.
-class IdentitySigninFlow : public content::NotificationObserver {
+class IdentitySigninFlow : public OAuth2TokenService::Observer {
  public:
   class Delegate {
    public:
     Delegate() {}
     virtual ~Delegate() {}
     // Called when the flow has completed successfully.
-    virtual void SigninSuccess(const std::string& token) = 0;
+    virtual void SigninSuccess() = 0;
     // Called when the flow has failed.
     virtual void SigninFailed() = 0;
 
@@ -40,16 +39,12 @@
   // Starts the flow. Should only be called once.
   void Start();
 
-  // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) OVERRIDE;
+  // OAuth2TokenService::Observer implementation:
+  virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE;
 
  private:
   Delegate* delegate_;
   Profile* profile_;
-  // Used to listen to notifications from the TokenService.
-  content::NotificationRegistrar registrar_;
 
   DISALLOW_COPY_AND_ASSIGN(IdentitySigninFlow);
 };
diff --git a/chrome/browser/extensions/api/identity/web_auth_flow.cc b/chrome/browser/extensions/api/identity/web_auth_flow.cc
index 4a8f2ad..fa2e3cf 100644
--- a/chrome/browser/extensions/api/identity/web_auth_flow.cc
+++ b/chrome/browser/extensions/api/identity/web_auth_flow.cc
@@ -27,8 +27,8 @@
 #include "content/public/browser/resource_request_details.h"
 #include "content/public/browser/web_contents.h"
 #include "crypto/random.h"
-#include "googleurl/src/gurl.h"
 #include "grit/browser_resources.h"
+#include "url/gurl.h"
 
 using apps::ShellWindow;
 using content::RenderViewHost;
@@ -207,7 +207,7 @@
   }
 }
 
-void WebAuthFlow::RenderViewGone(base::TerminationStatus status) {
+void WebAuthFlow::RenderProcessGone(base::TerminationStatus status) {
   if (delegate_)
     delegate_->OnAuthFlowFailure(WebAuthFlow::WINDOW_CLOSED);
 }
diff --git a/chrome/browser/extensions/api/identity/web_auth_flow.h b/chrome/browser/extensions/api/identity/web_auth_flow.h
index cbe42c6..077b1f0 100644
--- a/chrome/browser/extensions/api/identity/web_auth_flow.h
+++ b/chrome/browser/extensions/api/identity/web_auth_flow.h
@@ -11,8 +11,8 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/rect.h"
+#include "url/gurl.h"
 
 class Profile;
 class WebAuthFlowTest;
@@ -108,7 +108,7 @@
   virtual void DidNavigateMainFrame(
       const content::LoadCommittedDetails& details,
       const content::FrameNavigateParams& params) OVERRIDE;
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
   virtual void DidStartProvisionalLoadForFrame(
       int64 frame_id,
       int64 parent_frame_id,
diff --git a/chrome/browser/extensions/api/idle/idle_api_unittest.cc b/chrome/browser/extensions/api/idle/idle_api_unittest.cc
index 61f385b..bbffd00 100644
--- a/chrome/browser/extensions/api/idle/idle_api_unittest.cc
+++ b/chrome/browser/extensions/api/idle/idle_api_unittest.cc
@@ -8,12 +8,12 @@
 #include <string>
 
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/idle/idle_api_constants.h"
 #include "chrome/browser/extensions/api/idle/idle_manager.h"
 #include "chrome/browser/extensions/api/idle/idle_manager_factory.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_function_test_utils.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
diff --git a/chrome/browser/extensions/api/idle/idle_manager.cc b/chrome/browser/extensions/api/idle/idle_manager.cc
index bf02c33..8b66e86 100644
--- a/chrome/browser/extensions/api/idle/idle_manager.cc
+++ b/chrome/browser/extensions/api/idle/idle_manager.cc
@@ -7,11 +7,11 @@
 #include <utility>
 
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/idle/idle_api_constants.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.cc b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
index 0e4845b..e14c620 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api.cc
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
@@ -4,132 +4,66 @@
 
 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h"
 
-#include "base/json/json_writer.h"
-#include "base/lazy_instance.h"
-#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/input_method/input_method_engine.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_function_registry.h"
-#include "chrome/browser/extensions/extension_input_module_constants.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/extensions/api/input_ime.h"
 #include "chrome/common/extensions/api/input_ime/input_components_handler.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 
-namespace keys = extension_input_module_constants;
+namespace input_ime = extensions::api::input_ime;
+namespace KeyEventHandled = extensions::api::input_ime::KeyEventHandled;
+namespace DeleteSurroundingText =
+    extensions::api::input_ime::DeleteSurroundingText;
+namespace UpdateMenuItems = extensions::api::input_ime::UpdateMenuItems;
+namespace SetMenuItems = extensions::api::input_ime::SetMenuItems;
+namespace SetCursorPosition = extensions::api::input_ime::SetCursorPosition;
+namespace SetCandidates = extensions::api::input_ime::SetCandidates;
+namespace SetCandidateWindowProperties =
+    extensions::api::input_ime::SetCandidateWindowProperties;
+namespace CommitText = extensions::api::input_ime::CommitText;
+namespace ClearComposition = extensions::api::input_ime::ClearComposition;
+namespace SetComposition = extensions::api::input_ime::SetComposition;
 
 namespace {
 
-const char kStyleNone[] = "none";
-const char kStyleCheck[] = "check";
-const char kStyleRadio[] = "radio";
-const char kStyleSeparator[] = "separator";
-const char kWindowPositionComposition[] = "composition";
-
 const char kErrorEngineNotAvailable[] = "Engine is not available";
 const char kErrorBadCandidateList[] = "Invalid candidate list provided";
 const char kErrorSetMenuItemsFail[] = "Could not create menu Items";
 const char kErrorUpdateMenuItemsFail[] = "Could not update menu Items";
 
-bool ReadMenuItems(
-    base::ListValue* menu_items,
-    std::vector<chromeos::InputMethodEngine::MenuItem>* output) {
-  for (size_t i = 0; i < menu_items->GetSize(); ++i) {
-    base::DictionaryValue* item_dict;
-    if (!menu_items->GetDictionary(i, &item_dict)) {
-      return false;
-    }
-
-    std::string id;
-    std::string label;
-    chromeos::InputMethodEngine::MenuItemStyle style =
-        chromeos::InputMethodEngine::MENU_ITEM_STYLE_NONE;
-    bool visible = true;
-    bool enabled = true;
-    bool checked = false;
-    std::string icon;
-    chromeos::InputMethodEngine::KeyboardEvent shortcut_key;
-
-    unsigned int modified = 0;
-
-    if (!item_dict->GetString(keys::kIdKey, &id)) {
-      return false;
-    }
-
-    if (item_dict->HasKey(keys::kLabelKey)) {
-      if (!item_dict->GetString(keys::kLabelKey, &label)) {
-        return false;
-      }
-      modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_LABEL;
-    }
-    if (item_dict->HasKey(keys::kStyleKey)) {
-      std::string style_string;
-      if (!item_dict->GetString(keys::kStyleKey, &style_string)) {
-        return false;
-      }
-
-      if (style_string == kStyleNone) {
-        style = chromeos::InputMethodEngine::MENU_ITEM_STYLE_NONE;
-      } else if (style_string == kStyleCheck) {
-        style = chromeos::InputMethodEngine::MENU_ITEM_STYLE_CHECK;
-      } else if (style_string == kStyleRadio) {
-        style = chromeos::InputMethodEngine::MENU_ITEM_STYLE_RADIO;
-      } else if (style_string == kStyleSeparator) {
-        style = chromeos::InputMethodEngine::MENU_ITEM_STYLE_SEPARATOR;
-      } else {
-        return false;
-      }
-      modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_STYLE;
-    }
-
-    if (item_dict->HasKey(keys::kVisibleKey)) {
-      if (!item_dict->GetBoolean(keys::kVisibleKey, &visible)) {
-        return false;
-      }
-      modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_VISIBLE;
-    }
-
-    if (item_dict->HasKey(keys::kCheckedKey)) {
-      if (!item_dict->GetBoolean(keys::kCheckedKey, &checked)) {
-        return false;
-      }
-      modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_CHECKED;
-    }
-
-    if (item_dict->HasKey(keys::kEnabledKey)) {
-      if (!item_dict->GetBoolean(keys::kEnabledKey, &enabled)) {
-        return false;
-      }
-      modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_ENABLED;
-    }
-
-    output->push_back(chromeos::InputMethodEngine::MenuItem());
-    output->back().id = id;
-    output->back().label = label;
-    output->back().style = style;
-    output->back().visible = visible;
-    output->back().enabled = enabled;
-    output->back().checked = checked;
-
-    output->back().modified = modified;
-
-    if (item_dict->HasKey(keys::kItemsKey)) {
-      base::ListValue* sub_list;
-      if (!item_dict->GetList(keys::kItemsKey, &sub_list)) {
-        return false;
-      }
-
-      if (!ReadMenuItems(sub_list, &(output->back().children))) {
-        return false;
-      }
-    }
+void SetMenuItemToMenu(const input_ime::MenuItem& input,
+                       chromeos::InputMethodEngine::MenuItem* out) {
+  out->modified = 0;
+  out->id = input.id;
+  if (input.label) {
+    out->modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_LABEL;
+    out->label = *input.label;
   }
 
-  return true;
+  if (input.style != input_ime::MenuItem::STYLE_NONE) {
+    out->modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_STYLE;
+    out->style = static_cast<chromeos::InputMethodEngine::MenuItemStyle>(
+        input.style);
+  }
+
+  if (input.visible)
+    out->modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_VISIBLE;
+  out->visible = input.visible ? *input.visible : true;
+
+  if (input.checked)
+    out->modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_CHECKED;
+  out->checked = input.checked ? *input.checked : false;
+
+  if (input.enabled)
+    out->modified |= chromeos::InputMethodEngine::MENU_ITEM_MODIFIED_ENABLED;
+  out->enabled = input.enabled ? *input.enabled : true;
 }
 
 static void DispatchEventToExtension(Profile* profile,
@@ -367,9 +301,8 @@
 
   std::map<std::string, chromeos::InputMethodEngine*>::iterator engine_ix =
       engine_map.find(component.id);
-  if (engine_ix != engine_map.end()) {
+  if (engine_ix != engine_map.end())
     return false;
-  }
 
   std::string error;
   chromeos::ImeObserver* observer = new chromeos::ImeObserver(profile,
@@ -378,11 +311,14 @@
   std::vector<std::string> layouts;
   layouts.assign(component.layouts.begin(), component.layouts.end());
 
+  std::vector<std::string> languages;
+  languages.assign(component.languages.begin(), component.languages.end());
+
   chromeos::InputMethodEngine* engine =
       chromeos::InputMethodEngine::CreateEngine(
           observer, component.name.c_str(), extension_id.c_str(),
           component.id.c_str(), component.description.c_str(),
-          component.language.c_str(), layouts, component.options_page_url,
+          languages, layouts, component.options_page_url,
           &error);
   if (!engine) {
     delete observer;
@@ -432,9 +368,8 @@
   if (engine_list != engines_.end()) {
     std::map<std::string, chromeos::InputMethodEngine*>::const_iterator
         engine_ix = engine_list->second.find(engine_id);
-    if (engine_ix != engine_list->second.end()) {
+    if (engine_ix != engine_list->second.end())
       return engine_ix->second;
-    }
   }
   return NULL;
 }
@@ -450,9 +385,8 @@
     for (engine_ix = engine_list->second.begin();
          engine_ix != engine_list->second.end();
          ++engine_ix) {
-      if (engine_ix->second->IsActive()) {
+      if (engine_ix->second->IsActive())
         return engine_ix->second;
-      }
     }
   }
   return NULL;
@@ -498,7 +432,7 @@
 
 InputImeEventRouter::~InputImeEventRouter() {}
 
-bool SetCompositionFunction::RunImpl() {
+bool InputImeSetCompositionFunction::RunImpl() {
   chromeos::InputMethodEngine* engine =
       InputImeEventRouter::GetInstance()->GetActiveEngine(extension_id());
   if (!engine) {
@@ -506,74 +440,45 @@
     return true;
   }
 
-  base::DictionaryValue* args;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
-  int context_id;
-  std::string text;
-  int selection_start;
-  int selection_end;
-  int cursor;
+  scoped_ptr<SetComposition::Params> parent_params(
+      SetComposition::Params::Create(*args_));
+  const SetComposition::Params::Parameters& params = parent_params->parameters;
   std::vector<chromeos::InputMethodEngine::SegmentInfo> segments;
-
-  EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kContextIdKey,
-                                               &context_id));
-  EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kTextKey, &text));
-  EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kCursorKey, &cursor));
-  if (args->HasKey(keys::kSelectionStartKey)) {
-    EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kSelectionStartKey,
-                                                 &selection_start));
-  } else {
-    selection_start = cursor;
-  }
-  if (args->HasKey(keys::kSelectionEndKey)) {
-    EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kSelectionEndKey,
-                                                 &selection_end));
-  } else {
-    selection_end = cursor;
-  }
-
-  if (args->HasKey(keys::kSegmentsKey)) {
-    base::ListValue* segment_list = NULL;
-    EXTENSION_FUNCTION_VALIDATE(args->GetList(keys::kSegmentsKey,
-                                              &segment_list));
-
-    for (size_t i = 0; i < segment_list->GetSize(); ++i) {
-      base::DictionaryValue* segment = NULL;
-      if (!segment_list->GetDictionary(i, &segment))
-        continue;
-
-      int start;
-      int end;
-      std::string style;
-
-      EXTENSION_FUNCTION_VALIDATE(segment->GetInteger(keys::kStartKey,
-                                                      &start));
-      EXTENSION_FUNCTION_VALIDATE(segment->GetInteger(keys::kEndKey, &end));
-      EXTENSION_FUNCTION_VALIDATE(segment->GetString(keys::kStyleKey, &style));
-
+  if (params.segments) {
+    const std::vector<linked_ptr<
+        SetComposition::Params::Parameters::SegmentsType> >&
+            segments_args = *params.segments;
+    for (size_t i = 0; i < segments_args.size(); ++i) {
+      EXTENSION_FUNCTION_VALIDATE(
+          segments_args[i]->style !=
+          SetComposition::Params::Parameters::SegmentsType::STYLE_NONE);
       segments.push_back(chromeos::InputMethodEngine::SegmentInfo());
-      segments.back().start = start;
-      segments.back().end = end;
-      if (style == keys::kStyleUnderline) {
+      segments.back().start = segments_args[i]->start;
+      segments.back().end = segments_args[i]->end;
+      if (segments_args[i]->style ==
+          SetComposition::Params::Parameters::SegmentsType::STYLE_UNDERLINE) {
         segments.back().style =
             chromeos::InputMethodEngine::SEGMENT_STYLE_UNDERLINE;
-      } else if (style == keys::kStyleDoubleUnderline) {
+      } else {
         segments.back().style =
             chromeos::InputMethodEngine::SEGMENT_STYLE_DOUBLE_UNDERLINE;
       }
     }
   }
 
-  if (engine->SetComposition(context_id, text.c_str(), selection_start,
-                             selection_end, cursor, segments, &error_)) {
-    SetResult(Value::CreateBooleanValue(true));
-  } else {
-    SetResult(Value::CreateBooleanValue(false));
-  }
+  int selection_start =
+      params.selection_start ? *params.selection_start : params.cursor;
+  int selection_end =
+      params.selection_end ? *params.selection_end : params.cursor;
+
+  SetResult(Value::CreateBooleanValue(
+      engine->SetComposition(params.context_id, params.text.c_str(),
+                             selection_start, selection_end, params.cursor,
+                             segments, &error_)));
   return true;
 }
 
-bool ClearCompositionFunction::RunImpl() {
+bool InputImeClearCompositionFunction::RunImpl() {
   chromeos::InputMethodEngine* engine =
       InputImeEventRouter::GetInstance()->GetActiveEngine(extension_id());
   if (!engine) {
@@ -581,22 +486,17 @@
     return true;
   }
 
-  base::DictionaryValue* args;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
-  int context_id;
+  scoped_ptr<ClearComposition::Params> parent_params(
+      ClearComposition::Params::Create(*args_));
+  const ClearComposition::Params::Parameters& params =
+      parent_params->parameters;
 
-  EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kContextIdKey,
-                                               &context_id));
-
-  if (engine->ClearComposition(context_id, &error_)) {
-    SetResult(Value::CreateBooleanValue(true));
-  } else {
-    SetResult(Value::CreateBooleanValue(false));
-  }
+  SetResult(Value::CreateBooleanValue(
+      engine->ClearComposition(params.context_id, &error_)));
   return true;
 }
 
-bool CommitTextFunction::RunImpl() {
+bool InputImeCommitTextFunction::RunImpl() {
   // TODO(zork): Support committing when not active.
   chromeos::InputMethodEngine* engine =
       InputImeEventRouter::GetInstance()->GetActiveEngine(extension_id());
@@ -605,99 +505,67 @@
     return true;
   }
 
-  base::DictionaryValue* args;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
-  int context_id;
-  std::string text;
+  scoped_ptr<CommitText::Params> parent_params(
+      CommitText::Params::Create(*args_));
+  const CommitText::Params::Parameters& params =
+      parent_params->parameters;
 
-  EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kContextIdKey,
-                                                     &context_id));
-  EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kTextKey, &text));
-
-  if (engine->CommitText(context_id, text.c_str(), &error_)) {
-    SetResult(Value::CreateBooleanValue(true));
-  } else {
-    SetResult(Value::CreateBooleanValue(false));
-  }
+  SetResult(Value::CreateBooleanValue(
+      engine->CommitText(params.context_id, params.text.c_str(), &error_)));
   return true;
 }
 
-bool SetCandidateWindowPropertiesFunction::RunImpl() {
-  base::DictionaryValue* args;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
-
-  std::string engine_id;
-  EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kEngineIdKey, &engine_id));
+bool InputImeSetCandidateWindowPropertiesFunction::RunImpl() {
+  scoped_ptr<SetCandidateWindowProperties::Params> parent_params(
+      SetCandidateWindowProperties::Params::Create(*args_));
+  const SetCandidateWindowProperties::Params::Parameters&
+      params = parent_params->parameters;
 
   chromeos::InputMethodEngine* engine =
-      InputImeEventRouter::GetInstance()->GetEngine(extension_id(), engine_id);
+      InputImeEventRouter::GetInstance()->GetEngine(extension_id(),
+                                                    params.engine_id);
+
   if (!engine) {
     SetResult(Value::CreateBooleanValue(false));
     return true;
   }
 
-  base::DictionaryValue* properties;
-  EXTENSION_FUNCTION_VALIDATE(args->GetDictionary(keys::kPropertiesKey,
-                                                  &properties));
+  const SetCandidateWindowProperties::Params::Parameters::Properties&
+      properties = params.properties;
 
-  if (properties->HasKey(keys::kVisibleKey)) {
-    bool visible;
-    EXTENSION_FUNCTION_VALIDATE(properties->GetBoolean(keys::kVisibleKey,
-                                                       &visible));
-    if (!engine->SetCandidateWindowVisible(visible, &error_)) {
-      SetResult(Value::CreateBooleanValue(false));
-      return true;
-    }
+  if (properties.visible &&
+      !engine->SetCandidateWindowVisible(*properties.visible, &error_)) {
+    SetResult(Value::CreateBooleanValue(false));
+    return true;
   }
 
-  if (properties->HasKey(keys::kCursorVisibleKey)) {
-    bool visible;
-    EXTENSION_FUNCTION_VALIDATE(properties->GetBoolean(keys::kCursorVisibleKey,
-                                                       &visible));
-    engine->SetCandidateWindowCursorVisible(visible);
+  if (properties.cursor_visible)
+    engine->SetCandidateWindowCursorVisible(*properties.cursor_visible);
+
+  if (properties.vertical)
+    engine->SetCandidateWindowVertical(*properties.vertical);
+
+  if (properties.page_size)
+    engine->SetCandidateWindowPageSize(*properties.page_size);
+
+  if (properties.auxiliary_text)
+    engine->SetCandidateWindowAuxText(properties.auxiliary_text->c_str());
+
+  if (properties.auxiliary_text_visible) {
+    engine->SetCandidateWindowAuxTextVisible(
+        *properties.auxiliary_text_visible);
   }
 
-  if (properties->HasKey(keys::kVerticalKey)) {
-    bool vertical;
-    EXTENSION_FUNCTION_VALIDATE(properties->GetBoolean(keys::kVerticalKey,
-                                                       &vertical));
-    engine->SetCandidateWindowVertical(vertical);
-  }
-
-  if (properties->HasKey(keys::kPageSizeKey)) {
-    int page_size;
-    EXTENSION_FUNCTION_VALIDATE(properties->GetInteger(keys::kPageSizeKey,
-                                                       &page_size));
-    engine->SetCandidateWindowPageSize(page_size);
-  }
-
-  if (properties->HasKey(keys::kAuxiliaryTextKey)) {
-    std::string aux_text;
-    EXTENSION_FUNCTION_VALIDATE(properties->GetString(keys::kAuxiliaryTextKey,
-                                                      &aux_text));
-    engine->SetCandidateWindowAuxText(aux_text.c_str());
-  }
-
-  if (properties->HasKey(keys::kAuxiliaryTextVisibleKey)) {
-    bool visible;
-    EXTENSION_FUNCTION_VALIDATE(properties->GetBoolean(
-        keys::kAuxiliaryTextVisibleKey,
-        &visible));
-    engine->SetCandidateWindowAuxTextVisible(visible);
-  }
-
-  if (properties->HasKey(keys::kWindowPositionKey)) {
-    // TODO(nona): Switch to scheme compiler. (crbug.com/235552)
-    chromeos::InputMethodEngine::CandidateWindowPosition window_position =
-      chromeos::InputMethodEngine::WINDOW_POS_CURSOR;
-    std::string position_in_str;
-    EXTENSION_FUNCTION_VALIDATE(properties->GetString(
-        keys::kWindowPositionKey,
-        &position_in_str));
-    window_position = (position_in_str == kWindowPositionComposition) ?
-        chromeos::InputMethodEngine::WINDOW_POS_COMPOSITTION :
-        chromeos::InputMethodEngine::WINDOW_POS_CURSOR;
-    engine->SetCandidateWindowPosition(window_position);
+  if (properties.window_position ==
+      SetCandidateWindowProperties::Params::Parameters::Properties::
+          WINDOW_POSITION_COMPOSITION) {
+    engine->SetCandidateWindowPosition(
+        chromeos::InputMethodEngine::WINDOW_POS_COMPOSITTION);
+  } else if (properties.window_position ==
+             SetCandidateWindowProperties::Params::Parameters::Properties::
+                 WINDOW_POSITION_CURSOR) {
+    engine->SetCandidateWindowPosition(
+        chromeos::InputMethodEngine::WINDOW_POS_CURSOR);
   }
 
   SetResult(Value::CreateBooleanValue(true));
@@ -706,65 +574,7 @@
 }
 
 #if defined(OS_CHROMEOS)
-bool SetCandidatesFunction::ReadCandidates(
-    base::ListValue* candidates,
-    std::vector<chromeos::InputMethodEngine::Candidate>* output) {
-  for (size_t i = 0; i < candidates->GetSize(); ++i) {
-    base::DictionaryValue* candidate_dict;
-    EXTENSION_FUNCTION_VALIDATE(candidates->GetDictionary(i, &candidate_dict));
-
-    std::string candidate;
-    int id;
-    std::string label;
-    std::string annotation;
-    chromeos::InputMethodEngine::UsageEntry usage_entry;
-
-    EXTENSION_FUNCTION_VALIDATE(candidate_dict->GetString(keys::kCandidateKey,
-                                                          &candidate));
-    EXTENSION_FUNCTION_VALIDATE(candidate_dict->GetInteger(keys::kIdKey, &id));
-
-    if (candidate_dict->HasKey(keys::kLabelKey)) {
-      EXTENSION_FUNCTION_VALIDATE(candidate_dict->GetString(keys::kLabelKey,
-                                                            &label));
-    }
-    if (candidate_dict->HasKey(keys::kAnnotationKey)) {
-      EXTENSION_FUNCTION_VALIDATE(candidate_dict->GetString(
-          keys::kAnnotationKey,
-          &annotation));
-    }
-
-    if (candidate_dict->HasKey(keys::kUsageKey)) {
-      base::DictionaryValue* usage_dict;
-      EXTENSION_FUNCTION_VALIDATE(candidate_dict->GetDictionary(keys::kUsageKey,
-                                                                &usage_dict));
-      EXTENSION_FUNCTION_VALIDATE(usage_dict->GetString(keys::kUsageTitleKey,
-                                                        &usage_entry.title));
-      EXTENSION_FUNCTION_VALIDATE(usage_dict->GetString(keys::kUsageBodyKey,
-                                                        &usage_entry.body));
-    }
-
-    output->push_back(chromeos::InputMethodEngine::Candidate());
-    output->back().value = candidate;
-    output->back().id = id;
-    output->back().label = label;
-    output->back().annotation = annotation;
-    output->back().usage = usage_entry;
-
-    if (candidate_dict->HasKey(keys::kCandidatesKey)) {
-      base::ListValue* sub_list;
-      EXTENSION_FUNCTION_VALIDATE(candidate_dict->GetList(keys::kCandidatesKey,
-                                                          &sub_list));
-      if (!ReadCandidates(sub_list, &(output->back().candidates))) {
-        error_ = kErrorBadCandidateList;
-        return false;
-      }
-    }
-  }
-
-  return true;
-}
-
-bool SetCandidatesFunction::RunImpl() {
+bool InputImeSetCandidatesFunction::RunImpl() {
   chromeos::InputMethodEngine* engine =
       InputImeEventRouter::GetInstance()->GetActiveEngine(extension_id());
   if (!engine) {
@@ -772,33 +582,35 @@
     return true;
   }
 
-  base::DictionaryValue* args;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
+  scoped_ptr<SetCandidates::Params> parent_params(
+      SetCandidates::Params::Create(*args_));
+  const SetCandidates::Params::Parameters& params =
+      parent_params->parameters;
 
-  int context_id;
-  std::vector<chromeos::InputMethodEngine::Candidate> candidates;
-
-  EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kContextIdKey,
-                                                     &context_id));
-
-  base::ListValue* candidate_list;
-  EXTENSION_FUNCTION_VALIDATE(args->GetList(keys::kCandidatesKey,
-                                            &candidate_list));
-  if (!ReadCandidates(candidate_list, &candidates)) {
-    error_ = kErrorBadCandidateList;
-    return false;
+  std::vector<chromeos::InputMethodEngine::Candidate> candidates_out;
+  const std::vector<linked_ptr<
+      SetCandidates::Params::Parameters::CandidatesType> >& candidates_in =
+          params.candidates;
+  for (size_t i = 0; i < candidates_in.size(); ++i) {
+    candidates_out.push_back(chromeos::InputMethodEngine::Candidate());
+    candidates_out.back().value = candidates_in[i]->candidate;
+    candidates_out.back().id = candidates_in[i]->id;
+    if (candidates_in[i]->label)
+      candidates_out.back().label = *candidates_in[i]->label;
+    if (candidates_in[i]->annotation)
+      candidates_out.back().annotation = *candidates_in[i]->annotation;
+    if (candidates_in[i]->usage) {
+      candidates_out.back().usage.title = candidates_in[i]->usage->title;
+      candidates_out.back().usage.body = candidates_in[i]->usage->body;
+    }
   }
 
-  std::string error;
-  if (engine->SetCandidates(context_id, candidates, &error_)) {
-    SetResult(Value::CreateBooleanValue(true));
-  } else {
-    SetResult(Value::CreateBooleanValue(false));
-  }
+  SetResult(Value::CreateBooleanValue(
+      engine->SetCandidates(params.context_id, candidates_out, &error_)));
   return true;
 }
 
-bool SetCursorPositionFunction::RunImpl() {
+bool InputImeSetCursorPositionFunction::RunImpl() {
   chromeos::InputMethodEngine* engine =
       InputImeEventRouter::GetInstance()->GetActiveEngine(extension_id());
   if (!engine) {
@@ -806,112 +618,95 @@
     return true;
   }
 
-  base::DictionaryValue* args;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
-  int context_id;
-  int candidate_id;
+  scoped_ptr<SetCursorPosition::Params> parent_params(
+      SetCursorPosition::Params::Create(*args_));
+  const SetCursorPosition::Params::Parameters& params =
+      parent_params->parameters;
 
-  EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kContextIdKey,
-                                               &context_id));
-  EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kCandidateIdKey,
-                                               &candidate_id));
-
-  if (engine->SetCursorPosition(context_id, candidate_id, &error_)) {
-    SetResult(Value::CreateBooleanValue(true));
-  } else {
-    SetResult(Value::CreateBooleanValue(false));
-  }
+  SetResult(Value::CreateBooleanValue(
+      engine->SetCursorPosition(params.context_id, params.candidate_id,
+                                &error_)));
   return true;
 }
 
-bool SetMenuItemsFunction::RunImpl() {
-  base::DictionaryValue* args;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
-
-  std::string engine_id;
-  EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kEngineIdKey, &engine_id));
+bool InputImeSetMenuItemsFunction::RunImpl() {
+  scoped_ptr<SetMenuItems::Params> parent_params(
+      SetMenuItems::Params::Create(*args_));
+  const SetMenuItems::Params::Parameters& params =
+      parent_params->parameters;
 
   chromeos::InputMethodEngine* engine =
-      InputImeEventRouter::GetInstance()->GetEngine(extension_id(), engine_id);
+      InputImeEventRouter::GetInstance()->GetEngine(extension_id(),
+                                                    params.engine_id);
   if (!engine) {
     error_ = kErrorEngineNotAvailable;
     return false;
   }
 
-  base::ListValue* items;
-  EXTENSION_FUNCTION_VALIDATE(args->GetList(keys::kItemsKey, &items));
+  const std::vector<linked_ptr<input_ime::MenuItem> >& items = params.items;
+  std::vector<chromeos::InputMethodEngine::MenuItem> items_out;
 
-  std::vector<chromeos::InputMethodEngine::MenuItem> menu_items;
-  EXTENSION_FUNCTION_VALIDATE(ReadMenuItems(items, &menu_items));
+  for (size_t i = 0; i < items.size(); ++i) {
+    items_out.push_back(chromeos::InputMethodEngine::MenuItem());
+    SetMenuItemToMenu(*items[i], &items_out.back());
+  }
 
-  if (!engine->SetMenuItems(menu_items)) {
+  if (!engine->SetMenuItems(items_out))
     error_ = kErrorSetMenuItemsFail;
-  }
   return true;
 }
 
-bool UpdateMenuItemsFunction::RunImpl() {
-  base::DictionaryValue* args;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
-
-  std::string engine_id;
-  EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kEngineIdKey, &engine_id));
+bool InputImeUpdateMenuItemsFunction::RunImpl() {
+  scoped_ptr<UpdateMenuItems::Params> parent_params(
+      UpdateMenuItems::Params::Create(*args_));
+  const UpdateMenuItems::Params::Parameters& params =
+      parent_params->parameters;
 
   chromeos::InputMethodEngine* engine =
-      InputImeEventRouter::GetInstance()->GetEngine(extension_id(), engine_id);
+      InputImeEventRouter::GetInstance()->GetEngine(extension_id(),
+                                                    params.engine_id);
   if (!engine) {
     error_ = kErrorEngineNotAvailable;
     return false;
   }
 
-  base::ListValue* items;
-  EXTENSION_FUNCTION_VALIDATE(args->GetList(keys::kItemsKey, &items));
+  const std::vector<linked_ptr<input_ime::MenuItem> >& items = params.items;
+  std::vector<chromeos::InputMethodEngine::MenuItem> items_out;
 
-  std::vector<chromeos::InputMethodEngine::MenuItem> menu_items;
-  EXTENSION_FUNCTION_VALIDATE(ReadMenuItems(items, &menu_items));
+  for (size_t i = 0; i < items.size(); ++i) {
+    items_out.push_back(chromeos::InputMethodEngine::MenuItem());
+    SetMenuItemToMenu(*items[i], &items_out.back());
+  }
 
-  if (!engine->UpdateMenuItems(menu_items)) {
+  if (!engine->UpdateMenuItems(items_out))
     error_ = kErrorUpdateMenuItemsFail;
-  }
   return true;
 }
 
-bool DeleteSurroundingTextFunction::RunImpl() {
-  base::DictionaryValue* args;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
-
-  std::string engine_id;
-  EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kEngineIdKey, &engine_id));
+bool InputImeDeleteSurroundingTextFunction::RunImpl() {
+  scoped_ptr<DeleteSurroundingText::Params> parent_params(
+      DeleteSurroundingText::Params::Create(*args_));
+  const DeleteSurroundingText::Params::Parameters& params =
+      parent_params->parameters;
 
   chromeos::InputMethodEngine* engine =
-      InputImeEventRouter::GetInstance()->GetEngine(extension_id(), engine_id);
+      InputImeEventRouter::GetInstance()->GetEngine(extension_id(),
+                                                    params.engine_id);
   if (!engine) {
     error_ = kErrorEngineNotAvailable;
     return false;
   }
 
-  int context_id = 0;
-  int offset = 0;
-  int length = 0;
-  EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kContextIdKey,
-                                               &context_id));
-  EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kOffsetKey, &offset));
-  EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kLengthKey, &length));
-
-  engine->DeleteSurroundingText(context_id, offset, length, &error_);
+  engine->DeleteSurroundingText(params.context_id, params.offset, params.length,
+                                &error_);
   return true;
 }
 
-bool KeyEventHandled::RunImpl() {
-  std::string request_id_str;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &request_id_str));
-
-  bool handled = false;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &handled));
-
+bool InputImeKeyEventHandledFunction::RunImpl() {
+  scoped_ptr<KeyEventHandled::Params> params(
+      KeyEventHandled::Params::Create(*args_));
   InputImeEventRouter::GetInstance()->OnKeyEventHandled(
-      extension_id(), request_id_str, handled);
-
+      extension_id(), params->request_id, params->response);
   return true;
 }
 #endif
@@ -922,19 +717,6 @@
                  content::Source<Profile>(profile));
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
                  content::Source<Profile>(profile));
-
-  ExtensionFunctionRegistry* registry =
-      ExtensionFunctionRegistry::GetInstance();
-  registry->RegisterFunction<SetCompositionFunction>();
-  registry->RegisterFunction<ClearCompositionFunction>();
-  registry->RegisterFunction<CommitTextFunction>();
-  registry->RegisterFunction<SetCandidateWindowPropertiesFunction>();
-  registry->RegisterFunction<SetCandidatesFunction>();
-  registry->RegisterFunction<SetCursorPositionFunction>();
-  registry->RegisterFunction<SetMenuItemsFunction>();
-  registry->RegisterFunction<UpdateMenuItemsFunction>();
-  registry->RegisterFunction<DeleteSurroundingTextFunction>();
-  registry->RegisterFunction<KeyEventHandled>();
 }
 
 InputImeAPI::~InputImeAPI() {
@@ -973,9 +755,8 @@
         extensions::InputComponents::GetInputComponents(extension);
     if (!input_components)
       return;
-    if (input_components->size() > 0) {
+    if (input_components->size() > 0)
       input_ime_event_router()->UnregisterAllImes(profile_, extension->id());
-    }
   }
 }
 
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.h b/chrome/browser/extensions/api/input_ime/input_ime_api.h
index e744195..1eef451 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api.h
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api.h
@@ -69,122 +69,118 @@
   DISALLOW_COPY_AND_ASSIGN(InputImeEventRouter);
 };
 
-class SetCompositionFunction : public SyncExtensionFunction {
+class InputImeSetCompositionFunction : public SyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("input.ime.setComposition",
                              INPUT_IME_SETCOMPOSITION)
 
  protected:
-  virtual ~SetCompositionFunction() {}
+  virtual ~InputImeSetCompositionFunction() {}
 
   // ExtensionFunction:
   virtual bool RunImpl() OVERRIDE;
 };
 
-class ClearCompositionFunction : public SyncExtensionFunction {
+class InputImeClearCompositionFunction : public SyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("input.ime.clearComposition",
                              INPUT_IME_CLEARCOMPOSITION)
 
  protected:
-  virtual ~ClearCompositionFunction() {}
+  virtual ~InputImeClearCompositionFunction() {}
 
   // ExtensionFunction:
   virtual bool RunImpl() OVERRIDE;
 };
 
-class CommitTextFunction : public SyncExtensionFunction {
+class InputImeCommitTextFunction : public SyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("input.ime.commitText", INPUT_IME_COMMITTEXT)
 
  protected:
-  virtual ~CommitTextFunction() {}
+  virtual ~InputImeCommitTextFunction() {}
 
   // ExtensionFunction:
   virtual bool RunImpl() OVERRIDE;
 };
 
-class SetCandidateWindowPropertiesFunction : public SyncExtensionFunction {
+class InputImeSetCandidateWindowPropertiesFunction
+    : public SyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("input.ime.setCandidateWindowProperties",
                              INPUT_IME_SETCANDIDATEWINDOWPROPERTIES)
 
  protected:
-  virtual ~SetCandidateWindowPropertiesFunction() {}
+  virtual ~InputImeSetCandidateWindowPropertiesFunction() {}
 
   // ExtensionFunction:
   virtual bool RunImpl() OVERRIDE;
 };
 
-class SetCandidatesFunction : public SyncExtensionFunction {
+class InputImeSetCandidatesFunction : public SyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("input.ime.setCandidates", INPUT_IME_SETCANDIDATES)
 
  protected:
-  virtual ~SetCandidatesFunction() {}
+  virtual ~InputImeSetCandidatesFunction() {}
 
   // ExtensionFunction:
   virtual bool RunImpl() OVERRIDE;
-
- private:
-  bool ReadCandidates(
-      base::ListValue* candidates,
-      std::vector<chromeos::InputMethodEngine::Candidate>* output);
 };
 
-class SetCursorPositionFunction : public SyncExtensionFunction {
+class InputImeSetCursorPositionFunction : public SyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("input.ime.setCursorPosition",
                              INPUT_IME_SETCURSORPOSITION)
 
  protected:
-  virtual ~SetCursorPositionFunction() {}
+  virtual ~InputImeSetCursorPositionFunction() {}
 
   // ExtensionFunction:
   virtual bool RunImpl() OVERRIDE;
 };
 
-class SetMenuItemsFunction : public SyncExtensionFunction {
+class InputImeSetMenuItemsFunction : public SyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("input.ime.setMenuItems", INPUT_IME_SETMENUITEMS)
 
  protected:
-  virtual ~SetMenuItemsFunction() {}
+  virtual ~InputImeSetMenuItemsFunction() {}
 
   // ExtensionFunction:
   virtual bool RunImpl() OVERRIDE;
 };
 
-class UpdateMenuItemsFunction : public SyncExtensionFunction {
+class InputImeUpdateMenuItemsFunction : public SyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("input.ime.updateMenuItems",
                              INPUT_IME_UPDATEMENUITEMS)
 
  protected:
-  virtual ~UpdateMenuItemsFunction() {}
+  virtual ~InputImeUpdateMenuItemsFunction() {}
 
   // ExtensionFunction:
   virtual bool RunImpl() OVERRIDE;
 };
 
-class DeleteSurroundingTextFunction : public SyncExtensionFunction {
+class InputImeDeleteSurroundingTextFunction : public SyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("input.ime.deleteSurroundingText",
                              INPUT_IME_DELETESURROUNDINGTEXT)
  protected:
-  virtual ~DeleteSurroundingTextFunction() {}
+  virtual ~InputImeDeleteSurroundingTextFunction() {}
 
   // ExtensionFunction:
   virtual bool RunImpl() OVERRIDE;
 };
 
-class KeyEventHandled : public AsyncExtensionFunction {
+class InputImeKeyEventHandledFunction : public AsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("input.ime.keyEventHandled",
                              INPUT_IME_KEYEVENTHANDLED)
 
  protected:
-  virtual ~KeyEventHandled() {}
+  virtual ~InputImeKeyEventHandledFunction() {}
 
   // ExtensionFunction:
   virtual bool RunImpl() OVERRIDE;
diff --git a/chrome/browser/extensions/api/location/location_manager.cc b/chrome/browser/extensions/api/location/location_manager.cc
index 173a44a..5611a43 100644
--- a/chrome/browser/extensions/api/location/location_manager.cc
+++ b/chrome/browser/extensions/api/location/location_manager.cc
@@ -10,9 +10,9 @@
 #include "base/bind.h"
 #include "base/lazy_instance.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_system.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/location.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/permissions/permission_set.h"
diff --git a/chrome/browser/extensions/api/management/management_api.cc b/chrome/browser/extensions/api/management/management_api.cc
index 7f98037..4227330 100644
--- a/chrome/browser/extensions/api/management/management_api.cc
+++ b/chrome/browser/extensions/api/management/management_api.cc
@@ -18,6 +18,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/management/management_api_constants.h"
 #include "chrome/browser/extensions/event_names.h"
 #include "chrome/browser/extensions/event_router.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_utility_messages.h"
 #include "chrome/common/extensions/api/management.h"
 #include "chrome/common/extensions/extension.h"
diff --git a/chrome/browser/extensions/api/management/management_api_browsertest.cc b/chrome/browser/extensions/api/management/management_api_browsertest.cc
index 834cade..9f73188 100644
--- a/chrome/browser/extensions/api/management/management_api_browsertest.cc
+++ b/chrome/browser/extensions/api/management/management_api_browsertest.cc
@@ -7,6 +7,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/management/management_api.h"
 #include "chrome/browser/extensions/api/management/management_api_constants.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/extensions/extension_test_message_listener.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/common/url_constants.h"
diff --git a/chrome/browser/extensions/api/management/management_apitest.cc b/chrome/browser/extensions/api/management/management_apitest.cc
index 9f72e60..0203b2f 100644
--- a/chrome/browser/extensions/api/management/management_apitest.cc
+++ b/chrome/browser/extensions/api/management/management_apitest.cc
@@ -4,6 +4,7 @@
 
 #include <map>
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/manifest.h"
 #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/extensions/api/management/management_browsertest.cc b/chrome/browser/extensions/api/management/management_browsertest.cc
index ae05985..999ae85 100644
--- a/chrome/browser/extensions/api/management/management_browsertest.cc
+++ b/chrome/browser/extensions/api/management/management_browsertest.cc
@@ -7,6 +7,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/prefs/pref_service.h"
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -18,7 +19,6 @@
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc b/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
index 49d55f0..0fec3dc 100644
--- a/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
+++ b/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
@@ -192,8 +192,6 @@
     if (has_read_permission) {
       content::ChildProcessSecurityPolicy* policy =
           ChildProcessSecurityPolicy::GetInstance();
-      if (!policy->CanReadFile(child_id, filesystems[i].path))
-        policy->GrantReadFile(child_id, filesystems[i].path);
       policy->GrantReadFileSystem(child_id, filesystems[i].fsid);
     }
   }
@@ -206,13 +204,6 @@
   WebContents* contents = WebContents::FromRenderViewHost(render_view_host());
   WebContentsModalDialogManager* web_contents_modal_dialog_manager =
       WebContentsModalDialogManager::FromWebContents(contents);
-  // If there's no user gesture associated with the API call, do not show
-  // the dialog.
-  if (!user_gesture()) {
-    GetAndReturnGalleries();
-    return;
-  }
-
   if (!web_contents_modal_dialog_manager) {
     // If there is no WebContentsModalDialogManager, then this contents is
     // probably the background page for an app. Try to find a shell window to
diff --git a/chrome/browser/extensions/api/media_galleries_private/gallery_watch_state_tracker.cc b/chrome/browser/extensions/api/media_galleries_private/gallery_watch_state_tracker.cc
index 309b008..3455232 100644
--- a/chrome/browser/extensions/api/media_galleries_private/gallery_watch_state_tracker.cc
+++ b/chrome/browser/extensions/api/media_galleries_private/gallery_watch_state_tracker.cc
@@ -13,6 +13,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/media_galleries_private/gallery_watch_manager.h"
 #include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.h"
 #include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_event_router.h"
@@ -22,7 +23,6 @@
 #include "chrome/browser/media_galleries/media_file_system_registry.h"
 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc
index 86a414a..e3e974d 100644
--- a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc
+++ b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc
@@ -19,11 +19,11 @@
 #include "chrome/browser/extensions/extension_function.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/extensions/media_galleries_handler.h"
 #include "chrome/browser/media_galleries/media_file_system_registry.h"
 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/storage_monitor/storage_monitor.h"
+#include "chrome/common/extensions/api/media_galleries_private/media_galleries_handler.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_view_host.h"
 
@@ -86,7 +86,6 @@
     : profile_(profile),
       weak_ptr_factory_(this) {
   DCHECK(profile_);
-  (new MediaGalleriesHandlerParser)->Register();
   ExtensionSystem::Get(profile_)->event_router()->RegisterObserver(
       this, event_names::kOnAttachEventName);
   ExtensionSystem::Get(profile_)->event_router()->RegisterObserver(
diff --git a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_apitest.cc b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_apitest.cc
index c85d58a..45737e5 100644
--- a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_apitest.cc
+++ b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_apitest.cc
@@ -19,7 +19,7 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/extensions/api/messaging/message_service.cc b/chrome/browser/extensions/api/messaging/message_service.cc
index 6ef2531..e1ef8b3 100644
--- a/chrome/browser/extensions/api/messaging/message_service.cc
+++ b/chrome/browser/extensions/api/messaging/message_service.cc
@@ -9,8 +9,10 @@
 #include "base/callback.h"
 #include "base/json/json_writer.h"
 #include "base/lazy_instance.h"
+#include "base/metrics/histogram.h"
 #include "base/stl_util.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/messaging/extension_message_port.h"
 #include "chrome/browser/extensions/api/messaging/native_message_port.h"
 #include "chrome/browser/extensions/extension_host.h"
@@ -22,7 +24,6 @@
 #include "chrome/browser/extensions/process_map.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
@@ -35,7 +36,7 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::SiteInstance;
 using content::WebContents;
@@ -105,6 +106,7 @@
 namespace {
 
 static base::StaticAtomicSequenceNumber g_next_channel_id;
+static base::StaticAtomicSequenceNumber g_channel_id_overflow_count;
 
 static content::RenderProcessHost* GetExtensionProcess(
     Profile* profile, const std::string& extension_id) {
@@ -128,9 +130,17 @@
 
 // static
 void MessageService::AllocatePortIdPair(int* port1, int* port2) {
-  int channel_id = g_next_channel_id.GetNext();
-  int port1_id = channel_id * 2;
-  int port2_id = channel_id * 2 + 1;
+  unsigned channel_id =
+      static_cast<unsigned>(g_next_channel_id.GetNext()) % (kint32max/2);
+
+  if (channel_id == 0) {
+    int overflow_count = g_channel_id_overflow_count.GetNext();
+    if (overflow_count > 0)
+      UMA_HISTOGRAM_BOOLEAN("Extensions.AllocatePortIdPairOverflow", true);
+  }
+
+  unsigned port1_id = channel_id * 2;
+  unsigned port2_id = channel_id * 2 + 1;
 
   // Sanity checks to make sure our channel<->port converters are correct.
   DCHECK(IS_OPENER_PORT_ID(port1_id));
diff --git a/chrome/browser/extensions/api/messaging/native_message_process_host.cc b/chrome/browser/extensions/api/messaging/native_message_process_host.cc
index 9187a08..b39ea79 100644
--- a/chrome/browser/extensions/api/messaging/native_message_process_host.cc
+++ b/chrome/browser/extensions/api/messaging/native_message_process_host.cc
@@ -15,11 +15,11 @@
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/extensions/features/feature.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/file_stream.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_util.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/extensions/api/messaging/native_messaging_host_manifest_unittest.cc b/chrome/browser/extensions/api/messaging/native_messaging_host_manifest_unittest.cc
index 4a8a24d..d9236ba 100644
--- a/chrome/browser/extensions/api/messaging/native_messaging_host_manifest_unittest.cc
+++ b/chrome/browser/extensions/api/messaging/native_messaging_host_manifest_unittest.cc
@@ -9,8 +9,8 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/json/string_escape.h"
 #include "extensions/common/url_pattern_set.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/api/messaging/native_process_launcher.cc b/chrome/browser/extensions/api/messaging/native_process_launcher.cc
index c973aa0..a10801e 100644
--- a/chrome/browser/extensions/api/messaging/native_process_launcher.cc
+++ b/chrome/browser/extensions/api/messaging/native_process_launcher.cc
@@ -18,7 +18,7 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc
index b5f9600..d0a5800 100644
--- a/chrome/browser/extensions/api/notifications/notifications_api.cc
+++ b/chrome/browser/extensions/api/notifications/notifications_api.cc
@@ -21,13 +21,13 @@
 #include "chrome/common/extensions/features/feature.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
-#include "googleurl/src/gurl.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_rep.h"
 #include "ui/message_center/message_center_style.h"
 #include "ui/message_center/message_center_util.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/api/notifications/notifications_apitest.cc b/chrome/browser/extensions/api/notifications/notifications_apitest.cc
index 9320262..3a6e2b2 100644
--- a/chrome/browser/extensions/api/notifications/notifications_apitest.cc
+++ b/chrome/browser/extensions/api/notifications/notifications_apitest.cc
@@ -4,10 +4,10 @@
 
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/notifications/notifications_api.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_function_test_utils.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/features/feature.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/extensions/api/omnibox/omnibox_api.cc b/chrome/browser/extensions/api/omnibox/omnibox_api.cc
index 400fc32..64066db 100644
--- a/chrome/browser/extensions/api/omnibox/omnibox_api.cc
+++ b/chrome/browser/extensions/api/omnibox/omnibox_api.cc
@@ -10,6 +10,7 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -19,7 +20,6 @@
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/omnibox.h"
 #include "chrome/common/extensions/api/omnibox/omnibox_handler.h"
 #include "chrome/common/extensions/extension.h"
diff --git a/chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h b/chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h
index f8b2f3c..f13d616 100644
--- a/chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h
+++ b/chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h
@@ -10,13 +10,13 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
 #include "chrome/browser/autocomplete/autocomplete_result.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/omnibox/location_bar.h"
 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
 #include "chrome/browser/ui/omnibox/omnibox_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/test/test_utils.h"
 
 
diff --git a/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc b/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc
index a2bb28b..5eb86da 100644
--- a/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc
+++ b/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc
@@ -48,5 +48,5 @@
   // Flush the message loops to make sure the delete happens.
   content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
   content::RunAllPendingInMessageLoop(content::BrowserThread::IO);
-  ASSERT_FALSE(file_util::PathExists(delegate.temp_file_));
+  ASSERT_FALSE(base::PathExists(delegate.temp_file_));
 }
diff --git a/chrome/browser/extensions/api/page_launcher/page_launcher_api.cc b/chrome/browser/extensions/api/page_launcher/page_launcher_api.cc
index c52a012..e0f8241 100644
--- a/chrome/browser/extensions/api/page_launcher/page_launcher_api.cc
+++ b/chrome/browser/extensions/api/page_launcher/page_launcher_api.cc
@@ -9,7 +9,7 @@
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/common/extensions/api/page_launcher.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/api/permissions/permissions_api.cc b/chrome/browser/extensions/api/permissions/permissions_api.cc
index c758578..0e888eb 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api.cc
+++ b/chrome/browser/extensions/api/permissions/permissions_api.cc
@@ -5,18 +5,18 @@
 #include "chrome/browser/extensions/api/permissions/permissions_api.h"
 
 #include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/permissions/permissions_api_helpers.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/permissions_updater.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/permissions.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/permissions/permissions_data.h"
 #include "chrome/common/extensions/permissions/permissions_info.h"
 #include "extensions/common/error_utils.h"
 #include "extensions/common/url_pattern_set.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc b/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc
index 3ec4abc..22e2015 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc
+++ b/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc
@@ -8,8 +8,8 @@
 #include "chrome/common/extensions/api/permissions.h"
 #include "chrome/common/extensions/permissions/permission_set.h"
 #include "extensions/common/url_pattern_set.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 using extensions::api::permissions::Permissions;
 using extensions::permissions_api_helpers::PackPermissionSet;
diff --git a/chrome/browser/extensions/api/power/power_api_manager.cc b/chrome/browser/extensions/api/power/power_api_manager.cc
index 1a1c37b..849989e 100644
--- a/chrome/browser/extensions/api/power/power_api_manager.cc
+++ b/chrome/browser/extensions/api/power/power_api_manager.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/extensions/api/power/power_api_manager.h"
 
 #include "base/bind.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/extensions/api/power/power_api_unittest.cc b/chrome/browser/extensions/api/power/power_api_unittest.cc
index 9e7ca2e..2f55901 100644
--- a/chrome/browser/extensions/api/power/power_api_unittest.cc
+++ b/chrome/browser/extensions/api/power/power_api_unittest.cc
@@ -11,9 +11,9 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/power/power_api_manager.h"
 #include "chrome/browser/extensions/extension_function_test_utils.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/extensions/api/preference/chrome_direct_setting.cc b/chrome/browser/extensions/api/preference/chrome_direct_setting.cc
new file mode 100644
index 0000000..161ef9b
--- /dev/null
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting.cc
@@ -0,0 +1,128 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/api/preference/chrome_direct_setting.h"
+
+#include "base/containers/hash_tables.h"
+#include "base/prefs/pref_service.h"
+#include "base/values.h"
+#include "chrome/browser/extensions/api/preference/preference_api_constants.h"
+#include "chrome/browser/profiles/profile.h"
+
+namespace extensions {
+namespace chromedirectsetting {
+
+namespace {
+
+class PreferenceWhitelist {
+ public:
+  PreferenceWhitelist() {
+    whitelist_.insert("googlegeolocationaccess.enabled");
+  }
+
+  ~PreferenceWhitelist() {}
+
+  bool IsPreferenceOnWhitelist(const std::string& pref_key){
+    return whitelist_.find(pref_key) != whitelist_.end();
+  }
+
+ private:
+  base::hash_set<std::string> whitelist_;
+
+  DISALLOW_COPY_AND_ASSIGN(PreferenceWhitelist);
+};
+
+static base::LazyInstance<PreferenceWhitelist> preference_whitelist_ =
+    LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
+DirectSettingFunctionBase::DirectSettingFunctionBase() {}
+
+DirectSettingFunctionBase::~DirectSettingFunctionBase() {}
+
+PrefService* DirectSettingFunctionBase::GetPrefService() {
+  return profile()->GetPrefs();
+}
+
+bool DirectSettingFunctionBase::IsCalledFromComponentExtension() {
+  return GetExtension()->location() == Manifest::COMPONENT;
+}
+
+bool DirectSettingFunctionBase::IsPreferenceOnWhitelist(
+    const std::string& pref_key) {
+  return preference_whitelist_.Get().IsPreferenceOnWhitelist(pref_key);
+}
+
+GetDirectSettingFunction::GetDirectSettingFunction() {}
+
+bool GetDirectSettingFunction::RunImpl() {
+  EXTENSION_FUNCTION_VALIDATE(IsCalledFromComponentExtension());
+
+  std::string pref_key;
+  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key));
+  EXTENSION_FUNCTION_VALIDATE(IsPreferenceOnWhitelist(pref_key));
+
+  const PrefService::Preference* preference =
+      GetPrefService()->FindPreference(pref_key.c_str());
+  EXTENSION_FUNCTION_VALIDATE(preference);
+  const base::Value* value = preference->GetValue();
+
+  scoped_ptr<DictionaryValue> result(new DictionaryValue);
+  result->Set(preference_api_constants::kValue, value->DeepCopy());
+  SetResult(result.release());
+
+  return true;
+}
+
+GetDirectSettingFunction::~GetDirectSettingFunction() {}
+
+SetDirectSettingFunction::SetDirectSettingFunction() {}
+
+bool SetDirectSettingFunction::RunImpl() {
+  EXTENSION_FUNCTION_VALIDATE(IsCalledFromComponentExtension());
+
+  std::string pref_key;
+  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key));
+  EXTENSION_FUNCTION_VALIDATE(IsPreferenceOnWhitelist(pref_key));
+
+  DictionaryValue* details = NULL;
+  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details));
+
+  Value* value = NULL;
+  EXTENSION_FUNCTION_VALIDATE(
+      details->Get(preference_api_constants::kValue, &value));
+
+  PrefService* pref_service = GetPrefService();
+  const PrefService::Preference* preference =
+      pref_service->FindPreference(pref_key.c_str());
+  EXTENSION_FUNCTION_VALIDATE(preference);
+
+  EXTENSION_FUNCTION_VALIDATE(value->GetType() == preference->GetType());
+
+  pref_service->Set(pref_key.c_str(), *value);
+
+  return true;
+}
+
+SetDirectSettingFunction::~SetDirectSettingFunction() {}
+
+ClearDirectSettingFunction::ClearDirectSettingFunction() {}
+
+bool ClearDirectSettingFunction::RunImpl() {
+  EXTENSION_FUNCTION_VALIDATE(IsCalledFromComponentExtension());
+
+  std::string pref_key;
+  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key));
+  EXTENSION_FUNCTION_VALIDATE(IsPreferenceOnWhitelist(pref_key));
+  GetPrefService()->ClearPref(pref_key.c_str());
+
+  return true;
+}
+
+ClearDirectSettingFunction::~ClearDirectSettingFunction() {}
+
+}  // namespace chromedirectsetting
+}  // namespace extensions
+
diff --git a/chrome/browser/extensions/api/preference/chrome_direct_setting.h b/chrome/browser/extensions/api/preference/chrome_direct_setting.h
new file mode 100644
index 0000000..1a8164b
--- /dev/null
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting.h
@@ -0,0 +1,87 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_PREFERENCE_CHROME_DIRECT_SETTING_H__
+#define CHROME_BROWSER_EXTENSIONS_API_PREFERENCE_CHROME_DIRECT_SETTING_H__
+
+#include "base/lazy_instance.h"
+#include "chrome/browser/extensions/extension_function.h"
+
+class PrefService;
+
+namespace extensions {
+namespace chromedirectsetting {
+
+// Base class to host instance method helpers.
+class DirectSettingFunctionBase : public SyncExtensionFunction {
+ protected:
+  DirectSettingFunctionBase();
+  virtual ~DirectSettingFunctionBase();
+
+  // Returns the user pref service.
+  PrefService* GetPrefService();
+
+  // Returns true if the caller is a component extension.
+  bool IsCalledFromComponentExtension();
+
+  // Returns true if the preference is on the whitelist.
+  bool IsPreferenceOnWhitelist(const std::string& pref_key);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DirectSettingFunctionBase);
+};
+
+class GetDirectSettingFunction : public DirectSettingFunctionBase {
+ public:
+  DECLARE_EXTENSION_FUNCTION("types.private.ChromeDirectSetting.get",
+                             TYPES_PRIVATE_CHROMEDIRECTSETTING_GET)
+
+  GetDirectSettingFunction();
+
+ protected:
+  // ExtensionFunction:
+  virtual bool RunImpl() OVERRIDE;
+
+ private:
+  virtual ~GetDirectSettingFunction();
+  DISALLOW_COPY_AND_ASSIGN(GetDirectSettingFunction);
+};
+
+class SetDirectSettingFunction : public DirectSettingFunctionBase {
+ public:
+  DECLARE_EXTENSION_FUNCTION("types.private.ChromeDirectSetting.set",
+                             TYPES_PRIVATE_CHROMEDIRECTSETTING_SET)
+
+  SetDirectSettingFunction();
+
+ protected:
+  // ExtensionFunction:
+  virtual bool RunImpl() OVERRIDE;
+
+ private:
+  virtual ~SetDirectSettingFunction();
+  DISALLOW_COPY_AND_ASSIGN(SetDirectSettingFunction);
+};
+
+class ClearDirectSettingFunction : public DirectSettingFunctionBase {
+ public:
+  DECLARE_EXTENSION_FUNCTION("types.private.ChromeDirectSetting.clear",
+                             TYPES_PRIVATE_CHROMEDIRECTSETTING_CLEAR)
+
+  ClearDirectSettingFunction();
+
+ protected:
+  // ExtensionFunction:
+  virtual bool RunImpl() OVERRIDE;
+
+ private:
+  virtual ~ClearDirectSettingFunction();
+  DISALLOW_COPY_AND_ASSIGN(ClearDirectSettingFunction);
+};
+
+}  // namespace chromedirectsetting
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_API_PREFERENCE_CHROME_DIRECT_SETTING_H__
+
diff --git a/chrome/browser/extensions/api/preference/preference_api.cc b/chrome/browser/extensions/api/preference/preference_api.cc
index d5a7faf..b792fd4 100644
--- a/chrome/browser/extensions/api/preference/preference_api.cc
+++ b/chrome/browser/extensions/api/preference/preference_api.cc
@@ -13,6 +13,7 @@
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/preference/preference_api_constants.h"
 #include "chrome/browser/extensions/api/preference/preference_helpers.h"
 #include "chrome/browser/extensions/api/proxy/proxy_api.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/permissions/api_permission.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
@@ -75,10 +75,6 @@
     prefs::kEnableHyperlinkAuditing,
     APIPermission::kPrivacy
   },
-  { "managedModeEnabled",
-    prefs::kInManagedMode,
-    APIPermission::kManagedModePrivate
-  },
   { "networkPredictionEnabled",
     prefs::kNetworkPredictionEnabled,
     APIPermission::kPrivacy
@@ -111,12 +107,6 @@
     prefs::kEnableTranslate,
     APIPermission::kPrivacy
   },
-#if defined(ENABLE_GOOGLE_NOW)
-  { "googlegeolocationaccessEnabled",
-    prefs::kGoogleGeolocationAccessEnabled,
-    APIPermission::kPreferencesPrivate
-  },
-#endif
 };
 
 class IdentityPrefTransformer : public PrefTransformerInterface {
diff --git a/chrome/browser/extensions/api/preference/preference_helpers.cc b/chrome/browser/extensions/api/preference/preference_helpers.cc
index e4192dd..8649f8e 100644
--- a/chrome/browser/extensions/api/preference/preference_helpers.cc
+++ b/chrome/browser/extensions/api/preference/preference_helpers.cc
@@ -8,7 +8,6 @@
 #include "base/prefs/pref_service.h"
 #include "base/values.h"
 #include "chrome/browser/extensions/api/preference/preference_api.h"
-#include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -73,10 +72,7 @@
     return kControlledByThisExtension;
   }
 
-  extensions::ComponentLoader* component_loader =
-      profile->GetExtensionService()->component_loader();
-  if (component_loader->Exists(extension_id) ||
-      PreferenceAPI::Get(profile)->CanExtensionControlPref(extension_id,
+  if (PreferenceAPI::Get(profile)->CanExtensionControlPref(extension_id,
                                                            browser_pref,
                                                            incognito)) {
     return kControllableByThisExtension;
diff --git a/chrome/browser/extensions/api/processes/processes_api.cc b/chrome/browser/extensions/api/processes/processes_api.cc
index 5472844..abe7b1a 100644
--- a/chrome/browser/extensions/api/processes/processes_api.cc
+++ b/chrome/browser/extensions/api/processes/processes_api.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/processes/processes_api_constants.h"
 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
 #include "chrome/browser/extensions/event_router.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/task_manager/resource_provider.h"
 #include "chrome/browser/task_manager/task_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.cc b/chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.cc
index 6063b1f..2603e55 100644
--- a/chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.cc
+++ b/chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.cc
@@ -42,13 +42,6 @@
   }
 }
 
-// Returns a vector of scopes needed to call the API to get obfuscated Gaia ID.
-std::vector<std::string> GetScopes() {
-  std::vector<std::string> scopes;
-  scopes.push_back("https://www.googleapis.com/auth/gcm_for_chrome.readonly");
-  return scopes;
-}
-
 }  // namespace
 
 namespace extensions {
@@ -56,14 +49,21 @@
 ObfuscatedGaiaIdFetcher::ObfuscatedGaiaIdFetcher(
     URLRequestContextGetter* context,
     Delegate* delegate,
-    const std::string& refresh_token)
-    : OAuth2ApiCallFlow(context, refresh_token, std::string(), GetScopes()),
+    const std::string& access_token)
+    : OAuth2ApiCallFlow(context, std::string(), access_token, GetScopes()),
       delegate_(delegate) {
   DCHECK(delegate);
 }
 
 ObfuscatedGaiaIdFetcher::~ObfuscatedGaiaIdFetcher() { }
 
+// Returns a vector of scopes needed to call the API to get obfuscated Gaia ID.
+std::vector<std::string> ObfuscatedGaiaIdFetcher::GetScopes() {
+  std::vector<std::string> scopes;
+  scopes.push_back("https://www.googleapis.com/auth/gcm_for_chrome.readonly");
+  return scopes;
+}
+
 void ObfuscatedGaiaIdFetcher::ReportSuccess(const std::string& obfuscated_id) {
   if (delegate_)
     delegate_->OnObfuscatedGaiaIdFetchSuccess(obfuscated_id);
diff --git a/chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.h b/chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.h
index 54065dc..bcb52b2 100644
--- a/chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.h
+++ b/chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.h
@@ -45,6 +45,8 @@
                           const std::string& refresh_token);
   virtual ~ObfuscatedGaiaIdFetcher();
 
+  static std::vector<std::string> GetScopes();
+
  protected:
   // OAuth2ApiCallFlow implementation
   virtual GURL CreateApiCallUrl() OVERRIDE;
diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc b/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc
index 9d89f17..adc41ea 100644
--- a/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc
+++ b/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc
@@ -11,6 +11,7 @@
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler.h"
 #include "chrome/browser/extensions/event_names.h"
 #include "chrome/browser/extensions/event_router.h"
@@ -22,10 +23,9 @@
 #include "chrome/browser/invalidation/invalidation_service.h"
 #include "chrome/browser/invalidation/invalidation_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/token_service.h"
-#include "chrome/browser/signin/token_service_factory.h"
+#include "chrome/browser/signin/profile_oauth2_token_service.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/push_messaging.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_set.h"
@@ -34,13 +34,15 @@
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "google_apis/gaia/gaia_constants.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
 namespace {
 const char kChannelIdSeparator[] = "/";
 const char kUserNotSignedIn[] = "The user is not signed in.";
+const char kUserAccessTokenFailure[] =
+    "Cannot obtain access token for the user.";
 const char kTokenServiceNotAvailable[] = "Failed to get token service.";
 const int kObfuscatedGaiaIdTimeoutInDays = 30;
 }
@@ -104,16 +106,9 @@
 
   if (!IsUserLoggedIn()) {
     if (interactive_) {
-      LoginUIService* login_ui_service =
-          LoginUIServiceFactory::GetForProfile(profile());
-      TokenService* token_service = TokenServiceFactory::GetForProfile(
-          profile());
-      // Register for token available so we can tell when the logon is done.
-      // Observe() will be called if token is issued.
-      registrar_.Add(this,
-                     chrome::NOTIFICATION_TOKEN_AVAILABLE,
-                     content::Source<TokenService>(token_service));
-      login_ui_service->ShowLoginPopup();
+      ProfileOAuth2TokenServiceFactory::GetForProfile(profile())
+          ->AddObserver(this);
+      LoginUIServiceFactory::GetForProfile(profile())->ShowLoginPopup();
       return true;
     } else {
       error_ = kUserNotSignedIn;
@@ -122,42 +117,55 @@
     }
   }
 
-  return StartGaiaIdFetch();
+  StartAccessTokenFetch();
+  return true;
 }
 
-// If we are in an interactive login and it succeeds, start token fetch.
-void PushMessagingGetChannelIdFunction::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  DCHECK_EQ(chrome::NOTIFICATION_TOKEN_AVAILABLE, type);
-
-  TokenService::TokenAvailableDetails* token_details =
-      content::Details<TokenService::TokenAvailableDetails>(details).ptr();
-  if (token_details->service() == GaiaConstants::kGaiaOAuth2LoginRefreshToken) {
-    TokenService* token_service = TokenServiceFactory::GetForProfile(profile());
-    registrar_.Remove(this,
-                      chrome::NOTIFICATION_TOKEN_AVAILABLE,
-                      content::Source<TokenService>(token_service));
-    // If we got a token, the logon succeeded, continue fetching Obfuscated
-    // Gaia Id.
-    if (!StartGaiaIdFetch())
-      SendResponse(false);
-  }
+void PushMessagingGetChannelIdFunction::StartAccessTokenFetch() {
+  std::vector<std::string> scope_vector =
+      extensions::ObfuscatedGaiaIdFetcher::GetScopes();
+  OAuth2TokenService::ScopeSet scopes(scope_vector.begin(), scope_vector.end());
+  fetcher_access_token_request_ =
+      ProfileOAuth2TokenServiceFactory::GetForProfile(profile())
+          ->StartRequest(scopes, this);
 }
 
-bool PushMessagingGetChannelIdFunction::StartGaiaIdFetch() {
+void PushMessagingGetChannelIdFunction::OnRefreshTokenAvailable(
+    const std::string& account_id) {
+  ProfileOAuth2TokenServiceFactory::GetForProfile(profile())
+      ->RemoveObserver(this);
+  StartAccessTokenFetch();
+}
+
+void PushMessagingGetChannelIdFunction::OnGetTokenSuccess(
+    const OAuth2TokenService::Request* request,
+    const std::string& access_token,
+    const base::Time& expiration_time) {
+  DCHECK_EQ(fetcher_access_token_request_.get(), request);
+  fetcher_access_token_request_.reset();
+
+  StartGaiaIdFetch(access_token);
+}
+
+void PushMessagingGetChannelIdFunction::OnGetTokenFailure(
+    const OAuth2TokenService::Request* request,
+    const GoogleServiceAuthError& error) {
+  DCHECK_EQ(fetcher_access_token_request_.get(), request);
+  fetcher_access_token_request_.reset();
+
+  // TODO(fgorski): We are currently ignoring the error passed in upon failure.
+  // It should be revisited when we are working on improving general error
+  // handling for the identity related code.
+  error_ = kUserAccessTokenFailure;
+  ReportResult(std::string(), error_);
+}
+
+void PushMessagingGetChannelIdFunction::StartGaiaIdFetch(
+    const std::string& access_token) {
   // Start the async fetch of the Gaia Id.
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   net::URLRequestContextGetter* context = profile()->GetRequestContext();
-  TokenService* token_service = TokenServiceFactory::GetForProfile(profile());
-  if (!token_service) {
-    ReportResult(std::string(), std::string(kTokenServiceNotAvailable));
-    return false;
-  }
-  const std::string& refresh_token =
-      token_service->GetOAuth2LoginRefreshToken();
-  fetcher_.reset(new ObfuscatedGaiaIdFetcher(context, this, refresh_token));
+  fetcher_.reset(new ObfuscatedGaiaIdFetcher(context, this, access_token));
 
   // Get the token cache and see if we have already cached a Gaia Id.
   TokenCacheService* token_cache =
@@ -169,21 +177,16 @@
       token_cache->RetrieveToken(GaiaConstants::kObfuscatedGaiaId);
   if (!gaia_id.empty()) {
     ReportResult(gaia_id, std::string());
-    return true;
+    return;
   }
 
   fetcher_->Start();
-
-  // Will finish asynchronously.
-  return true;
 }
 
 // Check if the user is logged in.
 bool PushMessagingGetChannelIdFunction::IsUserLoggedIn() const {
-  TokenService* token_service = TokenServiceFactory::GetForProfile(profile());
-  if (!token_service)
-    return false;
-  return token_service->HasOAuthLoginToken();
+  return ProfileOAuth2TokenServiceFactory::GetForProfile(profile())
+      ->RefreshTokenIsAvailable();
 }
 
 void PushMessagingGetChannelIdFunction::ReportResult(
diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_api.h b/chrome/browser/extensions/api/push_messaging/push_messaging_api.h
index 0fee1f0..70e37a9 100644
--- a/chrome/browser/extensions/api/push_messaging/push_messaging_api.h
+++ b/chrome/browser/extensions/api/push_messaging/push_messaging_api.h
@@ -15,6 +15,7 @@
 #include "chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.h"
 #include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_delegate.h"
 #include "chrome/browser/extensions/extension_function.h"
+#include "chrome/browser/signin/oauth2_token_service.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -53,7 +54,8 @@
 class PushMessagingGetChannelIdFunction
     : public AsyncExtensionFunction,
       public ObfuscatedGaiaIdFetcher::Delegate,
-    public content::NotificationObserver {
+      public OAuth2TokenService::Observer,
+      public OAuth2TokenService::Consumer {
  public:
   PushMessagingGetChannelIdFunction();
 
@@ -73,12 +75,22 @@
                           const std::string& error_message);
 
   // Begin the async fetch of the Gaia ID.
-  bool StartGaiaIdFetch();
+  void StartGaiaIdFetch(const std::string& access_token);
 
-  // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) OVERRIDE;
+  // Begin the async fetch of the access token for Gaia ID fetcher.
+  void StartAccessTokenFetch();
+
+  // OAuth2TokenService::Observer implementation.
+  virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE;
+
+  // OAuth2TokenService::Consumer implementation.
+  virtual void OnGetTokenSuccess(
+      const OAuth2TokenService::Request* request,
+      const std::string& access_token,
+      const base::Time& expiration_time) OVERRIDE;
+  virtual void OnGetTokenFailure(
+      const OAuth2TokenService::Request* request,
+      const GoogleServiceAuthError& error) OVERRIDE;
 
   // Check if the user is signed into chrome.
   bool IsUserLoggedIn() const;
@@ -90,9 +102,7 @@
       const GoogleServiceAuthError& error) OVERRIDE;
   scoped_ptr<ObfuscatedGaiaIdFetcher> fetcher_;
   bool interactive_;
-
-  // We use this to register for notifications if the login attempt succeeds.
-  content::NotificationRegistrar registrar_;
+  scoped_ptr<OAuth2TokenService::Request> fetcher_access_token_request_;
 
   DISALLOW_COPY_AND_ASSIGN(PushMessagingGetChannelIdFunction);
 };
diff --git a/chrome/browser/extensions/api/record/record_api.cc b/chrome/browser/extensions/api/record/record_api.cc
index 866aae0..820c346 100644
--- a/chrome/browser/extensions/api/record/record_api.cc
+++ b/chrome/browser/extensions/api/record/record_api.cc
@@ -125,14 +125,14 @@
 
   // Run the test browser (or a mockup, depending on |process_strategy_|.
   while (repeat_count_-- && errors_.empty() &&
-      !file_util::PathExists(error_file_path))
+      !base::PathExists(error_file_path))
     process_strategy_->RunProcess(line, &errors_);
 
   // Read URL errors file if there is one, and save errors in |errors_|.
   // Odd extension handling needed because temp files have lots of "."s in
   // their names, and we need to cleanly add kURLErrorsSuffix as a final
   // extension.
-  if (errors_.empty() && file_util::PathExists(error_file_path)) {
+  if (errors_.empty() && base::PathExists(error_file_path)) {
     std::string error_content;
     file_util::ReadFileToString(error_file_path, &error_content);
 
diff --git a/chrome/browser/extensions/api/record/record_api_test.cc b/chrome/browser/extensions/api/record/record_api_test.cc
index 4548501..40813a2 100644
--- a/chrome/browser/extensions/api/record/record_api_test.cc
+++ b/chrome/browser/extensions/api/record/record_api_test.cc
@@ -104,15 +104,15 @@
             base::FilePath(base::FilePath::StringType(kMockCacheFile)));
 
         if (command_line.HasSwitch(switches::kRecordMode)) {
-          file_util::CopyFile(url_path, url_path_copy);
+          base::CopyFile(url_path, url_path_copy);
         } else {
-          if (!file_util::ContentsEqual(url_path, url_path_copy)) {
+          if (!base::ContentsEqual(url_path, url_path_copy)) {
             std::string contents1, contents2;
             file_util::ReadFileToString(url_path, &contents1);
             file_util::ReadFileToString(url_path_copy, &contents2);
             LOG(ERROR) << "FILE MISMATCH" << contents1 << " VS " << contents2;
           }
-          EXPECT_TRUE(file_util::ContentsEqual(url_path, url_path_copy));
+          EXPECT_TRUE(base::ContentsEqual(url_path, url_path_copy));
         }
       }
 
@@ -188,7 +188,7 @@
     InProcessBrowserTest::CleanUpOnMainThread();
     for (std::vector<base::FilePath>::const_iterator it = temp_files_.begin();
         it != temp_files_.end(); ++it) {
-      if (!base::Delete(*it, false))
+      if (!base::DeleteFile(*it, false))
         NOTREACHED();
     }
   }
diff --git a/chrome/browser/extensions/api/rtc_private/rtc_private_api.cc b/chrome/browser/extensions/api/rtc_private/rtc_private_api.cc
index 5a0a120..7df7c35 100644
--- a/chrome/browser/extensions/api/rtc_private/rtc_private_api.cc
+++ b/chrome/browser/extensions/api/rtc_private/rtc_private_api.cc
@@ -11,13 +11,13 @@
 #include "base/time/time.h"
 #include "base/value_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/contacts/contact.pb.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/state_store.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/rtc_private.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/extensions/api/rtc_private/rtc_private_apitest.cc b/chrome/browser/extensions/api/rtc_private/rtc_private_apitest.cc
index d0bd835..ba0cf57 100644
--- a/chrome/browser/extensions/api/rtc_private/rtc_private_apitest.cc
+++ b/chrome/browser/extensions/api/rtc_private/rtc_private_apitest.cc
@@ -13,7 +13,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/extensions/api/runtime/runtime_api.cc b/chrome/browser/extensions/api/runtime/runtime_api.cc
index c04d181..146410f 100644
--- a/chrome/browser/extensions/api/runtime/runtime_api.cc
+++ b/chrome/browser/extensions/api/runtime/runtime_api.cc
@@ -10,6 +10,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
@@ -22,7 +23,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/omaha_query_params/omaha_query_params.h"
@@ -31,7 +31,7 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "extensions/common/error_utils.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 #include "webkit/browser/fileapi/isolated_context.h"
 
 namespace GetPlatformInfo = extensions::api::runtime::GetPlatformInfo;
@@ -426,10 +426,6 @@
   content::ChildProcessSecurityPolicy* policy =
       content::ChildProcessSecurityPolicy::GetInstance();
   policy->GrantReadFileSystem(renderer_id, filesystem_id);
-
-  if (!policy->CanReadFile(renderer_id, path))
-    policy->GrantReadFile(renderer_id, path);
-
   base::DictionaryValue* dict = new base::DictionaryValue();
   SetResult(dict);
   dict->SetString("fileSystemId", filesystem_id);
diff --git a/chrome/browser/extensions/api/socket/socket.cc b/chrome/browser/extensions/api/socket/socket.cc
index 0f526a2..845b895 100644
--- a/chrome/browser/extensions/api/socket/socket.cc
+++ b/chrome/browser/extensions/api/socket/socket.cc
@@ -85,10 +85,6 @@
     WriteData();
 }
 
-bool Socket::IsConnected() {
-  return is_connected_;
-}
-
 bool Socket::SetKeepAlive(bool enable, int delay) {
   return false;
 }
diff --git a/chrome/browser/extensions/api/socket/socket.h b/chrome/browser/extensions/api/socket/socket.h
index e1e5fb9..2e73cb0 100644
--- a/chrome/browser/extensions/api/socket/socket.h
+++ b/chrome/browser/extensions/api/socket/socket.h
@@ -76,7 +76,7 @@
                      std::string* error_msg);
   virtual void Accept(const AcceptCompletionCallback &callback);
 
-  bool IsConnected();
+  virtual bool IsConnected() = 0;
 
   virtual bool GetPeerAddress(net::IPEndPoint* address) = 0;
   virtual bool GetLocalAddress(net::IPEndPoint* address) = 0;
diff --git a/chrome/browser/extensions/api/socket/tcp_socket.cc b/chrome/browser/extensions/api/socket/tcp_socket.cc
index 832e114..d685ab2 100644
--- a/chrome/browser/extensions/api/socket/tcp_socket.cc
+++ b/chrome/browser/extensions/api/socket/tcp_socket.cc
@@ -41,8 +41,9 @@
 // static
 TCPSocket* TCPSocket::CreateSocketForTesting(
     net::TCPClientSocket* tcp_client_socket,
-    const std::string& owner_extension_id) {
-  return new TCPSocket(tcp_client_socket, owner_extension_id);
+    const std::string& owner_extension_id,
+    bool is_connected) {
+  return new TCPSocket(tcp_client_socket, owner_extension_id, is_connected);
 }
 
 // static
@@ -127,7 +128,7 @@
       break;
     }
 
-    if (!socket_.get() || !socket_->IsConnected()) {
+    if (!socket_.get() || !IsConnected()) {
         result = net::ERR_SOCKET_NOT_CONNECTED;
         break;
     }
@@ -183,7 +184,6 @@
   if (!server_socket_.get()) {
     server_socket_.reset(new net::TCPServerSocket(NULL,
                                                   net::NetLog::Source()));
-    server_socket_->AllowAddressReuse();
   }
   int result = server_socket_->Listen(*bind_address, backlog);
   if (result)
@@ -215,6 +215,11 @@
   }
 }
 
+bool TCPSocket::IsConnected() {
+  RefreshConnectionStatus();
+  return is_connected_;
+}
+
 bool TCPSocket::GetPeerAddress(net::IPEndPoint* address) {
   if (!socket_.get())
     return false;
@@ -240,12 +245,21 @@
                          const net::CompletionCallback& callback) {
   if (socket_mode_ != CLIENT)
     return net::ERR_FAILED;
-  else if (!socket_.get() || !socket_->IsConnected())
+  else if (!socket_.get() || !IsConnected())
     return net::ERR_SOCKET_NOT_CONNECTED;
   else
     return socket_->Write(io_buffer, io_buffer_size, callback);
 }
 
+void TCPSocket::RefreshConnectionStatus() {
+  if (!is_connected_) return;
+  if (server_socket_) return;
+  if (!socket_->IsConnected()) {
+    is_connected_ = false;
+    socket_->Disconnect();
+  }
+}
+
 void TCPSocket::OnConnectComplete(int result) {
   DCHECK(!connect_callback_.is_null());
   DCHECK(!is_connected_);
diff --git a/chrome/browser/extensions/api/socket/tcp_socket.h b/chrome/browser/extensions/api/socket/tcp_socket.h
index c0b0b0f..3c6547c 100644
--- a/chrome/browser/extensions/api/socket/tcp_socket.h
+++ b/chrome/browser/extensions/api/socket/tcp_socket.h
@@ -49,13 +49,16 @@
                      int backlog, std::string* error_msg) OVERRIDE;
   virtual void Accept(const AcceptCompletionCallback &callback) OVERRIDE;
 
+  virtual bool IsConnected() OVERRIDE;
+
   virtual bool GetPeerAddress(net::IPEndPoint* address) OVERRIDE;
   virtual bool GetLocalAddress(net::IPEndPoint* address) OVERRIDE;
   virtual Socket::SocketType GetSocketType() const OVERRIDE;
 
   static TCPSocket* CreateSocketForTesting(
       net::TCPClientSocket* tcp_client_socket,
-      const std::string& owner_extension_id);
+      const std::string& owner_extension_id,
+      bool is_connected = false);
   static TCPSocket* CreateServerSocketForTesting(
       net::TCPServerSocket* tcp_server_socket,
       const std::string& owner_extension_id);
@@ -66,6 +69,7 @@
                         const net::CompletionCallback& callback) OVERRIDE;
 
  private:
+  void RefreshConnectionStatus();
   void OnConnectComplete(int result);
   void OnReadComplete(scoped_refptr<net::IOBuffer> io_buffer,
                       int result);
diff --git a/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc b/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
index 0170397..9919805 100644
--- a/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
+++ b/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
@@ -73,7 +73,7 @@
   CompleteHandler handler;
 
   scoped_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting(
-      tcp_client_socket, FAKE_ID));
+      tcp_client_socket, FAKE_ID, true));
 
   EXPECT_CALL(*tcp_client_socket, Read(_, _, _))
       .Times(1);
@@ -91,7 +91,7 @@
   CompleteHandler handler;
 
   scoped_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting(
-      tcp_client_socket, FAKE_ID));
+      tcp_client_socket, FAKE_ID, true));
 
   net::CompletionCallback callback;
   EXPECT_CALL(*tcp_client_socket, Write(_, _, _))
@@ -113,7 +113,7 @@
   CompleteHandler handler;
 
   scoped_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting(
-      tcp_client_socket, FAKE_ID));
+      tcp_client_socket, FAKE_ID, true));
 
   net::CompletionCallback callback;
   EXPECT_CALL(*tcp_client_socket, Write(_, _, _))
@@ -138,7 +138,7 @@
   CompleteHandler handlers[5];
 
   scoped_ptr<TCPSocket> socket(TCPSocket::CreateSocketForTesting(
-      tcp_client_socket, FAKE_ID));
+      tcp_client_socket, FAKE_ID, true));
 
   net::CompletionCallback callback;
   EXPECT_CALL(*tcp_client_socket, Write(_, _, _))
diff --git a/chrome/browser/extensions/api/socket/udp_socket.cc b/chrome/browser/extensions/api/socket/udp_socket.cc
index 3f6080d..4a77aea 100644
--- a/chrome/browser/extensions/api/socket/udp_socket.cc
+++ b/chrome/browser/extensions/api/socket/udp_socket.cc
@@ -186,6 +186,10 @@
     OnSendToComplete(result);
 }
 
+bool UDPSocket::IsConnected() {
+  return is_connected_;
+}
+
 bool UDPSocket::GetPeerAddress(net::IPEndPoint* address) {
   return !socket_.GetPeerAddress(address);
 }
diff --git a/chrome/browser/extensions/api/socket/udp_socket.h b/chrome/browser/extensions/api/socket/udp_socket.h
index 5e02850..b301cb2 100644
--- a/chrome/browser/extensions/api/socket/udp_socket.h
+++ b/chrome/browser/extensions/api/socket/udp_socket.h
@@ -32,6 +32,9 @@
                       const std::string& address,
                       int port,
                       const CompletionCallback& callback) OVERRIDE;
+
+  virtual bool IsConnected() OVERRIDE;
+
   virtual bool GetPeerAddress(net::IPEndPoint* address) OVERRIDE;
   virtual bool GetLocalAddress(net::IPEndPoint* address) OVERRIDE;
   virtual Socket::SocketType GetSocketType() const OVERRIDE;
diff --git a/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc b/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc
index ecc2573..8c43e53 100644
--- a/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc
+++ b/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/extensions/api/spellcheck/spellcheck_api.h"
 
 #include "base/lazy_instance.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/spellchecker/spellcheck_factory.h"
 #include "chrome/browser/spellchecker/spellcheck_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/spellcheck/spellcheck_handler.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/extensions/api/storage/managed_value_store_cache.cc b/chrome/browser/extensions/api/storage/managed_value_store_cache.cc
index 6710a32..6184cfc 100644
--- a/chrome/browser/extensions/api/storage/managed_value_store_cache.cc
+++ b/chrome/browser/extensions/api/storage/managed_value_store_cache.cc
@@ -11,25 +11,25 @@
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop_proxy.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/storage/policy_value_store.h"
 #include "chrome/browser/extensions/api/storage/settings_storage_factory.h"
-#include "chrome/browser/extensions/api/storage/storage_schema_manifest_handler.h"
 #include "chrome/browser/extensions/event_names.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/policy/policy_domain_descriptor.h"
-#include "chrome/browser/policy/policy_schema.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
 #include "chrome/browser/policy/profile_policy_connector_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/value_store/value_store_change.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/extensions/api/storage/storage_schema_manifest_handler.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "chrome/common/extensions/extension_set.h"
 #include "chrome/common/extensions/manifest.h"
 #include "chrome/common/extensions/permissions/api_permission.h"
+#include "chrome/common/policy/policy_schema.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -186,8 +186,6 @@
   GetPolicyService()->AddObserver(policy::POLICY_DOMAIN_EXTENSIONS, this);
 
   extension_tracker_.reset(new ExtensionTracker(profile_));
-
-  (new StorageSchemaManifestHandler)->Register();
 }
 
 ManagedValueStoreCache::~ManagedValueStoreCache() {
@@ -237,7 +235,7 @@
     // (because the extension is unloaded, for example). Open the database to
     // clear it if it exists.
     // TODO(joaodasilva): move this check to a ValueStore method.
-    if (file_util::DirectoryExists(base_path_.AppendASCII(extension_id))) {
+    if (base::DirectoryExists(base_path_.AppendASCII(extension_id))) {
       CreateStoreFor(
           extension_id,
           false,
@@ -385,7 +383,7 @@
     // If the database doesn't exist yet then this is the initial install,
     // and no notifications should be issued in that case.
     // TODO(joaodasilva): move this check to a ValueStore method.
-    if (!file_util::DirectoryExists(base_path_.AppendASCII(extension_id)))
+    if (!base::DirectoryExists(base_path_.AppendASCII(extension_id)))
       notify_if_changed = false;
 
     store = new PolicyValueStore(
diff --git a/chrome/browser/extensions/api/storage/policy_value_store_unittest.cc b/chrome/browser/extensions/api/storage/policy_value_store_unittest.cc
index dc3a183..627dbfc 100644
--- a/chrome/browser/extensions/api/storage/policy_value_store_unittest.cc
+++ b/chrome/browser/extensions/api/storage/policy_value_store_unittest.cc
@@ -4,12 +4,14 @@
 
 #include "chrome/browser/extensions/api/storage/policy_value_store.h"
 
+#include "base/callback.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "chrome/browser/extensions/api/storage/settings_observer.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/value_store/leveldb_value_store.h"
 #include "chrome/browser/value_store/value_store_unittest.h"
@@ -119,9 +121,10 @@
   policy::PolicyMap policies;
   base::FundamentalValue expected(123);
   policies.Set("must", policy::POLICY_LEVEL_MANDATORY,
-               policy::POLICY_SCOPE_USER, expected.DeepCopy());
+               policy::POLICY_SCOPE_USER, expected.DeepCopy(), NULL);
   policies.Set("may", policy::POLICY_LEVEL_RECOMMENDED,
-               policy::POLICY_SCOPE_USER, base::Value::CreateIntegerValue(456));
+               policy::POLICY_SCOPE_USER,
+               base::Value::CreateIntegerValue(456), NULL);
   store_->SetCurrentPolicy(policies, false);
   ValueStore::ReadResult result = store_->Get();
   ASSERT_FALSE(result->HasError());
@@ -152,7 +155,7 @@
 TEST_F(PolicyValueStoreTest, NotifyOnChanges) {
   policy::PolicyMap policies;
   policies.Set("aaa", policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
-               base::Value::CreateStringValue("111"));
+               base::Value::CreateStringValue("111"), NULL);
   EXPECT_CALL(observer_, OnSettingsChanged(_, _, _)).Times(0);
   // No notification when setting the initial policy.
   store_->SetCurrentPolicy(policies, false);
@@ -161,9 +164,9 @@
 
   // And no notifications on changes when not asked for.
   policies.Set("aaa", policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
-               base::Value::CreateStringValue("222"));
+               base::Value::CreateStringValue("222"), NULL);
   policies.Set("bbb", policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
-               base::Value::CreateStringValue("223"));
+               base::Value::CreateStringValue("223"), NULL);
   EXPECT_CALL(observer_, OnSettingsChanged(_, _, _)).Times(0);
   store_->SetCurrentPolicy(policies, false);
   loop_.RunUntilIdle();
@@ -174,7 +177,7 @@
   base::StringValue value("333");
   changes.push_back(ValueStoreChange("ccc", NULL, value.DeepCopy()));
   policies.Set("ccc", policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
-               value.DeepCopy());
+               value.DeepCopy(), NULL);
   EXPECT_CALL(observer_, OnSettingsChanged(kTestExtensionId,
                                            settings_namespace::MANAGED,
                                            ValueStoreChange::ToJson(changes)));
@@ -188,7 +191,7 @@
   changes.push_back(
       ValueStoreChange("ccc", value.DeepCopy(), new_value.DeepCopy()));
   policies.Set("ccc", policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
-               new_value.DeepCopy());
+               new_value.DeepCopy(), NULL);
   EXPECT_CALL(observer_, OnSettingsChanged(kTestExtensionId,
                                            settings_namespace::MANAGED,
                                            ValueStoreChange::ToJson(changes)));
diff --git a/chrome/browser/extensions/api/storage/settings_frontend_unittest.cc b/chrome/browser/extensions/api/storage/settings_frontend_unittest.cc
index 9705531..d05a733 100644
--- a/chrome/browser/extensions/api/storage/settings_frontend_unittest.cc
+++ b/chrome/browser/extensions/api/storage/settings_frontend_unittest.cc
@@ -8,12 +8,12 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/storage/leveldb_settings_storage_factory.h"
 #include "chrome/browser/extensions/api/storage/settings_frontend.h"
 #include "chrome/browser/extensions/api/storage/settings_namespace.h"
 #include "chrome/browser/extensions/api/storage/settings_test_util.h"
 #include "chrome/browser/value_store/value_store.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -165,7 +165,7 @@
     StringValue bar("bar");
     ValueStore::WriteResult result = storage->Set(DEFAULTS, "foo", bar);
     ASSERT_FALSE(result->HasError());
-    EXPECT_TRUE(file_util::PathExists(temp_dir_.path()));
+    EXPECT_TRUE(base::PathExists(temp_dir_.path()));
   }
 
   // Should need to both clear the database and delete the frontend for the
@@ -173,7 +173,7 @@
   {
     ValueStore::WriteResult result = storage->Clear();
     ASSERT_FALSE(result->HasError());
-    EXPECT_TRUE(file_util::PathExists(temp_dir_.path()));
+    EXPECT_TRUE(base::PathExists(temp_dir_.path()));
   }
 
   frontend_.reset();
@@ -181,7 +181,7 @@
   // TODO(kalman): Figure out why this fails, despite appearing to work.
   // Leaving this commented out rather than disabling the whole test so that the
   // deletion code paths are at least exercised.
-  //EXPECT_FALSE(file_util::PathExists(temp_dir_.path()));
+  //EXPECT_FALSE(base::PathExists(temp_dir_.path()));
 }
 
 TEST_F(ExtensionSettingsFrontendTest,
diff --git a/chrome/browser/extensions/api/storage/storage_schema_manifest_handler.cc b/chrome/browser/extensions/api/storage/storage_schema_manifest_handler.cc
deleted file mode 100644
index 9537c4b..0000000
--- a/chrome/browser/extensions/api/storage/storage_schema_manifest_handler.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/storage/storage_schema_manifest_handler.h"
-
-#include <string>
-#include <vector>
-
-#include "base/file_util.h"
-#include "base/files/file_path.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/string16.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/policy/policy_schema.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_manifest_constants.h"
-#include "chrome/common/extensions/manifest.h"
-#include "chrome/common/extensions/permissions/api_permission.h"
-#include "extensions/common/install_warning.h"
-
-using extension_manifest_keys::kStorageManagedSchema;
-
-namespace extensions {
-
-StorageSchemaManifestHandler::StorageSchemaManifestHandler() {}
-
-StorageSchemaManifestHandler::~StorageSchemaManifestHandler() {}
-
-// static
-scoped_ptr<policy::PolicySchema> StorageSchemaManifestHandler::GetSchema(
-    const Extension* extension,
-    std::string* error) {
-  if (!extension->HasAPIPermission(APIPermission::kStorage)) {
-    *error = base::StringPrintf("The storage permission is required to use %s",
-                                kStorageManagedSchema);
-    return scoped_ptr<policy::PolicySchema>();
-  }
-  std::string path;
-  extension->manifest()->GetString(kStorageManagedSchema, &path);
-  base::FilePath file = base::FilePath::FromUTF8Unsafe(path);
-  if (file.IsAbsolute() || file.ReferencesParent()) {
-    *error = base::StringPrintf("%s must be a relative path without ..",
-                                kStorageManagedSchema);
-    return scoped_ptr<policy::PolicySchema>();
-  }
-  file = extension->path().AppendASCII(path);
-  if (!file_util::PathExists(file)) {
-    *error =
-        base::StringPrintf("File does not exist: %s", file.value().c_str());
-    return scoped_ptr<policy::PolicySchema>();
-  }
-  std::string content;
-  if (!file_util::ReadFileToString(file, &content)) {
-    *error = base::StringPrintf("Can't read %s", file.value().c_str());
-    return scoped_ptr<policy::PolicySchema>();
-  }
-  return policy::PolicySchema::Parse(content, error);
-}
-
-bool StorageSchemaManifestHandler::Parse(Extension* extension,
-                                         string16* error) {
-  std::string path;
-  if (!extension->manifest()->GetString(kStorageManagedSchema, &path)) {
-    *error = ASCIIToUTF16(
-        base::StringPrintf("%s must be a string", kStorageManagedSchema));
-    return false;
-  }
-  return true;
-}
-
-bool StorageSchemaManifestHandler::Validate(
-    const Extension* extension,
-    std::string* error,
-    std::vector<InstallWarning>* warnings) const {
-  return !!GetSchema(extension, error);
-}
-
-const std::vector<std::string> StorageSchemaManifestHandler::Keys() const {
-  return SingleKey(kStorageManagedSchema);
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/api/storage/storage_schema_manifest_handler.h b/chrome/browser/extensions/api/storage/storage_schema_manifest_handler.h
deleted file mode 100644
index 61ba8b0..0000000
--- a/chrome/browser/extensions/api/storage/storage_schema_manifest_handler.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_STORAGE_STORAGE_SCHEMA_MANIFEST_HANDLER_H_
-#define CHROME_BROWSER_EXTENSIONS_API_STORAGE_STORAGE_SCHEMA_MANIFEST_HANDLER_H_
-
-#include "base/basictypes.h"
-#include "chrome/common/extensions/manifest_handler.h"
-
-namespace policy {
-class PolicySchema;
-}
-
-namespace extensions {
-
-// Handles the "storage.managed_schema" manifest key.
-class StorageSchemaManifestHandler : public ManifestHandler {
- public:
-  StorageSchemaManifestHandler();
-  virtual ~StorageSchemaManifestHandler();
-
-  // Returns the managed storage schema defined for |extension|.
-  // If the schema is invalid then NULL is returned, and the failure reason
-  // is stored in |error|.
-  // This function does file I/O and must be called on a thread that allows I/O.
-  static scoped_ptr<policy::PolicySchema> GetSchema(const Extension* extension,
-                                                    std::string* error);
-
- private:
-  // ManifestHandler implementation:
-  virtual bool Parse(Extension* extension, string16* error) OVERRIDE;
-  virtual bool Validate(const Extension* extension,
-                        std::string* error,
-                        std::vector<InstallWarning>* warnings) const OVERRIDE;
-  virtual const std::vector<std::string> Keys() const OVERRIDE;
-
-  DISALLOW_COPY_AND_ASSIGN(StorageSchemaManifestHandler);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_API_STORAGE_STORAGE_SCHEMA_MANIFEST_HANDLER_H_
diff --git a/chrome/browser/extensions/api/storage/storage_schema_manifest_handler_unittest.cc b/chrome/browser/extensions/api/storage/storage_schema_manifest_handler_unittest.cc
deleted file mode 100644
index a7fd429..0000000
--- a/chrome/browser/extensions/api/storage/storage_schema_manifest_handler_unittest.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/storage/storage_schema_manifest_handler.h"
-
-#include <string>
-#include <vector>
-
-#include "base/file_util.h"
-#include "base/files/file_path.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/values.h"
-#include "chrome/common/chrome_version_info.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/features/feature.h"
-#include "chrome/common/extensions/manifest.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace extensions {
-
-class StorageSchemaManifestHandlerTest : public testing::Test {
- public:
-  StorageSchemaManifestHandlerTest()
-      : scoped_channel_(chrome::VersionInfo::CHANNEL_DEV) {}
-
-  virtual ~StorageSchemaManifestHandlerTest() {}
-
-  virtual void SetUp() OVERRIDE {
-    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-
-    manifest_.SetString("name", "test");
-    manifest_.SetString("version", "1.2.3.4");
-    manifest_.SetInteger("manifest_version", 2);
-
-    storage_schema_manifest_handler_ = new StorageSchemaManifestHandler();
-    storage_schema_manifest_handler_->Register();
-    // This is used to invoke the private virtual methods.
-    handler_ = storage_schema_manifest_handler_;
-  }
-
-  scoped_refptr<Extension> CreateExtension(const std::string& schema) {
-    std::string error;
-    scoped_refptr<Extension> extension = Extension::Create(
-        temp_dir_.path(), Manifest::UNPACKED, manifest_,
-        Extension::NO_FLAGS, "", &error);
-    if (!extension.get())
-      return NULL;
-    base::FilePath schema_path = temp_dir_.path().AppendASCII("schema.json");
-    if (schema.empty()) {
-      base::Delete(schema_path, false);
-    } else {
-      if (file_util::WriteFile(schema_path, schema.data(), schema.size()) !=
-          static_cast<int>(schema.size())) {
-        return NULL;
-      }
-    }
-    return extension;
-  }
-
-  testing::AssertionResult Validates(const std::string& schema) {
-    scoped_refptr<Extension> extension = CreateExtension(schema);
-    if (!extension.get())
-      return testing::AssertionFailure() << "Failed to create test extension";
-    std::string error;
-    std::vector<InstallWarning> warnings;
-    if (handler_->Validate(extension.get(), &error, &warnings))
-      return testing::AssertionSuccess();
-    return testing::AssertionFailure() << error;
-  }
-
-  base::ScopedTempDir temp_dir_;
-  Feature::ScopedCurrentChannel scoped_channel_;
-  ManifestHandler* handler_;
-  StorageSchemaManifestHandler* storage_schema_manifest_handler_;
-  base::DictionaryValue manifest_;
-};
-
-TEST_F(StorageSchemaManifestHandlerTest, Parse) {
-  scoped_refptr<Extension> extension = CreateExtension("");
-  ASSERT_TRUE(extension.get());
-
-  // No storage.managed_schema entry.
-  string16 error;
-  EXPECT_FALSE(handler_->Parse(extension.get(), &error));
-
-  // Not a string.
-  manifest_.SetInteger("storage.managed_schema", 123);
-  extension = CreateExtension("");
-  EXPECT_FALSE(extension.get());
-
-  // All good now.
-  manifest_.SetString("storage.managed_schema", "schema.json");
-  extension = CreateExtension("");
-  ASSERT_TRUE(extension.get());
-  EXPECT_TRUE(handler_->Parse(extension.get(), &error)) << error;
-}
-
-TEST_F(StorageSchemaManifestHandlerTest, Validate) {
-  // Doesn't have storage permission.
-  EXPECT_FALSE(Validates(""));
-
-  // File doesn't exist.
-  base::ListValue permissions;
-  permissions.AppendString("storage");
-  manifest_.Set("permissions", permissions.DeepCopy());
-  EXPECT_FALSE(Validates(""));
-
-  // Absolute path.
-  manifest_.SetString("storage.managed_storage", "/etc/passwd");
-  EXPECT_FALSE(Validates(""));
-
-  // Path with ..
-  manifest_.SetString("storage.managed_storage", "../../../../../etc/passwd");
-  EXPECT_FALSE(Validates(""));
-
-  // Does not exist.
-  manifest_.SetString("storage.managed_storage", "not-there");
-  EXPECT_FALSE(Validates(""));
-
-  // Invalid JSON.
-  manifest_.SetString("storage.managed_schema", "schema.json");
-  EXPECT_FALSE(Validates("-invalid-"));
-
-  // No version.
-  EXPECT_FALSE(Validates("{}"));
-
-  // Invalid version.
-  EXPECT_FALSE(Validates(
-      "{"
-      "  \"$schema\": \"http://json-schema.org/draft-42/schema#\""
-      "}"));
-
-  // Missing type.
-  EXPECT_FALSE(Validates(
-      "{"
-      "  \"$schema\": \"http://json-schema.org/draft-03/schema#\""
-      "}"));
-
-  // Invalid type.
-  EXPECT_FALSE(Validates(
-      "{"
-      "  \"$schema\": \"http://json-schema.org/draft-03/schema#\","
-      "  \"type\": \"string\""
-      "}"));
-
-  // "additionalProperties" not supported at top level.
-  EXPECT_FALSE(Validates(
-      "{"
-      "  \"$schema\": \"http://json-schema.org/draft-03/schema#\","
-      "  \"type\": \"object\","
-      "  \"additionalProperties\": {}"
-      "}"));
-
-  // All good now.
-  EXPECT_TRUE(Validates(
-      "{"
-      "  \"$schema\": \"http://json-schema.org/draft-03/schema#\","
-      "  \"type\": \"object\""
-      "}"));
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_api.cc b/chrome/browser/extensions/api/streams_private/streams_private_api.cc
index dc1fb07..61fceb2 100644
--- a/chrome/browser/extensions/api/streams_private/streams_private_api.cc
+++ b/chrome/browser/extensions/api/streams_private/streams_private_api.cc
@@ -9,19 +9,16 @@
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_function_registry.h"
-#include "chrome/browser/extensions/extension_input_module_constants.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/stream_handle.h"
 
-namespace keys = extension_input_module_constants;
-
 namespace events {
 
 const char kOnExecuteMimeTypeHandler[] =
diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
index 640ad9e..fda5d44 100644
--- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
+++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
@@ -14,7 +14,7 @@
 #include "chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer_factory.h"
 #include "chrome/browser/extensions/api/sync_file_system/sync_file_system_api_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
 #include "chrome/browser/sync_file_system/sync_file_system_service.h"
 #include "chrome/browser/sync_file_system/sync_file_system_service_factory.h"
 #include "chrome/common/extensions/api/sync_file_system.h"
diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc b/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc
index f226979..fe67130 100644
--- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc
+++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc
@@ -7,7 +7,7 @@
 #include "base/run_loop.h"
 #include "chrome/browser/extensions/event_names.h"
 #include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
 #include "chrome/browser/sync_file_system/file_status_observer.h"
 #include "chrome/browser/sync_file_system/local_change_processor.h"
 #include "chrome/browser/sync_file_system/mock_remote_file_sync_service.h"
diff --git a/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc b/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc
index 51cf082..f708074 100644
--- a/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc
+++ b/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/extensions/api/system_indicator/system_indicator_manager.h"
 
 #include "base/memory/linked_ptr.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_names.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_action.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/status_icons/status_icon.h"
 #include "chrome/browser/status_icons/status_icon_observer.h"
 #include "chrome/browser/status_icons/status_tray.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/system_indicator.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/extensions/api/system_info/system_info_api.cc b/chrome/browser/extensions/api/system_info/system_info_api.cc
index fdca73e..d203948 100644
--- a/chrome/browser/extensions/api/system_info/system_info_api.cc
+++ b/chrome/browser/extensions/api/system_info/system_info_api.cc
@@ -17,6 +17,9 @@
 #include "chrome/browser/extensions/api/system_info_storage/storage_info_provider.h"
 #include "chrome/browser/extensions/event_names.h"
 #include "chrome/browser/extensions/event_router_forwarder.h"
+#include "chrome/browser/storage_monitor/removable_storage_observer.h"
+#include "chrome/browser/storage_monitor/storage_info.h"
+#include "chrome/browser/storage_monitor/storage_monitor.h"
 #include "chrome/common/extensions/api/experimental_system_info_storage.h"
 #include "ui/gfx/display_observer.h"
 
@@ -27,9 +30,9 @@
 
 namespace extensions {
 
+using api::experimental_system_info_storage::StorageFreeSpaceChangeInfo;
 using api::experimental_system_info_storage::StorageUnitInfo;
 using api::experimental_system_info_storage::StorageUnitType;
-using api::experimental_system_info_storage::StorageChangeInfo;
 using content::BrowserThread;
 
 namespace {
@@ -49,8 +52,9 @@
 
 // Event router for systemInfo API. It is a singleton instance shared by
 // multiple profiles.
-class SystemInfoEventRouter
-    : public gfx::DisplayObserver, public StorageInfoObserver {
+class SystemInfoEventRouter : public gfx::DisplayObserver,
+                              public StorageFreeSpaceObserver,
+                              public chrome::RemovableStorageObserver {
  public:
   static SystemInfoEventRouter* GetInstance();
 
@@ -65,22 +69,25 @@
   static bool IsSystemInfoEvent(const std::string& event_name);
 
  private:
-  // StorageInfoObserver:
-  virtual void OnStorageFreeSpaceChanged(const std::string& id,
-                                         double new_value,
-                                         double old_value) OVERRIDE;
-  virtual void OnStorageAttached(
-      const std::string& id,
-      api::experimental_system_info_storage::StorageUnitType type,
-      double capacity,
-      double available_capacity) OVERRIDE;
-  virtual void OnStorageDetached(const std::string& id) OVERRIDE;
+  // StorageFreeSpaceObserver:
+  virtual void OnFreeSpaceChanged(const std::string& id,
+                                  double new_value,
+                                  double old_value) OVERRIDE;
 
   // gfx::DisplayObserver:
   virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE;
   virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE;
   virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE;
 
+  // chrome::RemovableStorageObserver implementation.
+  virtual void OnRemovableStorageAttached(
+      const chrome::StorageInfo& info) OVERRIDE;
+  virtual void OnRemovableStorageDetached(
+      const chrome::StorageInfo& info) OVERRIDE;
+
+  void DispatchStorageAttachedEvent(const chrome::StorageInfo& info,
+                                    int64 avail_bytes);
+
   // Called from any thread to dispatch the systemInfo event to all extension
   // processes cross multiple profiles.
   void DispatchEvent(const std::string& event_name,
@@ -88,8 +95,8 @@
 
   // The callbacks of querying storage info to start and stop watching the
   // storages. Called from UI thread.
-  void StartWatchingStorages(const StorageInfo& info, bool success);
-  void StopWatchingStorages(const StorageInfo& info, bool success);
+  void StartWatchingStorages(bool success);
+  void StopWatchingStorages(bool success);
 
   // Called to dispatch the systemInfo.display.onDisplayChanged event.
   void OnDisplayChanged();
@@ -110,32 +117,30 @@
 
 SystemInfoEventRouter::SystemInfoEventRouter() {
   StorageInfoProvider::Get()->AddObserver(this);
+  chrome::StorageMonitor::GetInstance()->AddObserver(this);
 }
 
 SystemInfoEventRouter::~SystemInfoEventRouter() {
   StorageInfoProvider::Get()->RemoveObserver(this);
+  if (chrome::StorageMonitor* storage_monitor =
+          chrome::StorageMonitor::GetInstance())
+    storage_monitor->RemoveObserver(this);
 }
 
-void SystemInfoEventRouter::StartWatchingStorages(
-    const StorageInfo& info, bool success) {
+void SystemInfoEventRouter::StartWatchingStorages(bool success) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   if (!success)
     return;
 
-  for (StorageInfo::const_iterator it = info.begin(); it != info.end(); ++it) {
-    StorageInfoProvider::Get()->StartWatching((*it)->id);
-  }
+  StorageInfoProvider::Get()->StartWatchingAllStorages();
 }
 
-void SystemInfoEventRouter::StopWatchingStorages(
-    const StorageInfo& info, bool success) {
+void SystemInfoEventRouter::StopWatchingStorages(bool success) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   if (!success)
     return;
 
-  for (StorageInfo::const_iterator it = info.begin(); it != info.end(); ++it) {
-    StorageInfoProvider::Get()->StopWatching((*it)->id);
-  }
+  StorageInfoProvider::Get()->StopWatchingAllStorages();
 }
 
 void SystemInfoEventRouter::AddEventListener(const std::string& event_name) {
@@ -198,10 +203,10 @@
 }
 
 // Called on UI thread since the observer is added from UI thread.
-void SystemInfoEventRouter::OnStorageFreeSpaceChanged(
-    const std::string& id, double new_value, double old_value) {
-  StorageChangeInfo info;
-  info.id = id;
+void SystemInfoEventRouter::OnFreeSpaceChanged(
+    const std::string& transient_id, double new_value, double old_value) {
+  StorageFreeSpaceChangeInfo info;
+  info.id = transient_id;
   info.available_capacity = static_cast<double>(new_value);
 
   scoped_ptr<base::ListValue> args(new base::ListValue());
@@ -210,25 +215,41 @@
   DispatchEvent(event_names::kOnStorageAvailableCapacityChanged, args.Pass());
 }
 
-void SystemInfoEventRouter::OnStorageAttached(const std::string& id,
-                                              StorageUnitType type,
-                                              double capacity,
-                                              double available_capacity) {
-  StorageUnitInfo info;
-  info.id = id;
-  info.type = type;
-  info.capacity = capacity;
-  info.available_capacity = available_capacity;
+void SystemInfoEventRouter::OnRemovableStorageAttached(
+    const chrome::StorageInfo& info) {
+  base::PostTaskAndReplyWithResult(
+      BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
+          base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN),
+      FROM_HERE,
+      base::Bind(&StorageInfoProvider::GetStorageFreeSpaceFromTransientId,
+                 StorageInfoProvider::Get(),
+                 StorageInfoProvider::Get()->GetTransientIdForDeviceId(
+                     info.device_id())),
+      base::Bind(&SystemInfoEventRouter::DispatchStorageAttachedEvent,
+                 // Since SystemInfoEventRouter is a global lazy instance, this
+                 // pointer will be alive when the reply comes back.
+                 base::Unretained(this),
+                 info));
+}
+
+void SystemInfoEventRouter::DispatchStorageAttachedEvent(
+    const chrome::StorageInfo& info, int64 avail_bytes) {
+  StorageUnitInfo unit;
+  systeminfo::BuildStorageUnitInfo(info, &unit);
+
+  unit.available_capacity =
+      avail_bytes > 0 ? static_cast<double>(avail_bytes) : 0;
 
   scoped_ptr<base::ListValue> args(new base::ListValue);
-  args->Append(info.ToValue().release());
-
+  args->Append(unit.ToValue().release());
   DispatchEvent(event_names::kOnStorageAttached, args.Pass());
 }
 
-void SystemInfoEventRouter::OnStorageDetached(const std::string& id) {
+void SystemInfoEventRouter::OnRemovableStorageDetached(
+    const chrome::StorageInfo& info) {
   scoped_ptr<base::ListValue> args(new base::ListValue);
-  args->Append(new base::StringValue(id));
+  args->Append(new base::StringValue(StorageInfoProvider::Get()->
+                   GetTransientIdForDeviceId(info.device_id())));
 
   DispatchEvent(event_names::kOnStorageDetached, args.Pass());
 }
diff --git a/chrome/browser/extensions/api/system_info/system_info_provider.h b/chrome/browser/extensions/api/system_info/system_info_provider.h
index 574e629..0215820 100644
--- a/chrome/browser/extensions/api/system_info/system_info_provider.h
+++ b/chrome/browser/extensions/api/system_info/system_info_provider.h
@@ -29,34 +29,62 @@
 //
 // Template parameter T is the system information type. It could be the
 // structure type generated by IDL parser.
+//
+// The class member |info_| is accessed on multiple threads, but that the whole
+// class is being guarded by SystemInfoProvider.
+//
+// |info_| is accessed on the UI thread while |is_waiting_for_completion_| is
+// false and on the sequenced worker pool while |is_waiting_for_completion_| is
+// true.
 template<class T>
 class SystemInfoProvider
     : public base::RefCountedThreadSafe<SystemInfoProvider<T> > {
  public:
-  // Callback type for completing to get information. The callback accepts
-  // two arguments. The first one is the information got already, the second
-  // one indicates whether its contents are valid, for example, no error
-  // occurs in querying the information.
-  typedef base::Callback<void(const T&, bool)> QueryInfoCompletionCallback;
+  // Callback type for completing to get information. The argument indicates
+  // whether its contents are valid, for example, no error occurs in querying
+  // the information.
+  typedef base::Callback<void(bool)> QueryInfoCompletionCallback;
   typedef std::queue<QueryInfoCompletionCallback> CallbackQueue;
 
   SystemInfoProvider()
     : is_waiting_for_completion_(false) {
-    worker_pool_token_ =
-      content::BrowserThread::GetBlockingPool()->GetSequenceToken();
+    base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
+    worker_pool_ = pool->GetSequencedTaskRunnerWithShutdownBehavior(
+                       pool->GetSequenceToken(),
+                       base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
   }
 
   virtual ~SystemInfoProvider() {}
 
+  // Override to do any prepare work on UI thread before |QueryInfo()| gets
+  // called.
+  virtual void PrepareQueryOnUIThread() {}
+
+  // The parameter |do_query_info_callback| is query info task which is posts to
+  // SystemInfoProvider sequenced worker pool.
+  //
+  // You can do any initial things of *InfoProvider before start to query info.
+  // While overriding this method, |do_query_info_callback| *must* be called
+  // directly or indirectly.
+  //
+  // Sample usage please refer to StorageInfoProvider.
+  virtual void InitializeProvider(const base::Closure& do_query_info_callback) {
+    do_query_info_callback.Run();
+  }
+
   // For testing
   static void InitializeForTesting(
       scoped_refptr<SystemInfoProvider<T> > provider) {
     DCHECK(provider.get() != NULL);
-    single_shared_provider_.Get() = provider;
+    provider_.Get() = provider;
   }
 
   // Start to query the system information. Should be called on UI thread.
   // The |callback| will get called once the query is completed.
+  //
+  // If the parameter |callback| itself calls StartQueryInfo(callback2),
+  // callback2 will be called immediately rather than triggering another call to
+  // the system.
   void StartQueryInfo(const QueryInfoCompletionCallback& callback) {
     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     DCHECK(!callback.is_null());
@@ -68,51 +96,23 @@
 
     is_waiting_for_completion_ = true;
 
-    base::SequencedWorkerPool* worker_pool =
-        content::BrowserThread::GetBlockingPool();
-    // The query task posted to the worker pool won't block shutdown, and any
-    // running query task at shutdown time will be ignored.
-    worker_pool->PostSequencedWorkerTaskWithShutdownBehavior(
-          worker_pool_token_,
-          FROM_HERE,
-          base::Bind(&SystemInfoProvider<T>::QueryOnWorkerPool, this),
-          base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
+    InitializeProvider(base::Bind(
+          &SystemInfoProvider<T>::StartQueryInfoPostInitialization, this));
   }
 
  protected:
-  // Query the system information synchronously and output the result to the
-  // |info| parameter. The |info| contents MUST be reset firstly in its
-  // platform specific implementation. Return true if it succeeds, otherwise
-  // false is returned.
-  virtual bool QueryInfo(T* info) = 0;
-
-  virtual void QueryOnWorkerPool() {
-    bool success = QueryInfo(&info_);
-    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
-        base::Bind(&SystemInfoProvider<T>::OnQueryCompleted, this, success));
-  }
-
-  // Called on UI thread. The |success| parameter means whether it succeeds
-  // to get the information.
-  virtual void OnQueryCompleted(bool success) {
-    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-
-    while (!callbacks_.empty()) {
-      QueryInfoCompletionCallback callback = callbacks_.front();
-      callback.Run(info_, success);
-      callbacks_.pop();
-    }
-
-    is_waiting_for_completion_ = false;
- }
+  // Query the system information synchronously and put the result into |info_|.
+  // Return true if no error occurs.
+  // Should be called in the blocking pool.
+  virtual bool QueryInfo() = 0;
 
   // Template function for creating the single shared provider instance.
   // Template paramter I is the type of SystemInfoProvider implementation.
   template<class I>
   static I* GetInstance() {
-    if (!single_shared_provider_.Get().get())
-      single_shared_provider_.Get() = new I();
-    return static_cast<I*>(single_shared_provider_.Get().get());
+    if (!provider_.Get().get())
+      provider_.Get() = new I();
+    return static_cast<I*>(provider_.Get().get());
   }
 
   // The latest information filled up by QueryInfo implementation. Here we
@@ -121,9 +121,34 @@
   T info_;
 
  private:
+  // Called on UI thread. The |success| parameter means whether it succeeds
+  // to get the information.
+  void OnQueryCompleted(bool success) {
+    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+    while (!callbacks_.empty()) {
+      QueryInfoCompletionCallback callback = callbacks_.front();
+      callback.Run(success);
+      callbacks_.pop();
+    }
+
+    is_waiting_for_completion_ = false;
+  }
+
+  void StartQueryInfoPostInitialization() {
+    PrepareQueryOnUIThread();
+    // Post the custom query info task to blocking pool for information querying
+    // and reply with OnQueryCompleted.
+    base::PostTaskAndReplyWithResult(
+        worker_pool_,
+        FROM_HERE,
+        base::Bind(&SystemInfoProvider<T>::QueryInfo, this),
+        base::Bind(&SystemInfoProvider<T>::OnQueryCompleted, this));
+  }
+
   // The single shared provider instance. We create it only when needed.
   static typename base::LazyInstance<
-      scoped_refptr<SystemInfoProvider<T> > > single_shared_provider_;
+      scoped_refptr<SystemInfoProvider<T> > > provider_;
 
   // The queue of callbacks waiting for the info querying completion. It is
   // maintained on the UI thread.
@@ -132,18 +157,13 @@
   // Indicates if it is waiting for the querying completion.
   bool is_waiting_for_completion_;
 
-  // Unqiue sequence token so that the operation of querying inforation can
-  // be executed in order.
-  base::SequencedWorkerPool::SequenceToken worker_pool_token_;
+  // Sequenced worker pool to make the operation of querying information get
+  // executed in order.
+  scoped_refptr<base::SequencedTaskRunner> worker_pool_;
 
   DISALLOW_COPY_AND_ASSIGN(SystemInfoProvider<T>);
 };
 
-// Static member intialization.
-template<class T>
-typename base::LazyInstance<scoped_refptr<SystemInfoProvider<T> > >
-  SystemInfoProvider<T>::single_shared_provider_ = LAZY_INSTANCE_INITIALIZER;
-
 }  // namespace extensions
 
 #endif  // CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_SYSTEM_INFO_PROVIDER_H_
diff --git a/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.cc b/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.cc
index edc56fe..9c83112 100644
--- a/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.cc
+++ b/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.cc
@@ -10,17 +10,23 @@
 
 using api::system_info_cpu::CpuInfo;
 
+// Static member intialization.
+template<>
+base::LazyInstance<scoped_refptr<SystemInfoProvider<CpuInfo> > >
+  SystemInfoProvider<CpuInfo>::provider_ = LAZY_INSTANCE_INITIALIZER;
+
 CpuInfoProvider::CpuInfoProvider() {}
 
 CpuInfoProvider::~CpuInfoProvider() {}
 
-bool CpuInfoProvider::QueryInfo(CpuInfo* info) {
-  if (info == NULL)
-    return false;
+const CpuInfo& CpuInfoProvider::cpu_info() const {
+  return info_;
+}
 
-  info->num_of_processors = base::SysInfo::NumberOfProcessors();
-  info->arch_name = base::SysInfo::OperatingSystemArchitecture();
-  info->model_name = base::SysInfo::CPUModelName();
+bool CpuInfoProvider::QueryInfo() {
+  info_.num_of_processors = base::SysInfo::NumberOfProcessors();
+  info_.arch_name = base::SysInfo::OperatingSystemArchitecture();
+  info_.model_name = base::SysInfo::CPUModelName();
   return true;
 }
 
diff --git a/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.h b/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.h
index df7d77c..ccad39b 100644
--- a/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.h
+++ b/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.h
@@ -16,12 +16,13 @@
     : public SystemInfoProvider<api::system_info_cpu::CpuInfo> {
  public:
   // Overriden from SystemInfoProvider<CpuInfo>.
-  virtual bool QueryInfo(
-      api::system_info_cpu::CpuInfo* info) OVERRIDE;
+  virtual bool QueryInfo() OVERRIDE;
 
   // Return the single shared instance of CpuInfoProvider.
   static CpuInfoProvider* Get();
 
+  const api::system_info_cpu::CpuInfo& cpu_info() const;
+
  private:
   friend class SystemInfoProvider<api::system_info_cpu::CpuInfo>;
   friend class MockCpuInfoProviderImpl;
diff --git a/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider_unittest.cc b/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider_unittest.cc
index 8b8d630..05ac22f 100644
--- a/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider_unittest.cc
+++ b/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider_unittest.cc
@@ -28,7 +28,7 @@
 class TestCpuInfoProvider : public CpuInfoProvider {
  public:
   TestCpuInfoProvider();
-  virtual bool QueryInfo(CpuInfo* info) OVERRIDE;
+  virtual bool QueryInfo() OVERRIDE;
 
  private:
   virtual ~TestCpuInfoProvider();
@@ -38,12 +38,10 @@
 
 TestCpuInfoProvider::~TestCpuInfoProvider() {}
 
-bool TestCpuInfoProvider::QueryInfo(CpuInfo* info) {
-  if (info == NULL)
-    return false;
-  info->arch_name = kTestingCpuInfoData.arch_name;
-  info->model_name = kTestingCpuInfoData.model_name;
-  info->num_of_processors = kTestingCpuInfoData.num_of_processors;
+bool TestCpuInfoProvider::QueryInfo() {
+  info_.arch_name = kTestingCpuInfoData.arch_name;
+  info_.model_name = kTestingCpuInfoData.model_name;
+  info_.num_of_processors = kTestingCpuInfoData.num_of_processors;
   return true;
 }
 
@@ -59,11 +57,13 @@
 
 TEST_F(CpuInfoProviderTest, QueryCpuInfo) {
   cpu_info_provider_ = new TestCpuInfoProvider();
-  scoped_ptr<CpuInfo> cpu_info(new CpuInfo());
-  EXPECT_TRUE(cpu_info_provider_->QueryInfo(cpu_info.get()));
-  EXPECT_EQ(kTestingCpuInfoData.arch_name, cpu_info->arch_name);
-  EXPECT_EQ(kTestingCpuInfoData.model_name, cpu_info->model_name);
-  EXPECT_EQ(kTestingCpuInfoData.num_of_processors, cpu_info->num_of_processors);
+  EXPECT_TRUE(cpu_info_provider_->QueryInfo());
+  EXPECT_EQ(kTestingCpuInfoData.arch_name,
+            cpu_info_provider_->cpu_info().arch_name);
+  EXPECT_EQ(kTestingCpuInfoData.model_name,
+            cpu_info_provider_->cpu_info().model_name);
+  EXPECT_EQ(kTestingCpuInfoData.num_of_processors,
+            cpu_info_provider_->cpu_info().num_of_processors);
 }
 
 }
diff --git a/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_api.cc b/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_api.cc
index 34af82c..175bcdb 100644
--- a/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_api.cc
+++ b/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_api.cc
@@ -24,10 +24,9 @@
   return true;
 }
 
-void SystemInfoCpuGetFunction::OnGetCpuInfoCompleted(const CpuInfo& info,
-    bool success) {
+void SystemInfoCpuGetFunction::OnGetCpuInfoCompleted(bool success) {
   if (success)
-    SetResult(info.ToValue().release());
+    SetResult(CpuInfoProvider::Get()->cpu_info().ToValue().release());
   else
     SetError("Error occurred when querying cpu information.");
   SendResponse(success);
diff --git a/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_api.h b/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_api.h
index 89ad54d..8a2fb52 100644
--- a/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_api.h
+++ b/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_api.h
@@ -17,8 +17,7 @@
  private:
   virtual ~SystemInfoCpuGetFunction();
   virtual bool RunImpl() OVERRIDE;
-  void OnGetCpuInfoCompleted(
-      const api::system_info_cpu::CpuInfo& info, bool success);
+  void OnGetCpuInfoCompleted(bool success);
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_apitest.cc b/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_apitest.cc
index 149a60c..fcc27d0 100644
--- a/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_apitest.cc
+++ b/chrome/browser/extensions/api/system_info_cpu/system_info_cpu_apitest.cc
@@ -17,13 +17,10 @@
  public:
   MockCpuInfoProviderImpl() {}
 
-  virtual bool QueryInfo(CpuInfo* info) OVERRIDE {
-    if (!info) return false;
-
-    info->num_of_processors = 4;
-    info->arch_name = "x86";
-    info->model_name = "unknown";
-
+  virtual bool QueryInfo() OVERRIDE {
+    info_.num_of_processors = 4;
+    info_.arch_name = "x86";
+    info_.model_name = "unknown";
     return true;
   }
 
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider.cc b/chrome/browser/extensions/api/system_info_display/display_info_provider.cc
index fc3724a..9534ed3 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider.cc
+++ b/chrome/browser/extensions/api/system_info_display/display_info_provider.cc
@@ -6,6 +6,15 @@
 
 namespace extensions {
 
+// Static member intialization.
+template<>
+base::LazyInstance<scoped_refptr<SystemInfoProvider<DisplayInfo> > >
+  SystemInfoProvider<DisplayInfo>::provider_ = LAZY_INSTANCE_INITIALIZER;
+
+const DisplayInfo& DisplayInfoProvider::display_info() const {
+  return info_;
+}
+
 // static
 DisplayInfoProvider* DisplayInfoProvider::GetProvider() {
   return DisplayInfoProvider::GetInstance<DisplayInfoProvider>();
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider.h b/chrome/browser/extensions/api/system_info_display/display_info_provider.h
index 5820ff5..63a7077 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider.h
+++ b/chrome/browser/extensions/api/system_info_display/display_info_provider.h
@@ -17,7 +17,7 @@
 
 class DisplayInfoProvider : public SystemInfoProvider<DisplayInfo> {
  public:
-  typedef base::Callback<void(const DisplayInfo& info, bool success)>
+  typedef base::Callback<void(bool success)>
       RequestInfoCallback;
   typedef base::Callback<void(bool success, const std::string& error)>
       SetInfoCallback;
@@ -42,10 +42,12 @@
       const api::system_info_display::DisplayProperties& info,
       const SetInfoCallback& callback);
 
+  const DisplayInfo& display_info() const;
+
  protected:
   // Overriden from SystemInfoProvider<DisplayInfo>.
   // The implementation is platform specific.
-  virtual bool QueryInfo(DisplayInfo* info) OVERRIDE;
+  virtual bool QueryInfo() OVERRIDE;
 
   friend class SystemInfoProvider<DisplayInfo>;
 
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos.cc b/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos.cc
index 7ce7621..e680bc2 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos.cc
+++ b/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos.cc
@@ -411,12 +411,11 @@
 }  // namespace
 
 void DisplayInfoProvider::RequestInfo(const RequestInfoCallback& callback) {
-  DisplayInfo requested_info;
-  bool success = QueryInfo(&requested_info);
+  bool success = QueryInfo();
 
   base::MessageLoopProxy::current()->PostTask(
       FROM_HERE,
-      base::Bind(callback, requested_info, success));
+      base::Bind(callback, success));
 }
 
 void DisplayInfoProvider::SetInfo(const std::string& display_id,
@@ -429,9 +428,8 @@
       base::Bind(callback, success, error));
 }
 
-bool DisplayInfoProvider::QueryInfo(DisplayInfo* info) {
-  DCHECK(info);
-  info->clear();
+bool DisplayInfoProvider::QueryInfo() {
+  info_.clear();
 
   DisplayManager* display_manager =
       ash::Shell::GetInstance()->display_manager();
@@ -440,7 +438,7 @@
   int64 primary_id = ash::Shell::GetScreen()->GetPrimaryDisplay().id();
   for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
     AddInfoForDisplay(*display_manager->GetDisplayAt(i), display_manager,
-                      primary_id, info);
+                      primary_id, &info_);
   }
 
   return true;
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos_unittest.cc b/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos_unittest.cc
index d9aaa6b..d157a26 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos_unittest.cc
+++ b/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos_unittest.cc
@@ -17,11 +17,9 @@
 namespace extensions {
 namespace {
 
-void BindRequestDisplayInfoResult(DisplayInfo* target,
-                                  const DisplayInfo& result,
-                                  bool success) {
+void BindRequestDisplayInfoResult(DisplayInfo* target, bool success) {
   ASSERT_TRUE(success);
-  *target = result;
+  *target = DisplayInfoProvider::GetProvider()->display_info();
 }
 
 void BindSetDisplayUnitInfoResult(bool* success,
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider_mac.cc b/chrome/browser/extensions/api/system_info_display/display_info_provider_mac.cc
index cdb986f..3ff9d6b 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider_mac.cc
+++ b/chrome/browser/extensions/api/system_info_display/display_info_provider_mac.cc
@@ -21,7 +21,7 @@
 }
 
 // TODO(hongbo): implement display info querying on Mac OS X.
-bool DisplayInfoProvider::QueryInfo(DisplayInfo* info) {
+bool DisplayInfoProvider::QueryInfo() {
   return false;
 }
 
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider_unittest.cc b/chrome/browser/extensions/api/system_info_display/display_info_provider_unittest.cc
index 46d5062..d0e2bd6 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider_unittest.cc
+++ b/chrome/browser/extensions/api/system_info_display/display_info_provider_unittest.cc
@@ -40,7 +40,7 @@
 
 class TestDisplayInfoProvider : public DisplayInfoProvider {
  public:
-  virtual bool QueryInfo(DisplayInfo* info) OVERRIDE;
+  virtual bool QueryInfo() OVERRIDE;
 
  private:
   virtual ~TestDisplayInfoProvider();
@@ -48,10 +48,8 @@
 
 TestDisplayInfoProvider::~TestDisplayInfoProvider() {}
 
-bool TestDisplayInfoProvider::QueryInfo(DisplayInfo* info) {
-  if (info == NULL)
-    return false;
-  info->clear();
+bool TestDisplayInfoProvider::QueryInfo() {
+  info_.clear();
   for (size_t i = 0; i < arraysize(kTestingDisplayInfoData); ++i) {
     linked_ptr<DisplayUnitInfo> unit(new DisplayUnitInfo());
     unit->id = kTestingDisplayInfoData[i].id;
@@ -69,7 +67,7 @@
     unit->work_area.top = kTestingDisplayInfoData[i].work_area.top;
     unit->work_area.width = kTestingDisplayInfoData[i].work_area.width;
     unit->work_area.height = kTestingDisplayInfoData[i].work_area.height;
-    info->push_back(unit);
+    info_.push_back(unit);
   }
   return true;
 }
@@ -87,12 +85,12 @@
 }
 
 TEST_F(DisplayInfoProviderTest, QueryDisplayInfo) {
-  scoped_ptr<DisplayInfo> display_info(new DisplayInfo());
-  EXPECT_TRUE(display_info_provider_->QueryInfo(display_info.get()));
-  EXPECT_EQ(arraysize(kTestingDisplayInfoData), display_info->size());
+  EXPECT_TRUE(display_info_provider_->QueryInfo());
+  const DisplayInfo& display_info = display_info_provider_->display_info();
+  EXPECT_EQ(arraysize(kTestingDisplayInfoData), display_info.size());
   for (size_t i = 0; i < arraysize(kTestingDisplayInfoData); ++i) {
     const linked_ptr<api::system_info_display::DisplayUnitInfo> unit =
-        (*display_info.get())[i];
+        display_info[i];
     EXPECT_EQ(kTestingDisplayInfoData[i].id, unit->id);
     EXPECT_EQ(kTestingDisplayInfoData[i].name, unit->name);
     EXPECT_DOUBLE_EQ(kTestingDisplayInfoData[i].dpi_x, unit->dpi_x);
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider_win.cc b/chrome/browser/extensions/api/system_info_display/display_info_provider_win.cc
index 42acbc9..e242fbb 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider_win.cc
+++ b/chrome/browser/extensions/api/system_info_display/display_info_provider_win.cc
@@ -81,12 +81,11 @@
       base::Bind(callback, false, "Not implemented"));
 }
 
-bool DisplayInfoProvider::QueryInfo(DisplayInfo* info) {
-  DCHECK(info);
-  info->clear();
+bool DisplayInfoProvider::QueryInfo() {
+  info_.clear();
 
   if (EnumDisplayMonitors(NULL, NULL, EnumMonitorCallback,
-        reinterpret_cast<LPARAM>(info)))
+        reinterpret_cast<LPARAM>(&info_)))
     return true;
   return false;
 }
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider_x11.cc b/chrome/browser/extensions/api/system_info_display/display_info_provider_x11.cc
index 54c847a..a3f46d0 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider_x11.cc
+++ b/chrome/browser/extensions/api/system_info_display/display_info_provider_x11.cc
@@ -21,7 +21,7 @@
 }
 
 // TODO(hongbo): implement X11 display info querying.
-bool DisplayInfoProvider::QueryInfo(DisplayInfo* info) {
+bool DisplayInfoProvider::QueryInfo() {
   return false;
 }
 
diff --git a/chrome/browser/extensions/api/system_info_display/system_info_display_api.cc b/chrome/browser/extensions/api/system_info_display/system_info_display_api.cc
index 2c20e67..d2c8748 100644
--- a/chrome/browser/extensions/api/system_info_display/system_info_display_api.cc
+++ b/chrome/browser/extensions/api/system_info_display/system_info_display_api.cc
@@ -22,9 +22,10 @@
 }
 
 void SystemInfoDisplayGetDisplayInfoFunction::OnGetDisplayInfoCompleted(
-    const DisplayInfo& info, bool success) {
+    bool success) {
   if (success) {
-    results_ = api::system_info_display::GetDisplayInfo::Results::Create(info);
+    results_ = api::system_info_display::GetDisplayInfo::Results::Create(
+                   DisplayInfoProvider::GetProvider()->display_info());
   } else {
     SetError("Error occurred when querying display information.");
   }
diff --git a/chrome/browser/extensions/api/system_info_display/system_info_display_api.h b/chrome/browser/extensions/api/system_info_display/system_info_display_api.h
index 1a6e53c..db427e5 100644
--- a/chrome/browser/extensions/api/system_info_display/system_info_display_api.h
+++ b/chrome/browser/extensions/api/system_info_display/system_info_display_api.h
@@ -22,7 +22,7 @@
   virtual bool RunImpl() OVERRIDE;
 
  private:
-  void OnGetDisplayInfoCompleted(const DisplayInfo& info, bool success);
+  void OnGetDisplayInfoCompleted(bool success);
 };
 
 class SystemInfoDisplaySetDisplayPropertiesFunction
diff --git a/chrome/browser/extensions/api/system_info_display/system_info_display_apitest.cc b/chrome/browser/extensions/api/system_info_display/system_info_display_apitest.cc
index 94637d3..ec254d7 100644
--- a/chrome/browser/extensions/api/system_info_display/system_info_display_apitest.cc
+++ b/chrome/browser/extensions/api/system_info_display/system_info_display_apitest.cc
@@ -20,8 +20,8 @@
  public:
   MockDisplayInfoProvider() {}
 
-  virtual bool QueryInfo(DisplayInfo* info) OVERRIDE {
-    info->clear();
+  virtual bool QueryInfo() OVERRIDE {
+    info_.clear();
     for (int i = 0; i < 4; i++) {
       linked_ptr<DisplayUnitInfo> unit(new DisplayUnitInfo());
       unit->id = base::IntToString(i);
@@ -48,7 +48,7 @@
       unit->work_area.top = 0;
       unit->work_area.width = 960;
       unit->work_area.height = 720;
-      info->push_back(unit);
+      info_.push_back(unit);
     }
     return true;
   }
diff --git a/chrome/browser/extensions/api/system_info_memory/memory_info_provider.cc b/chrome/browser/extensions/api/system_info_memory/memory_info_provider.cc
index f1964be..4bef0ed 100644
--- a/chrome/browser/extensions/api/system_info_memory/memory_info_provider.cc
+++ b/chrome/browser/extensions/api/system_info_memory/memory_info_provider.cc
@@ -10,13 +10,22 @@
 
 using api::system_info_memory::MemoryInfo;
 
+// Static member intialization.
+template<>
+base::LazyInstance<scoped_refptr<SystemInfoProvider<MemoryInfo> > >
+  SystemInfoProvider<MemoryInfo>::provider_ = LAZY_INSTANCE_INITIALIZER;
+
 MemoryInfoProvider::MemoryInfoProvider() {}
 
 MemoryInfoProvider::~MemoryInfoProvider() {}
 
-bool MemoryInfoProvider::QueryInfo(MemoryInfo* info) {
-  info->capacity = static_cast<double>(base::SysInfo::AmountOfPhysicalMemory());
-  info->available_capacity =
+const MemoryInfo& MemoryInfoProvider::memory_info() const {
+  return info_;
+}
+
+bool MemoryInfoProvider::QueryInfo() {
+  info_.capacity = static_cast<double>(base::SysInfo::AmountOfPhysicalMemory());
+  info_.available_capacity =
      static_cast<double>(base::SysInfo::AmountOfAvailablePhysicalMemory());
   return true;
 }
diff --git a/chrome/browser/extensions/api/system_info_memory/memory_info_provider.h b/chrome/browser/extensions/api/system_info_memory/memory_info_provider.h
index 589d3ac..d920036 100644
--- a/chrome/browser/extensions/api/system_info_memory/memory_info_provider.h
+++ b/chrome/browser/extensions/api/system_info_memory/memory_info_provider.h
@@ -17,8 +17,9 @@
   static MemoryInfoProvider* Get();
 
   // Overriden from SystemInfoProvider<MemoryInfo>.
-  virtual bool QueryInfo(
-      api::system_info_memory::MemoryInfo* info) OVERRIDE;
+  virtual bool QueryInfo() OVERRIDE;
+
+  const api::system_info_memory::MemoryInfo& memory_info() const;
 
  private:
   friend class SystemInfoProvider<
diff --git a/chrome/browser/extensions/api/system_info_memory/memory_info_provider_unittest.cc b/chrome/browser/extensions/api/system_info_memory/memory_info_provider_unittest.cc
index 9e008b3..1f4aae4 100644
--- a/chrome/browser/extensions/api/system_info_memory/memory_info_provider_unittest.cc
+++ b/chrome/browser/extensions/api/system_info_memory/memory_info_provider_unittest.cc
@@ -20,18 +20,17 @@
 
 class TestMemoryInfoProvider : public MemoryInfoProvider {
  public:
-  virtual bool QueryInfo(MemoryInfo* info) OVERRIDE;
+  virtual bool QueryInfo() OVERRIDE;
+
  private:
   virtual ~TestMemoryInfoProvider();
 };
 
 TestMemoryInfoProvider::~TestMemoryInfoProvider() {}
 
-bool TestMemoryInfoProvider::QueryInfo(MemoryInfo* info) {
-  if (info == NULL)
-    return false;
-  info->capacity = kTestingMemoryInfoData.capacity;
-  info->available_capacity = kTestingMemoryInfoData.available_capacity;
+bool TestMemoryInfoProvider::QueryInfo() {
+  info_.capacity = kTestingMemoryInfoData.capacity;
+  info_.available_capacity = kTestingMemoryInfoData.available_capacity;
   return true;
 }
 
@@ -48,11 +47,11 @@
 }
 
 TEST_F(MemoryInfoProviderTest, QueryMemoryInfo) {
-  scoped_ptr<MemoryInfo> memory_info(new MemoryInfo());
-  EXPECT_TRUE(memory_info_provider_->QueryInfo(memory_info.get()));
-  EXPECT_DOUBLE_EQ(kTestingMemoryInfoData.capacity, memory_info->capacity);
+  EXPECT_TRUE(memory_info_provider_->QueryInfo());
+  EXPECT_DOUBLE_EQ(kTestingMemoryInfoData.capacity,
+                   memory_info_provider_->memory_info().capacity);
   EXPECT_DOUBLE_EQ(kTestingMemoryInfoData.available_capacity,
-                   memory_info->available_capacity);
+                   memory_info_provider_->memory_info().available_capacity);
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/system_info_memory/system_info_memory_api.cc b/chrome/browser/extensions/api/system_info_memory/system_info_memory_api.cc
index 38bf680..7439294 100644
--- a/chrome/browser/extensions/api/system_info_memory/system_info_memory_api.cc
+++ b/chrome/browser/extensions/api/system_info_memory/system_info_memory_api.cc
@@ -20,10 +20,9 @@
   return true;
 }
 
-void SystemInfoMemoryGetFunction::OnGetMemoryInfoCompleted(
-    const MemoryInfo& info, bool success) {
+void SystemInfoMemoryGetFunction::OnGetMemoryInfoCompleted(bool success) {
   if (success)
-    SetResult(info.ToValue().release());
+    SetResult(MemoryInfoProvider::Get()->memory_info().ToValue().release());
   else
     SetError("Error occurred when querying memory information.");
   SendResponse(success);
diff --git a/chrome/browser/extensions/api/system_info_memory/system_info_memory_api.h b/chrome/browser/extensions/api/system_info_memory/system_info_memory_api.h
index 3a157b8..410fbf6 100644
--- a/chrome/browser/extensions/api/system_info_memory/system_info_memory_api.h
+++ b/chrome/browser/extensions/api/system_info_memory/system_info_memory_api.h
@@ -18,9 +18,7 @@
  private:
   virtual ~SystemInfoMemoryGetFunction();
   virtual bool RunImpl() OVERRIDE;
-  void OnGetMemoryInfoCompleted(
-      const api::system_info_memory::MemoryInfo& info,
-      bool success);
+  void OnGetMemoryInfoCompleted(bool success);
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/system_info_memory/system_info_memory_apitest.cc b/chrome/browser/extensions/api/system_info_memory/system_info_memory_apitest.cc
index a101640..8170b1f 100644
--- a/chrome/browser/extensions/api/system_info_memory/system_info_memory_apitest.cc
+++ b/chrome/browser/extensions/api/system_info_memory/system_info_memory_apitest.cc
@@ -20,9 +20,9 @@
  public:
   MockMemoryInfoProviderImpl() {}
 
-  virtual bool QueryInfo(MemoryInfo* info) OVERRIDE {
-    info->capacity = 4096;
-    info->available_capacity = 1024;
+  virtual bool QueryInfo() OVERRIDE {
+    info_.capacity = 4096;
+    info_.available_capacity = 1024;
     return true;
   }
  private:
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_free_space_observer.h b/chrome/browser/extensions/api/system_info_storage/storage_free_space_observer.h
new file mode 100644
index 0000000..1d1957f
--- /dev/null
+++ b/chrome/browser/extensions/api/system_info_storage/storage_free_space_observer.h
@@ -0,0 +1,28 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_STORAGE_FREE_SPACE_OBSERVER_H_
+#define CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_STORAGE_FREE_SPACE_OBSERVER_H_
+
+#include <string>
+
+namespace extensions {
+
+// Observes the storage free space changes.
+//
+// StorageInfoProvider class maintains a StorageFreeSpaceObserver list for
+// storage devices' free space change event.
+class StorageFreeSpaceObserver {
+ public:
+  // Called when the storage free space changes.
+  virtual void OnFreeSpaceChanged(const std::string& transient_id,
+                                  double old_value, /* in bytes */
+                                  double new_value  /* in bytes */) = 0;
+ protected:
+  virtual ~StorageFreeSpaceObserver() {}
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_STORAGE_FREE_SPACE_OBSERVER_H_
+
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_observer.h b/chrome/browser/extensions/api/system_info_storage/storage_info_observer.h
deleted file mode 100644
index 914a51a..0000000
--- a/chrome/browser/extensions/api/system_info_storage/storage_info_observer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#ifndef CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_STORAGE_INFO_OBSERVER_H_
-#define CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_STORAGE_INFO_OBSERVER_H_
-
-#include "chrome/common/extensions/api/experimental_system_info_storage.h"
-
-namespace extensions {
-
-// Observes the changes happening on the storage devices, including free space
-// changes, storage arrival and removal.
-class StorageInfoObserver {
- public:
-  virtual ~StorageInfoObserver() {}
-
-  // Called when the storage free space changes.
-  virtual void OnStorageFreeSpaceChanged(const std::string& device_id,
-                                         double old_value,
-                                         double new_value) {}
-
-  // Called when a new removable storage device is attached.
-  virtual void OnStorageAttached(
-      const std::string& device_id,
-      api::experimental_system_info_storage::StorageUnitType type,
-      double capacity,
-      double available_capacity) {}
-
-  // Called when a removable storage device is detached.
-  virtual void OnStorageDetached(const std::string& device_id) {}
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_STORAGE_INFO_OBSERVER_H_
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider.cc b/chrome/browser/extensions/api/system_info_storage/storage_info_provider.cc
index b29afa0..c43fe8f 100644
--- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider.cc
+++ b/chrome/browser/extensions/api/system_info_storage/storage_info_provider.cc
@@ -6,6 +6,7 @@
 
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/sys_info.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/storage_monitor/storage_monitor.h"
 #include "content/public/browser/browser_thread.h"
@@ -13,7 +14,10 @@
 namespace extensions {
 
 using content::BrowserThread;
+using chrome::StorageMonitor;
 using api::experimental_system_info_storage::StorageUnitInfo;
+using api::experimental_system_info_storage::STORAGE_UNIT_TYPE_FIXED;
+using api::experimental_system_info_storage::STORAGE_UNIT_TYPE_REMOVABLE;
 
 namespace systeminfo {
 
@@ -21,127 +25,170 @@
 const char kStorageTypeFixed[] = "fixed";
 const char kStorageTypeRemovable[] = "removable";
 
+void BuildStorageUnitInfo(const chrome::StorageInfo& info,
+                          StorageUnitInfo* unit) {
+  unit->id = StorageInfoProvider::Get()->GetTransientIdForDeviceId(
+                 info.device_id());
+  unit->name = UTF16ToUTF8(info.name());
+  // TODO(hmin): Might need to take MTP device into consideration.
+  unit->type = chrome::StorageInfo::IsRemovableDevice(info.device_id()) ?
+      STORAGE_UNIT_TYPE_REMOVABLE : STORAGE_UNIT_TYPE_FIXED;
+  unit->capacity = static_cast<double>(info.total_size_in_bytes());
+  unit->available_capacity = 0;
+}
+
 }  // namespace systeminfo
 
 const int kDefaultPollingIntervalMs = 1000;
 const char kWatchingTokenName[] = "_storage_info_watching_token_";
 
+// Static member intialization.
+template<>
+base::LazyInstance<scoped_refptr<SystemInfoProvider<StorageUnitInfoList> > >
+  SystemInfoProvider<StorageUnitInfoList>::provider_
+      = LAZY_INSTANCE_INITIALIZER;
+
 StorageInfoProvider::StorageInfoProvider()
-    : observers_(new ObserverListThreadSafe<StorageInfoObserver>()),
+    : observers_(new ObserverListThreadSafe<StorageFreeSpaceObserver>()),
       watching_interval_(kDefaultPollingIntervalMs) {
-  DCHECK(chrome::StorageMonitor::GetInstance());
-  chrome::StorageMonitor::GetInstance()->AddObserver(this);
 }
 
 StorageInfoProvider::~StorageInfoProvider() {
-  // Note that StorageInfoProvider is defined as a LazyInstance which would be
-  // destroyed at process exiting, so its lifetime should be longer than the
-  // StorageMonitor instance that would be destroyed before
-  // StorageInfoProvider.
-  if (chrome::StorageMonitor::GetInstance())
-    chrome::StorageMonitor::GetInstance()->RemoveObserver(this);
 }
 
-void StorageInfoProvider::AddObserver(StorageInfoObserver* obs) {
+const StorageUnitInfoList& StorageInfoProvider::storage_unit_info_list() const {
+  return info_;
+}
+
+void StorageInfoProvider::PrepareQueryOnUIThread() {
+  // Get all available storage devices before invoking |QueryInfo()| to get
+  // available capacity.
+  GetAllStoragesIntoInfoList();
+}
+
+void StorageInfoProvider::InitializeProvider(
+    const base::Closure& do_query_info_callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  // Register the |do_query_info_callback| callback to StorageMonitor.
+  // See the comments of StorageMonitor::EnsureInitialized about when the
+  // callback gets run.
+  StorageMonitor::GetInstance()->EnsureInitialized(do_query_info_callback);
+}
+
+bool StorageInfoProvider::QueryInfo() {
+  DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
+  for (StorageUnitInfoList::iterator it = info_.begin();
+       it != info_.end(); ++it) {
+    int64 amount = GetStorageFreeSpaceFromTransientId((*it)->id);
+    if (amount > 0)
+      (*it)->available_capacity = static_cast<double>(amount);
+  }
+
+  return true;
+}
+
+std::vector<chrome::StorageInfo> StorageInfoProvider::GetAllStorages() const {
+  return StorageMonitor::GetInstance()->GetAllAvailableStorages();
+}
+
+void StorageInfoProvider::GetAllStoragesIntoInfoList() {
+  info_.clear();
+  std::vector<chrome::StorageInfo> storage_list = GetAllStorages();
+  std::vector<chrome::StorageInfo>::const_iterator it = storage_list.begin();
+  for (; it != storage_list.end(); ++it) {
+    linked_ptr<StorageUnitInfo> unit(new StorageUnitInfo());
+    systeminfo::BuildStorageUnitInfo(*it, unit.get());
+    info_.push_back(unit);
+  }
+}
+
+void StorageInfoProvider::AddObserver(StorageFreeSpaceObserver* obs) {
   observers_->AddObserver(obs);
 }
 
-void StorageInfoProvider::RemoveObserver(StorageInfoObserver* obs) {
+void StorageInfoProvider::RemoveObserver(StorageFreeSpaceObserver* obs) {
   observers_->RemoveObserver(obs);
 }
 
-void StorageInfoProvider::OnRemovableStorageAttached(
-    const chrome::StorageInfo& info) {
-  // Since the storage API uses the location as identifier, e.g.
-  // the drive letter on Windows while mount point on Posix. Here we has to
-  // convert the |info.location| to UTF-8 encoding.
-  //
-  // TODO(hongbo): use |info.device_id| instead of using |info.location|
-  // to keep the id persisting between device attachments, like
-  // StorageMonitor does.
-#if defined(OS_POSIX)
-  std::string id = info.location();
-#elif defined(OS_WIN)
-  std::string id = UTF16ToUTF8(info.location());
-#endif
-  // Post a task to blocking pool for querying the information.
-  BrowserThread::PostBlockingPoolTask(FROM_HERE,
-      base::Bind(&StorageInfoProvider::QueryAttachedStorageInfoOnBlockingPool,
-                 this, id));
-}
+void StorageInfoProvider::StartWatching(const std::string& transient_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-void StorageInfoProvider::QueryAttachedStorageInfoOnBlockingPool(
-    const std::string& id) {
-  DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
-
-  StorageUnitInfo info;
-  if (!QueryUnitInfo(id, &info))
-    return;
-  observers_->Notify(&StorageInfoObserver::OnStorageAttached,
-                     info.id,
-                     info.type,
-                     info.capacity,
-                     info.available_capacity);
-}
-
-void StorageInfoProvider::OnRemovableStorageDetached(
-    const chrome::StorageInfo& info) {
-  // TODO(hongbo): Use |info.device_id| instead. Same as the above.
-#if defined(OS_POSIX)
-  std::string id = info.location();
-#elif defined(OS_WIN)
-  std::string id = UTF16ToUTF8(info.location());
-#endif
-  observers_->Notify(&StorageInfoObserver::OnStorageDetached, id);
-}
-
-void StorageInfoProvider::StartWatching(const std::string& id) {
   BrowserThread::PostBlockingPoolSequencedTask(
       kWatchingTokenName,
       FROM_HERE,
       base::Bind(&StorageInfoProvider::AddWatchedStorageOnBlockingPool,
-                 this, id));
+                 this, transient_id));
 }
 
-void StorageInfoProvider::StopWatching(const std::string& id) {
+void StorageInfoProvider::StopWatching(const std::string& transient_id) {
+  base::FilePath mount_path;
   BrowserThread::PostBlockingPoolSequencedTask(
       kWatchingTokenName,
       FROM_HERE,
       base::Bind(&StorageInfoProvider::RemoveWatchedStorageOnBlockingPool,
-                 this, id));
+                 this, transient_id));
+}
+
+void StorageInfoProvider::StartWatchingAllStorages() {
+  for (StorageUnitInfoList::const_iterator it = info_.begin();
+       it != info_.end(); ++it) {
+    StartWatching((*it)->id);
+  }
+}
+
+void StorageInfoProvider::StopWatchingAllStorages() {
+  for (StorageUnitInfoList::const_iterator it = info_.begin();
+       it != info_.end(); ++it) {
+    StopWatching((*it)->id);
+  }
+}
+
+int64 StorageInfoProvider::GetStorageFreeSpaceFromTransientId(
+    const std::string& transient_id) {
+  std::vector<chrome::StorageInfo> storage_list = GetAllStorages();
+  std::string device_id = GetDeviceIdForTransientId(transient_id);
+
+  // Lookup the matched storage info by |device_id|.
+  for (std::vector<chrome::StorageInfo>::const_iterator it =
+       storage_list.begin();
+       it != storage_list.end(); ++it) {
+    if (device_id == it->device_id())
+      return base::SysInfo::AmountOfFreeDiskSpace(
+                 base::FilePath(it->location()));
+  }
+
+  return -1;
 }
 
 void StorageInfoProvider::AddWatchedStorageOnBlockingPool(
-    const std::string& id) {
+    const std::string& transient_id) {
   DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
-  // If the storage |id| is already being watched.
-  if (ContainsKey(storage_id_to_size_map_, id))
+  // If the storage |transient_id| is already being watched.
+  if (ContainsKey(storage_transient_id_to_size_map_, transient_id))
     return;
 
-  StorageUnitInfo info;
-  if (!QueryUnitInfo(id, &info))
+  int64 available_bytes = GetStorageFreeSpaceFromTransientId(transient_id);
+  if (available_bytes < 0)
     return;
 
-  storage_id_to_size_map_[id] = info.available_capacity;
+  storage_transient_id_to_size_map_[transient_id] = available_bytes;
 
   // If it is the first storage to be watched, we need to start the watching
   // timer.
-  if (storage_id_to_size_map_.size() == 1) {
+  if (storage_transient_id_to_size_map_.size() == 1) {
     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
         base::Bind(&StorageInfoProvider::StartWatchingTimerOnUIThread, this));
   }
 }
 
 void StorageInfoProvider::RemoveWatchedStorageOnBlockingPool(
-    const std::string& id) {
+    const std::string& transient_id) {
   DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
-  if (!ContainsKey(storage_id_to_size_map_, id))
+  if (storage_transient_id_to_size_map_.erase(transient_id) == 0)
     return;
 
-  storage_id_to_size_map_.erase(id);
-
   // Stop watching timer if there is no storage to be watched.
-  if (storage_id_to_size_map_.empty()) {
+  if (storage_transient_id_to_size_map_.empty()) {
     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
         base::Bind(&StorageInfoProvider::StopWatchingTimerOnUIThread, this));
   }
@@ -149,38 +196,52 @@
 
 void StorageInfoProvider::CheckWatchedStorages() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  BrowserThread::PostBlockingPoolSequencedTask(kWatchingTokenName, FROM_HERE,
-      base::Bind(&StorageInfoProvider::CheckWatchedStoragesOnBlockingPool,
-                 this));
+  std::vector<chrome::StorageInfo> storage_list = GetAllStorages();
+
+  for (std::vector<chrome::StorageInfo>::iterator it = storage_list.begin();
+       it != storage_list.end(); ++it) {
+    BrowserThread::PostBlockingPoolSequencedTask(
+        kWatchingTokenName,
+        FROM_HERE,
+        base::Bind(&StorageInfoProvider::CheckWatchedStorageOnBlockingPool,
+                   this, GetTransientIdForDeviceId(it->device_id())));
+  }
 }
 
-void StorageInfoProvider::CheckWatchedStoragesOnBlockingPool() {
+void StorageInfoProvider::CheckWatchedStorageOnBlockingPool(
+    const std::string& transient_id) {
   DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
-  for (StorageIDToSizeMap::iterator it = storage_id_to_size_map_.begin();
-       it != storage_id_to_size_map_.end(); ) {
-    StorageUnitInfo info;
-    if (!QueryUnitInfo(it->first, &info)) {
-      storage_id_to_size_map_.erase(it++);
-      continue;
-    }
-    if (it->second != info.available_capacity) {
-      observers_->Notify(&StorageInfoObserver::OnStorageFreeSpaceChanged,
-                         it->first, /* storage id */
-                         it->second, /* old free space value */
-                         info.available_capacity /* new value */);
-      it->second = info.available_capacity;
-    }
-    ++it;
-  }
+  if (!ContainsKey(storage_transient_id_to_size_map_, transient_id))
+    return;
 
-  if (storage_id_to_size_map_.size() == 0) {
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::Bind(&StorageInfoProvider::StopWatchingTimerOnUIThread,
-                   this));
+  double new_available_bytes = GetStorageFreeSpaceFromTransientId(transient_id);
+  double old_available_bytes = storage_transient_id_to_size_map_[transient_id];
+
+  // No free space change.
+  if (new_available_bytes == old_available_bytes)
+    return;
+
+  if (new_available_bytes < 0) {
+    // In case we can't establish the new free space value from |transient_id|,
+    // the |transient_id| is currently not available, so we need to remove it
+    // from |storage_transient_id_to_size_map_|.
+    storage_transient_id_to_size_map_.erase(transient_id);
+    if (storage_transient_id_to_size_map_.size() == 0) {
+      BrowserThread::PostTask(
+          BrowserThread::UI, FROM_HERE,
+          base::Bind(&StorageInfoProvider::StopWatchingTimerOnUIThread, this));
+    }
     return;
   }
-  OnCheckWatchedStoragesFinishedForTesting();
+
+  // Ignore free space change event if the old available capacity is 0.
+  if (old_available_bytes > 0) {
+    observers_->Notify(&StorageFreeSpaceObserver::OnFreeSpaceChanged,
+                       transient_id,
+                       old_available_bytes,
+                       new_available_bytes);
+  }
+  storage_transient_id_to_size_map_[transient_id] = new_available_bytes;
 }
 
 void StorageInfoProvider::StartWatchingTimerOnUIThread() {
@@ -198,4 +259,19 @@
   watching_timer_.Stop();
 }
 
+std::string StorageInfoProvider::GetTransientIdForDeviceId(
+    const std::string& device_id) const {
+  return StorageMonitor::GetInstance()->GetTransientIdForDeviceId(device_id);
+}
+
+std::string StorageInfoProvider::GetDeviceIdForTransientId(
+    const std::string& transient_id) const {
+  return StorageMonitor::GetInstance()->GetDeviceIdForTransientId(transient_id);
+}
+
+// static
+StorageInfoProvider* StorageInfoProvider::Get() {
+  return StorageInfoProvider::GetInstance<StorageInfoProvider>();
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider.h b/chrome/browser/extensions/api/system_info_storage/storage_info_provider.h
index 88c147b..a6138dd 100644
--- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider.h
+++ b/chrome/browser/extensions/api/system_info_storage/storage_info_provider.h
@@ -10,7 +10,7 @@
 #include "base/observer_list_threadsafe.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/extensions/api/system_info/system_info_provider.h"
-#include "chrome/browser/extensions/api/system_info_storage/storage_info_observer.h"
+#include "chrome/browser/extensions/api/system_info_storage/storage_free_space_observer.h"
 #include "chrome/browser/storage_monitor/removable_storage_observer.h"
 #include "chrome/browser/storage_monitor/storage_info.h"
 #include "chrome/common/extensions/api/experimental_system_info_storage.h"
@@ -25,64 +25,86 @@
 extern const char kStorageTypeFixed[];
 extern const char kStorageTypeRemovable[];
 
+// Build StorageUnitInfo struct from chrome::StorageInfo instance. The |unit|
+// parameter is the output value.
+void BuildStorageUnitInfo(const chrome::StorageInfo& info,
+    api::experimental_system_info_storage::StorageUnitInfo* unit);
+
 }  // namespace systeminfo
 
 typedef std::vector<linked_ptr<
-    api::experimental_system_info_storage::StorageUnitInfo> > StorageInfo;
+    api::experimental_system_info_storage::StorageUnitInfo> >
+        StorageUnitInfoList;
 
-class StorageInfoProvider
-    : public SystemInfoProvider<StorageInfo>,
-      public chrome::RemovableStorageObserver {
+class StorageInfoProvider : public SystemInfoProvider<StorageUnitInfoList> {
  public:
+  StorageInfoProvider();
+
   // Get the single shared instance of StorageInfoProvider.
   static StorageInfoProvider* Get();
 
   // Add and remove observer, both can be called from any thread.
-  void AddObserver(StorageInfoObserver* obs);
-  void RemoveObserver(StorageInfoObserver* obs);
+  void AddObserver(StorageFreeSpaceObserver* obs);
+  void RemoveObserver(StorageFreeSpaceObserver* obs);
 
-  // Start and stop watching the given storage |id|.
-  virtual void StartWatching(const std::string& id);
-  virtual void StopWatching(const std::string& id);
+  // Start and stop watching the given storage |transient_id|.
+  void StartWatching(const std::string& transient_id);
+  void StopWatching(const std::string& transient_id);
 
-  // Get the information for the storage unit specified by the |id| parameter,
-  // and output the result to the |info|.
-  virtual bool QueryUnitInfo(const std::string& id,
-      api::experimental_system_info_storage::StorageUnitInfo* info) = 0;
+  // Start and stop watching all available storages.
+  void StartWatchingAllStorages();
+  void StopWatchingAllStorages();
+
+  // Returns all available storages, including fixed and removable.
+  virtual std::vector<chrome::StorageInfo> GetAllStorages() const;
+
+  // SystemInfoProvider implementations
+  virtual void PrepareQueryOnUIThread() OVERRIDE;
+  virtual void InitializeProvider(const base::Closure& do_query_info_callback)
+      OVERRIDE;
+
+  // Get the amount of storage free space from |transient_id|, or -1 on failure.
+  virtual int64 GetStorageFreeSpaceFromTransientId(
+      const std::string& transient_id);
+
+  virtual std::string GetTransientIdForDeviceId(
+      const std::string& device_id) const;
+  virtual std::string GetDeviceIdForTransientId(
+      const std::string& transient_id) const;
+
+  const StorageUnitInfoList& storage_unit_info_list() const;
 
  protected:
-  StorageInfoProvider();
   virtual ~StorageInfoProvider();
 
+  // TODO(Haojian): Put this method in a testing subclass rather than here.
   void SetWatchingIntervalForTesting(size_t ms) { watching_interval_ = ms; }
 
+  // Put all available storages' information into |info_|.
+  virtual void GetAllStoragesIntoInfoList();
+
  private:
-  typedef std::map<std::string, double> StorageIDToSizeMap;
+  typedef std::map<std::string, double> StorageTransientIdToSizeMap;
 
-  // chrome::RemovableStorageObserver implementation.
-  virtual void OnRemovableStorageAttached(
-      const chrome::StorageInfo& info) OVERRIDE;
-  virtual void OnRemovableStorageDetached(
-      const chrome::StorageInfo& info) OVERRIDE;
-
+  // SystemInfoProvider implementations.
+  // Override to query the available capacity of all known storage devices on
+  // the blocking pool, including fixed and removable devices.
+  virtual bool QueryInfo() OVERRIDE;
   // Query the new attached removable storage info on the blocking pool.
-  void QueryAttachedStorageInfoOnBlockingPool(const std::string& id);
+  void QueryAttachedStorageInfoOnBlockingPool(const std::string& transient_id);
 
   // Posts a task to check for free space changes on the blocking pool.
   // Should be called on the UI thread.
   void CheckWatchedStorages();
 
   // Check if the free space changes for the watched storages by iterating over
-  // the |storage_id_to_size_map_|. It is called on blocking pool.
-  void CheckWatchedStoragesOnBlockingPool();
+  // the |storage_transient_id_to_size_map_|. It is called on blocking pool.
+  void CheckWatchedStorageOnBlockingPool(const std::string& transient_id);
 
-  // Provides an explicit hook that tests can wait for to determine that the
-  // call to CheckWatchedStorages() has completed.
-  virtual void OnCheckWatchedStoragesFinishedForTesting() {}
-
-  // Add and remove the storage to be watched.
-  void AddWatchedStorageOnBlockingPool(const std::string& id);
-  void RemoveWatchedStorageOnBlockingPool(const std::string& id);
+  // Add the storage identified by |transient_id| into watching list.
+  void AddWatchedStorageOnBlockingPool(const std::string& transient_id);
+  // Remove the storage identified by |transient_id| from watching list.
+  void RemoveWatchedStorageOnBlockingPool(const std::string& transient_id);
 
   void StartWatchingTimerOnUIThread();
   // Force to stop the watching timer or there is no any one storage to be
@@ -91,14 +113,14 @@
 
   // Mapping of the storage being watched and the recent free space value. It
   // is maintained on the blocking pool.
-  StorageIDToSizeMap storage_id_to_size_map_;
+  StorageTransientIdToSizeMap storage_transient_id_to_size_map_;
 
   // The timer used for watching the storage free space changes periodically.
   base::RepeatingTimer<StorageInfoProvider> watching_timer_;
 
   // The thread-safe observer list that observe the changes happening on the
   // storages.
-  scoped_refptr<ObserverListThreadSafe<StorageInfoObserver> > observers_;
+  scoped_refptr<ObserverListThreadSafe<StorageFreeSpaceObserver> > observers_;
 
   // The time interval for watching the free space change, in milliseconds.
   // Only changed for testing purposes.
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_android.cc b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_android.cc
deleted file mode 100644
index 25e9f6e..0000000
--- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_android.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/system_info_storage/storage_info_provider.h"
-
-namespace extensions {
-
-namespace {
-
-using api::experimental_system_info_storage::StorageUnitInfo;
-
-// Empty StorageInfoProvider implementation on Android platform.
-class StorageInfoProviderAndroid : public StorageInfoProvider {
- public:
-  StorageInfoProviderAndroid() {}
-
-  virtual bool QueryInfo(StorageInfo* info) OVERRIDE {
-    NOTIMPLEMENTED();
-    return false;
-  }
-  virtual bool QueryUnitInfo(const std::string& id,
-                             StorageUnitInfo* info) OVERRIDE {
-    NOTIMPLEMENTED();
-    return false;
-  }
-
- private:
-  virtual ~StorageInfoProviderAndroid() {}
-};
-
-}  //
-
-// static
-StorageInfoProvider* StorageInfoProvider::Get() {
-  return StorageInfoProvider::GetInstance<StorageInfoProviderAndroid>();
-}
-
-}  // namespace extensions
-
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_linux.cc b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_linux.cc
deleted file mode 100644
index a850f34..0000000
--- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_linux.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/system_info_storage/storage_info_provider_linux.h"
-
-#include <mntent.h>
-#include <sys/vfs.h>
-
-namespace extensions {
-
-using api::experimental_system_info_storage::StorageUnitInfo;
-using api::experimental_system_info_storage::ParseStorageUnitType;
-using chrome::GetUdevDevicePropertyValue;
-using chrome::ScopedUdevDeviceObject;
-
-namespace {
-
-const char kMtabPath[] = "/etc/mtab";
-const char kDevPath[] = "/dev/";
-
-}  // namespace
-
-StorageInfoProviderLinux::StorageInfoProviderLinux()
-  : udev_context_(udev_new()),
-    mtab_file_path_(kMtabPath) {
-}
-
-StorageInfoProviderLinux::~StorageInfoProviderLinux() {}
-
-StorageInfoProviderLinux::StorageInfoProviderLinux(
-    const base::FilePath& mtab_path)
-    : udev_context_(udev_new()),
-      mtab_file_path_(mtab_path) {
-}
-
-bool StorageInfoProviderLinux::QueryInfo(StorageInfo* info) {
-  info->clear();
-  FILE* fp = setmntent(mtab_file_path_.value().c_str(), "r");
-  if (!fp) {
-    DPLOG(INFO) << "Failed to open " << kMtabPath;
-    return false;
-  }
-  struct mntent* p_mntent = NULL;
-  while ((p_mntent = getmntent(fp))) {
-    if (strncmp(p_mntent->mnt_fsname, kDevPath, strlen(kDevPath)) != 0)
-      continue;
-    linked_ptr<StorageUnitInfo> unit(new StorageUnitInfo());
-    if (QueryUnitInfo(p_mntent->mnt_dir, unit.get())) {
-        info->push_back(unit);
-    }
-  }
-  endmntent(fp);
-  return true;
-}
-
-bool StorageInfoProviderLinux::QueryUnitInfo(const std::string& mount_path,
-                                             StorageUnitInfo* info) {
-  std::string type;
-  if (!QueryStorageType(mount_path, &type))
-    return false;
-
-  struct statfs fs_info;
-  if (statfs(mount_path.c_str(), &fs_info) != 0) {
-    DPLOG(INFO) << "Failed to get filesystem information about " << mount_path;
-    return false;
-  }
-  // Currently the mount path is used as the identifier of a storage unit.
-  info->id = mount_path;
-  info->type = ParseStorageUnitType(type);
-  info->capacity = static_cast<double>(fs_info.f_blocks) * fs_info.f_bsize;
-  info->available_capacity =
-    static_cast<double>(fs_info.f_bavail) * fs_info.f_bsize;
-
-  return true;
-}
-
-bool StorageInfoProviderLinux::QueryStorageType(const std::string& mount_path,
-                                                std::string* type) {
-  struct stat stat_info;
-  if (stat(mount_path.c_str(), &stat_info) != 0) {
-    DPLOG(INFO) << "Failed to get information about " << mount_path;
-    return false;
-  }
-
-  // Create a udev device from a block device number.
-  ScopedUdevDeviceObject device(udev_device_new_from_devnum(
-        udev_context_.get(), 'b', stat_info.st_dev));
-  if (!device)
-    return false;
-  if (GetUdevDevicePropertyValue(device.get(), "ID_BUS") == "usb") {
-    *type = systeminfo::kStorageTypeRemovable;
-  } else if (GetUdevDevicePropertyValue(device.get(), "ID_TYPE") == "disk") {
-    *type = systeminfo::kStorageTypeFixed;
-  } else {
-    *type = systeminfo::kStorageTypeUnknown;
-  }
-  return true;
-}
-
-// static
-StorageInfoProvider* StorageInfoProvider::Get() {
-  return StorageInfoProvider::GetInstance<StorageInfoProviderLinux>();
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_linux.h b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_linux.h
deleted file mode 100644
index 5c14848..0000000
--- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_linux.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_STORAGE_INFO_PROVIDER_LINUX_H_
-#define CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_STORAGE_INFO_PROVIDER_LINUX_H_
-
-#include "base/files/file_path.h"
-#include "chrome/browser/extensions/api/system_info_storage/storage_info_provider.h"
-#include "chrome/browser/storage_monitor/udev_util_linux.h"
-
-namespace extensions {
-
-class StorageInfoProviderLinux : public StorageInfoProvider {
- public:
-  StorageInfoProviderLinux();
-
- protected:
-  virtual ~StorageInfoProviderLinux();
-
-  // For unit test.
-  explicit StorageInfoProviderLinux(const base::FilePath& mtab_path);
-
-  virtual bool QueryInfo(StorageInfo* info) OVERRIDE;
-
-  virtual bool QueryUnitInfo(const std::string& mount_path,
-      api::experimental_system_info_storage::StorageUnitInfo* info) OVERRIDE;
-
-  // Query the storage type for the given |mount_path|. The returned value is
-  // placed in |type|. Return false if the |mount_path| is not found.
-  virtual bool QueryStorageType(const std::string& mount_path,
-                                std::string* type);
-
-  // The udev context for querying device information.
-  chrome::ScopedUdevObject udev_context_;
-
-  // The mtab file path on the system.
-  const base::FilePath mtab_file_path_;
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_STORAGE_INFO_PROVIDER_LINUX_H_
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_linux_unittest.cc b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_linux_unittest.cc
deleted file mode 100644
index 46a013d..0000000
--- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_linux_unittest.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright (c) 2012 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.
-
-// StorageInfoProviderLinux unit tests.
-
-#include "chrome/browser/extensions/api/system_info_storage/storage_info_provider_linux.h"
-
-#include <map>
-
-#include "base/file_util.h"
-#include "base/stl_util.h"
-#include "chrome/browser/storage_monitor/test_storage_monitor.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace extensions {
-
-using api::experimental_system_info_storage::ParseStorageUnitType;
-using api::experimental_system_info_storage::StorageUnitInfo;
-using api::experimental_system_info_storage::ToString;
-using chrome::test::TestStorageMonitor;
-
-namespace {
-
-// Test data in mntent format.
-const char mtab_test_data[] =
-  "proc /proc proc rw,noexec,nosuid,nodev 0 0\n"
-  "sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0\n"
-  "udev /dev devtmpfs rw,mode=0755 0 0\n"
-  "/dev/sda1 /boot ext4 rw 0 0\n"
-  "/dev/sda2 / ext4 rw 0 0\n"
-  "/dev/sdb /home ext4 rw 0 0";
-
-struct TestMountEntry {
-  std::string mnt_path;
-  std::string type;
-  double capacity;
-  double available_capacity;
-};
-
-const TestMountEntry mount_entries[] = {
-  { "/boot", systeminfo::kStorageTypeFixed, 100, 50 },
-  { "/", systeminfo::kStorageTypeFixed, 200, 100 },
-  { "/home", systeminfo::kStorageTypeRemovable, 300, 100 }
-};
-
-typedef std::map<std::string, struct TestMountEntry> TestMountEntryMap;
-
-}  // namespace
-
-class StorageInfoProviderLinuxWrapper : public StorageInfoProviderLinux {
- public:
-  explicit StorageInfoProviderLinuxWrapper(const base::FilePath& mtab_path)
-    : StorageInfoProviderLinux(mtab_path) {
-    for (size_t i = 0; i < arraysize(mount_entries); i++) {
-      std::string mnt_path = mount_entries[i].mnt_path;
-      mount_entry_map_[mnt_path] = mount_entries[i];
-    }
-   }
-
-  TestMountEntryMap& storage_map() { return mount_entry_map_; }
-
- private:
-  friend class StorageInfoProviderLinuxTest;
-
-  virtual ~StorageInfoProviderLinuxWrapper() {}
-
-  virtual bool QueryUnitInfo(const std::string& mount_path,
-                             StorageUnitInfo* info) OVERRIDE {
-    std::string type;
-    if (!QueryStorageType(mount_path, &type))
-      return false;
-    info->id = mount_path;
-    info->type = ParseStorageUnitType(type);
-    info->capacity = mount_entry_map_[mount_path].capacity;
-    info->available_capacity = mount_entry_map_[mount_path].available_capacity;
-    return true;
-  }
-
-  virtual bool QueryStorageType(const std::string& mount_path,
-                                std::string* type) OVERRIDE {
-    if (!ContainsKey(mount_entry_map_, mount_path))
-      return false;
-    *type = mount_entry_map_[mount_path].type;
-    return true;
-  }
-
-  TestMountEntryMap mount_entry_map_;
-};
-
-class StorageInfoProviderLinuxTest : public testing::Test {
- public:
-  StorageInfoProviderLinuxTest() {}
-  virtual ~StorageInfoProviderLinuxTest() {}
-
-  bool QueryInfo(StorageInfo* info) {
-    return storage_info_provider_->QueryInfo(info);
-  }
-
- protected:
-  virtual void SetUp() OVERRIDE {
-    // Create and set up a temp file for mtab data.
-    ASSERT_TRUE(file_util::CreateTemporaryFile(&mtab_file_));
-    int bytes = file_util::WriteFile(mtab_file_, mtab_test_data,
-                                     strlen(mtab_test_data));
-    ASSERT_EQ(static_cast<int>(strlen(mtab_test_data)), bytes);
-    test_storage_notifications_.reset(new TestStorageMonitor);
-    storage_info_provider_ = new StorageInfoProviderLinuxWrapper(mtab_file_);
-  }
-
-  virtual void TearDown() OVERRIDE {
-    base::Delete(mtab_file_, false);
-  }
-
-  scoped_refptr<StorageInfoProviderLinuxWrapper> storage_info_provider_;
-
- private:
-  base::FilePath mtab_file_;
-  scoped_ptr<TestStorageMonitor> test_storage_notifications_;
-};
-
-TEST_F(StorageInfoProviderLinuxTest, QueryInfo) {
-  StorageInfo info;
-  ASSERT_TRUE(QueryInfo(&info));
-
-  TestMountEntryMap& entries = storage_info_provider_->storage_map();
-  ASSERT_EQ(info.size(), entries.size());
-  EXPECT_EQ(3u, info.size());
-  for (size_t i = 0; i < info.size(); i++) {
-    const std::string& id = info[i]->id;
-    ASSERT_TRUE(ContainsKey(entries, id));
-    EXPECT_EQ(entries[id].mnt_path, id);
-    EXPECT_EQ(entries[id].type, ToString(info[i]->type));
-    EXPECT_DOUBLE_EQ(entries[id].capacity, info[i]->capacity);
-    EXPECT_DOUBLE_EQ(entries[id].available_capacity,
-                     info[i]->available_capacity);
-  }
-}
-
-TEST_F(StorageInfoProviderLinuxTest, QueryInfoFailed) {
-  storage_info_provider_ =
-      new StorageInfoProviderLinuxWrapper(base::FilePath("/invalid/file/path"));
-  StorageInfo info;
-  ASSERT_FALSE(QueryInfo(&info));
-  EXPECT_EQ(0u, info.size());
-}
-
-}  // namespace extensions
-
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_mac.cc b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_mac.cc
deleted file mode 100644
index 0041224..0000000
--- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_mac.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/system_info_storage/storage_info_provider.h"
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <IOKit/IOBSD.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/storage/IOMedia.h>
-#include <IOKit/storage/IOMediaBSDClient.h>
-#include <paths.h>
-#include <sys/mount.h>
-#include <sys/param.h>
-#include <sys/ucred.h>
-
-#include <map>
-
-#include "base/mac/foundation_util.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "base/mac/scoped_ioobject.h"
-#include "base/strings/sys_string_conversions.h"
-
-namespace extensions {
-
-namespace {
-
-using api::experimental_system_info_storage::StorageUnitInfo;
-
-// StorageInfoProvider implementation on MacOS platform.
-class StorageInfoProviderMac : public StorageInfoProvider {
- public:
-  StorageInfoProviderMac() {}
-
-  virtual bool QueryInfo(StorageInfo* info) OVERRIDE;
-  virtual bool QueryUnitInfo(const std::string& id,
-                             StorageUnitInfo* info) OVERRIDE;
-
- private:
-  virtual ~StorageInfoProviderMac() {}
-  void BuildStorageTypeMap();
-  std::map<std::string, std::string> dev_path_to_type_map_;
-};
-
-bool StorageInfoProviderMac::QueryInfo(StorageInfo* info) {
-  info->clear();
-
-  struct statfs* mounted_volumes;
-  int num_volumes = getmntinfo(&mounted_volumes, 0);
-  if (num_volumes == 0)
-    return false;
-
-  BuildStorageTypeMap();
-
-  for (int i = 0; i < num_volumes; ++i) {
-    // Skip volumes which aren't displayed in the Finder
-    if (mounted_volumes[i].f_flags & MNT_DONTBROWSE)
-      continue;
-
-    linked_ptr<StorageUnitInfo> unit(new StorageUnitInfo());
-    if (QueryUnitInfo(mounted_volumes[i].f_mntonname, unit.get()))
-      info->push_back(unit);
-  }
-  return true;
-}
-
-bool StorageInfoProviderMac::QueryUnitInfo(const std::string& id,
-                                           StorageUnitInfo* info) {
-  struct statfs volume_info;
-  if (statfs(id.c_str(), &volume_info) != 0)
-    return false;
-
-  std::string volume_dev(volume_info.f_mntfromname);
-  int32 block_size = volume_info.f_bsize;
-  info->id = id;
-  std::string type = dev_path_to_type_map_[volume_dev];
-  if (type.empty()) {
-    BuildStorageTypeMap();
-    type = dev_path_to_type_map_[volume_dev].empty() ?
-        systeminfo::kStorageTypeUnknown : dev_path_to_type_map_[volume_dev];
-  }
-  info->type =
-      api::experimental_system_info_storage::ParseStorageUnitType(type);
-  // TODO(joshuagl): we're reporting different values than Disk Utility.
-  // Is there an alternative API to get this information that doesn't use
-  // statfs? NSFileManager's attributesOfFileSystemForPath uses statfs.
-  info->capacity = volume_info.f_blocks * block_size;
-  info->available_capacity = volume_info.f_bfree * block_size;
-  return true;
-}
-
-void StorageInfoProviderMac::BuildStorageTypeMap() {
-  io_iterator_t media_iterator;
-  kern_return_t retval;
-
-  retval = IOServiceGetMatchingServices(kIOMasterPortDefault,
-                                        IOServiceMatching(kIOMediaClass),
-                                        &media_iterator);
-  if (retval != KERN_SUCCESS)
-    return;
-
-  base::mac::ScopedIOObject<io_iterator_t> iterator(media_iterator);
-  media_iterator = IO_OBJECT_NULL;
-
-  for (base::mac::ScopedIOObject<io_service_t> media(IOIteratorNext(iterator));
-       media;
-       media.reset(IOIteratorNext(iterator))) {
-    base::ScopedCFTypeRef<CFTypeRef> dev_path_cf(
-        IORegistryEntryCreateCFProperty(
-            media, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, 0));
-
-    if (!dev_path_cf)
-      continue;
-
-    std::string dev_path(_PATH_DEV);
-    dev_path.append(
-        base::SysCFStringRefToUTF8(
-            base::mac::CFCast<CFStringRef>(dev_path_cf)));
-
-    base::ScopedCFTypeRef<CFTypeRef> removable_cf(
-        IORegistryEntryCreateCFProperty(
-            media, CFSTR(kIOMediaEjectableKey), kCFAllocatorDefault, 0));
-    if (!removable_cf)
-      dev_path_to_type_map_[dev_path] = systeminfo::kStorageTypeUnknown;
-    else if (CFBooleanGetValue(base::mac::CFCast<CFBooleanRef>(removable_cf)))
-      dev_path_to_type_map_[dev_path] = systeminfo::kStorageTypeRemovable;
-    else
-      dev_path_to_type_map_[dev_path] =  systeminfo::kStorageTypeFixed;
-  }
-}
-
-}  // namespace
-
-// static
-StorageInfoProvider* StorageInfoProvider::Get() {
-  return StorageInfoProvider::GetInstance<StorageInfoProviderMac>();
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_unittest.cc b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_unittest.cc
index a225735..6a3b3ec 100644
--- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_unittest.cc
+++ b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/message_loop.h"
 #include "base/stl_util.h"
 #include "chrome/browser/extensions/api/system_info_storage/storage_info_provider.h"
+#include "chrome/browser/extensions/api/system_info_storage/test_storage_info_provider.h"
 #include "chrome/browser/storage_monitor/test_storage_monitor.h"
 #include "content/public/test/test_browser_thread.h"
 #include "content/public/test/test_utils.h"
@@ -18,6 +19,7 @@
 using api::experimental_system_info_storage::ParseStorageUnitType;
 using api::experimental_system_info_storage::StorageUnitInfo;
 using api::experimental_system_info_storage::StorageUnitType;
+using base::MessageLoop;
 using chrome::test::TestStorageMonitor;
 using content::BrowserThread;
 using content::RunAllPendingInMessageLoop;
@@ -25,20 +27,15 @@
 using testing::Return;
 using testing::_;
 
-struct TestUnitInfo {
-  std::string id;
-  std::string type;
-  double capacity;
-  double available_capacity;
-  // The change step of free space.
-  int change_step;
-};
-
-const struct TestUnitInfo kTestingData[] = {
-  {"C:", systeminfo::kStorageTypeUnknown, 1000, 10, 0},
-  {"d:", systeminfo::kStorageTypeRemovable, 2000, 10, 1 },
-  {"/home", systeminfo::kStorageTypeFixed, 3000, 10, 2},
-  {"/", systeminfo::kStorageTypeRemovable, 4000, 10, 3}
+const struct TestStorageUnitInfo kTestingData[] = {
+  {"device:001", "transient:01", "C:", systeminfo::kStorageTypeUnknown,
+    1000, 10, 0},
+  {"device:002", "transient:02", "d:", systeminfo::kStorageTypeRemovable,
+    2000, 10, 1},
+  {"device:003", "transient:03", "/home", systeminfo::kStorageTypeFixed,
+    3000, 10, 2},
+  {"device:004", "transient:04", "/", systeminfo::kStorageTypeRemovable,
+    4000, 10, 3}
 };
 
 // The watching interval for unit test is 1 milliseconds.
@@ -46,135 +43,97 @@
 // The number of times of checking watched storages.
 const int kCheckTimes = 10;
 
-class MockStorageObserver : public StorageInfoObserver {
+class MockStorageObserver : public StorageFreeSpaceObserver {
  public:
   MockStorageObserver() {}
   virtual ~MockStorageObserver() {}
 
-  MOCK_METHOD3(OnStorageFreeSpaceChanged, void(const std::string&,
+  MOCK_METHOD3(OnFreeSpaceChanged, void(const std::string&,
      double, double));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockStorageObserver);
 };
 
+const int kMaxCheckWatchStorageTimes = 10;
+
 // A testing observer used to provide the statistics of how many times
 // that the storage free space has been changed and check the change against
 // our expectation.
-class TestStorageObserver : public StorageInfoObserver {
+class TestStorageObserver : public StorageFreeSpaceObserver {
  public:
-  TestStorageObserver() {
+  TestStorageObserver() : change_times_(0) {
     for (size_t i = 0; i < arraysize(kTestingData); ++i)
       testing_data_.push_back(kTestingData[i]);
   }
 
   virtual ~TestStorageObserver() {}
 
-  virtual void OnStorageFreeSpaceChanged(const std::string& id,
-                                         double old_value,
-                                         double new_value) OVERRIDE {
+  virtual void OnFreeSpaceChanged(const std::string& transient_id,
+                                  double old_value,
+                                  double new_value) OVERRIDE {
     // The observer is added on UI thread, so the callback should be also
     // called on UI thread.
     ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
-    for (size_t i = 0; i < testing_data_.size(); ++i) {
-      if (testing_data_[i].id == id) {
-        EXPECT_DOUBLE_EQ(old_value, testing_data_[i].available_capacity);
-        EXPECT_DOUBLE_EQ(new_value, testing_data_[i].available_capacity +
-                  testing_data_[i].change_step);
-        // Increase the available capacity with the change step for comparison
-        // next time.
-        testing_data_[i].available_capacity += testing_data_[i].change_step;
-        ++free_space_change_times_[id];
-        return;
+    size_t i = 0;
+    for (; i < testing_data_.size(); ++i) {
+      if (testing_data_[i].transient_id == transient_id) {
+        EXPECT_DOUBLE_EQ(new_value-old_value, testing_data_[i].change_step);
+        ++change_times_;
+        break;
       }
     }
-    EXPECT_TRUE(false);
-  }
 
-  // Returns the number of change times for the given storage |id|.
-  int GetFreeSpaceChangeTimes(const std::string& id) {
-    if (ContainsKey(free_space_change_times_, id))
-      return free_space_change_times_[id];
-    return 0;
+    ASSERT_TRUE(i != testing_data_.size());
   }
 
  private:
   // A copy of |kTestingData|.
-  std::vector<TestUnitInfo> testing_data_;
-  // Mapping of storage id and the times of free space has been changed.
-  std::map<std::string, int> free_space_change_times_;
+  std::vector<TestStorageUnitInfo> testing_data_;
+  int change_times_;
 };
 
-class TestStorageInfoProvider : public StorageInfoProvider {
- public:
-  TestStorageInfoProvider();
+class UnitTestStorageInfoProvider : public TestStorageInfoProvider {
+ public :
+  UnitTestStorageInfoProvider(const struct TestStorageUnitInfo* testing_data,
+                              size_t n)
+      : TestStorageInfoProvider(testing_data, n),
+        check_watch_storage_times_(0) {}
+
+ protected:
+  virtual ~UnitTestStorageInfoProvider() {}
 
  private:
-  virtual ~TestStorageInfoProvider();
+  virtual int64 GetStorageFreeSpaceFromTransientId(
+      const std::string& transient_id) OVERRIDE {
+    int64 available_capacity = -1;
+    for (size_t i = 0; i < testing_data_.size(); ++i) {
+      if (testing_data_[i].transient_id == transient_id) {
+        available_capacity = testing_data_[i].available_capacity;
+        // We simulate free space change by increasing the |available_capacity|
+        // with a fixed change step.
+        testing_data_[i].available_capacity += testing_data_[i].change_step;
 
-  virtual bool QueryInfo(StorageInfo* info) OVERRIDE;
-  virtual bool QueryUnitInfo(const std::string& id,
-                             StorageUnitInfo* info) OVERRIDE;
+        // Add up the counting variable.
+        ++check_watch_storage_times_;
 
-  // Called each time CheckWatchedStoragesOnBlockingPool is finished.
-  virtual void OnCheckWatchedStoragesFinishedForTesting() OVERRIDE;
+        // Post a quit task to UI thread for test result verification
+        // if |check_watch_storage_times_| is greater than the threshold value
+        // |kMaxCheckWatchStorageTimes|.
+        if (check_watch_storage_times_ > kMaxCheckWatchStorageTimes) {
+          BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+                MessageLoop::QuitClosure());
+          check_watch_storage_times_ = 0;
+        }
 
-  // The testing data maintained on the blocking pool.
-  std::vector<TestUnitInfo> testing_data_;
-  // The number of times for checking watched storage.
-  int checking_times_;
-};
-
-//
-// TestStorageInfoProvider Impl.
-//
-TestStorageInfoProvider::TestStorageInfoProvider(): checking_times_(0) {
-  for (size_t i = 0; i < arraysize(kTestingData); ++i)
-    testing_data_.push_back(kTestingData[i]);
-  SetWatchingIntervalForTesting(kWatchingIntervalMs);
-}
-
-TestStorageInfoProvider::~TestStorageInfoProvider() {}
-
-bool TestStorageInfoProvider::QueryInfo(StorageInfo* info) {
-  info->clear();
-
-  for (size_t i = 0; i < testing_data_.size(); ++i) {
-    linked_ptr<StorageUnitInfo> unit(new StorageUnitInfo());
-    QueryUnitInfo(testing_data_[i].id, unit.get());
-    info->push_back(unit);
-  }
-  return true;
-}
-
-bool TestStorageInfoProvider::QueryUnitInfo(
-    const std::string& id, StorageUnitInfo* info) {
-  for (size_t i = 0; i < testing_data_.size(); ++i) {
-    if (testing_data_[i].id == id) {
-      info->id = testing_data_[i].id;
-      info->type = ParseStorageUnitType(testing_data_[i].type);
-      info->capacity = testing_data_[i].capacity;
-      info->available_capacity = testing_data_[i].available_capacity;
-      // Increase the available capacity with a fixed change step.
-      testing_data_[i].available_capacity += testing_data_[i].change_step;
-      return true;
+        break;
+      }
     }
+    return available_capacity;
   }
-  return false;
-}
 
-void TestStorageInfoProvider::OnCheckWatchedStoragesFinishedForTesting() {
-  ++checking_times_;
-  if (checking_times_ < kCheckTimes)
-    return;
-  checking_times_ = 0;
-  // Once the number of checking times reaches up to kCheckTimes, we need to
-  // quit the message loop to given UI thread a chance to verify the results.
-  // Note the QuitClosure is actually bound to QuitCurrentWhenIdle, it means
-  // that the UI thread wil continue to process pending messages util idle.
-  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-      base::MessageLoop::QuitClosure());
-}
+  int check_watch_storage_times_;
+};
 
 class StorageInfoProviderTest : public testing::Test {
  public:
@@ -192,7 +151,7 @@
 
   base::MessageLoop message_loop_;
   content::TestBrowserThread ui_thread_;
-  scoped_refptr<TestStorageInfoProvider> storage_info_provider_;
+  scoped_refptr<UnitTestStorageInfoProvider> storage_info_provider_;
   scoped_ptr<TestStorageMonitor> storage_test_notifications_;
 };
 
@@ -207,7 +166,8 @@
 void StorageInfoProviderTest::SetUp() {
   ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
   storage_test_notifications_.reset(new TestStorageMonitor);
-  storage_info_provider_= new TestStorageInfoProvider();
+  storage_info_provider_ = new UnitTestStorageInfoProvider(
+      kTestingData, arraysize(kTestingData));
 }
 
 void StorageInfoProviderTest::TearDown() {
@@ -228,13 +188,14 @@
   // Case 1: watching a storage that the free space is not changed.
   MockStorageObserver observer;
   storage_info_provider_->AddObserver(&observer);
-  storage_info_provider_->StartWatching(kTestingData[0].id);
-  EXPECT_CALL(observer, OnStorageFreeSpaceChanged(kTestingData[0].id,  _,  _))
+  storage_info_provider_->StartWatching(kTestingData[0].transient_id);
+  EXPECT_CALL(observer, OnFreeSpaceChanged(kTestingData[0].transient_id, _, _))
       .Times(0);
+
   RunLoopAndFlushBlockingPool();
 
   storage_info_provider_->RemoveObserver(&observer);
-  storage_info_provider_->StopWatching(kTestingData[0].id);
+  storage_info_provider_->StopWatching(kTestingData[0].device_id);
   RunAllPendingAndFlushBlockingPool();
 }
 
@@ -242,23 +203,10 @@
   // Case 2: only watching one storage.
   TestStorageObserver observer;
   storage_info_provider_->AddObserver(&observer);
-  storage_info_provider_->StartWatching(kTestingData[1].id);
+  storage_info_provider_->StartWatching(kTestingData[1].transient_id);
   RunLoopAndFlushBlockingPool();
 
-  // The times of free space change is at least |kCheckTimes|, it is not easy
-  // to anticiapte the accurate number since it is still possible for blocking
-  // pool to run the pending checking task after completing |kCheckTimes|
-  // checking tasks and posting Quit to the message loop of UI thread. The
-  // observer guarantees that the free space is changed with the expected
-  // delta value.
-  EXPECT_GE(observer.GetFreeSpaceChangeTimes(kTestingData[1].id),
-            kCheckTimes);
-  // Other storages should not be changed. The first two entries are skipped.
-  for (size_t i = 2; i < arraysize(kTestingData); ++i) {
-    EXPECT_EQ(0, observer.GetFreeSpaceChangeTimes(kTestingData[i].id));
-  }
-
-  storage_info_provider_->StopWatching(kTestingData[1].id);
+  storage_info_provider_->StopWatching(kTestingData[1].transient_id);
   // Give a chance to run StopWatching task on the blocking pool.
   RunAllPendingAndFlushBlockingPool();
 
@@ -266,7 +214,7 @@
   storage_info_provider_->AddObserver(&mock_observer);
   // The watched storage won't get free space change notification.
   EXPECT_CALL(mock_observer,
-      OnStorageFreeSpaceChanged(kTestingData[1].id, _, _)).Times(0);
+      OnFreeSpaceChanged(kTestingData[1].transient_id, _, _)).Times(0);
   RunAllPendingAndFlushBlockingPool();
 
   storage_info_provider_->RemoveObserver(&observer);
@@ -280,37 +228,29 @@
   storage_info_provider_->AddObserver(&observer);
 
   for (size_t k = 1; k < arraysize(kTestingData); ++k) {
-    storage_info_provider_->StartWatching(kTestingData[k].id);
+    storage_info_provider_->StartWatching(kTestingData[k].transient_id);
   }
   RunLoopAndFlushBlockingPool();
 
-  // Right now let's verify the results.
-  for (size_t k = 1; k < arraysize(kTestingData); ++k) {
-    // See the above comments about the reason why the times of free space
-    // changes is at least kCheckTimes.
-    EXPECT_GE(observer.GetFreeSpaceChangeTimes(kTestingData[k].id),
-              kCheckTimes);
-  }
-
   // Stop watching the first storage.
-  storage_info_provider_->StopWatching(kTestingData[1].id);
+  storage_info_provider_->StopWatching(kTestingData[1].transient_id);
   RunAllPendingAndFlushBlockingPool();
 
   MockStorageObserver mock_observer;
   storage_info_provider_->AddObserver(&mock_observer);
   for (size_t k = 2; k < arraysize(kTestingData); ++k) {
     EXPECT_CALL(mock_observer,
-        OnStorageFreeSpaceChanged(kTestingData[k].id,  _, _))
+        OnFreeSpaceChanged(kTestingData[k].transient_id,  _, _))
         .WillRepeatedly(Return());
   }
 
   // After stopping watching, the observer won't get change notification.
   EXPECT_CALL(mock_observer,
-      OnStorageFreeSpaceChanged(kTestingData[1].id, _, _)).Times(0);
+      OnFreeSpaceChanged(kTestingData[1].transient_id, _, _)).Times(0);
   RunLoopAndFlushBlockingPool();
 
   for (size_t k = 1; k < arraysize(kTestingData); ++k) {
-    storage_info_provider_->StopWatching(kTestingData[k].id);
+    storage_info_provider_->StopWatching(kTestingData[k].transient_id);
   }
   RunAllPendingAndFlushBlockingPool();
   storage_info_provider_->RemoveObserver(&observer);
@@ -324,7 +264,7 @@
   storage_info_provider_->AddObserver(&mock_observer);
   storage_info_provider_->StartWatching(invalid_id);
   EXPECT_CALL(mock_observer,
-      OnStorageFreeSpaceChanged(invalid_id, _, _)).Times(0);
+      OnFreeSpaceChanged(invalid_id, _, _)).Times(0);
   RunAllPendingAndFlushBlockingPool();
   storage_info_provider_->RemoveObserver(&mock_observer);
 }
diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc
deleted file mode 100644
index 322d15d..0000000
--- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/system_info_storage/storage_info_provider.h"
-
-#include <windows.h>
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-
-namespace extensions {
-
-namespace {
-
-using api::experimental_system_info_storage::StorageUnitInfo;
-
-// Logical drive string length is 4. It contains one driver letter character,
-// L":", L"\" and a terminating null character.
-const unsigned long kMaxLogicalDriveString = 4 * 26;
-
-// StorageInfoProvider implementation on Windows platform.
-class StorageInfoProviderWin : public StorageInfoProvider {
- public:
-  StorageInfoProviderWin() {}
-
-  virtual bool QueryInfo(StorageInfo* info) OVERRIDE;
-  virtual bool QueryUnitInfo(const std::string& id,
-                             StorageUnitInfo* info) OVERRIDE;
- private:
-  virtual ~StorageInfoProviderWin() {}
-};
-
-bool StorageInfoProviderWin::QueryInfo(StorageInfo* info) {
-  info->clear();
-
-  WCHAR logical_drive_strings[kMaxLogicalDriveString];
-
-  // The total length of drive string returned from GetLogicalDriveStrings
-  // must be divided exactly by 4 since each drive is represented by 4 wchars.
-  DWORD string_length = GetLogicalDriveStrings(
-      kMaxLogicalDriveString - 1, logical_drive_strings);
-  DCHECK(string_length % 4 == 0);
-  // No drive found, return false.
-  if (string_length == 0)
-    return false;
-
-  // Iterate the drive string by 4 wchars each step
-  for (unsigned int i = 0; i < string_length; i += 4) {
-    linked_ptr<StorageUnitInfo> unit(new StorageUnitInfo());
-    if (QueryUnitInfo(WideToUTF8(&logical_drive_strings[i]), unit.get())) {
-      info->push_back(unit);
-    }
-  }
-  return true;
-}
-
-bool StorageInfoProviderWin::QueryUnitInfo(const std::string& id,
-                                           StorageUnitInfo* info) {
-  DCHECK(info);
-  string16 drive = UTF8ToUTF16(id);
-
-  std::string type;
-  DWORD ret = GetDriveType(drive.c_str());
-  switch (ret) {
-    case DRIVE_FIXED:
-      type = systeminfo::kStorageTypeFixed;
-      break;
-    case DRIVE_REMOVABLE:
-      type = systeminfo::kStorageTypeRemovable;
-      break;
-    case DRIVE_UNKNOWN:
-      type = systeminfo::kStorageTypeUnknown;
-      break;
-    case DRIVE_CDROM:       // CD ROM
-    case DRIVE_REMOTE:      // Remote network drive
-    case DRIVE_NO_ROOT_DIR: // Invalid root path
-    case DRIVE_RAMDISK:     // RAM disk
-      // TODO(hmin): Do we need to care about these drive types?
-      return false;
-  }
-
-  ULARGE_INTEGER total_bytes;
-  ULARGE_INTEGER free_bytes;
-
-  if (GetDiskFreeSpaceEx(drive.c_str(), NULL, &total_bytes, &free_bytes)) {
-    info->id = id;
-    info->type =
-        api::experimental_system_info_storage::ParseStorageUnitType(type);
-    info->capacity = static_cast<double>(total_bytes.QuadPart);
-    info->available_capacity = static_cast<double>(free_bytes.QuadPart);
-    return true;
-  }
-  return false;
-}
-
-}  // namespace
-
-// static
-StorageInfoProvider* StorageInfoProvider::Get() {
-  return StorageInfoProvider::GetInstance<StorageInfoProviderWin>();
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/api/system_info_storage/system_info_storage_api.cc b/chrome/browser/extensions/api/system_info_storage/system_info_storage_api.cc
index cc9d905..8249eaa 100644
--- a/chrome/browser/extensions/api/system_info_storage/system_info_storage_api.cc
+++ b/chrome/browser/extensions/api/system_info_storage/system_info_storage_api.cc
@@ -6,6 +6,7 @@
 namespace extensions {
 
 using api::experimental_system_info_storage::StorageUnitInfo;
+namespace EjectDevice = api::experimental_system_info_storage::EjectDevice;
 
 SystemInfoStorageGetFunction::SystemInfoStorageGetFunction() {
 }
@@ -20,12 +21,11 @@
   return true;
 }
 
-void SystemInfoStorageGetFunction::OnGetStorageInfoCompleted(
-    const StorageInfo& info, bool success) {
-
+void SystemInfoStorageGetFunction::OnGetStorageInfoCompleted(bool success) {
   if (success) {
     results_ =
-      api::experimental_system_info_storage::Get::Results::Create(info);
+      api::experimental_system_info_storage::Get::Results::Create(
+          StorageInfoProvider::Get()->storage_unit_info_list());
   } else {
     SetError("Error occurred when querying storage information.");
   }
@@ -33,6 +33,68 @@
   SendResponse(success);
 }
 
+SystemInfoStorageEjectDeviceFunction::~SystemInfoStorageEjectDeviceFunction() {
+}
+
+bool SystemInfoStorageEjectDeviceFunction::RunImpl() {
+  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+  scoped_ptr<EjectDevice::Params> params(EjectDevice::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+
+  chrome::StorageMonitor::GetInstance()->EnsureInitialized(base::Bind(
+      &SystemInfoStorageEjectDeviceFunction::OnStorageMonitorInit,
+      this,
+      params->id));
+  return true;
+}
+
+void SystemInfoStorageEjectDeviceFunction::OnStorageMonitorInit(
+    const std::string& transient_device_id) {
+  DCHECK(chrome::StorageMonitor::GetInstance()->IsInitialized());
+  chrome::StorageMonitor* monitor = chrome::StorageMonitor::GetInstance();
+  std::string device_id_str =
+      StorageInfoProvider::Get()->GetDeviceIdForTransientId(
+          transient_device_id);
+
+  if (device_id_str == "") {
+    HandleResponse(chrome::StorageMonitor::EJECT_NO_SUCH_DEVICE);
+    return;
+  }
+
+  monitor->EjectDevice(
+      device_id_str,
+      base::Bind(&SystemInfoStorageEjectDeviceFunction::HandleResponse,
+                 this));
+}
+
+void SystemInfoStorageEjectDeviceFunction::HandleResponse(
+    chrome::StorageMonitor::EjectStatus status) {
+  api::experimental_system_info_storage:: EjectDeviceResultCode result =
+      api::experimental_system_info_storage::EJECT_DEVICE_RESULT_CODE_FAILURE;
+  switch (status) {
+    case chrome::StorageMonitor::EJECT_OK:
+      result = api::experimental_system_info_storage::
+          EJECT_DEVICE_RESULT_CODE_SUCCESS;
+      break;
+    case chrome::StorageMonitor::EJECT_IN_USE:
+      result = api::experimental_system_info_storage::
+          EJECT_DEVICE_RESULT_CODE_IN_USE;
+      break;
+    case chrome::StorageMonitor::EJECT_NO_SUCH_DEVICE:
+      result = api::experimental_system_info_storage::
+          EJECT_DEVICE_RESULT_CODE_NO_SUCH_DEVICE;
+      break;
+    case chrome::StorageMonitor::EJECT_FAILURE:
+      result = api::experimental_system_info_storage::
+          EJECT_DEVICE_RESULT_CODE_FAILURE;
+  }
+
+  SetResult(base::StringValue::CreateStringValue(
+      api::experimental_system_info_storage::ToString(result)));
+  SendResponse(true);
+}
+
 SystemInfoStorageAddWatchFunction::SystemInfoStorageAddWatchFunction() {
 }
 
diff --git a/chrome/browser/extensions/api/system_info_storage/system_info_storage_api.h b/chrome/browser/extensions/api/system_info_storage/system_info_storage_api.h
index 02a4ff8..7d99e84 100644
--- a/chrome/browser/extensions/api/system_info_storage/system_info_storage_api.h
+++ b/chrome/browser/extensions/api/system_info_storage/system_info_storage_api.h
@@ -6,6 +6,7 @@
 
 #include "chrome/browser/extensions/api/system_info_storage/storage_info_provider.h"
 #include "chrome/browser/extensions/extension_function.h"
+#include "chrome/browser/storage_monitor/storage_monitor.h"
 
 namespace extensions {
 
@@ -21,7 +22,26 @@
   virtual ~SystemInfoStorageGetFunction();
   virtual bool RunImpl() OVERRIDE;
 
-  void OnGetStorageInfoCompleted(const StorageInfo& info, bool success);
+  void OnGetStorageInfoCompleted(bool success);
+};
+
+class SystemInfoStorageEjectDeviceFunction
+    : public AsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("experimental.systemInfo.storage.ejectDevice",
+                             EXPERIMENTAL_SYSTEMINFO_STORAGE_EJECTDEVICE);
+
+ protected:
+  virtual ~SystemInfoStorageEjectDeviceFunction();
+
+  // AsyncExtensionFunction overrides.
+  virtual bool RunImpl() OVERRIDE;
+
+ private:
+  void OnStorageMonitorInit(const std::string& transient_device_id);
+
+  // Eject device request handler.
+  void HandleResponse(chrome::StorageMonitor::EjectStatus status);
 };
 
 class SystemInfoStorageAddWatchFunction : public AsyncExtensionFunction {
diff --git a/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc b/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc
index b4ca0fe..3c87491 100644
--- a/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc
+++ b/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc
@@ -6,6 +6,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/extensions/api/system_info_storage/storage_info_provider.h"
+#include "chrome/browser/extensions/api/system_info_storage/test_storage_info_provider.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_test_message_listener.h"
 #include "chrome/browser/storage_monitor/storage_info.h"
@@ -14,81 +15,35 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
 
+namespace {
+
 using chrome::StorageMonitor;
 using chrome::test::TestStorageMonitor;
 using extensions::api::experimental_system_info_storage::ParseStorageUnitType;
 using extensions::api::experimental_system_info_storage::StorageUnitInfo;
 using extensions::StorageInfoProvider;
-using extensions::StorageInfo;
+using extensions::StorageUnitInfoList;
 using extensions::systeminfo::kStorageTypeFixed;
 using extensions::systeminfo::kStorageTypeRemovable;
 using extensions::systeminfo::kStorageTypeUnknown;
+using extensions::TestStorageUnitInfo;
+using extensions::TestStorageInfoProvider;
 
-struct TestUnitInfo {
-  std::string id;
-  std::string type;
-  double capacity;
-  double available_capacity;
-  // The change step of free space.
-  int change_step;
+struct TestStorageUnitInfo kTestingData[] = {
+  {"dcim:device:0004", "transient:0004", "0xbeaf", kStorageTypeUnknown,
+    4098, 1000, 0},
+  {"path:device:002", "transient:002", "/home", kStorageTypeFixed,
+    4098, 1000, 10},
+  {"path:device:003", "transient:003", "/data", kStorageTypeFixed,
+    10000, 1000, 4097}
 };
 
-struct TestUnitInfo kTestingData[] = {
-  {"0xbeaf", kStorageTypeUnknown, 4098, 1000, 0},
-  {"/home", kStorageTypeFixed, 4098, 1000, 10},
-  {"/data", kStorageTypeFixed, 10000, 1000, 4097}
+struct TestStorageUnitInfo kRemovableStorageData[] = {
+  {"dcim:device:0004", "transient:0004", "/media/usb1",
+    kStorageTypeRemovable, 4098, 1000, 1}
 };
 
-struct TestUnitInfo kRemovableStorageData[] = {
-  {"/media/usb1", kStorageTypeRemovable, 4098, 1000, 1}
-};
-
-const char kRemovableStorageDeviceName[] = "deviceName";
-const char kRemovableStorageDeviceId[] = "dcim:device:0001";
-const base::FilePath::CharType kRemovableStorageLocation[] =
-    FILE_PATH_LITERAL("/media/usb1");
-const size_t kTestingIntervalMS = 10;
-
-class TestStorageInfoProvider : public StorageInfoProvider {
- public:
-  TestStorageInfoProvider(struct TestUnitInfo testing_data[], size_t n)
-      : testing_data_(testing_data, testing_data + n) {
-    SetWatchingIntervalForTesting(kTestingIntervalMS);
-  }
-
- private:
-  virtual ~TestStorageInfoProvider() {}
-
-  virtual bool QueryInfo(StorageInfo* info) OVERRIDE {
-    info->clear();
-
-    for (size_t i = 0; i < testing_data_.size(); i++) {
-      linked_ptr<StorageUnitInfo> unit(new StorageUnitInfo());
-      QueryUnitInfo(testing_data_[i].id, unit.get());
-      info->push_back(unit);
-    }
-    return true;
-  }
-
-  virtual bool QueryUnitInfo(const std::string& id,
-                             StorageUnitInfo* info) OVERRIDE {
-    for (size_t i = 0; i < testing_data_.size(); i++) {
-      if (testing_data_[i].id == id) {
-        info->id = testing_data_[i].id;
-        info->type = ParseStorageUnitType(testing_data_[i].type);
-        info->capacity = testing_data_[i].capacity;
-        info->available_capacity = testing_data_[i].available_capacity;
-        // Increase the available capacity with a fixed change step.
-        testing_data_[i].available_capacity += testing_data_[i].change_step;
-        return true;
-      }
-    }
-    return false;
-  }
-
- private:
-  std::vector<struct TestUnitInfo> testing_data_;
-};
+}  // namespace
 
 class SystemInfoStorageApiTest: public ExtensionApiTest {
  public:
@@ -105,15 +60,18 @@
     message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_UI));
   }
 
-  void ProcessAttach(const std::string& device_id,
-                     const string16& name,
-                     const base::FilePath::StringType& location) {
-    chrome::StorageInfo info(device_id, name, location,
-                             string16(), string16(), string16(), 0);
-    StorageMonitor::GetInstance()->receiver()->ProcessAttach(info);
+  void AttachRemovableStorage(const std::string& device_id) {
+    size_t len = arraysize(kRemovableStorageData);
+    for (size_t i = 0; i < len; ++i) {
+      if (kRemovableStorageData[i].device_id != device_id)
+        continue;
+
+      StorageMonitor::GetInstance()->receiver()->ProcessAttach(
+          TestStorageInfoProvider::BuildStorageInfo(kRemovableStorageData[i]));
+    }
   }
 
-  void ProcessDetach(const std::string& id) {
+  void DetachRemovableStorage(const std::string& id) {
     StorageMonitor::GetInstance()->receiver()->ProcessDetach(id);
   }
 
@@ -146,12 +104,10 @@
 
   // Simulate triggering onAttached event.
   ASSERT_TRUE(attach_listener.WaitUntilSatisfied());
-  ProcessAttach(kRemovableStorageDeviceId,
-                ASCIIToUTF16(kRemovableStorageDeviceName),
-                kRemovableStorageLocation);
+  AttachRemovableStorage(kRemovableStorageData[0].device_id);
   // Simulate triggering onDetached event.
   ASSERT_TRUE(detach_listener.WaitUntilSatisfied());
-  ProcessDetach(kRemovableStorageDeviceId);
+  DetachRemovableStorage(kRemovableStorageData[0].device_id);
 
   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
 }
diff --git a/chrome/browser/extensions/api/system_info_storage/system_info_storage_eject_apitest.cc b/chrome/browser/extensions/api/system_info_storage/system_info_storage_eject_apitest.cc
new file mode 100644
index 0000000..ba51993
--- /dev/null
+++ b/chrome/browser/extensions/api/system_info_storage/system_info_storage_eject_apitest.cc
@@ -0,0 +1,126 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SystemInfoStorage eject API browser tests.
+
+#include "base/files/file_path.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/extensions/api/system_info_storage/storage_info_provider.h"
+#include "chrome/browser/extensions/api/system_info_storage/test_storage_info_provider.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/extensions/extension_process_manager.h"
+#include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/extensions/extension_test_message_listener.h"
+#include "chrome/browser/storage_monitor/storage_info.h"
+#include "chrome/browser/storage_monitor/storage_monitor.h"
+#include "chrome/browser/storage_monitor/test_storage_monitor.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/extensions/extension.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/test/test_utils.h"
+
+namespace {
+
+using extensions::TestStorageUnitInfo;
+using extensions::TestStorageInfoProvider;
+
+struct TestStorageUnitInfo kRemovableStorageData[] = {
+  { "dcim:device:0004", "transient:0004", "/media/usb1",
+    extensions::systeminfo::kStorageTypeRemovable, 0, 0, 0}
+};
+
+}  // namespace
+
+class SystemInfoStorageEjectApiTest : public ExtensionApiTest {
+ public:
+  SystemInfoStorageEjectApiTest() {}
+  virtual ~SystemInfoStorageEjectApiTest() {}
+
+ protected:
+  // ExtensionApiTest overrides.
+  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+    ExtensionApiTest::SetUpCommandLine(command_line);
+    command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
+  }
+
+  content::RenderViewHost* GetHost() {
+    const extensions::Extension* extension =
+        LoadExtension(test_data_dir_.AppendASCII("systeminfo/storage_eject"));
+    return extensions::ExtensionSystem::Get(browser()->profile())->
+        process_manager()->GetBackgroundHostForExtension(extension->id())->
+            render_view_host();
+  }
+
+  void ExecuteCmdAndCheckReply(content::RenderViewHost* host,
+                               const std::string& js_command,
+                               const std::string& ok_message) {
+    ExtensionTestMessageListener listener(ok_message, false);
+    host->ExecuteJavascriptInWebFrame(string16(), ASCIIToUTF16(js_command));
+    EXPECT_TRUE(listener.WaitUntilSatisfied());
+  }
+
+  void Attach() {
+    DCHECK(chrome::StorageMonitor::GetInstance()->IsInitialized());
+    chrome::StorageMonitor::GetInstance()->receiver()->ProcessAttach(
+        TestStorageInfoProvider::BuildStorageInfo(kRemovableStorageData[0]));
+    content::RunAllPendingInMessageLoop();
+  }
+
+  void Detach() {
+    DCHECK(chrome::StorageMonitor::GetInstance()->IsInitialized());
+    chrome::StorageMonitor::GetInstance()->receiver()->ProcessDetach(
+        kRemovableStorageData[0].device_id);
+    content::RunAllPendingInMessageLoop();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SystemInfoStorageEjectApiTest);
+};
+
+
+IN_PROC_BROWSER_TEST_F(SystemInfoStorageEjectApiTest, EjectTest) {
+  scoped_ptr<chrome::test::TestStorageMonitor> monitor(
+      chrome::test::TestStorageMonitor::CreateForBrowserTests());
+  monitor->Init();
+  monitor->MarkInitialized();
+
+  TestStorageInfoProvider* provider =
+      new TestStorageInfoProvider(kRemovableStorageData,
+                                  arraysize(kRemovableStorageData));
+  extensions::StorageInfoProvider::InitializeForTesting(provider);
+
+  content::RenderViewHost* host = GetHost();
+  ExecuteCmdAndCheckReply(host, "addAttachListener()", "add_attach_ok");
+
+  // Attach / detach
+  const std::string expect_attach_msg =
+      base::StringPrintf("%s,%s", "attach_test_ok",
+                         kRemovableStorageData[0].name);
+  ExtensionTestMessageListener attach_finished_listener(expect_attach_msg,
+                                                        false  /* no reply */);
+  Attach();
+  EXPECT_TRUE(attach_finished_listener.WaitUntilSatisfied());
+
+  ExecuteCmdAndCheckReply(host, "ejectTest()", "eject_ok");
+  EXPECT_EQ(kRemovableStorageData[0].device_id, monitor->ejected_device());
+
+  Detach();
+}
+
+IN_PROC_BROWSER_TEST_F(SystemInfoStorageEjectApiTest, EjectBadDeviceTest) {
+  scoped_ptr<chrome::test::TestStorageMonitor> monitor(
+      chrome::test::TestStorageMonitor::CreateForBrowserTests());
+  monitor->Init();
+  monitor->MarkInitialized();
+
+  TestStorageInfoProvider* provider =
+      new TestStorageInfoProvider(kRemovableStorageData,
+                                  arraysize(kRemovableStorageData));
+  extensions::StorageInfoProvider::InitializeForTesting(provider);
+
+  ExecuteCmdAndCheckReply(GetHost(), "ejectFailTest()", "eject_no_such_device");
+
+  EXPECT_EQ("", monitor->ejected_device());
+}
diff --git a/chrome/browser/extensions/api/system_info_storage/test_storage_info_provider.cc b/chrome/browser/extensions/api/system_info_storage/test_storage_info_provider.cc
new file mode 100644
index 0000000..f90d2e1
--- /dev/null
+++ b/chrome/browser/extensions/api/system_info_storage/test_storage_info_provider.cc
@@ -0,0 +1,97 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/api/system_info_storage/test_storage_info_provider.h"
+
+#include "base/strings/utf_string_conversions.h"
+
+namespace extensions {
+
+using api::experimental_system_info_storage::ParseStorageUnitType;
+using api::experimental_system_info_storage::StorageUnitInfo;
+using systeminfo::kStorageTypeFixed;
+using systeminfo::kStorageTypeRemovable;
+using systeminfo::kStorageTypeUnknown;
+
+// Watching interval for testing.
+const size_t kTestingIntervalMS = 10;
+
+TestStorageInfoProvider::TestStorageInfoProvider(
+    const struct TestStorageUnitInfo* testing_data, size_t n)
+      : testing_data_(testing_data, testing_data + n) {
+    SetWatchingIntervalForTesting(kTestingIntervalMS);
+}
+
+TestStorageInfoProvider::~TestStorageInfoProvider() {
+}
+
+// static
+chrome::StorageInfo TestStorageInfoProvider::BuildStorageInfo(
+    const TestStorageUnitInfo& unit) {
+  chrome::StorageInfo info(
+      unit.device_id,
+      UTF8ToUTF16(unit.name),
+      base::FilePath::StringType(), /* no location */
+      string16(), /* no storage label */
+      string16(), /* no storage vendor */
+      string16(), /* no storage model */
+      unit.capacity);
+  return info;
+}
+
+void TestStorageInfoProvider::GetAllStoragesIntoInfoList() {
+  info_.clear();
+  for (size_t i = 0; i < testing_data_.size(); ++i) {
+    linked_ptr<StorageUnitInfo> unit(new StorageUnitInfo());
+    unit->id = testing_data_[i].transient_id;
+    unit->name = testing_data_[i].name;
+    unit->type = ParseStorageUnitType(testing_data_[i].type);
+    unit->capacity = testing_data_[i].capacity;
+    info_.push_back(unit);
+  }
+}
+
+std::vector<chrome::StorageInfo>
+TestStorageInfoProvider::GetAllStorages() const {
+  std::vector<chrome::StorageInfo> results;
+  for (size_t i = 0; i < testing_data_.size(); ++i)
+    results.push_back(BuildStorageInfo(testing_data_[i]));
+
+  return results;
+}
+
+int64 TestStorageInfoProvider::GetStorageFreeSpaceFromTransientId(
+    const std::string& transient_id) {
+  int64 available_capacity = -1;
+  for (size_t i = 0; i < testing_data_.size(); ++i) {
+    if (testing_data_[i].transient_id == transient_id) {
+      available_capacity = testing_data_[i].available_capacity;
+      // We simulate free space change by increasing the |available_capacity|
+      // with a fixed change step.
+      testing_data_[i].available_capacity += testing_data_[i].change_step;
+      break;
+    }
+  }
+  return available_capacity;
+}
+
+std::string TestStorageInfoProvider::GetTransientIdForDeviceId(
+    const std::string& device_id) const {
+  for (size_t i = 0; i < testing_data_.size(); ++i) {
+    if (testing_data_[i].device_id == device_id)
+      return testing_data_[i].transient_id;
+  }
+  return std::string();
+}
+
+std::string TestStorageInfoProvider::GetDeviceIdForTransientId(
+    const std::string& transient_id) const {
+  for (size_t i = 0; i < testing_data_.size(); ++i) {
+    if (testing_data_[i].transient_id == transient_id)
+      return testing_data_[i].device_id;
+  }
+  return std::string();
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/api/system_info_storage/test_storage_info_provider.h b/chrome/browser/extensions/api/system_info_storage/test_storage_info_provider.h
new file mode 100644
index 0000000..0ab3d4c
--- /dev/null
+++ b/chrome/browser/extensions/api/system_info_storage/test_storage_info_provider.h
@@ -0,0 +1,61 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_TEST_STORAGE_INFO_PROVIDER_H_
+#define CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_TEST_STORAGE_INFO_PROVIDER_H_
+
+#include <vector>
+
+#include "chrome/browser/extensions/api/system_info_storage/storage_info_provider.h"
+#include "chrome/browser/storage_monitor/storage_info.h"
+
+namespace extensions {
+
+struct TestStorageUnitInfo {
+  const char* device_id;
+  const char* transient_id;
+  const char* name;
+  const char* type;
+  // Total amount of the storage device space, in bytes.
+  double capacity;
+  // The available amount of the storage space, in bytes.
+  double available_capacity;
+  // The change step of available capacity for simulating the free space change.
+  // Each querying operation will increase the |available_capacity| with this
+  // value.
+  int change_step;
+};
+
+// StorageInfoProvider for unit_tests and browser_tests.
+// Override related methods to avoid calling out to the actual system.
+//
+// TODO(Haojian) : Improve StorageInfoProvider test. Create a interface that
+// represents system storage functions, with a googlemock implementation.
+class TestStorageInfoProvider : public extensions::StorageInfoProvider {
+ public:
+  TestStorageInfoProvider(const struct TestStorageUnitInfo* testing_data,
+                          size_t n);
+
+  static chrome::StorageInfo BuildStorageInfo(const TestStorageUnitInfo& unit);
+
+  virtual std::string GetTransientIdForDeviceId(
+      const std::string& device_id) const OVERRIDE;
+  virtual std::string GetDeviceIdForTransientId(
+      const std::string& transient_id) const OVERRIDE;
+
+ protected:
+  virtual ~TestStorageInfoProvider();
+
+  // StorageInfoProvider implementations.
+  virtual void GetAllStoragesIntoInfoList() OVERRIDE;
+  virtual std::vector<chrome::StorageInfo> GetAllStorages() const OVERRIDE;
+  virtual int64 GetStorageFreeSpaceFromTransientId(
+      const std::string& transient_id) OVERRIDE;
+
+  std::vector<struct TestStorageUnitInfo> testing_data_;
+};
+
+}  // namespace extensions
+#endif  // CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_STORAGE_TEST_STORAGE_INFO_PROVIDER_H_
+
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
index 88d37be..757db57 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
@@ -6,12 +6,12 @@
 
 #include <utility>
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_names.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/extensions/api/tabs/ash_panel_contents.cc b/chrome/browser/extensions/api/tabs/ash_panel_contents.cc
index 27b7d5e..64a7f81 100644
--- a/chrome/browser/extensions/api/tabs/ash_panel_contents.cc
+++ b/chrome/browser/extensions/api/tabs/ash_panel_contents.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/extensions/api/tabs/ash_panel_contents.h"
 
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h"
 #include "chrome/browser/extensions/api/tabs/windows_event_router.h"
@@ -13,7 +14,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/browser/ui/extensions/native_app_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_messages.h"
 #include "content/public/browser/site_instance.h"
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index 1a7027e..32134b3 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -22,6 +22,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
 #include "chrome/browser/extensions/extension_function_dispatcher.h"
 #include "chrome/browser/extensions/extension_function_util.h"
@@ -48,7 +49,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/window_sizer/window_sizer.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/api/i18n/default_locale_handler.h"
 #include "chrome/common/extensions/api/tabs.h"
@@ -594,9 +594,6 @@
       shell_window->Init(urls[0], ash_panel_contents, create_params);
       SetResult(ash_panel_contents->GetExtensionWindowController()->
                 CreateWindowValueWithTabs(GetExtension()));
-      // Add the panel to the shell window registry so that it shows up in
-      // the launcher and as an active render process.
-      ShellWindowRegistry::Get(window_profile)->AddShellWindow(shell_window);
       return true;
     }
 #else
@@ -1238,17 +1235,15 @@
   ui::ListSelectionModel selection;
   int active_index = -1;
 
-  if (params->highlight_info.tabs.as_array.get()) {
-    std::vector<int> tab_indices = *params->highlight_info.tabs.as_array;
-
+  if (params->highlight_info.tabs.as_integers) {
+    std::vector<int>& tab_indices = *params->highlight_info.tabs.as_integers;
     // Create a new selection model as we read the list of tab indices.
     for (size_t i = 0; i < tab_indices.size(); ++i) {
-      if (!HighlightTab(tabstrip, &selection, &active_index, tab_indices[i])) {
-          return false;
-      }
+      if (!HighlightTab(tabstrip, &selection, &active_index, tab_indices[i]))
+        return false;
     }
   } else {
-    EXTENSION_FUNCTION_VALIDATE(params->highlight_info.tabs.as_integer.get());
+    EXTENSION_FUNCTION_VALIDATE(params->highlight_info.tabs.as_integer);
     if (!HighlightTab(tabstrip,
                       &selection,
                       &active_index,
@@ -1471,17 +1466,17 @@
   int* window_id = params->move_properties.window_id.get();
   base::ListValue tab_values;
 
-  std::vector<int> tab_ids;
-  if (params->tab_ids.as_array.get()) {
-    tab_ids = *params->tab_ids.as_array;
-
+  size_t num_tabs = 0;
+  if (params->tab_ids.as_integers) {
+    std::vector<int>& tab_ids = *params->tab_ids.as_integers;
+    num_tabs = tab_ids.size();
     for (size_t i = 0; i < tab_ids.size(); ++i) {
-      if (!MoveTab(tab_ids[i], &new_index, i, &tab_values, window_id)) {
+      if (!MoveTab(tab_ids[i], &new_index, i, &tab_values, window_id))
         return false;
-      }
     }
   } else {
     EXTENSION_FUNCTION_VALIDATE(params->tab_ids.as_integer);
+    num_tabs = 1;
     if (!MoveTab(*params->tab_ids.as_integer,
                  &new_index,
                  0,
@@ -1495,7 +1490,7 @@
     return true;
 
   // Only return the results as an array if there are multiple tabs.
-  if (tab_ids.size() > 1) {
+  if (num_tabs > 1) {
     SetResult(tab_values.DeepCopy());
   } else {
     Value* value = NULL;
@@ -1653,19 +1648,16 @@
   scoped_ptr<tabs::Remove::Params> params(tabs::Remove::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
-  if (params->tab_ids.as_array.get()) {
-    std::vector<int> tab_ids = *params->tab_ids.as_array;
-
+  if (params->tab_ids.as_integers) {
+    std::vector<int>& tab_ids = *params->tab_ids.as_integers;
     for (size_t i = 0; i < tab_ids.size(); ++i) {
-      if (!RemoveTab(tab_ids[i])) {
+      if (!RemoveTab(tab_ids[i]))
         return false;
-      }
     }
   } else {
-    EXTENSION_FUNCTION_VALIDATE(params->tab_ids.as_integer.get());
-    if (!RemoveTab(*params->tab_ids.as_integer.get())) {
+    EXTENSION_FUNCTION_VALIDATE(params->tab_ids.as_integer);
+    if (!RemoveTab(*params->tab_ids.as_integer.get()))
       return false;
-    }
   }
   return true;
 }
@@ -1873,7 +1865,7 @@
   SendResponse(true);
 }
 
-void TabsCaptureVisibleTabFunction::RegisterUserPrefs(
+void TabsCaptureVisibleTabFunction::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kDisableScreenshots,
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.h b/chrome/browser/extensions/api/tabs/tabs_api.h
index 80e47a6..15f47eb 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.h
+++ b/chrome/browser/extensions/api/tabs/tabs_api.h
@@ -16,7 +16,7 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "extensions/common/extension_resource.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class BackingStore;
 class GURL;
@@ -190,7 +190,7 @@
 };
 class TabsCaptureVisibleTabFunction : public AsyncExtensionFunction {
  public:
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  protected:
   typedef api::tabs::CaptureVisibleTab::Params::Options::Format ImageFormat;
diff --git a/chrome/browser/extensions/api/tabs/windows_event_router.cc b/chrome/browser/extensions/api/tabs/windows_event_router.cc
index 54d9b2d..1138a73 100644
--- a/chrome/browser/extensions/api/tabs/windows_event_router.cc
+++ b/chrome/browser/extensions/api/tabs/windows_event_router.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/extensions/api/tabs/windows_event_router.h"
 
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_names.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -12,7 +13,6 @@
 #include "chrome/browser/extensions/window_controller.h"
 #include "chrome/browser/extensions/window_controller_list.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/extensions/api/terminal/terminal_extension_helper.h b/chrome/browser/extensions/api/terminal/terminal_extension_helper.h
index 1599387..bd20147 100644
--- a/chrome/browser/extensions/api/terminal/terminal_extension_helper.h
+++ b/chrome/browser/extensions/api/terminal/terminal_extension_helper.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Profile;
 
diff --git a/chrome/browser/extensions/api/test/test_api.cc b/chrome/browser/extensions/api/test/test_api.cc
index c6efce0..cd55a58 100644
--- a/chrome/browser/extensions/api/test/test_api.cc
+++ b/chrome/browser/extensions/api/test/test_api.cc
@@ -8,12 +8,12 @@
 
 #include "base/command_line.h"
 #include "base/memory/singleton.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_function_dispatcher.h"
 #include "chrome/browser/extensions/extensions_quota_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_commands.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/api/test.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/extensions/api/web_navigation/frame_navigation_state.h b/chrome/browser/extensions/api/web_navigation/frame_navigation_state.h
index d51c283..0f2823c 100644
--- a/chrome/browser/extensions/api/web_navigation/frame_navigation_state.h
+++ b/chrome/browser/extensions/api/web_navigation/frame_navigation_state.h
@@ -9,7 +9,7 @@
 #include <set>
 
 #include "base/compiler_specific.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace content {
 class RenderViewHost;
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
index 575a4de..590c681 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
@@ -7,6 +7,7 @@
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
 
 #include "base/lazy_instance.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_constants.h"
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.h"
 #include "chrome/browser/extensions/event_router.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/browser_list.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/web_navigation.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
index bae2e27..d0a6a69 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
@@ -23,7 +23,7 @@
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 struct RetargetingDetails;
 
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
index d57a78e..5f70e7a 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/chrome_browser_main.h"
 #include "chrome/browser/chrome_browser_main_extra_parts.h"
 #include "chrome/browser/chrome_content_browser_client.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/tab_contents/render_view_context_menu.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/extensions/api/web_request/web_request_api.cc b/chrome/browser/extensions/api/web_request/web_request_api.cc
index 38e35f3..882034a 100644
--- a/chrome/browser/extensions/api/web_request/web_request_api.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_api.cc
@@ -53,7 +53,6 @@
 #include "extensions/common/error_utils.h"
 #include "extensions/common/event_filtering_info.h"
 #include "extensions/common/url_pattern.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "net/base/auth.h"
 #include "net/base/net_errors.h"
@@ -61,6 +60,7 @@
 #include "net/http/http_response_headers.h"
 #include "net/url_request/url_request.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
 
 using base::DictionaryValue;
 using base::ListValue;
@@ -419,6 +419,9 @@
   // The request that is being blocked.
   net::URLRequest* request;
 
+  // Whether the request originates from an incognito tab.
+  bool is_incognito;
+
   // The event that we're currently blocked on.
   EventTypes event;
 
@@ -469,6 +472,7 @@
 
   BlockedRequest()
       : request(NULL),
+        is_incognito(false),
         event(kInvalidEvent),
         num_handlers_blocking(0),
         net_log(NULL),
@@ -650,6 +654,8 @@
     return net::OK;  // Nobody saw a reason for modifying the request.
 
   blocked_requests_[request->identifier()].event = kOnBeforeRequest;
+  blocked_requests_[request->identifier()].is_incognito |=
+      IsIncognitoProfile(profile);
   blocked_requests_[request->identifier()].request = request;
   blocked_requests_[request->identifier()].callback = callback;
   blocked_requests_[request->identifier()].new_url = new_url;
@@ -705,6 +711,8 @@
     return net::OK;  // Nobody saw a reason for modifying the request.
 
   blocked_requests_[request->identifier()].event = kOnBeforeSendHeaders;
+  blocked_requests_[request->identifier()].is_incognito |=
+      IsIncognitoProfile(profile);
   blocked_requests_[request->identifier()].request = request;
   blocked_requests_[request->identifier()].callback = callback;
   blocked_requests_[request->identifier()].request_headers = headers;
@@ -800,6 +808,8 @@
     return net::OK;  // Nobody saw a reason for modifying the request.
 
   blocked_requests_[request->identifier()].event = kOnHeadersReceived;
+  blocked_requests_[request->identifier()].is_incognito |=
+      IsIncognitoProfile(profile);
   blocked_requests_[request->identifier()].request = request;
   blocked_requests_[request->identifier()].callback = callback;
   blocked_requests_[request->identifier()].net_log = &request->net_log();
@@ -861,6 +871,8 @@
 
   if (DispatchEvent(profile, request, listeners, args)) {
     blocked_requests_[request->identifier()].event = kOnAuthRequired;
+    blocked_requests_[request->identifier()].is_incognito |=
+        IsIncognitoProfile(profile);
     blocked_requests_[request->identifier()].request = request;
     blocked_requests_[request->identifier()].auth_callback = callback;
     blocked_requests_[request->identifier()].auth_credentials = credentials;
@@ -1117,6 +1129,8 @@
 
   if (num_handlers_blocking > 0) {
     blocked_requests_[request->identifier()].request = request;
+    blocked_requests_[request->identifier()].is_incognito |=
+        IsIncognitoProfile(profile_id);
     blocked_requests_[request->identifier()].num_handlers_blocking +=
         num_handlers_blocking;
     blocked_requests_[request->identifier()].blocking_time = base::Time::Now();
@@ -1256,8 +1270,8 @@
 
 void ExtensionWebRequestEventRouter::OnOTRProfileCreated(
     void* original_profile, void* otr_profile) {
-  cross_profile_map_[original_profile] = otr_profile;
-  cross_profile_map_[otr_profile] = original_profile;
+  cross_profile_map_[original_profile] = std::make_pair(false, otr_profile);
+  cross_profile_map_[otr_profile] = std::make_pair(true, original_profile);
 }
 
 void ExtensionWebRequestEventRouter::OnOTRProfileDestroyed(
@@ -1305,7 +1319,15 @@
       cross_profile_map_.find(profile);
   if (cross_profile == cross_profile_map_.end())
     return NULL;
-  return cross_profile->second;
+  return cross_profile->second.second;
+}
+
+bool ExtensionWebRequestEventRouter::IsIncognitoProfile(void* profile) const {
+  CrossProfileMap::const_iterator cross_profile =
+      cross_profile_map_.find(profile);
+  if (cross_profile == cross_profile_map_.end())
+    return false;
+  return cross_profile->second.first;
 }
 
 bool ExtensionWebRequestEventRouter::WasSignaled(
@@ -1541,9 +1563,8 @@
 }
 
 // Converts an EventResponseDelta object to a dictionary value suitable for the
-// activity log.  The caller takes ownership of the returned DictionaryValue
-// object.
-DictionaryValue* SummarizeResponseDelta(
+// activity log.
+scoped_ptr<DictionaryValue> SummarizeResponseDelta(
     const std::string& event_name,
     const helpers::EventResponseDelta& delta) {
   scoped_ptr<DictionaryValue> details(new DictionaryValue());
@@ -1590,28 +1611,32 @@
         SummarizeCookieModifications(delta.response_cookie_modifications));
   }
 
-  return details.release();
+  return details.Pass();
 }
 
-void LogExtensionActivity(Profile* profile,
+void LogExtensionActivity(void* profile_id,
+                          bool is_incognito,
                           const std::string& extension_id,
                           const GURL& url,
                           const std::string& api_call,
-                          DictionaryValue* details_raw) {
-  scoped_ptr<DictionaryValue> details(details_raw);
+                          scoped_ptr<DictionaryValue> details) {
   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
     BrowserThread::PostTask(BrowserThread::UI,
                             FROM_HERE,
                             base::Bind(&LogExtensionActivity,
-                                       profile,
+                                       profile_id,
+                                       is_incognito,
                                        extension_id,
                                        url,
                                        api_call,
-                                       details.release()));
+                                       base::Passed(&details)));
   } else {
+    Profile* profile = static_cast<Profile*>(profile_id);
+    if (!g_browser_process->profile_manager()->IsValidProfile(profile))
+      return;
     extensions::ActivityLog::GetInstance(profile)->LogWebRequestAction(
         extension_id,
-        url,
+        is_incognito ?  GURL(extensions::APIAction::kIncognitoUrl) : url,
         api_call,
         details.Pass(),
         "");
@@ -1642,7 +1667,8 @@
         CalculateDelta(&blocked_request, response);
 
     if (extensions::ActivityLog::IsLogEnabledOnAnyProfile()) {
-      LogExtensionActivity(static_cast<Profile*>(profile),
+      LogExtensionActivity(profile,
+                           blocked_request.is_incognito,
                            extension_id,
                            blocked_request.request->url(),
                            event_name,
@@ -1862,6 +1888,8 @@
                      request_stage));
       blocked_requests_[request->identifier()].num_handlers_blocking++;
       blocked_requests_[request->identifier()].request = request;
+      blocked_requests_[request->identifier()].is_incognito |=
+          IsIncognitoProfile(profile);
       blocked_requests_[request->identifier()].blocking_time =
           base::Time::Now();
       blocked_requests_[request->identifier()].original_response_headers =
diff --git a/chrome/browser/extensions/api/web_request/web_request_api.h b/chrome/browser/extensions/api/web_request/web_request_api.h
index 1f717f4..4e9ea49 100644
--- a/chrome/browser/extensions/api/web_request/web_request_api.h
+++ b/chrome/browser/extensions/api/web_request/web_request_api.h
@@ -282,7 +282,9 @@
   typedef std::map<uint64, BlockedRequest> BlockedRequestMap;
   // Map of request_id -> bit vector of EventTypes already signaled
   typedef std::map<uint64, int> SignaledRequestMap;
-  typedef std::map<void*, void*> CrossProfileMap;
+  // For each profile: a bool indicating whether it is an incognito profile,
+  // and a pointer to the corresponding (non-)incognito profile.
+  typedef std::map<void*, std::pair<bool, void*> > CrossProfileMap;
   typedef std::list<base::Closure> CallbacksForPageLoad;
 
   ExtensionWebRequestEventRouter();
@@ -391,6 +393,11 @@
   // OTR and vice versa).
   void* GetCrossProfile(void* profile) const;
 
+  // Determines whether the specified profile is an incognito profile (based on
+  // the contents of the cross-profile table and without dereferencing the
+  // profile pointer).
+  bool IsIncognitoProfile(void* profile) const;
+
   // Returns true if |request| was already signaled to some event handlers.
   bool WasSignaled(const net::URLRequest& request) const;
 
diff --git a/chrome/browser/extensions/api/web_request/web_request_api_helpers.h b/chrome/browser/extensions/api/web_request/web_request_api_helpers.h
index 76325b3..9b849c1 100644
--- a/chrome/browser/extensions/api/web_request/web_request_api_helpers.h
+++ b/chrome/browser/extensions/api/web_request/web_request_api_helpers.h
@@ -16,10 +16,10 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
 #include "chrome/browser/extensions/extension_warning_set.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/auth.h"
 #include "net/http/http_request_headers.h"
 #include "net/http/http_response_headers.h"
+#include "url/gurl.h"
 #include "webkit/glue/resource_type.h"
 
 namespace base {
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
index 0cca09d..063a07d 100644
--- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -12,7 +13,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/login/login_prompt.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/features/feature.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -284,7 +284,8 @@
       message_;
 }
 
-IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, MAYBE_PostData2) {
+// TODO(dslomov): update expectations and re-eanble, http://crbug.com/257128.
+IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, DISABLED_PostData2) {
   // Test HTML form POST data access with the multipart and plaintext encoding.
   ASSERT_TRUE(StartEmbeddedTestServer());
   ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_post2.html")) <<
diff --git a/chrome/browser/extensions/api/web_request/web_request_permissions.cc b/chrome/browser/extensions/api/web_request/web_request_permissions.cc
index a3d4b50..a0970d6 100644
--- a/chrome/browser/extensions/api/web_request/web_request_permissions.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_permissions.cc
@@ -13,8 +13,8 @@
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/resource_request_info.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_request.h"
+#include "url/gurl.h"
 
 using content::ResourceRequestInfo;
 
diff --git a/chrome/browser/extensions/api/web_request/web_request_time_tracker.h b/chrome/browser/extensions/api/web_request/web_request_time_tracker.h
index ff33e70..3985563 100644
--- a/chrome/browser/extensions/api/web_request/web_request_time_tracker.h
+++ b/chrome/browser/extensions/api/web_request/web_request_time_tracker.h
@@ -13,7 +13,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace base {
 class Time;
diff --git a/chrome/browser/extensions/api/web_socket_proxy_private/web_socket_proxy_private_api.cc b/chrome/browser/extensions/api/web_socket_proxy_private/web_socket_proxy_private_api.cc
index 3e551a3..451654c 100644
--- a/chrome/browser/extensions/api/web_socket_proxy_private/web_socket_proxy_private_api.cc
+++ b/chrome/browser/extensions/api/web_socket_proxy_private/web_socket_proxy_private_api.cc
@@ -9,9 +9,9 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/internal_auth.h"
 #include "chrome/browser/io_thread.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
index 2f398b5..f64add1 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -15,6 +15,7 @@
 #include "base/values.h"
 #include "chrome/browser/about_flags.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_function_dispatcher.h"
 #include "chrome/browser/extensions/extension_prefs.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/app_list/app_list_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/extension_l10n_util.h"
@@ -176,16 +176,6 @@
 
 WebstoreInstaller::Delegate* test_webstore_installer_delegate = NULL;
 
-void EnableAppLauncher(base::Callback<void(bool)> callback) {
-#if defined(OS_WIN)
-  LOG(INFO) << "Enabling App Launcher via internal enable";
-  AppListService::Get()->EnableAppList();
-  callback.Run(true);
-#else
-  callback.Run(true);
-#endif
-}
-
 // We allow the web store to set a string containing login information when a
 // purchase is made, so that when a user logs into sync with a different
 // account we can recognize the situation. The Get function returns the login if
@@ -503,6 +493,9 @@
           profile(), id_, parsed_manifest_.Pass()));
   approval->use_app_installed_bubble = use_app_installed_bubble_;
   approval->enable_launcher = enable_launcher_;
+  // If we are enabling the launcher, we should not show the app list in order
+  // to train the user to open it themselves at least once.
+  approval->skip_post_install_ui = enable_launcher_;
   approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_);
   g_pending_approvals.Get().PushApproval(approval.Pass());
 
@@ -566,24 +559,13 @@
   // Balanced in OnExtensionInstallSuccess() or OnExtensionInstallFailure().
   AddRef();
 
-  if (approval_->enable_launcher) {
-    EnableAppLauncher(
-        base::Bind(&CompleteInstallFunction::AfterMaybeInstallAppLauncher,
-                   this));
-  } else {
-    AfterMaybeInstallAppLauncher(true);
-  }
+  if (approval_->enable_launcher)
+    AppListService::Get()->EnableAppList(profile());
 
-  return true;
-}
-
-void CompleteInstallFunction::AfterMaybeInstallAppLauncher(bool ok) {
-  if (!ok)
-    LOG(ERROR) << "Error installing app launcher";
-  std::string id = approval_->extension_id;
   if (apps::IsAppLauncherEnabled()) {
-    // Show the app list so it receives install progress notifications.
-    if (approval_->manifest->is_app())
+    // Show the app list to show download is progressing. Don't show the app
+    // list on first app install so users can be trained to open it themselves.
+    if (approval_->manifest->is_app() && !approval_->enable_launcher)
       AppListService::Get()->ShowAppList(profile());
   }
 
@@ -594,6 +576,8 @@
       &(dispatcher()->delegate()->GetAssociatedWebContents()->GetController()),
       id, approval_.Pass(), WebstoreInstaller::FLAG_NONE);
   installer->Start();
+
+  return true;
 }
 
 void CompleteInstallFunction::OnExtensionInstallSuccess(
@@ -632,17 +616,11 @@
 EnableAppLauncherFunction::~EnableAppLauncherFunction() {}
 
 bool EnableAppLauncherFunction::RunImpl() {
-  EnableAppLauncher(
-      base::Bind(&EnableAppLauncherFunction::AfterEnableAppLauncher, this));
+  AppListService::Get()->EnableAppList(profile());
+  SendResponse(true);
   return true;
 }
 
-void EnableAppLauncherFunction::AfterEnableAppLauncher(bool ok) {
-  if (!ok)
-    LOG(ERROR) << "Error installing app launcher";
-  SendResponse(ok);
-}
-
 bool GetBrowserLoginFunction::RunImpl() {
   SetResult(CreateLoginResult(profile_->GetOriginalProfile()));
   return true;
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.h b/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
index 5866259..2337bc3 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
@@ -190,8 +190,6 @@
   virtual bool RunImpl() OVERRIDE;
 
  private:
-  void AfterMaybeInstallAppLauncher(bool ok);
-
   scoped_ptr<WebstoreInstaller::Approval> approval_;
 };
 
@@ -208,9 +206,6 @@
 
   // ExtensionFunction:
   virtual bool RunImpl() OVERRIDE;
-
- private:
-  void AfterEnableAppLauncher(bool ok);
 };
 
 class GetBrowserLoginFunction : public SyncExtensionFunction {
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc
index ad7dfbe..b4f80d2 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc
@@ -8,6 +8,7 @@
 #include "base/files/file_path.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/webstore_private/webstore_private_api.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_function_test_utils.h"
@@ -18,7 +19,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/test_launcher_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -191,15 +191,15 @@
   base::ScopedTempDir temp_dir;
   EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
   base::FilePath missing_directory = temp_dir.Take();
-  EXPECT_TRUE(base::Delete(missing_directory, true));
+  EXPECT_TRUE(base::DeleteFile(missing_directory, true));
   WebstoreInstaller::SetDownloadDirectoryForTests(&missing_directory);
 
   // Now run the install test, which should succeed.
   ASSERT_TRUE(RunInstallTest("accepted.html", "extension.crx"));
 
   // Cleanup.
-  if (file_util::DirectoryExists(missing_directory))
-    EXPECT_TRUE(base::Delete(missing_directory, true));
+  if (base::DirectoryExists(missing_directory))
+    EXPECT_TRUE(base::DeleteFile(missing_directory, true));
 }
 
 // Tests passing a localized name.
diff --git a/chrome/browser/extensions/api/webview/webview_api.cc b/chrome/browser/extensions/api/webview/webview_api.cc
index c342072..bfc7c6f 100644
--- a/chrome/browser/extensions/api/webview/webview_api.cc
+++ b/chrome/browser/extensions/api/webview/webview_api.cc
@@ -107,3 +107,60 @@
   guest->Go(relative_index);
   return true;
 }
+
+WebviewStopFunction::WebviewStopFunction() {
+}
+
+WebviewStopFunction::~WebviewStopFunction() {
+}
+
+bool WebviewStopFunction::RunImpl() {
+  int instance_id = 0;
+  EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id));
+
+  WebViewGuest* guest = WebViewGuest::From(
+      render_view_host()->GetProcess()->GetID(), instance_id);
+  if (!guest)
+    return false;
+
+  guest->Stop();
+  return true;
+}
+
+WebviewReloadFunction::WebviewReloadFunction() {
+}
+
+WebviewReloadFunction::~WebviewReloadFunction() {
+}
+
+bool WebviewReloadFunction::RunImpl() {
+  int instance_id = 0;
+  EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id));
+
+  WebViewGuest* guest = WebViewGuest::From(
+      render_view_host()->GetProcess()->GetID(), instance_id);
+  if (!guest)
+    return false;
+
+  guest->Reload();
+  return true;
+}
+
+WebviewTerminateFunction::WebviewTerminateFunction() {
+}
+
+WebviewTerminateFunction::~WebviewTerminateFunction() {
+}
+
+bool WebviewTerminateFunction::RunImpl() {
+  int instance_id = 0;
+  EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id));
+
+  WebViewGuest* guest = WebViewGuest::From(
+      render_view_host()->GetProcess()->GetID(), instance_id);
+  if (!guest)
+    return false;
+
+  guest->Terminate();
+  return true;
+}
diff --git a/chrome/browser/extensions/api/webview/webview_api.h b/chrome/browser/extensions/api/webview/webview_api.h
index a015119..6ffe72e 100644
--- a/chrome/browser/extensions/api/webview/webview_api.h
+++ b/chrome/browser/extensions/api/webview/webview_api.h
@@ -80,4 +80,52 @@
   DISALLOW_COPY_AND_ASSIGN(WebviewGoFunction);
 };
 
+class WebviewReloadFunction : public AsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("webview.reload", WEBVIEW_RELOAD);
+
+  WebviewReloadFunction();
+
+ protected:
+  virtual ~WebviewReloadFunction();
+
+  // ExtensionFunction implementation.
+  virtual bool RunImpl() OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WebviewReloadFunction);
+};
+
+class WebviewStopFunction : public AsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("webview.stop", WEBVIEW_STOP);
+
+  WebviewStopFunction();
+
+ protected:
+  virtual ~WebviewStopFunction();
+
+  // ExtensionFunction implementation.
+  virtual bool RunImpl() OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WebviewStopFunction);
+};
+
+class WebviewTerminateFunction : public AsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("webview.terminate", WEBVIEW_TERMINATE);
+
+  WebviewTerminateFunction();
+
+ protected:
+  virtual ~WebviewTerminateFunction();
+
+  // ExtensionFunction implementation.
+  virtual bool RunImpl() OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WebviewTerminateFunction);
+};
+
 #endif  // CHROME_BROWSER_EXTENSIONS_API_WEBVIEW_WEBVIEW_API_H_
diff --git a/chrome/browser/extensions/app_background_page_apitest.cc b/chrome/browser/extensions/app_background_page_apitest.cc
index 75fe6cf..f07952c 100644
--- a/chrome/browser/extensions/app_background_page_apitest.cc
+++ b/chrome/browser/extensions/app_background_page_apitest.cc
@@ -8,12 +8,12 @@
 #include "chrome/browser/background/background_contents_service_factory.h"
 #include "chrome/browser/background/background_mode_manager.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc
index e48b29d..7f4dd7b 100644
--- a/chrome/browser/extensions/app_process_apitest.cc
+++ b/chrome/browser/extensions/app_process_apitest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_file_util.h"
diff --git a/chrome/browser/extensions/app_sync_bundle.cc b/chrome/browser/extensions/app_sync_bundle.cc
index 62ffc60..8038fed 100644
--- a/chrome/browser/extensions/app_sync_bundle.cc
+++ b/chrome/browser/extensions/app_sync_bundle.cc
@@ -119,8 +119,8 @@
   pending_sync_data_[id] = app_sync_data;
 }
 
-bool AppSyncBundle::HandlesApp(const Extension& extension) const {
-  return sync_processor_ != NULL && sync_helper::IsSyncableApp(&extension);
+bool AppSyncBundle::IsSyncing() const {
+  return sync_processor_ != NULL;
 }
 
 std::vector<AppSyncData> AppSyncBundle::GetPendingData() const {
@@ -144,7 +144,7 @@
     // If we have pending app data for this app, then this
     // version is out of date.  We'll sync back the version we got from
     // sync.
-    if (HandlesApp(extension) &&
+    if (IsSyncing() && sync_helper::IsSyncableApp(&extension) &&
         !HasPendingExtensionId(extension.id())) {
       sync_data_list->push_back(extension_service_->GetAppSyncData(extension));
     }
diff --git a/chrome/browser/extensions/app_sync_bundle.h b/chrome/browser/extensions/app_sync_bundle.h
index 60bffa3..d5172ff 100644
--- a/chrome/browser/extensions/app_sync_bundle.h
+++ b/chrome/browser/extensions/app_sync_bundle.h
@@ -72,9 +72,6 @@
   void AddPendingApp(const std::string& id,
                      const AppSyncData& app_sync_data);
 
-  // Returns true if |extension| should be handled by this sync bundle.
-  bool HandlesApp(const Extension& extension) const;
-
   // Returns a vector of all the pending sync data.
   std::vector<AppSyncData> GetPendingData() const;
 
@@ -83,6 +80,9 @@
       const ExtensionSet& extensions,
       std::vector<extensions::AppSyncData>* sync_data_list) const;
 
+  // Returns true if SetupSync has been called, false otherwise.
+  bool IsSyncing() const;
+
  private:
   // Add a synced app.
   void AddApp(const std::string& id);
diff --git a/chrome/browser/extensions/app_window_contents.cc b/chrome/browser/extensions/app_window_contents.cc
deleted file mode 100644
index 5c6ff07..0000000
--- a/chrome/browser/extensions/app_window_contents.cc
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/app_window_contents.h"
-
-#include "chrome/browser/printing/print_preview_message_handler.h"
-#include "chrome/browser/printing/print_view_manager.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/extensions/native_app_window.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/extensions/api/app_window.h"
-#include "chrome/common/extensions/extension_messages.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/resource_dispatcher_host.h"
-#include "content/public/browser/site_instance.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/common/renderer_preferences.h"
-
-namespace app_window = extensions::api::app_window;
-
-using apps::ShellWindow;
-
-AppWindowContents::AppWindowContents(ShellWindow* host)
-    : host_(host) {
-}
-
-AppWindowContents::~AppWindowContents() {
-}
-
-void AppWindowContents::Initialize(Profile* profile, const GURL& url) {
-  url_ = url;
-
-  extension_function_dispatcher_.reset(
-      new ExtensionFunctionDispatcher(profile, this));
-
-  web_contents_.reset(content::WebContents::Create(
-      content::WebContents::CreateParams(
-          profile, content::SiteInstance::CreateForURL(profile, url_))));
-
-  content::WebContentsObserver::Observe(web_contents_.get());
-  web_contents_->GetMutableRendererPrefs()->
-      browser_handles_all_top_level_requests = true;
-  web_contents_->GetRenderViewHost()->SyncRendererPrefs();
-
-#if defined(ENABLE_PRINTING)
-  printing::PrintPreviewMessageHandler::CreateForWebContents(
-      web_contents_.get());
-  printing::PrintViewManager::CreateForWebContents(web_contents_.get());
-#endif
-}
-
-void AppWindowContents::LoadContents(int32 creator_process_id) {
-  // If the new view is in the same process as the creator, block the created
-  // RVH from loading anything until the background page has had a chance to
-  // do any initialization it wants. If it's a different process, the new RVH
-  // shouldn't communicate with the background page anyway (e.g. sandboxed).
-  if (web_contents_->GetRenderViewHost()->GetProcess()->GetID() ==
-      creator_process_id) {
-    SuspendRenderViewHost(web_contents_->GetRenderViewHost());
-  } else {
-    VLOG(1) << "ShellWindow created in new process ("
-            << web_contents_->GetRenderViewHost()->GetProcess()->GetID()
-            << ") != creator (" << creator_process_id
-            << "). Routing disabled.";
-  }
-
-  // TODO(jeremya): there's a bug where navigating a web contents to an
-  // extension URL causes it to create a new RVH and discard the old
-  // (perfectly usable) one. To work around this, we watch for a RVH_CHANGED
-  // message from the web contents (which will be sent during LoadURL) and
-  // suspend resource requests on the new RVH to ensure that we block the new
-  // RVH from loading anything. It should be okay to remove the
-  // NOTIFICATION_RVH_CHANGED registration once http://crbug.com/123007 is
-  // fixed.
-  registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
-                 content::Source<content::NavigationController>(
-                     &web_contents()->GetController()));
-  web_contents_->GetController().LoadURL(
-      url_, content::Referrer(), content::PAGE_TRANSITION_LINK,
-      std::string());
-  registrar_.RemoveAll();
-}
-
-void AppWindowContents::NativeWindowChanged(
-    NativeAppWindow* native_app_window) {
-  base::ListValue args;
-  DictionaryValue* dictionary = new DictionaryValue();
-  args.Append(dictionary);
-
-  gfx::Rect bounds = host_->GetClientBounds();
-  app_window::Bounds update;
-  update.left.reset(new int(bounds.x()));
-  update.top.reset(new int(bounds.y()));
-  update.width.reset(new int(bounds.width()));
-  update.height.reset(new int(bounds.height()));
-  dictionary->Set("bounds", update.ToValue().release());
-  dictionary->SetBoolean("fullscreen",
-                         native_app_window->IsFullscreenOrPending());
-  dictionary->SetBoolean("minimized", native_app_window->IsMinimized());
-  dictionary->SetBoolean("maximized", native_app_window->IsMaximized());
-
-  content::RenderViewHost* rvh = web_contents_->GetRenderViewHost();
-  rvh->Send(new ExtensionMsg_MessageInvoke(rvh->GetRoutingID(),
-                                           host_->extension()->id(),
-                                           "app.window",
-                                           "updateAppWindowProperties",
-                                           args,
-                                           false));
-}
-
-void AppWindowContents::NativeWindowClosed() {
-  content::RenderViewHost* rvh = web_contents_->GetRenderViewHost();
-  rvh->Send(new ExtensionMsg_AppWindowClosed(rvh->GetRoutingID()));
-}
-
-content::WebContents* AppWindowContents::GetWebContents() const {
-  return web_contents_.get();
-}
-
-void AppWindowContents::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  switch (type) {
-    case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED: {
-      // TODO(jeremya): once http://crbug.com/123007 is fixed, we'll no longer
-      // need to suspend resource requests here (the call in the constructor
-      // should be enough).
-      content::Details<std::pair<content::RenderViewHost*,
-                                 content::RenderViewHost*> >
-          host_details(details);
-      if (host_details->first)
-        SuspendRenderViewHost(host_details->second);
-      break;
-    }
-    default:
-      NOTREACHED() << "Received unexpected notification";
-  }
-}
-
-bool AppWindowContents::OnMessageReceived(const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(AppWindowContents, message)
-    IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
-    IPC_MESSAGE_HANDLER(ExtensionHostMsg_UpdateDraggableRegions,
-                        UpdateDraggableRegions)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-extensions::WindowController*
-AppWindowContents::GetExtensionWindowController() const {
-  return NULL;
-}
-
-content::WebContents* AppWindowContents::GetAssociatedWebContents() const {
-  return web_contents_.get();
-}
-
-void AppWindowContents::OnRequest(
-    const ExtensionHostMsg_Request_Params& params) {
-  extension_function_dispatcher_->Dispatch(
-      params, web_contents_->GetRenderViewHost());
-}
-
-void AppWindowContents::UpdateDraggableRegions(
-    const std::vector<extensions::DraggableRegion>& regions) {
-  host_->UpdateDraggableRegions(regions);
-}
-
-void AppWindowContents::SuspendRenderViewHost(
-    content::RenderViewHost* rvh) {
-  DCHECK(rvh);
-  content::BrowserThread::PostTask(
-      content::BrowserThread::IO, FROM_HERE,
-      base::Bind(&content::ResourceDispatcherHost::BlockRequestsForRoute,
-                 base::Unretained(content::ResourceDispatcherHost::Get()),
-                 rvh->GetProcess()->GetID(), rvh->GetRoutingID()));
-}
diff --git a/chrome/browser/extensions/app_window_contents.h b/chrome/browser/extensions/app_window_contents.h
deleted file mode 100644
index bb37787..0000000
--- a/chrome/browser/extensions/app_window_contents.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_APP_WINDOW_CONTENTS_H_
-#define CHROME_BROWSER_EXTENSIONS_APP_WINDOW_CONTENTS_H_
-
-#include <vector>
-
-#include "apps/shell_window.h"
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/extensions/extension_function_dispatcher.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/web_contents_observer.h"
-
-class GURL;
-
-namespace content {
-class RenderViewHost;
-}
-
-namespace extensions {
-struct DraggableRegion;
-}
-
-// apps::ShellWindowContents class specific to app windows. It maintains a
-// WebContents instance and observes it for the purpose of passing
-// messages to the extensions system.
-class AppWindowContents : public apps::ShellWindowContents,
-                          public content::NotificationObserver,
-                          public content::WebContentsObserver,
-                          public ExtensionFunctionDispatcher::Delegate {
- public:
-  explicit AppWindowContents(apps::ShellWindow* host);
-  virtual ~AppWindowContents();
-
-  // apps::ShellWindowContents
-  virtual void Initialize(Profile* profile, const GURL& url) OVERRIDE;
-  virtual void LoadContents(int32 creator_process_id) OVERRIDE;
-  virtual void NativeWindowChanged(NativeAppWindow* native_app_window) OVERRIDE;
-  virtual void NativeWindowClosed() OVERRIDE;
-  virtual content::WebContents* GetWebContents() const OVERRIDE;
-
- private:
-  // content::NotificationObserver
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) OVERRIDE;
-
-  // content::WebContentsObserver
-  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-
-  // ExtensionFunctionDispatcher::Delegate
-  virtual extensions::WindowController* GetExtensionWindowController() const
-      OVERRIDE;
-  virtual content::WebContents* GetAssociatedWebContents() const OVERRIDE;
-
-  void OnRequest(const ExtensionHostMsg_Request_Params& params);
-  void UpdateDraggableRegions(
-      const std::vector<extensions::DraggableRegion>& regions);
-  void SuspendRenderViewHost(content::RenderViewHost* rvh);
-
-  apps::ShellWindow* host_;  // This class is owned by |host_|
-  GURL url_;
-  content::NotificationRegistrar registrar_;
-  scoped_ptr<content::WebContents> web_contents_;
-  scoped_ptr<ExtensionFunctionDispatcher> extension_function_dispatcher_;
-
-  DISALLOW_COPY_AND_ASSIGN(AppWindowContents);
-};
-
-#endif  // CHROME_BROWSER_EXTENSIONS_APP_WINDOW_CONTENTS_H_
diff --git a/chrome/browser/extensions/blacklist.cc b/chrome/browser/extensions/blacklist.cc
index 9e1ef1b..87c7e28 100644
--- a/chrome/browser/extensions/blacklist.cc
+++ b/chrome/browser/extensions/blacklist.cc
@@ -11,11 +11,11 @@
 #include "base/memory/ref_counted.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/safe_browsing/database_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/extensions/browser_event_router.cc b/chrome/browser/extensions/browser_event_router.cc
index 3f85d96..ebbb8d0 100644
--- a/chrome/browser/extensions/browser_event_router.cc
+++ b/chrome/browser/extensions/browser_event_router.cc
@@ -6,6 +6,7 @@
 
 #include "base/json/json_writer.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_api_constants.h"
 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "content/public/browser/favicon_status.h"
diff --git a/chrome/browser/extensions/chrome_app_api_browsertest.cc b/chrome/browser/extensions/chrome_app_api_browsertest.cc
index a1950d1..97f923d 100644
--- a/chrome/browser/extensions/chrome_app_api_browsertest.cc
+++ b/chrome/browser/extensions/chrome_app_api_browsertest.cc
@@ -20,8 +20,8 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "net/dns/mock_host_resolver.h"
+#include "url/gurl.h"
 
 using extensions::Extension;
 
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc
index b2b10b6..152e92f 100644
--- a/chrome/browser/extensions/component_loader.cc
+++ b/chrome/browser/extensions/component_loader.cc
@@ -4,15 +4,18 @@
 
 #include "chrome/browser/extensions/component_loader.h"
 
+#include <map>
+#include <string>
+
 #include "base/command_line.h"
 #include "base/file_util.h"
 #include "base/json/json_string_value_serializer.h"
 #include "base/metrics/field_trial.h"
 #include "base/path_service.h"
 #include "base/prefs/pref_change_registrar.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
@@ -23,6 +26,8 @@
 #include "content/public/browser/notification_source.h"
 #include "extensions/common/id_util.h"
 #include "grit/browser_resources.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 
 #if defined(USE_AURA)
@@ -44,12 +49,11 @@
 #include "chromeos/chromeos_switches.h"
 #include "content/public/browser/storage_partition.h"
 #include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/browser/fileapi/sandbox_mount_point_provider.h"
+#include "webkit/browser/fileapi/sandbox_file_system_backend.h"
 #endif
 
 #if defined(ENABLE_APP_LIST)
 #include "grit/chromium_strings.h"
-#include "ui/base/l10n/l10n_util.h"
 #endif
 
 namespace extensions {
@@ -58,6 +62,30 @@
 
 static bool enable_background_extensions_during_testing = false;
 
+std::string LookupWebstoreName() {
+  const char kWebStoreNameFieldTrialName[] = "WebStoreName";
+  const char kStoreControl[] = "StoreControl";
+  const char kWebStore[] = "WebStore";
+  const char kGetApps[] = "GetApps";
+  const char kAddApps[] = "AddApps";
+  const char kMoreApps[] = "MoreApps";
+
+  typedef std::map<std::string, int> NameMap;
+  CR_DEFINE_STATIC_LOCAL(NameMap, names, ());
+  if (names.empty()) {
+    names.insert(std::make_pair(kStoreControl, IDS_WEBSTORE_NAME_STORE));
+    names.insert(std::make_pair(kWebStore, IDS_WEBSTORE_NAME_WEBSTORE));
+    names.insert(std::make_pair(kGetApps, IDS_WEBSTORE_NAME_GET_APPS));
+    names.insert(std::make_pair(kAddApps, IDS_WEBSTORE_NAME_ADD_APPS));
+    names.insert(std::make_pair(kMoreApps, IDS_WEBSTORE_NAME_MORE_APPS));
+  }
+  std::string field_trial_name =
+      base::FieldTrialList::FindFullName(kWebStoreNameFieldTrialName);
+  NameMap::iterator it = names.find(field_trial_name);
+  int string_id = it == names.end() ? names[kStoreControl] : it->second;
+  return l10n_util::GetStringUTF8(string_id);
+}
+
 std::string GenerateId(const DictionaryValue* manifest,
                        const base::FilePath& path) {
   std::string raw_key;
@@ -269,11 +297,12 @@
 #endif  // defined(IMAGE_LOADER_EXTENSION)
 }
 
-void ComponentLoader::AddChromeApp() {
-#if defined(ENABLE_APP_LIST)
+void ComponentLoader::AddWithName(int manifest_resource_id,
+                                  const base::FilePath& root_directory,
+                                  const std::string& name) {
   std::string manifest_contents =
       ResourceBundle::GetSharedInstance().GetRawDataResource(
-          IDR_CHROME_APP_MANIFEST).as_string();
+          manifest_resource_id).as_string();
 
   // The Value is kept for the lifetime of the ComponentLoader. This is
   // required in case LoadAll() is called again.
@@ -281,10 +310,16 @@
 
   if (manifest) {
     // Update manifest to use a proper name.
-    manifest->SetString(extension_manifest_keys::kName,
-                        l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME));
-    Add(manifest, base::FilePath(FILE_PATH_LITERAL("chrome_app")));
+    manifest->SetString(extension_manifest_keys::kName, name);
+    Add(manifest, root_directory);
   }
+}
+
+void ComponentLoader::AddChromeApp() {
+#if defined(ENABLE_APP_LIST)
+  AddWithName(IDR_CHROME_APP_MANIFEST,
+              base::FilePath(FILE_PATH_LITERAL("chrome_app")),
+              l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME));
 #endif
 }
 
@@ -295,6 +330,12 @@
 #endif
 }
 
+void ComponentLoader::AddWebStoreApp() {
+  AddWithName(IDR_WEBSTORE_MANIFEST,
+              base::FilePath(FILE_PATH_LITERAL("web_store")),
+              LookupWebstoreName());
+}
+
 // static
 void ComponentLoader::EnableBackgroundExtensionsForTesting() {
   enable_background_extensions_during_testing = true;
@@ -335,7 +376,7 @@
 #endif
 
   if (!skip_session_components) {
-    Add(IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
+    AddWebStoreApp();
     AddChromeApp();
   }
 
diff --git a/chrome/browser/extensions/component_loader.h b/chrome/browser/extensions/component_loader.h
index 7acff02..ea66106 100644
--- a/chrome/browser/extensions/component_loader.h
+++ b/chrome/browser/extensions/component_loader.h
@@ -115,8 +115,12 @@
   void AddFileManagerExtension();
   void AddImageLoaderExtension();
 
+  void AddWithName(int manifest_resource_id,
+                   const base::FilePath& root_directory,
+                   const std::string& name);
   void AddChromeApp();
   void AddKeyboardApp();
+  void AddWebStoreApp();
 
   // Unloads |component| from the memory.
   void UnloadComponent(ComponentExtensionInfo* component);
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc
index 48f6cc6..55d7531 100644
--- a/chrome/browser/extensions/content_script_apitest.cc
+++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -3,20 +3,20 @@
 // found in the LICENSE file.
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/permissions/permissions_api.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "url/gurl.h"
 
 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptAllFrames) {
   ASSERT_TRUE(StartEmbeddedTestServer());
diff --git a/chrome/browser/extensions/convert_user_script.cc b/chrome/browser/extensions/convert_user_script.cc
index e823819..0d79540 100644
--- a/chrome/browser/extensions/convert_user_script.cc
+++ b/chrome/browser/extensions/convert_user_script.cc
@@ -23,7 +23,7 @@
 #include "chrome/common/extensions/user_script.h"
 #include "crypto/sha2.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace keys = extension_manifest_keys;
 namespace values = extension_manifest_values;
@@ -164,8 +164,8 @@
   }
 
   // Write the script file.
-  if (!file_util::CopyFile(user_script_path,
-                           temp_dir.path().AppendASCII("script.js"))) {
+  if (!base::CopyFile(user_script_path,
+                      temp_dir.path().AppendASCII("script.js"))) {
     *error = ASCIIToUTF16("Could not copy script file.");
     return NULL;
   }
diff --git a/chrome/browser/extensions/convert_user_script_unittest.cc b/chrome/browser/extensions/convert_user_script_unittest.cc
index cc534f5..e1d4be1 100644
--- a/chrome/browser/extensions/convert_user_script_unittest.cc
+++ b/chrome/browser/extensions/convert_user_script_unittest.cc
@@ -79,9 +79,9 @@
   EXPECT_TRUE(script.emulate_greasemonkey());
 
   // Make sure the files actually exist on disk.
-  EXPECT_TRUE(file_util::PathExists(
+  EXPECT_TRUE(base::PathExists(
       extension->path().Append(script.js_scripts()[0].relative_path())));
-  EXPECT_TRUE(file_util::PathExists(
+  EXPECT_TRUE(base::PathExists(
       extension->path().Append(kManifestFilename)));
 }
 
@@ -128,9 +128,9 @@
   EXPECT_EQ(expected, script.url_patterns());
 
   // Make sure the files actually exist on disk.
-  EXPECT_TRUE(file_util::PathExists(
+  EXPECT_TRUE(base::PathExists(
       extension->path().Append(script.js_scripts()[0].relative_path())));
-  EXPECT_TRUE(file_util::PathExists(
+  EXPECT_TRUE(base::PathExists(
       extension->path().Append(kManifestFilename)));
 }
 
@@ -230,7 +230,7 @@
   ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
   test_file = test_file.AppendASCII("extensions")
                        .AppendASCII("user_script_run_at_idle.user.js");
-  ASSERT_TRUE(file_util::PathExists(test_file)) << test_file.value();
+  ASSERT_TRUE(base::PathExists(test_file)) << test_file.value();
 
   string16 error;
   scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
diff --git a/chrome/browser/extensions/convert_web_app.cc b/chrome/browser/extensions/convert_web_app.cc
index e1dcf8e..5f844ab 100644
--- a/chrome/browser/extensions/convert_web_app.cc
+++ b/chrome/browser/extensions/convert_web_app.cc
@@ -26,9 +26,9 @@
 #include "chrome/common/web_application_info.h"
 #include "crypto/sha2.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/gurl.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/codec/png_codec.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/convert_web_app_browsertest.cc b/chrome/browser/extensions/convert_web_app_browsertest.cc
index bf1f816..c9ed528 100644
--- a/chrome/browser/extensions/convert_web_app_browsertest.cc
+++ b/chrome/browser/extensions/convert_web_app_browsertest.cc
@@ -4,11 +4,11 @@
 
 #include <string>
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_icon_set.h"
diff --git a/chrome/browser/extensions/convert_web_app_unittest.cc b/chrome/browser/extensions/convert_web_app_unittest.cc
index cea76d4..fe081da 100644
--- a/chrome/browser/extensions/convert_web_app_unittest.cc
+++ b/chrome/browser/extensions/convert_web_app_unittest.cc
@@ -24,9 +24,9 @@
 #include "chrome/common/web_application_info.h"
 #include "extensions/common/extension_resource.h"
 #include "extensions/common/url_pattern.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/codec/png_codec.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
@@ -150,7 +150,7 @@
                                    web_app.icons[i].width,
                                    ExtensionIconSet::MATCH_EXACTLY);
     ASSERT_TRUE(!resource.empty());
-    EXPECT_TRUE(file_util::PathExists(resource.GetFilePath()));
+    EXPECT_TRUE(base::PathExists(resource.GetFilePath()));
   }
 }
 
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index 4f15cb9..2d2e0ae 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -21,6 +21,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
 #include "base/version.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/convert_user_script.h"
 #include "chrome/browser/extensions/convert_web_app.h"
 #include "chrome/browser/extensions/crx_installer_error.h"
@@ -32,14 +33,12 @@
 #include "chrome/browser/extensions/webstore_installer.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/extension_file_util.h"
 #include "chrome/common/extensions/extension_icon_set.h"
 #include "chrome/common/extensions/feature_switch.h"
 #include "chrome/common/extensions/manifest.h"
-#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
 #include "chrome/common/extensions/manifest_handlers/shared_module_info.h"
 #include "chrome/common/extensions/manifest_url_handler.h"
 #include "chrome/common/extensions/user_script.h"
@@ -142,11 +141,14 @@
 }
 
 void CrxInstaller::InstallCrx(const base::FilePath& source_file) {
+  ExtensionService* service = service_weak_.get();
+  if (!service || service->browser_terminating())
+    return;
+
   source_file_ = source_file;
 
   scoped_refptr<SandboxedUnpacker> unpacker(
       new SandboxedUnpacker(source_file,
-                            content::ResourceDispatcherHost::Get() != NULL,
                             install_source_,
                             creation_flags_,
                             install_directory_,
@@ -181,7 +183,8 @@
     return;
   }
 
-  OnUnpackSuccess(extension->path(), extension->path(), NULL, extension.get());
+  OnUnpackSuccess(extension->path(), extension->path(), NULL, extension.get(),
+                  SkBitmap());
 }
 
 void CrxInstaller::InstallWebApp(const WebApplicationInfo& web_app) {
@@ -208,7 +211,8 @@
 
   // TODO(aa): conversion data gets lost here :(
 
-  OnUnpackSuccess(extension->path(), extension->path(), NULL, extension.get());
+  OnUnpackSuccess(extension->path(), extension->path(), NULL, extension.get(),
+                  SkBitmap());
 }
 
 CrxInstallerError CrxInstaller::AllowInstall(const Extension* extension) {
@@ -356,7 +360,8 @@
 void CrxInstaller::OnUnpackSuccess(const base::FilePath& temp_dir,
                                    const base::FilePath& extension_dir,
                                    const DictionaryValue* original_manifest,
-                                   const Extension* extension) {
+                                   const Extension* extension,
+                                   const SkBitmap& install_icon) {
   DCHECK(installer_task_runner_->RunsTasksOnCurrentThread());
 
   UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallSource",
@@ -369,6 +374,8 @@
 
   installer_.set_extension(extension);
   temp_dir_ = temp_dir;
+  if (!install_icon.empty())
+    install_icon_.reset(new SkBitmap(install_icon));
 
   if (original_manifest)
     original_manifest_.reset(new Manifest(
@@ -385,13 +392,6 @@
     return;
   }
 
-  if (client_) {
-    IconsInfo::DecodeIcon(installer_.extension().get(),
-                          extension_misc::EXTENSION_ICON_LARGE,
-                          ExtensionIconSet::MATCH_BIGGER,
-                          &install_icon_);
-  }
-
   if (!BrowserThread::PostTask(
         BrowserThread::UI, FROM_HERE,
         base::Bind(&CrxInstaller::CheckImportsAndRequirements, this)))
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h
index 5de41a9..dd2e9216 100644
--- a/chrome/browser/extensions/crx_installer.h
+++ b/chrome/browser/extensions/crx_installer.h
@@ -222,7 +222,8 @@
   virtual void OnUnpackSuccess(const base::FilePath& temp_dir,
                                const base::FilePath& extension_dir,
                                const base::DictionaryValue* original_manifest,
-                               const Extension* extension) OVERRIDE;
+                               const Extension* extension,
+                               const SkBitmap& install_icon) OVERRIDE;
 
   // Called on the UI thread to start the requirements check on the extension.
   void CheckImportsAndRequirements();
diff --git a/chrome/browser/extensions/data_deleter.h b/chrome/browser/extensions/data_deleter.h
index 1ded55a..f2dcbd4 100644
--- a/chrome/browser/extensions/data_deleter.h
+++ b/chrome/browser/extensions/data_deleter.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_DATA_DELETER_H_
 #define CHROME_BROWSER_EXTENSIONS_DATA_DELETER_H_
 
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Profile;
 
diff --git a/chrome/browser/extensions/default_apps.cc b/chrome/browser/extensions/default_apps.cc
index 8e684e0..957a935 100644
--- a/chrome/browser/extensions/default_apps.cc
+++ b/chrome/browser/extensions/default_apps.cc
@@ -50,7 +50,7 @@
 
 namespace default_apps {
 
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       prefs::kDefaultAppsInstallState,
       kUnknown,
diff --git a/chrome/browser/extensions/default_apps.h b/chrome/browser/extensions/default_apps.h
index 2fe6ede..ea41826 100644
--- a/chrome/browser/extensions/default_apps.h
+++ b/chrome/browser/extensions/default_apps.h
@@ -34,7 +34,7 @@
 
 // Register preference properties used by default apps to maintain
 // install state.
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
 // A specialization of the ExternalProviderImpl that conditionally installs apps
 // from the chrome::DIR_DEFAULT_APPS location based on a preference in the
diff --git a/chrome/browser/extensions/event_listener_map.cc b/chrome/browser/extensions/event_listener_map.cc
index 2ea49e9..33ba74c 100644
--- a/chrome/browser/extensions/event_listener_map.cc
+++ b/chrome/browser/extensions/event_listener_map.cc
@@ -7,6 +7,7 @@
 #include "base/values.h"
 
 #include "chrome/browser/extensions/event_router.h"
+#include "ipc/ipc_message.h"
 
 namespace extensions {
 
@@ -72,7 +73,7 @@
 scoped_ptr<EventMatcher> EventListenerMap::ParseEventMatcher(
     DictionaryValue* filter_dict) {
   return scoped_ptr<EventMatcher>(new EventMatcher(
-      scoped_ptr<DictionaryValue>(filter_dict->DeepCopy())));
+      scoped_ptr<DictionaryValue>(filter_dict->DeepCopy()), MSG_ROUTING_NONE));
 }
 
 bool EventListenerMap::RemoveListener(const EventListener* listener) {
@@ -188,7 +189,8 @@
   if (IsFilteredEvent(event)) {
     // Look up the interested listeners via the EventFilter.
     std::set<MatcherID> ids =
-        event_filter_.MatchEvent(event.event_name, event.filter_info);
+        event_filter_.MatchEvent(event.event_name, event.filter_info,
+            MSG_ROUTING_NONE);
     for (std::set<MatcherID>::iterator id = ids.begin(); id != ids.end();
          id++) {
       EventListener* listener = listeners_by_matcher_id_[*id];
diff --git a/chrome/browser/extensions/event_router.cc b/chrome/browser/extensions/event_router.cc
index 85f77d8..bcb7c2a 100644
--- a/chrome/browser/extensions/event_router.cc
+++ b/chrome/browser/extensions/event_router.cc
@@ -13,6 +13,7 @@
 #include "base/values.h"
 #include "base/version.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/activity_log/activity_log.h"
 #include "chrome/browser/extensions/api/runtime/runtime_api.h"
 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/extensions/process_map.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/extensions/api/extension_api.h"
@@ -167,7 +167,6 @@
 EventRouter::EventRouter(Profile* profile, ExtensionPrefs* extension_prefs)
     : profile_(profile),
       listeners_(this),
-      activity_log_(ActivityLog::GetInstance(profile)),
       dispatch_chrome_updated_event_(false) {
   registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
                  content::NotificationService::AllSources());
@@ -243,7 +242,7 @@
     scoped_ptr<ListValue> args(new ListValue());
     if (listener->filter)
       args->Append(listener->filter->DeepCopy());
-    activity_log_->LogAPIAction(
+    ActivityLog::GetInstance(profile)->LogAPIAction(
         extension, event_name + ".addListener", args.get(), std::string());
   }
 #endif
@@ -273,7 +272,7 @@
                                             ExtensionService::INCLUDE_ENABLED);
   if (extension) {
     scoped_ptr<ListValue> args(new ListValue());
-    activity_log_->LogAPIAction(
+    ActivityLog::GetInstance(profile)->LogAPIAction(
         extension, event_name + ".removeListener", args.get(), std::string());
   }
 #endif
diff --git a/chrome/browser/extensions/event_router.h b/chrome/browser/extensions/event_router.h
index 32a079c..16f64e9 100644
--- a/chrome/browser/extensions/event_router.h
+++ b/chrome/browser/extensions/event_router.h
@@ -268,8 +268,6 @@
   typedef base::hash_map<std::string, Observer*> ObserverMap;
   ObserverMap observers_;
 
-  ActivityLog* activity_log_;
-
   // True if we should dispatch the event signalling that Chrome was updated
   // upon loading an extension.
   bool dispatch_chrome_updated_event_;
diff --git a/chrome/browser/extensions/event_router_forwarder.cc b/chrome/browser/extensions/event_router_forwarder.cc
index f04c16e..0c67b31 100644
--- a/chrome/browser/extensions/event_router_forwarder.cc
+++ b/chrome/browser/extensions/event_router_forwarder.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
diff --git a/chrome/browser/extensions/event_router_forwarder_unittest.cc b/chrome/browser/extensions/event_router_forwarder_unittest.cc
index c3c1056..bb80d11 100644
--- a/chrome/browser/extensions/event_router_forwarder_unittest.cc
+++ b/chrome/browser/extensions/event_router_forwarder_unittest.cc
@@ -13,9 +13,9 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "content/public/test/test_browser_thread.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
diff --git a/chrome/browser/extensions/extension_action.cc b/chrome/browser/extensions/extension_action.cc
index 62172ea..264c548 100644
--- a/chrome/browser/extensions/extension_action.cc
+++ b/chrome/browser/extensions/extension_action.cc
@@ -12,7 +12,6 @@
 #include "chrome/common/badge_util.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/icon_with_badge_image_source.h"
-#include "googleurl/src/gurl.h"
 #include "grit/theme_resources.h"
 #include "grit/ui_resources.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -30,6 +29,7 @@
 #include "ui/gfx/rect.h"
 #include "ui/gfx/size.h"
 #include "ui/gfx/skbitmap_operations.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/extensions/extension_action_manager.cc b/chrome/browser/extensions/extension_action_manager.cc
index 4c32560..c92cad2 100644
--- a/chrome/browser/extensions/extension_action_manager.cc
+++ b/chrome/browser/extensions/extension_action_manager.cc
@@ -4,13 +4,13 @@
 
 #include "chrome/browser/extensions/extension_action_manager.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/system_indicator/system_indicator_manager.h"
 #include "chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
 #include "chrome/common/extensions/api/extension_action/page_action_handler.h"
 #include "chrome/common/extensions/api/extension_action/script_badge_handler.h"
diff --git a/chrome/browser/extensions/extension_action_unittest.cc b/chrome/browser/extensions/extension_action_unittest.cc
index 2aba574..7656b46 100644
--- a/chrome/browser/extensions/extension_action_unittest.cc
+++ b/chrome/browser/extensions/extension_action_unittest.cc
@@ -5,8 +5,8 @@
 #include "base/message_loop.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/extensions/extension_apitest.cc b/chrome/browser/extensions/extension_apitest.cc
index ed6d644..d2b9284 100644
--- a/chrome/browser/extensions/extension_apitest.cc
+++ b/chrome/browser/extensions/extension_apitest.cc
@@ -7,6 +7,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/test/test_api.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_registrar.h"
diff --git a/chrome/browser/extensions/extension_blacklist_browsertest.cc b/chrome/browser/extensions/extension_blacklist_browsertest.cc
index 4c590fc..a75706c 100644
--- a/chrome/browser/extensions/extension_blacklist_browsertest.cc
+++ b/chrome/browser/extensions/extension_blacklist_browsertest.cc
@@ -4,12 +4,12 @@
 
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/blacklist.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc
index 07fb324..ceb7264 100644
--- a/chrome/browser/extensions/extension_browsertest.cc
+++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_creator.h"
@@ -29,7 +30,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/omnibox/location_bar.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
@@ -170,7 +170,8 @@
     content::WindowedNotificationObserver load_signal(
         chrome::NOTIFICATION_EXTENSION_LOADED,
         content::Source<Profile>(profile()));
-    CHECK(!service->IsIncognitoEnabled(extension_id));
+    CHECK(!service->IsIncognitoEnabled(extension_id) ||
+          extension->force_incognito_enabled());
 
     if (flags & kFlagEnableIncognito) {
       service->SetIsIncognitoEnabled(extension_id, true);
@@ -239,7 +240,7 @@
 base::FilePath ExtensionBrowserTest::PackExtension(
     const base::FilePath& dir_path) {
   base::FilePath crx_path = temp_dir_.path().AppendASCII("temp.crx");
-  if (!base::Delete(crx_path, false)) {
+  if (!base::DeleteFile(crx_path, false)) {
     ADD_FAILURE() << "Failed to delete crx: " << crx_path.value();
     return base::FilePath();
   }
@@ -249,10 +250,10 @@
       dir_path.ReplaceExtension(FILE_PATH_LITERAL(".pem"));
   base::FilePath pem_path_out;
 
-  if (!file_util::PathExists(pem_path)) {
+  if (!base::PathExists(pem_path)) {
     pem_path = base::FilePath();
     pem_path_out = crx_path.DirName().AppendASCII("temp.pem");
-    if (!base::Delete(pem_path_out, false)) {
+    if (!base::DeleteFile(pem_path_out, false)) {
       ADD_FAILURE() << "Failed to delete pem: " << pem_path_out.value();
       return base::FilePath();
     }
@@ -266,12 +267,12 @@
     const base::FilePath& crx_path,
     const base::FilePath& pem_path,
     const base::FilePath& pem_out_path) {
-  if (!file_util::PathExists(dir_path)) {
+  if (!base::PathExists(dir_path)) {
     ADD_FAILURE() << "Extension dir not found: " << dir_path.value();
     return base::FilePath();
   }
 
-  if (!file_util::PathExists(pem_path) && pem_out_path.empty()) {
+  if (!base::PathExists(pem_path) && pem_out_path.empty()) {
     ADD_FAILURE() << "Must specify a PEM file or PEM output path";
     return base::FilePath();
   }
@@ -287,7 +288,7 @@
     return base::FilePath();
   }
 
-  if (!file_util::PathExists(crx_path)) {
+  if (!base::PathExists(crx_path)) {
     ADD_FAILURE() << crx_path.value() << " was not created.";
     return base::FilePath();
   }
diff --git a/chrome/browser/extensions/extension_creator.cc b/chrome/browser/extensions/extension_creator.cc
index cedc048..e344338 100644
--- a/chrome/browser/extensions/extension_creator.cc
+++ b/chrome/browser/extensions/extension_creator.cc
@@ -41,7 +41,7 @@
     int run_flags) {
   // Validate input |extension_dir|.
   if (extension_dir.value().empty() ||
-      !file_util::DirectoryExists(extension_dir)) {
+      !base::DirectoryExists(extension_dir)) {
     error_message_ =
         l10n_util::GetStringUTF8(IDS_EXTENSION_DIRECTORY_NO_EXISTS);
     return false;
@@ -57,7 +57,7 @@
 
   // Validate input |private_key| (if provided).
   if (!private_key_path.value().empty() &&
-      !file_util::PathExists(private_key_path)) {
+      !base::PathExists(private_key_path)) {
     error_message_ =
         l10n_util::GetStringUTF8(IDS_EXTENSION_PRIVATE_KEY_INVALID_PATH);
     return false;
@@ -67,7 +67,7 @@
   // an existing private key.
   if (private_key_path.value().empty() &&
       !private_key_output_path.value().empty() &&
-      file_util::PathExists(private_key_output_path)) {
+      base::PathExists(private_key_output_path)) {
       error_message_ =
           l10n_util::GetStringUTF8(IDS_EXTENSION_PRIVATE_KEY_EXISTS);
       return false;
@@ -75,7 +75,7 @@
 
   // Check whether crx file already exists. Should be last check, as this is
   // a warning only.
-  if (!(run_flags & kOverwriteCRX) && file_util::PathExists(crx_path)) {
+  if (!(run_flags & kOverwriteCRX) && base::PathExists(crx_path)) {
     error_message_ = l10n_util::GetStringUTF8(IDS_EXTENSION_CRX_EXISTS);
     error_type_ = kCRXExists;
 
@@ -120,7 +120,7 @@
 
 crypto::RSAPrivateKey* ExtensionCreator::ReadInputKey(const base::FilePath&
     private_key_path) {
-  if (!file_util::PathExists(private_key_path)) {
+  if (!base::PathExists(private_key_path)) {
     error_message_ =
         l10n_util::GetStringUTF8(IDS_EXTENSION_PRIVATE_KEY_NO_EXISTS);
     return NULL;
@@ -236,8 +236,8 @@
                                 crypto::RSAPrivateKey* private_key,
                                 const std::vector<uint8>& signature,
                                 const base::FilePath& crx_path) {
-  if (file_util::PathExists(crx_path))
-    base::Delete(crx_path, false);
+  if (base::PathExists(crx_path))
+    base::DeleteFile(crx_path, false);
   ScopedStdioHandle crx_handle(file_util::OpenFile(crx_path, "wb"));
   if (!crx_handle.get()) {
     error_message_ = l10n_util::GetStringUTF8(IDS_EXTENSION_SHARING_VIOLATION);
@@ -322,7 +322,7 @@
     result = true;
   }
 
-  base::Delete(zip_path, false);
+  base::DeleteFile(zip_path, false);
   return result;
 }
 
diff --git a/chrome/browser/extensions/extension_disabled_ui.cc b/chrome/browser/extensions/extension_disabled_ui.cc
index 6c887c1..07f7555 100644
--- a/chrome/browser/extensions/extension_disabled_ui.cc
+++ b/chrome/browser/extensions/extension_disabled_ui.cc
@@ -14,6 +14,7 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_install_prompt.h"
 #include "chrome/browser/extensions/extension_install_ui.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/ui/global_error/global_error_service.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_icon_set.h"
 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
diff --git a/chrome/browser/extensions/extension_dom_clipboard_apitest.cc b/chrome/browser/extensions/extension_dom_clipboard_apitest.cc
index 0d2e6a1..21c32dc 100644
--- a/chrome/browser/extensions/extension_dom_clipboard_apitest.cc
+++ b/chrome/browser/extensions/extension_dom_clipboard_apitest.cc
@@ -9,9 +9,9 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index daa25d2..14e384a 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -155,7 +155,7 @@
 
   CommonResponseCallback(ipc_sender.get(),
                          routing_id,
-                         ipc_sender->peer_handle(),
+                         ipc_sender->PeerHandle(),
                          request_id,
                          type,
                          results,
diff --git a/chrome/browser/extensions/extension_function_dispatcher.h b/chrome/browser/extensions/extension_function_dispatcher.h
index 85f15ef..27af9e1 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.h
+++ b/chrome/browser/extensions/extension_function_dispatcher.h
@@ -12,7 +12,7 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/extensions/extension_function.h"
 #include "ipc/ipc_sender.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class ChromeRenderMessageFilter;
 class ExtensionInfoMap;
diff --git a/chrome/browser/extensions/extension_function_histogram_value.h b/chrome/browser/extensions/extension_function_histogram_value.h
index 9a8ef6d..cf973d7 100644
--- a/chrome/browser/extensions/extension_function_histogram_value.h
+++ b/chrome/browser/extensions/extension_function_histogram_value.h
@@ -78,7 +78,7 @@
   BOOKMARKS_UPDATE,
   FILEBROWSERPRIVATE_GETDRIVEFILES,
   TERMINALPRIVATE_ONTERMINALRESIZE,
-  FILEBROWSERPRIVATE_REQUESTDIRECTORYREFRESH,
+  DELETED_FILEBROWSERPRIVATE_REQUESTDIRECTORYREFRESH,
   BLUETOOTH_GETADAPTERSTATE,
   FILEBROWSERPRIVATE_CANCELFILETRANSFERS,
   FILEBROWSERPRIVATE_PINDRIVEFILE,
@@ -251,7 +251,7 @@
   FILESYSTEM_GETDISPLAYPATH,
   FILEBROWSERPRIVATE_FORMATDEVICE,
   BOOKMARKS_GET,
-  MANAGEDMODEPRIVATE_GET,
+  DELETED_MANAGEDMODEPRIVATE_GET,
   ALARMS_CLEAR,
   SYNCFILESYSTEM_GETFILESYNCSTATUS,
   SOCKET_GETINFO,
@@ -265,7 +265,7 @@
   DEVELOPERPRIVATE_RELOAD,
   FILEBROWSERPRIVATE_GETMOUNTPOINTS,
   APP_RUNTIME_POSTINTENTRESPONSE,
-  MANAGEDMODEPRIVATE_SETPOLICY,
+  DELETED_MANAGEDMODEPRIVATE_SETPOLICY,
   WEBSTOREPRIVATE_BEGININSTALLWITHMANIFEST3,
   WALLPAPERPRIVATE_SETWALLPAPER,
   USB_CONTROLTRANSFER,
@@ -292,7 +292,7 @@
   METRICSPRIVATE_RECORDPERCENTAGE,
   TYPES_CHROMESETTING_GET,
   WINDOWS_GETLASTFOCUSED,
-  MANAGEDMODEPRIVATE_GETPOLICY,
+  DELETED_MANAGEDMODEPRIVATE_GETPOLICY,
   STORAGE_CLEAR,
   STORAGE_GETBYTESINUSE,
   TABS_QUERY,
@@ -372,7 +372,7 @@
   BLUETOOTH_GETSERVICES,
   TABS_UPDATE,
   BROWSINGDATA_REMOVEFORMDATA,
-  FILEBROWSERPRIVATE_RELOADDRIVE,
+  DELETED_FILEBROWSERPRIVATE_RELOADDRIVE,
   ALARMS_GET,
   BROWSINGDATA_REMOVEINDEXEDDB,
   FILEBROWSERPRIVATE_ADDFILEWATCH,
@@ -399,7 +399,7 @@
   SERIAL_READ,
   APP_CURRENTWINDOWINTERNAL_MAXIMIZE,
   EXPERIMENTAL_DISCOVERY_CLEARALLSUGGESTIONS,
-  MANAGEDMODEPRIVATE_ENTER,
+  DELETED_MANAGEDMODEPRIVATE_ENTER,
   FILEBROWSERPRIVATE_TRANSFERFILE,
   BROWSERACTION_SETPOPUP,
   TABS_GETSELECTED,
@@ -558,6 +558,14 @@
   FILEBROWSERPRIVATE_ZOOM,
   WEBVIEW_GO,
   WEBSTOREPRIVATE_ISININCOGNITOMODEFUNCTION,
+  FILEBROWSERPRIVATE_REQUESTACCESSTOKEN,
+  WEBVIEW_STOP,
+  WEBVIEW_RELOAD,
+  WEBVIEW_TERMINATE,
+  TYPES_PRIVATE_CHROMEDIRECTSETTING_GET,
+  TYPES_PRIVATE_CHROMEDIRECTSETTING_SET,
+  TYPES_PRIVATE_CHROMEDIRECTSETTING_CLEAR,
+  EXPERIMENTAL_SYSTEMINFO_STORAGE_EJECTDEVICE,
   ENUM_BOUNDARY // Last entry: Add new entries above.
 };
 
diff --git a/chrome/browser/extensions/extension_function_registry.cc b/chrome/browser/extensions/extension_function_registry.cc
index c6b3d4d..774328d 100644
--- a/chrome/browser/extensions/extension_function_registry.cc
+++ b/chrome/browser/extensions/extension_function_registry.cc
@@ -6,6 +6,7 @@
 
 #include "chrome/browser/extensions/api/browsing_data/browsing_data_api.h"
 #include "chrome/browser/extensions/api/identity/experimental_identity_api.h"
+#include "chrome/browser/extensions/api/preference/chrome_direct_setting.h"
 #include "chrome/browser/extensions/api/preference/preference_api.h"
 #include "chrome/browser/extensions/api/runtime/runtime_api.h"
 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
@@ -63,6 +64,12 @@
   RegisterFunction<extensions::SetPreferenceFunction>();
   RegisterFunction<extensions::ClearPreferenceFunction>();
 
+  // Direct Preference Access for Component Extensions.
+  RegisterFunction<extensions::chromedirectsetting::GetDirectSettingFunction>();
+  RegisterFunction<extensions::chromedirectsetting::SetDirectSettingFunction>();
+  RegisterFunction<
+      extensions::chromedirectsetting::ClearDirectSettingFunction>();
+
   // WebstorePrivate.
   RegisterFunction<extensions::GetBrowserLoginFunction>();
   RegisterFunction<extensions::GetStoreLoginFunction>();
diff --git a/chrome/browser/extensions/extension_functional_browsertest.cc b/chrome/browser/extensions/extension_functional_browsertest.cc
index 2699094..d06e419 100644
--- a/chrome/browser/extensions/extension_functional_browsertest.cc
+++ b/chrome/browser/extensions/extension_functional_browsertest.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_commands.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index 5668535..e945bad 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -31,7 +32,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
@@ -324,7 +324,7 @@
     view()->ResizeDueToAutoResize(new_size);
 }
 
-void ExtensionHost::RenderViewGone(base::TerminationStatus status) {
+void ExtensionHost::RenderProcessGone(base::TerminationStatus status) {
   // During browser shutdown, we may use sudden termination on an extension
   // process, so it is expected to lose our connection to the render view.
   // Do nothing.
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
index b9a9972..f4e8886 100644
--- a/chrome/browser/extensions/extension_host.h
+++ b/chrome/browser/extensions/extension_host.h
@@ -143,7 +143,7 @@
   virtual void RenderViewDeleted(
       content::RenderViewHost* render_view_host) OVERRIDE;
   virtual void RenderViewReady() OVERRIDE;
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
   virtual void DocumentAvailableInMainFrame() OVERRIDE;
   virtual void DidStopLoading(
       content::RenderViewHost* render_view_host) OVERRIDE;
diff --git a/chrome/browser/extensions/extension_icon_image.cc b/chrome/browser/extensions/extension_icon_image.cc
index c686d22..fbd1ee4 100644
--- a/chrome/browser/extensions/extension_icon_image.cc
+++ b/chrome/browser/extensions/extension_icon_image.cc
@@ -7,8 +7,8 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/image_loader.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_service.h"
 #include "ui/gfx/canvas.h"
diff --git a/chrome/browser/extensions/extension_icon_source_apitest.cc b/chrome/browser/extensions/extension_icon_source_apitest.cc
index 906fe64..8406ed7 100644
--- a/chrome/browser/extensions/extension_icon_source_apitest.cc
+++ b/chrome/browser/extensions/extension_icon_source_apitest.cc
@@ -12,8 +12,8 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "net/dns/mock_host_resolver.h"
+#include "url/gurl.h"
 
 class ExtensionIconSourceTest : public ExtensionApiTest {
  protected:
diff --git a/chrome/browser/extensions/extension_infobar_delegate.cc b/chrome/browser/extensions/extension_infobar_delegate.cc
index 6f215a0..0bcedd3 100644
--- a/chrome/browser/extensions/extension_infobar_delegate.cc
+++ b/chrome/browser/extensions/extension_infobar_delegate.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/extensions/extension_infobar_delegate.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -11,7 +12,6 @@
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
@@ -39,11 +39,13 @@
     const extensions::Extension* extension,
     const GURL& url,
     int height)
-        : InfoBarDelegate(infobar_service),
-          browser_(browser),
-          observer_(NULL),
-          extension_(extension),
-          closing_(false) {
+    : InfoBarDelegate(infobar_service),
+#if defined(TOOLKIT_VIEWS)
+      browser_(browser),
+#endif
+      observer_(NULL),
+      extension_(extension),
+      closing_(false) {
   ExtensionProcessManager* manager =
       extensions::ExtensionSystem::Get(browser->profile())->process_manager();
   extension_host_.reset(manager->CreateInfobarHost(url, browser));
@@ -110,10 +112,8 @@
       RemoveSelf();
   } else {
     DCHECK(type == chrome::NOTIFICATION_EXTENSION_UNLOADED);
-    if (extension_ ==
-        content::Details<extensions::UnloadedExtensionInfo>(
-            details)->extension) {
+    if (extension_ == content::Details<extensions::UnloadedExtensionInfo>(
+        details)->extension)
       RemoveSelf();
-    }
   }
 }
diff --git a/chrome/browser/extensions/extension_infobar_delegate.h b/chrome/browser/extensions/extension_infobar_delegate.h
index 400b4d4..a8a2f62 100644
--- a/chrome/browser/extensions/extension_infobar_delegate.h
+++ b/chrome/browser/extensions/extension_infobar_delegate.h
@@ -69,7 +69,9 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
-  Browser* browser_;
+#if defined(TOOLKIT_VIEWS)
+  Browser* browser_;  // We pass this to the ExtensionInfoBar.
+#endif
 
   // The extension host we are showing the InfoBar for. The delegate needs to
   // own this since the InfoBar gets deleted and recreated when you switch tabs
diff --git a/chrome/browser/extensions/extension_input_module_constants.cc b/chrome/browser/extensions/extension_input_module_constants.cc
deleted file mode 100644
index 67fd3a7..0000000
--- a/chrome/browser/extensions/extension_input_module_constants.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/extension_input_module_constants.h"
-
-namespace extension_input_module_constants {
-
-const char kAnnotationKey[] = "annotation";
-const char kAuxiliaryTextKey[] = "auxiliaryText";
-const char kAuxiliaryTextVisibleKey[] = "auxiliaryTextVisible";
-const char kCandidateIdKey[] = "candidateID";
-const char kCandidateKey[] = "candidate";
-const char kCandidatesKey[] = "candidates";
-const char kCheckedKey[] = "checked";
-const char kContextIdKey[] = "contextID";
-const char kCursorKey[] = "cursor";
-const char kCursorVisibleKey[] = "cursorVisible";
-const char kEnabledKey[] = "enabled";
-const char kEndKey[] = "end";
-const char kEngineIdKey[] = "engineID";
-const char kIdKey[] = "id";
-const char kItemsKey[] = "items";
-const char kKeyKey[] = "key";
-const char kLabelKey[] = "label";
-const char kLengthKey[] = "length";
-const char kOffsetKey[] = "offset";
-const char kPageSizeKey[] = "pageSize";
-const char kParentIdKey[] = "parentId";
-const char kPropertiesKey[] = "properties";
-const char kSegmentsKey[] = "segments";
-const char kSelectionEndKey[] = "selectionEnd";
-const char kSelectionStartKey[] = "selectionStart";
-const char kStartKey[] = "start";
-const char kStyleDoubleUnderline[] = "doubleUnderline";
-const char kStyleKey[] = "style";
-const char kStyleUnderline[] = "underline";
-const char kTextKey[] = "text";
-const char kUsageBodyKey[] = "body";
-const char kUsageKey[] = "usage";
-const char kUsageTitleKey[] = "title";
-const char kVerticalKey[] = "vertical";
-const char kVisibleKey[] = "visible";
-const char kWindowPositionKey[] = "windowPosition";
-
-}  // namespace extension_input_module_constants
diff --git a/chrome/browser/extensions/extension_input_module_constants.h b/chrome/browser/extensions/extension_input_module_constants.h
deleted file mode 100644
index fb93922..0000000
--- a/chrome/browser/extensions/extension_input_module_constants.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Constants used for the input API and the Windows API.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_INPUT_MODULE_CONSTANTS_H_
-#define CHROME_BROWSER_EXTENSIONS_EXTENSION_INPUT_MODULE_CONSTANTS_H_
-
-namespace extension_input_module_constants {
-
-// Keys used in serializing input data & events.
-extern const char kAnnotationKey[];
-extern const char kAuxiliaryTextKey[];
-extern const char kAuxiliaryTextVisibleKey[];
-extern const char kCandidateIdKey[];
-extern const char kCandidateKey[];
-extern const char kCandidatesKey[];
-extern const char kCheckedKey[];
-extern const char kContextIdKey[];
-extern const char kCursorKey[];
-extern const char kCursorVisibleKey[];
-extern const char kEnabledKey[];
-extern const char kEndKey[];
-extern const char kEngineIdKey[];
-extern const char kIdKey[];
-extern const char kItemsKey[];
-extern const char kKeyKey[];
-extern const char kLabelKey[];
-extern const char kLengthKey[];
-extern const char kOffsetKey[];
-extern const char kPageSizeKey[];
-extern const char kParentIdKey[];
-extern const char kPropertiesKey[];
-extern const char kSegmentsKey[];
-extern const char kSelectionEndKey[];
-extern const char kSelectionStartKey[];
-extern const char kStartKey[];
-extern const char kStyleDoubleUnderline[];
-extern const char kStyleKey[];
-extern const char kStyleUnderline[];
-extern const char kTextKey[];
-extern const char kUsageBodyKey[];
-extern const char kUsageKey[];
-extern const char kUsageTitleKey[];
-extern const char kVerticalKey[];
-extern const char kVisibleKey[];
-extern const char kWindowPositionKey[];
-
-};  // namespace extension_input_module_constants
-
-#endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_INPUT_MODULE_CONSTANTS_H_
diff --git a/chrome/browser/extensions/extension_install_prompt.cc b/chrome/browser/extensions/extension_install_prompt.cc
index 9faaa3a..66521c4 100644
--- a/chrome/browser/extensions/extension_install_prompt.cc
+++ b/chrome/browser/extensions/extension_install_prompt.cc
@@ -17,8 +17,8 @@
 #include "chrome/browser/extensions/extension_install_ui.h"
 #include "chrome/browser/extensions/image_loader.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/token_service.h"
-#include "chrome/browser/signin/token_service_factory.h"
+#include "chrome/browser/signin/profile_oauth2_token_service.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/common/chrome_switches.h"
@@ -202,6 +202,11 @@
   permissions_ = permissions;
 }
 
+void ExtensionInstallPrompt::Prompt::SetPermissionsDetails(
+    const std::vector<string16>& details) {
+  details_ = details;
+}
+
 void ExtensionInstallPrompt::Prompt::SetOAuthIssueAdvice(
     const IssueAdviceInfo& issue_advice) {
   oauth_issue_advice_ = issue_advice;
@@ -316,9 +321,18 @@
 }
 
 string16 ExtensionInstallPrompt::Prompt::GetRetainedFilesHeading() const {
+  // TODO(finnur): Remove this once all platforms are using
+  // GetRetainedFilesHeadingWithCount().
   return l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_RETAINED_FILES);
 }
 
+string16
+ExtensionInstallPrompt::Prompt::GetRetainedFilesHeadingWithCount() const {
+  return l10n_util::GetStringFUTF16(
+      IDS_EXTENSION_PROMPT_RETAINED_FILES_WITH_COUNT,
+      base::IntToString16(GetRetainedFileCount()));
+}
+
 bool ExtensionInstallPrompt::Prompt::ShouldShowPermissions() const {
   return GetPermissionCount() > 0 || type_ == POST_INSTALL_PERMISSIONS_PROMPT;
 }
@@ -370,11 +384,21 @@
   return permissions_.size();
 }
 
+size_t ExtensionInstallPrompt::Prompt::GetPermissionsDetailsCount() const {
+  return details_.size();
+}
+
 string16 ExtensionInstallPrompt::Prompt::GetPermission(size_t index) const {
   CHECK_LT(index, permissions_.size());
   return permissions_[index];
 }
 
+string16 ExtensionInstallPrompt::Prompt::GetPermissionsDetails(
+    size_t index) const {
+  CHECK_LT(index, details_.size());
+  return details_[index];
+}
+
 size_t ExtensionInstallPrompt::Prompt::GetOAuthIssueCount() const {
   return oauth_issue_advice_.size();
 }
@@ -680,19 +704,33 @@
     return;
   }
 
-  Profile* profile = install_ui_->profile();
-  // The token service can be NULL for incognito profiles.
-  TokenService* token_service = TokenServiceFactory::GetForProfile(profile);
-  if (!token_service) {
+  ProfileOAuth2TokenService* token_service =
+      ProfileOAuth2TokenServiceFactory::GetForProfile(install_ui_->profile());
+  if (!token_service || !token_service->RefreshTokenIsAvailable()) {
     ShowConfirmation();
     return;
   }
 
+  // Get an access token from the token service.
+  login_token_request_ = token_service->StartRequest(
+      OAuth2TokenService::ScopeSet(), this);
+}
+
+void ExtensionInstallPrompt::OnGetTokenSuccess(
+    const OAuth2TokenService::Request* request,
+    const std::string& access_token,
+    const base::Time& expiration_time) {
+  DCHECK_EQ(login_token_request_.get(), request);
+  login_token_request_.reset();
+
+  const extensions::OAuth2Info& oauth2_info =
+      extensions::OAuth2Info::GetOAuth2Info(extension_);
+
   token_flow_.reset(new OAuth2MintTokenFlow(
-      profile->GetRequestContext(),
+      install_ui_->profile()->GetRequestContext(),
       this,
       OAuth2MintTokenFlow::Parameters(
-          token_service->GetOAuth2LoginRefreshToken(),
+          access_token,
           extension_->id(),
           oauth2_info.client_id,
           oauth2_info.scopes,
@@ -700,6 +738,14 @@
   token_flow_->Start();
 }
 
+void ExtensionInstallPrompt::OnGetTokenFailure(
+    const OAuth2TokenService::Request* request,
+    const GoogleServiceAuthError& error) {
+  DCHECK_EQ(login_token_request_.get(), request);
+  login_token_request_.reset();
+  ShowConfirmation();
+}
+
 void ExtensionInstallPrompt::OnIssueAdviceSuccess(
     const IssueAdviceInfo& advice_info) {
   prompt_.SetOAuthIssueAdvice(advice_info);
@@ -719,7 +765,10 @@
            extension_))) {
     Manifest::Type extension_type = extension_ ?
         extension_->GetType() : Manifest::TYPE_UNKNOWN;
-    prompt_.SetPermissions(permissions_->GetWarningMessages(extension_type));
+    prompt_.SetPermissions(
+        permissions_->GetWarningMessages(extension_type));
+    prompt_.SetPermissionsDetails(
+        permissions_->GetWarningMessagesDetails(extension_type));
   }
 
   switch (prompt_.type()) {
diff --git a/chrome/browser/extensions/extension_install_prompt.h b/chrome/browser/extensions/extension_install_prompt.h
index 1b6ddbc..6fd0574 100644
--- a/chrome/browser/extensions/extension_install_prompt.h
+++ b/chrome/browser/extensions/extension_install_prompt.h
@@ -14,6 +14,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/extensions/crx_installer_error.h"
+#include "chrome/browser/signin/oauth2_token_service.h"
 #include "extensions/common/url_pattern.h"
 #include "google_apis/gaia/oauth2_mint_token_flow.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -47,6 +48,7 @@
 // Displays all the UI around extension installation.
 class ExtensionInstallPrompt
     : public OAuth2MintTokenFlow::Delegate,
+      public OAuth2TokenService::Consumer,
       public base::SupportsWeakPtr<ExtensionInstallPrompt> {
  public:
   enum PromptType {
@@ -70,7 +72,10 @@
     explicit Prompt(PromptType type);
     ~Prompt();
 
+    // Sets the permission list for this prompt.
     void SetPermissions(const std::vector<string16>& permissions);
+    // Sets the permission list details for this prompt.
+    void SetPermissionsDetails(const std::vector<string16>& details);
     void SetInlineInstallWebstoreData(const std::string& localized_user_count,
                                       double average_rating,
                                       int rating_count);
@@ -91,6 +96,8 @@
     string16 GetPermissionsHeading() const;
     string16 GetOAuthHeading() const;
     string16 GetRetainedFilesHeading() const;
+    string16 GetRetainedFilesHeadingWithCount() const;
+
     bool ShouldShowPermissions() const;
 
     // Getters for webstore metadata. Only populated when the type is
@@ -105,7 +112,9 @@
     string16 GetRatingCount() const;
     string16 GetUserCount() const;
     size_t GetPermissionCount() const;
+    size_t GetPermissionsDetailsCount() const;
     string16 GetPermission(size_t index) const;
+    string16 GetPermissionsDetails(size_t index) const;
     size_t GetOAuthIssueCount() const;
     const IssueAdviceInfoEntry& GetOAuthIssue(size_t index) const;
     size_t GetRetainedFileCount() const;
@@ -139,6 +148,7 @@
     // Permissions that are being requested (may not be all of an extension's
     // permissions if only additional ones are being requested)
     std::vector<string16> permissions_;
+    std::vector<string16> details_;
 
     // Descriptions and details for OAuth2 permissions to display to the user.
     // These correspond to permission scopes.
@@ -345,6 +355,13 @@
   // Starts fetching warnings for OAuth2 scopes, if there are any.
   void FetchOAuthIssueAdviceIfNeeded();
 
+  // OAuth2TokenService::Consumer implementation:
+  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                                 const std::string& access_token,
+                                 const base::Time& expiration_time) OVERRIDE;
+  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                                 const GoogleServiceAuthError& error) OVERRIDE;
+
   // OAuth2MintTokenFlow::Delegate implementation:
   virtual void OnIssueAdviceSuccess(
       const IssueAdviceInfo& issue_advice) OVERRIDE;
@@ -381,6 +398,7 @@
   // A pre-filled prompt.
   Prompt prompt_;
 
+  scoped_ptr<OAuth2TokenService::Request> login_token_request_;
   scoped_ptr<OAuth2MintTokenFlow> token_flow_;
 
   // Used to show the confirm dialog.
diff --git a/chrome/browser/extensions/extension_keybinding_registry.cc b/chrome/browser/extensions/extension_keybinding_registry.cc
index 9cc3cfb..edc6bde 100644
--- a/chrome/browser/extensions/extension_keybinding_registry.cc
+++ b/chrome/browser/extensions/extension_keybinding_registry.cc
@@ -5,12 +5,12 @@
 #include "chrome/browser/extensions/extension_keybinding_registry.h"
 
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/active_tab_permission_granter.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "chrome/common/extensions/extension_set.h"
 
diff --git a/chrome/browser/extensions/extension_loading_browsertest.cc b/chrome/browser/extensions/extension_loading_browsertest.cc
index 098bb65..2cd884d 100644
--- a/chrome/browser/extensions/extension_loading_browsertest.cc
+++ b/chrome/browser/extensions/extension_loading_browsertest.cc
@@ -5,14 +5,12 @@
 // This file contains tests for extension loading, reloading, and
 // unloading behavior.
 
-#include "base/json/json_writer.h"
 #include "base/run_loop.h"
-#include "base/safe_numerics.h"
-#include "base/test/values_test_util.h"
+#include "base/strings/stringprintf.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
-#include "chrome/browser/extensions/extension_creator.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/extensions/test_extension_dir.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -22,69 +20,6 @@
 namespace extensions {
 namespace {
 
-// Provides a temporary directory to build an extension into.  This lets all of
-// an extension's code live inside the test instead of in a separate directory.
-class TestExtensionDir {
- public:
-  TestExtensionDir() {
-    EXPECT_TRUE(dir_.CreateUniqueTempDir());
-    EXPECT_TRUE(crx_dir_.CreateUniqueTempDir());
-  }
-
-  // Writes |contents| to path()/filename, overwriting anything that was already
-  // there.
-  void WriteFile(base::FilePath::StringType filename,
-                 base::StringPiece contents) {
-    EXPECT_EQ(
-        base::checked_numeric_cast<int>(contents.size()),
-        file_util::WriteFile(
-            dir_.path().Append(filename), contents.data(), contents.size()));
-  }
-
-  // Converts |value| to JSON, and then writes it to path()/filename with
-  // WriteFile().
-  void WriteJson(base::FilePath::StringType filename, const Value& value) {
-    std::string json;
-    base::JSONWriter::Write(&value, &json);
-    WriteFile(filename, json);
-  }
-
-  // This function packs the extension into a .crx, and returns the path to that
-  // .crx. Multiple calls to Pack() will produce extensions with the same ID.
-  base::FilePath Pack() {
-    ExtensionCreator creator;
-    base::FilePath crx_path =
-        crx_dir_.path().Append(FILE_PATH_LITERAL("ext.crx"));
-    base::FilePath pem_path =
-        crx_dir_.path().Append(FILE_PATH_LITERAL("ext.pem"));
-    base::FilePath pem_in_path, pem_out_path;
-    if (file_util::PathExists(pem_path))
-      pem_in_path = pem_path;
-    else
-      pem_out_path = pem_path;
-    if (!creator.Run(dir_.path(),
-                     crx_path,
-                     pem_in_path,
-                     pem_out_path,
-                     ExtensionCreator::kOverwriteCRX)) {
-      ADD_FAILURE()
-          << "ExtensionCreator::Run() failed: " << creator.error_message();
-      return base::FilePath();
-    }
-    if (!file_util::PathExists(crx_path)) {
-      ADD_FAILURE() << crx_path.value() << " was not created.";
-      return base::FilePath();
-    }
-    return crx_path;
-  }
-
- private:
-  // Stores files that make up the extension.
-  base::ScopedTempDir dir_;
-  // Stores the generated .crx and .pem.
-  base::ScopedTempDir crx_dir_;
-};
-
 class ExtensionLoadingTest : public ExtensionBrowserTest {
 };
 
@@ -96,21 +31,21 @@
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
 
   TestExtensionDir extension_dir;
-  scoped_ptr<base::Value> manifest =
-      base::test::ParseJson("{"
-                            "  \"name\": \"Overrides New Tab\","
-                            "  \"version\": \"1\","
-                            "  \"description\": \"Overrides New Tab\","
-                            "  \"manifest_version\": 2,"
-                            "  \"background\": {"
-                            "    \"persistent\": false,"
-                            "    \"scripts\": [\"event.js\"]"
-                            "  },"
-                            "  \"chrome_url_overrides\": {"
-                            "    \"newtab\": \"newtab.html\""
-                            "  }"
-                            "}");
-  extension_dir.WriteJson(FILE_PATH_LITERAL("manifest.json"), *manifest);
+  const char* manifest_template =
+      "{"
+      "  \"name\": \"Overrides New Tab\","
+      "  \"version\": \"%d\","
+      "  \"description\": \"Overrides New Tab\","
+      "  \"manifest_version\": 2,"
+      "  \"background\": {"
+      "    \"persistent\": false,"
+      "    \"scripts\": [\"event.js\"]"
+      "  },"
+      "  \"chrome_url_overrides\": {"
+      "    \"newtab\": \"newtab.html\""
+      "  }"
+      "}";
+  extension_dir.WriteManifest(base::StringPrintf(manifest_template, 1));
   extension_dir.WriteFile(FILE_PATH_LITERAL("event.js"), "");
   extension_dir.WriteFile(FILE_PATH_LITERAL("newtab.html"),
                           "<h1>Overridden New Tab Page</h1>");
@@ -132,8 +67,7 @@
                      test_link_from_NTP);
 
   // Increase the extension's version.
-  static_cast<base::DictionaryValue&>(*manifest).SetString("version", "2");
-  extension_dir.WriteJson(FILE_PATH_LITERAL("manifest.json"), *manifest);
+  extension_dir.WriteManifest(base::StringPrintf(manifest_template, 2));
 
   // Upgrade the extension.
   new_tab_extension = UpdateExtension(
diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/extension_messages_apitest.cc
index 2b9d995..4275441 100644
--- a/chrome/browser/extensions/extension_messages_apitest.cc
+++ b/chrome/browser/extensions/extension_messages_apitest.cc
@@ -7,25 +7,25 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/extensions/test_extension_dir.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "url/gurl.h"
 
-using extensions::Extension;
-
+namespace extensions {
 namespace {
 
 class MessageSender : public content::NotificationObserver {
@@ -47,12 +47,10 @@
     return arguments.Pass();
   }
 
-  static scoped_ptr<extensions::Event> BuildEvent(
-      scoped_ptr<base::ListValue> event_args,
-      Profile* profile,
-      GURL event_url) {
-    scoped_ptr<extensions::Event> event(new extensions::Event(
-        "test.onMessage", event_args.Pass()));
+  static scoped_ptr<Event> BuildEvent(scoped_ptr<base::ListValue> event_args,
+                                      Profile* profile,
+                                      GURL event_url) {
+    scoped_ptr<Event> event(new Event("test.onMessage", event_args.Pass()));
     event->restrict_to_profile = profile;
     event->event_url = event_url;
     return event.Pass();
@@ -61,9 +59,8 @@
   virtual void Observe(int type,
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE {
-    extensions::EventRouter* event_router =
-        extensions::ExtensionSystem::Get(
-            content::Source<Profile>(source).ptr())->event_router();
+    EventRouter* event_router = ExtensionSystem::Get(
+        content::Source<Profile>(source).ptr())->event_router();
 
     // Sends four messages to the extension. All but the third message sent
     // from the origin http://b.com/ are supposed to arrive.
@@ -88,8 +85,6 @@
   content::NotificationRegistrar registrar_;
 };
 
-}  // namespace
-
 // Tests that message passing between extensions and content scripts works.
 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Messaging) {
   ASSERT_TRUE(StartEmbeddedTestServer());
@@ -135,7 +130,7 @@
 class ExternallyConnectableMessagingTest : public ExtensionApiTest {
  protected:
   // Result codes from the test. These must match up with |results| in
-  // c/t/d/extensions/api_test/externally_connectable/sites/assertions.json.
+  // c/t/d/extensions/api_test/externally_connectable/assertions.json.
   enum Result {
     OK = 0,
     NAMESPACE_NOT_DEFINED = 1,
@@ -205,33 +200,72 @@
   }
 
   GURL chromium_org_url() {
-    return GetURLForPath("www.chromium.org", "/sites/chromium.org.html");
+    return GetURLForPath("www.chromium.org", "/chromium.org.html");
   }
 
   GURL google_com_url() {
-    return GetURLForPath("www.google.com", "/sites/google.com.html");
+    return GetURLForPath("www.google.com", "/google.com.html");
   }
 
-  scoped_refptr<const Extension> LoadTestExtension(const std::string& name) {
-    return LoadExtension(test_data_dir_.AppendASCII(extension_dir())
-                                       .AppendASCII(name));
+  const Extension* LoadChromiumConnectableExtension() {
+    web_connectable_dir_.WriteManifest(base::StringPrintf(
+        "{"
+        "  \"name\": \"chromium_connectable\","
+        "  %s,"
+        "  \"externally_connectable\": {"
+        "    \"matches\": [\"*://*.chromium.org:*/*\"]"
+        "  }"
+        "}",
+        common_manifest()));
+    WriteBackgroundHtml(&web_connectable_dir_);
+    return LoadExtension(web_connectable_dir_.unpacked_path());
+  }
+
+  scoped_refptr<const Extension> LoadNotConnectableExtension() {
+    not_connectable_dir_.WriteManifest(base::StringPrintf(
+        "{"
+        "  \"name\": \"not_connectable\","
+        "  %s"
+        "}",
+        common_manifest()));
+    WriteBackgroundHtml(&not_connectable_dir_);
+    return LoadExtension(not_connectable_dir_.unpacked_path());
   }
 
   void InitializeTestServer() {
     base::FilePath test_data;
-    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data));
-    embedded_test_server()->ServeFilesFromDirectory(
-        test_data.AppendASCII("extensions/api_test")
-                 .AppendASCII(extension_dir()));
+    EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data));
+    embedded_test_server()->ServeFilesFromDirectory(test_data.AppendASCII(
+        "extensions/api_test/messaging/externally_connectable/sites"));
     ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-
     host_resolver()->AddRule("*", embedded_test_server()->base_url().host());
   }
 
  private:
-  const char* extension_dir() {
-    return "messaging/externally_connectable";
+  void WriteBackgroundHtml(TestExtensionDir* extension_dir) {
+    extension_dir->WriteFile(FILE_PATH_LITERAL("background.js"),
+        "chrome.runtime.onMessageExternal.addListener(\n"
+        "    function(message, sender, reply) {\n"
+        "  reply({ message: message, sender: sender });\n"
+        "});\n"
+        "chrome.runtime.onConnectExternal.addListener(function(port) {\n"
+        "  port.onMessage.addListener(function(message) {\n"
+        "    port.postMessage({ message: message, sender: port.sender });\n"
+        "  });\n"
+        "});\n");
   }
+
+  const char* common_manifest() {
+    return "\"version\": \"1.0\","
+           "\"background\": {"
+           "    \"scripts\": [\"background.js\"],"
+           "    \"persistent\": false"
+           "},"
+           "\"manifest_version\": 2";
+  }
+
+  TestExtensionDir web_connectable_dir_;
+  TestExtensionDir not_connectable_dir_;
 };
 
 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, NotInstalled) {
@@ -255,25 +289,25 @@
 
   // Install the web connectable extension. chromium.org can connect to it,
   // google.com can't.
-  scoped_refptr<const Extension> web_connectable =
-      LoadTestExtension("web_connectable");
+  const Extension* chromium_connectable = LoadChromiumConnectableExtension();
+  ASSERT_TRUE(chromium_connectable);
 
   ui_test_utils::NavigateToURL(browser(), chromium_org_url());
-  EXPECT_EQ(OK, CanConnectAndSendMessages(web_connectable->id()));
+  EXPECT_EQ(OK, CanConnectAndSendMessages(chromium_connectable->id()));
   EXPECT_FALSE(AreAnyNonWebApisDefined());
 
   ui_test_utils::NavigateToURL(browser(), google_com_url());
   EXPECT_EQ(NAMESPACE_NOT_DEFINED,
-            CanConnectAndSendMessages(web_connectable->id()));
+            CanConnectAndSendMessages(chromium_connectable->id()));
   EXPECT_FALSE(AreAnyNonWebApisDefined());
 
   // Install the non-connectable extension. Nothing can connect to it.
-  scoped_refptr<const Extension> not_connectable =
-      LoadTestExtension("not_connectable");
+  const Extension* not_connectable = LoadNotConnectableExtension();
+  ASSERT_TRUE(not_connectable);
 
   ui_test_utils::NavigateToURL(browser(), chromium_org_url());
-  // Namespace will be defined here because |web_connectable| can connect to
-  // it - so this will be the "cannot establish connection" error.
+  // Namespace will be defined here because |chromium_connectable| can connect
+  // to it - so this will be the "cannot establish connection" error.
   EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
             CanConnectAndSendMessages(not_connectable->id()));
   EXPECT_FALSE(AreAnyNonWebApisDefined());
@@ -293,24 +327,27 @@
                        EnablingAndDisabling) {
   InitializeTestServer();
 
-  scoped_refptr<const Extension> web_connectable =
-      LoadTestExtension("web_connectable");
-  scoped_refptr<const Extension> not_connectable =
-      LoadTestExtension("not_connectable");
+  const Extension* chromium_connectable = LoadChromiumConnectableExtension();
+  ASSERT_TRUE(chromium_connectable);
+  const Extension* not_connectable = LoadNotConnectableExtension();
+  ASSERT_TRUE(not_connectable);
 
   ui_test_utils::NavigateToURL(browser(), chromium_org_url());
-  EXPECT_EQ(OK, CanConnectAndSendMessages(web_connectable->id()));
+  EXPECT_EQ(OK, CanConnectAndSendMessages(chromium_connectable->id()));
   EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
             CanConnectAndSendMessages(not_connectable->id()));
 
   // Unloading the extension is the same as it never existing - so the bindings
   // will no longer exist.
-  DisableExtension(web_connectable->id());
+  DisableExtension(chromium_connectable->id());
   EXPECT_EQ(NAMESPACE_NOT_DEFINED,
-            CanConnectAndSendMessages(web_connectable->id()));
+            CanConnectAndSendMessages(chromium_connectable->id()));
 
-  EnableExtension(web_connectable->id());
-  EXPECT_EQ(OK, CanConnectAndSendMessages(web_connectable->id()));
+  EnableExtension(chromium_connectable->id());
+  EXPECT_EQ(OK, CanConnectAndSendMessages(chromium_connectable->id()));
   EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
             CanConnectAndSendMessages(not_connectable->id()));
 }
+
+}  // namespace
+}  // namespace extensions
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index 5dea347..ab300ff 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -10,6 +10,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/value_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/admin_policy.h"
 #include "chrome/browser/extensions/api/content_settings/content_settings_store.h"
 #include "chrome/browser/extensions/api/preference/preference_api.h"
@@ -19,7 +20,6 @@
 #include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/host_desktop.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/feature_switch.h"
 #include "chrome/common/extensions/manifest.h"
@@ -1681,7 +1681,7 @@
 }
 
 // static
-void ExtensionPrefs::RegisterUserPrefs(
+void ExtensionPrefs::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterDictionaryPref(
       kExtensionsPref, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h
index d721375..354420e 100644
--- a/chrome/browser/extensions/extension_prefs.h
+++ b/chrome/browser/extensions/extension_prefs.h
@@ -462,7 +462,7 @@
   // found.
   base::Time GetInstallTime(const std::string& extension_id) const;
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   bool extensions_disabled() { return extensions_disabled_; }
 
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index 7346c25..b18b2af 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/runtime/runtime_api.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_info_map.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/extensions/extension.h"
diff --git a/chrome/browser/extensions/extension_protocols.cc b/chrome/browser/extensions/extension_protocols.cc
index f8c97df..5bb7a98 100644
--- a/chrome/browser/extensions/extension_protocols.cc
+++ b/chrome/browser/extensions/extension_protocols.cc
@@ -38,7 +38,6 @@
 #include "content/public/browser/resource_request_info.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension_resource.h"
-#include "googleurl/src/url_util.h"
 #include "grit/component_extension_resources_map.h"
 #include "net/base/mime_util.h"
 #include "net/base/net_errors.h"
@@ -48,6 +47,7 @@
 #include "net/url_request/url_request_file_job.h"
 #include "net/url_request/url_request_simple_job.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "url/url_util.h"
 
 using content::ResourceRequestInfo;
 using extensions::Extension;
@@ -101,7 +101,7 @@
 
 void GetLastModifiedTime(const base::FilePath& filename,
                          base::Time* last_modified_time) {
-  if (file_util::PathExists(filename)) {
+  if (base::PathExists(filename)) {
     base::PlatformFileInfo info;
     if (file_util::GetFileInfo(filename, &info))
       *last_modified_time = info.last_modified;
diff --git a/chrome/browser/extensions/extension_renderer_state.cc b/chrome/browser/extensions/extension_renderer_state.cc
index 551d895..2075d30 100644
--- a/chrome/browser/extensions/extension_renderer_state.cc
+++ b/chrome/browser/extensions/extension_renderer_state.cc
@@ -6,9 +6,9 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/browser/tab_contents/retargeting_details.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/notification_observer.h"
diff --git a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
index ffd5d37..05e3588 100644
--- a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
+++ b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
@@ -10,8 +10,8 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "net/dns/mock_host_resolver.h"
+#include "url/gurl.h"
 
 class ExtensionResourceRequestPolicyTest : public ExtensionApiTest {
  protected:
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 2458305..73a7c63 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -28,6 +28,7 @@
 #include "base/version.h"
 #include "chrome/browser/app_mode/app_mode_utils.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/api/app_runtime/app_runtime_api.h"
 #include "chrome/browser/extensions/api/declarative/rules_registry_service.h"
@@ -71,7 +72,6 @@
 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h"
 #include "chrome/browser/ui/webui/theme_source.h"
 #include "chrome/common/child_process_logging.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/extensions/background_info.h"
@@ -103,19 +103,19 @@
 #include "content/public/browser/url_data_source.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/error_utils.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "sync/api/sync_change.h"
 #include "sync/api/sync_error_factory.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/gurl.h"
 #include "webkit/browser/database/database_tracker.h"
 #include "webkit/browser/database/database_util.h"
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/extensions/install_limiter.h"
+#include "webkit/browser/fileapi/file_system_backend.h"
 #include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/browser/fileapi/file_system_mount_point_provider.h"
 #endif
 
 using content::BrowserContext;
@@ -464,6 +464,11 @@
   }
 }
 
+void ExtensionService::SetSyncStartFlare(
+    const syncer::SyncableService::StartSyncFlare& flare) {
+  flare_ = flare;
+}
+
 void ExtensionService::InitEventRouters() {
   if (event_routers_initialized_)
     return;
@@ -692,10 +697,10 @@
         manager->GetBackgroundHostForExtension(extension_id);
     if (host && DevToolsAgentHost::HasFor(host->render_view_host())) {
       // Look for an open inspector for the background page.
-      std::string devtools_cookie = DevToolsAgentHost::DisconnectRenderViewHost(
-          host->render_view_host());
-      if (devtools_cookie != std::string())
-        orphaned_dev_tools_[extension_id] = devtools_cookie;
+      scoped_refptr<DevToolsAgentHost> agent_host =
+          DevToolsAgentHost::GetOrCreateFor(host->render_view_host());
+      agent_host->DisconnectRenderViewHost();
+      orphaned_dev_tools_[extension_id] = agent_host;
     }
 
     path = current_extension->path();
@@ -764,12 +769,21 @@
 
   // Extract the data we need for sync now, but don't actually sync until we've
   // completed the uninstallation.
+  // TODO(tim): If we get here and IsSyncing is false, this will cause
+  // "back from the dead" style bugs, because sync will add-back the extension
+  // that was uninstalled here when MergeDataAndStartSyncing is called.
+  // See crbug.com/256795.
   syncer::SyncChange sync_change;
-  if (app_sync_bundle_.HandlesApp(*extension.get())) {
-    sync_change = app_sync_bundle_.CreateSyncChangeToDelete(extension.get());
-  } else if (extension_sync_bundle_.HandlesExtension(*extension.get())) {
-    sync_change =
-        extension_sync_bundle_.CreateSyncChangeToDelete(extension.get());
+  if (extensions::sync_helper::IsSyncableApp(extension.get())) {
+    if (app_sync_bundle_.IsSyncing())
+      sync_change = app_sync_bundle_.CreateSyncChangeToDelete(extension.get());
+    else if (is_ready() && !flare_.is_null())
+      flare_.Run(syncer::APPS);  // Tell sync to start ASAP.
+  } else if (extensions::sync_helper::IsSyncableExtension(extension.get())) {
+    if (extension_sync_bundle_.IsSyncing())
+      sync_change = extension_sync_bundle_.CreateSyncChangeToDelete(extension);
+    else if (is_ready() && !flare_.is_null())
+      flare_.Run(syncer::EXTENSIONS);  // Tell sync to start ASAP.
   }
 
   if (IsUnacknowledgedExternalExtension(extension.get())) {
@@ -957,7 +971,8 @@
   SyncExtensionChangeIfNeeded(*extension);
 }
 
-void ExtensionService::DisableUserExtensions() {
+void ExtensionService::DisableUserExtensions(
+    const std::vector<std::string>& except_ids) {
   extensions::ManagementPolicy* management_policy =
       system_->management_policy();
   extensions::ExtensionList to_disable;
@@ -975,8 +990,9 @@
 
   for (extensions::ExtensionList::const_iterator extension = to_disable.begin();
       extension != to_disable.end(); ++extension) {
-    DisableExtension((*extension)->id(),
-                     extensions::Extension::DISABLE_USER_ACTION);
+    const std::string& id = (*extension)->id();
+    if (except_ids.end() == std::find(except_ids.begin(), except_ids.end(), id))
+      DisableExtension(id, extensions::Extension::DISABLE_USER_ACTION);
   }
 }
 
@@ -1135,8 +1151,8 @@
   fileapi::FileSystemContext* filesystem_context =
       BrowserContext::GetStoragePartitionForSite(profile_, site)->
           GetFileSystemContext();
-  if (filesystem_context && filesystem_context->external_provider()) {
-    filesystem_context->external_provider()->
+  if (filesystem_context && filesystem_context->external_backend()) {
+    filesystem_context->external_backend()->
         RevokeAccessForExtension(extension->id());
   }
 #endif
@@ -1512,6 +1528,8 @@
   // work in incognito mode.
   if (extension && extension->location() == Manifest::COMPONENT)
     return true;
+  if (extension && extension->force_incognito_enabled())
+    return true;
 
   // Check the prefs.
   return extension_prefs_->IsIncognitoEnabled(extension_id);
@@ -1943,10 +1961,16 @@
 }
 
 void ExtensionService::SyncExtensionChangeIfNeeded(const Extension& extension) {
-  if (app_sync_bundle_.HandlesApp(extension)) {
-    app_sync_bundle_.SyncChangeIfNeeded(extension);
-  } else if (extension_sync_bundle_.HandlesExtension(extension)) {
-    extension_sync_bundle_.SyncChangeIfNeeded(extension);
+  if (extensions::sync_helper::IsSyncableApp(&extension)) {
+    if (app_sync_bundle_.IsSyncing())
+      app_sync_bundle_.SyncChangeIfNeeded(extension);
+    else if (is_ready() && !flare_.is_null())
+      flare_.Run(syncer::APPS);
+  } else if (extensions::sync_helper::IsSyncableExtension(&extension)) {
+    if (extension_sync_bundle_.IsSyncing())
+      extension_sync_bundle_.SyncChangeIfNeeded(extension);
+    else if (is_ready() && !flare_.is_null())
+      flare_.Run(syncer::EXTENSIONS);
   }
 }
 
@@ -2153,7 +2177,7 @@
     // upgraded and recognized additional privileges, or an extension upgrades
     // to a version that requires additional privileges.
     is_privilege_increase = granted_permissions->HasLessPrivilegesThan(
-        extension->GetActivePermissions().get());
+        extension->GetActivePermissions().get(), extension->GetType());
   }
 
   if (is_extension_upgrade) {
@@ -2673,8 +2697,7 @@
   if (iter == orphaned_dev_tools_.end())
     return;
 
-  DevToolsAgentHost::ConnectRenderViewHost(iter->second,
-                                           host->render_view_host());
+  iter->second->ConnectRenderViewHost(host->render_view_host());
   orphaned_dev_tools_.erase(iter);
 }
 
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 8d0c6c3..4ff3178 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -35,6 +35,7 @@
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/extension_set.h"
 #include "chrome/common/extensions/manifest.h"
+#include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "extensions/common/one_shot_event.h"
@@ -350,8 +351,9 @@
   virtual void DisableExtension(const std::string& extension_id,
       extensions::Extension::DisableReason disable_reason);
 
-  // Disable non-builtin and non-managed extensions.
-  void DisableUserExtensions();
+  // Disable non-builtin and non-managed extensions with ids not in
+  // |except_ids|.
+  void DisableUserExtensions(const std::vector<std::string>& except_ids);
 
   // Updates the |extension|'s granted permissions lists to include all
   // permissions in the |extension|'s manifest and re-enables the
@@ -682,6 +684,10 @@
   void AddUpdateObserver(extensions::UpdateObserver* observer);
   void RemoveUpdateObserver(extensions::UpdateObserver* observer);
 
+  // |flare| provides a StartSyncFlare to the SyncableService. See
+  // sync_start_util for more.
+  void SetSyncStartFlare(const syncer::SyncableService::StartSyncFlare& flare);
+
  private:
   // Contains Extension data that can change during the life of the process,
   // but does not persist across restarts.
@@ -868,9 +874,10 @@
   // Store the ids of reloading extensions.
   std::set<std::string> reloading_extensions_;
 
-  // Map of inspector cookies that are detached, waiting for an extension to be
-  // reloaded.
-  typedef std::map<std::string, std::string> OrphanedDevTools;
+  // Map of DevToolsAgentHost instances that are detached,
+  // waiting for an extension to be reloaded.
+  typedef std::map<std::string, scoped_refptr<content::DevToolsAgentHost> >
+      OrphanedDevTools;
   OrphanedDevTools orphaned_dev_tools_;
 
   content::NotificationRegistrar registrar_;
@@ -937,6 +944,11 @@
 
   ObserverList<extensions::UpdateObserver, true> update_observers_;
 
+  // Run()ning tells sync to try and start soon, because syncable changes
+  // have started happening. It will cause sync to call us back
+  // asynchronously via MergeDataAndStartSyncing as soon as possible.
+  syncer::SyncableService::StartSyncFlare flare_;
+
   FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
                            InstallAppsWithUnlimtedStorage);
   FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 9297723..8811e48 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -29,6 +29,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/version.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/app_sync_data.h"
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/extensions/crx_installer.h"
@@ -60,7 +61,6 @@
 #include "chrome/browser/prefs/pref_service_syncable.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
@@ -82,13 +82,14 @@
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/plugin_service.h"
+#include "content/public/browser/render_process_host.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/common/content_constants.h"
 #include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_utils.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension_resource.h"
 #include "extensions/common/url_pattern.h"
-#include "googleurl/src/gurl.h"
 #include "gpu/config/gpu_info.h"
 #include "grit/browser_resources.h"
 #include "net/cookies/canonical_cookie.h"
@@ -99,11 +100,13 @@
 #include "sync/api/string_ordinal.h"
 #include "sync/api/sync_error_factory.h"
 #include "sync/api/sync_error_factory_mock.h"
+#include "sync/api/syncable_service.h"
 #include "sync/protocol/app_specifics.pb.h"
 #include "sync/protocol/extension_specifics.pb.h"
 #include "sync/protocol/sync.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
+#include "url/gurl.h"
 #include "webkit/browser/database/database_tracker.h"
 #include "webkit/browser/quota/quota_manager.h"
 #include "webkit/common/database/database_identifier.h"
@@ -195,6 +198,11 @@
   return temp_file;
 }
 
+
+bool WaitForCountNotificationsCallback(int *count) {
+  return --(*count) == 0;
+}
+
 }  // namespace
 
 class MockExtensionProvider : public extensions::ExternalProviderInterface {
@@ -464,7 +472,7 @@
   scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
       new user_prefs::PrefRegistrySyncable);
   scoped_ptr<PrefServiceSyncable> prefs(builder.CreateSyncable(registry.get()));
-  chrome::RegisterUserPrefs(registry.get());
+  chrome::RegisterUserProfilePrefs(registry.get());
   profile_builder.SetPrefService(prefs.Pass());
   profile_builder.SetPath(params.profile_path);
   profile_ = profile_builder.Build();
@@ -510,14 +518,14 @@
   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
   base::FilePath path = temp_dir_.path();
   path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
-  base::Delete(path, true);
+  base::DeleteFile(path, true);
   file_util::CreateDirectory(path);
   base::FilePath temp_prefs = path.Append(FILE_PATH_LITERAL("Preferences"));
-  file_util::CopyFile(prefs_file, temp_prefs);
+  base::CopyFile(prefs_file, temp_prefs);
 
   extensions_install_dir_ = path.Append(FILE_PATH_LITERAL("Extensions"));
-  base::Delete(extensions_install_dir_, true);
-  file_util::CopyDirectory(source_install_dir, extensions_install_dir_, true);
+  base::DeleteFile(extensions_install_dir_, true);
+  base::CopyDirectory(source_install_dir, extensions_install_dir_, true);
 
   ExtensionServiceInitParams params;
   params.profile_path = path;
@@ -546,12 +554,12 @@
   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
   base::FilePath path = temp_dir_.path();
   path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
-  base::Delete(path, true);
+  base::DeleteFile(path, true);
   file_util::CreateDirectory(path);
   base::FilePath prefs_filename =
       path.Append(FILE_PATH_LITERAL("TestPreferences"));
   extensions_install_dir_ = path.Append(FILE_PATH_LITERAL("Extensions"));
-  base::Delete(extensions_install_dir_, true);
+  base::DeleteFile(extensions_install_dir_, true);
   file_util::CreateDirectory(extensions_install_dir_);
 
   ExtensionServiceInitParams params;
@@ -577,6 +585,11 @@
 
 void ExtensionServiceTestBase::SetUp() {
   ExtensionErrorReporter::GetInstance()->ClearErrors();
+  content::RenderProcessHost::SetRunRendererInProcess(true);
+}
+
+void ExtensionServiceTestBase::TearDown() {
+  content::RenderProcessHost::SetRunRendererInProcess(false);
 }
 
 class ExtensionServiceTest
@@ -643,6 +656,13 @@
     service_->AddProviderForTesting(provider);
   }
 
+  void MockSyncStartFlare(bool* was_called,
+                          syncer::ModelType* model_type_passed_in,
+                          syncer::ModelType model_type) {
+    *was_called = true;
+    *model_type_passed_in = model_type;
+  }
+
  protected:
   void TestExternalProvider(MockExtensionProvider* provider,
                             Manifest::Location location);
@@ -655,10 +675,10 @@
     if (pem_path.value().empty()) {
       pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
     } else {
-      ASSERT_TRUE(file_util::PathExists(pem_path));
+      ASSERT_TRUE(base::PathExists(pem_path));
     }
 
-    ASSERT_TRUE(base::Delete(crx_path, false));
+    ASSERT_TRUE(base::DeleteFile(crx_path, false));
 
     scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
     ASSERT_TRUE(creator->Run(dir_path,
@@ -667,7 +687,7 @@
                              pem_output_path,
                              ExtensionCreator::kOverwriteCRX));
 
-    ASSERT_TRUE(file_util::PathExists(crx_path));
+    ASSERT_TRUE(base::PathExists(crx_path));
   }
 
   // Create a CrxInstaller and start installation. To allow the install
@@ -679,13 +699,18 @@
   }
 
   void StartCRXInstall(const base::FilePath& crx_path, int creation_flags) {
-    ASSERT_TRUE(file_util::PathExists(crx_path))
+    ASSERT_TRUE(base::PathExists(crx_path))
         << "Path does not exist: "<< crx_path.value().c_str();
     scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL));
     installer->set_creation_flags(creation_flags);
     if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT)) {
       installer->set_allow_silent_install(true);
     }
+
+    content::WindowedNotificationObserver windowed_observer(
+        chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+        content::Source<extensions::CrxInstaller>(installer));
+
     installer->InstallCrx(crx_path);
   }
 
@@ -759,7 +784,7 @@
   const Extension* InstallCRXWithLocation(const base::FilePath& crx_path,
                                           Manifest::Location install_location,
                                           InstallState install_state) {
-    EXPECT_TRUE(file_util::PathExists(crx_path))
+    EXPECT_TRUE(base::PathExists(crx_path))
         << "Path does not exist: "<< crx_path.value().c_str();
     // no client (silent install)
     scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL));
@@ -786,7 +811,10 @@
   const Extension* WaitForCrxInstall(const base::FilePath& path,
                                      InstallState install_state,
                                      const std::string& expected_old_name) {
-    loop_.RunUntilIdle();
+    content::WindowedNotificationObserver(
+        chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+        content::NotificationService::AllSources()).Wait();
+
     std::vector<string16> errors = GetErrors();
     const Extension* extension = NULL;
     if (install_state != INSTALL_FAILED) {
@@ -858,13 +886,13 @@
 
   void UpdateExtension(const std::string& id, const base::FilePath& in_path,
                        UpdateState expected_state) {
-    ASSERT_TRUE(file_util::PathExists(in_path));
+    ASSERT_TRUE(base::PathExists(in_path));
 
     // We need to copy this to a temporary location because Update() will delete
     // it.
     base::FilePath path = temp_dir_.path();
     path = path.Append(in_path.BaseName());
-    ASSERT_TRUE(file_util::CopyFile(in_path, path));
+    ASSERT_TRUE(base::CopyFile(in_path, path));
 
     int previous_enabled_extension_count =
         service_->extensions()->size();
@@ -872,8 +900,16 @@
         previous_enabled_extension_count +
         service_->disabled_extensions()->size();
 
-    service_->UpdateExtension(id, path, GURL(), NULL);
-    loop_.RunUntilIdle();
+    extensions::CrxInstaller* installer = NULL;
+    service_->UpdateExtension(id, path, GURL(), &installer);
+
+    if (installer) {
+      content::WindowedNotificationObserver(
+          chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+          content::Source<extensions::CrxInstaller>(installer)).Wait();
+    } else {
+      loop_.RunUntilIdle();
+    }
 
     std::vector<string16> errors = GetErrors();
     int error_count = errors.size();
@@ -902,7 +938,7 @@
     }
 
     // Update() should the temporary input file.
-    EXPECT_FALSE(file_util::PathExists(path));
+    EXPECT_FALSE(base::PathExists(path));
   }
 
   void TerminateExtension(const std::string& id) {
@@ -927,7 +963,7 @@
   void UninstallExtension(const std::string& id, bool use_helper) {
     // Verify that the extension is installed.
     base::FilePath extension_path = extensions_install_dir_.AppendASCII(id);
-    EXPECT_TRUE(file_util::PathExists(extension_path));
+    EXPECT_TRUE(base::PathExists(extension_path));
     size_t pref_key_count = GetPrefKeyCount();
     EXPECT_GT(pref_key_count, 0u);
     ValidateIntegerPref(id, "state", Extension::ENABLED);
@@ -958,7 +994,7 @@
     loop_.RunUntilIdle();
 
     // The directory should be gone.
-    EXPECT_FALSE(file_util::PathExists(extension_path));
+    EXPECT_FALSE(base::PathExists(extension_path));
   }
 
   void ValidatePrefKeyCount(size_t count) {
@@ -1169,7 +1205,7 @@
   base::MessageLoop::current()->Quit();
   EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
   EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
-  ASSERT_TRUE(file_util::PathExists(private_key_path));
+  ASSERT_TRUE(base::PathExists(private_key_path));
 }
 
 // The tests are designed so that we never expect to see a packing error.
@@ -1374,7 +1410,7 @@
   // And extension1 dir should now be toast.
   base::FilePath extension_dir = extensions_install_dir_
       .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
-  ASSERT_FALSE(file_util::PathExists(extension_dir));
+  ASSERT_FALSE(base::PathExists(extension_dir));
 }
 
 // Test that GarbageCollectExtensions deletes the right versions of an
@@ -1393,7 +1429,7 @@
 
   // This is the directory that is going to be deleted, so make sure it actually
   // is there before the garbage collection.
-  ASSERT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  ASSERT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
       "hpiknbiabeeppbpihjehijgoemciehgk/3")));
 
   service_->GarbageCollectExtensions();
@@ -1402,13 +1438,13 @@
 
   // Verify that the pending update for the first extension didn't get
   // deleted.
-  EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
       "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
-  EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
       "bjafgdebaacbbbecmhlhpofkepfkgcpa/2.0")));
-  EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
       "hpiknbiabeeppbpihjehijgoemciehgk/2")));
-  EXPECT_FALSE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
       "hpiknbiabeeppbpihjehijgoemciehgk/3")));
 }
 
@@ -1427,7 +1463,7 @@
 
   // This is the directory that is going to be deleted, so make sure it actually
   // is there before the garbage collection.
-  ASSERT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  ASSERT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
       "hpiknbiabeeppbpihjehijgoemciehgk/3")));
 
   service_->Init();
@@ -1439,13 +1475,13 @@
   loop_.RunUntilIdle();
 
   // Verify that the pending update for the first extension got installed.
-  EXPECT_FALSE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
       "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
-  EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
       "bjafgdebaacbbbecmhlhpofkepfkgcpa/2.0")));
-  EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
       "hpiknbiabeeppbpihjehijgoemciehgk/2")));
-  EXPECT_FALSE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
       "hpiknbiabeeppbpihjehijgoemciehgk/3")));
 
   // Make sure update information got deleted.
@@ -1476,9 +1512,9 @@
 
   // These extensions are used by the extensions we test below, they must be
   // installed.
-  EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
       "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
-  EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
       "hpiknbiabeeppbpihjehijgoemciehgk/2")));
 
   // Each of these extensions should have been rejected because of dependencies
@@ -1503,7 +1539,7 @@
   EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
       prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
 
-  EXPECT_FALSE(file_util::PathExists(extensions_install_dir_.AppendASCII(
+  EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
       "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
 
   EXPECT_TRUE(service_->pending_extension_manager()->HasPendingExtensions());
@@ -1584,14 +1620,17 @@
 
   // Register and install an external extension.
   Version version("1.0.0.0");
-  service_->OnExternalExtensionFileFound(
-      good_crx,
-      &version,
-      path,
-      Manifest::EXTERNAL_PREF,
-      Extension::FROM_BOOKMARK,
-      false /* mark_acknowledged */);
-  loop_.RunUntilIdle();
+  if (service_->OnExternalExtensionFileFound(
+          good_crx,
+          &version,
+          path,
+          Manifest::EXTERNAL_PREF,
+          Extension::FROM_BOOKMARK,
+          false /* mark_acknowledged */)) {
+    content::WindowedNotificationObserver(
+        chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+        content::NotificationService::AllSources()).Wait();
+  }
 
   const Extension* extension = service_->GetExtensionById(good_crx, false);
   ASSERT_TRUE(extension);
@@ -1616,10 +1655,14 @@
 
   Version version("1.0.0.0");
   // Install an external extension.
-  service_->OnExternalExtensionFileFound(good_crx, &version,
-                                         path, Manifest::EXTERNAL_PREF,
-                                         Extension::NO_FLAGS, false);
-  loop_.RunUntilIdle();
+  if (service_->OnExternalExtensionFileFound(good_crx, &version,
+                                             path, Manifest::EXTERNAL_PREF,
+                                             Extension::NO_FLAGS, false)) {
+    content::WindowedNotificationObserver(
+        chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+        content::NotificationService::AllSources()).Wait();
+  }
+
   ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
 
   // Uninstall it and check that its killbit gets set.
@@ -1702,14 +1745,19 @@
       wrong_id, &version, path, Manifest::EXTERNAL_PREF,
       Extension::NO_FLAGS, false);
 
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
   ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
 
   // Try again with the right ID. Expect success.
-  service_->OnExternalExtensionFileFound(
-      correct_id, &version, path, Manifest::EXTERNAL_PREF,
-      Extension::NO_FLAGS, false);
-  loop_.RunUntilIdle();
+  if (service_->OnExternalExtensionFileFound(
+          correct_id, &version, path, Manifest::EXTERNAL_PREF,
+          Extension::NO_FLAGS, false)) {
+    content::WindowedNotificationObserver(
+        chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+        content::NotificationService::AllSources()).Wait();
+  }
   ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
 }
 
@@ -1726,16 +1774,21 @@
       good_crx, &wrong_version, path, Manifest::EXTERNAL_PREF,
       Extension::NO_FLAGS, false);
 
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
   ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
 
   // Try again with the right version. Expect success.
   service_->pending_extension_manager()->Remove(good_crx);
   Version correct_version("1.0.0.0");
-  service_->OnExternalExtensionFileFound(
-      good_crx, &correct_version, path, Manifest::EXTERNAL_PREF,
-      Extension::NO_FLAGS, false);
-  loop_.RunUntilIdle();
+  if (service_->OnExternalExtensionFileFound(
+          good_crx, &correct_version, path, Manifest::EXTERNAL_PREF,
+          Extension::NO_FLAGS, false)) {
+    content::WindowedNotificationObserver(
+        chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+        content::NotificationService::AllSources()).Wait();
+  }
   ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
 }
 
@@ -1748,7 +1801,7 @@
   base::FilePath path = data_dir_
              .AppendASCII("user_script_basic.user.js");
 
-  ASSERT_TRUE(file_util::PathExists(path));
+  ASSERT_TRUE(base::PathExists(path));
   scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL));
   installer->set_allow_silent_install(true);
   installer->InstallUserScript(
@@ -1798,8 +1851,8 @@
   base::FilePath pem_path = path.AppendASCII("unknown.pem");
   path = path.AppendASCII("unknown");
 
-  ASSERT_TRUE(file_util::PathExists(pem_path));
-  ASSERT_TRUE(file_util::PathExists(path));
+  ASSERT_TRUE(base::PathExists(pem_path));
+  ASSERT_TRUE(base::PathExists(path));
 
   ExtensionPrefs* prefs = service_->extension_prefs();
 
@@ -1847,8 +1900,8 @@
   base::FilePath pem_path = path.AppendASCII("unknown.pem");
   path = path.AppendASCII("unknown");
 
-  ASSERT_TRUE(file_util::PathExists(pem_path));
-  ASSERT_TRUE(file_util::PathExists(path));
+  ASSERT_TRUE(base::PathExists(pem_path));
+  ASSERT_TRUE(base::PathExists(path));
 
   ExtensionPrefs* prefs = service_->extension_prefs();
 
@@ -1894,7 +1947,7 @@
       .AppendASCII(good1)
       .AppendASCII("2");
 
-  ASSERT_TRUE(file_util::PathExists(path));
+  ASSERT_TRUE(base::PathExists(path));
   const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
   EXPECT_EQ(0u, GetErrors().size());
   EXPECT_EQ(1u, service_->extensions()->size());
@@ -1922,7 +1975,7 @@
       .AppendASCII("permissions")
       .AppendASCII("unknown");
 
-  ASSERT_TRUE(file_util::PathExists(path));
+  ASSERT_TRUE(base::PathExists(path));
 
   const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
 
@@ -2033,12 +2086,12 @@
   scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
   ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
       privkey_path, ExtensionCreator::kNoRunFlags));
-  ASSERT_TRUE(file_util::PathExists(crx_path));
-  ASSERT_TRUE(file_util::PathExists(privkey_path));
+  ASSERT_TRUE(base::PathExists(crx_path));
+  ASSERT_TRUE(base::PathExists(privkey_path));
 
   // Repeat the run with the pem file gone, and no special flags
   // Should refuse to overwrite the existing crx.
-  base::Delete(privkey_path, false);
+  base::DeleteFile(privkey_path, false);
   ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
       privkey_path, ExtensionCreator::kNoRunFlags));
 
@@ -2051,7 +2104,7 @@
   ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
       privkey_path, ExtensionCreator::kOverwriteCRX));
 
-  ASSERT_TRUE(file_util::PathExists(privkey_path));
+  ASSERT_TRUE(base::PathExists(privkey_path));
   InstallCRX(crx_path, INSTALL_NEW);
 
   // Try packing with invalid paths.
@@ -2117,7 +2170,7 @@
 
     // Copy the extension into the output directory, as PackExtensionJob doesn't
     // let us choose where to output the packed extension.
-    ASSERT_TRUE(file_util::CopyDirectory(input_directory, output_dir, true));
+    ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
 
     base::FilePath expected_crx_path =
         temp_dir.path().Append(expected_crx_names[i]);
@@ -2151,7 +2204,7 @@
   base::ScopedTempDir extension_temp_dir;
   ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
   base::FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
-  ASSERT_TRUE(file_util::CopyDirectory(
+  ASSERT_TRUE(base::CopyDirectory(
       data_dir_
       .AppendASCII("good")
       .AppendASCII("Extensions")
@@ -2172,10 +2225,10 @@
   ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
       privkey_path, ExtensionCreator::kNoRunFlags))
       << creator->error_message();
-  ASSERT_TRUE(file_util::PathExists(crx_path));
-  ASSERT_TRUE(file_util::PathExists(privkey_path));
+  ASSERT_TRUE(base::PathExists(crx_path));
+  ASSERT_TRUE(base::PathExists(privkey_path));
 
-  base::Delete(crx_path, false);
+  base::DeleteFile(crx_path, false);
   // Move the pem file into the extension.
   base::Move(privkey_path,
                   input_directory.AppendASCII("privkey.pem"));
@@ -2203,7 +2256,7 @@
       .AppendASCII("1.0.0.0");
   base::FilePath privkey_path(data_dir_.AppendASCII(
       "openssl_privkey_asn1.pem"));
-  ASSERT_TRUE(file_util::PathExists(privkey_path));
+  ASSERT_TRUE(base::PathExists(privkey_path));
 
   base::ScopedTempDir temp_dir;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
@@ -2277,8 +2330,8 @@
   // temporary directory, but it automatically installs to the extension's
   // directory, and we don't want to copy the whole extension for a unittest.
   base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename);
-  ASSERT_TRUE(file_util::PathExists(theme_file));
-  ASSERT_TRUE(base::Delete(theme_file, false));  // Not recursive.
+  ASSERT_TRUE(base::PathExists(theme_file));
+  ASSERT_TRUE(base::DeleteFile(theme_file, false));  // Not recursive.
 }
 
 // Tests that we can change the ID of an unpacked extension by adding a key
@@ -2300,11 +2353,11 @@
       AppendASCII("unpacked").
       AppendASCII("manifest_with_key.json");
 
-  ASSERT_TRUE(file_util::PathExists(manifest_no_key));
-  ASSERT_TRUE(file_util::PathExists(manifest_with_key));
+  ASSERT_TRUE(base::PathExists(manifest_no_key));
+  ASSERT_TRUE(base::PathExists(manifest_with_key));
 
   // Load the unpacked extension with no key.
-  file_util::CopyFile(manifest_no_key, manifest_path);
+  base::CopyFile(manifest_no_key, manifest_path);
   extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
 
   loop_.RunUntilIdle();
@@ -2313,7 +2366,7 @@
   EXPECT_EQ(1u, service_->extensions()->size());
 
   // Add the key to the manifest.
-  file_util::CopyFile(manifest_with_key, manifest_path);
+  base::CopyFile(manifest_with_key, manifest_path);
   loaded_.clear();
 
   // Reload the extensions.
@@ -2334,9 +2387,9 @@
 
   // Paths to test data files.
   base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
-  ASSERT_TRUE(file_util::PathExists(source_manifest));
+  ASSERT_TRUE(base::PathExists(source_manifest));
   base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
-  ASSERT_TRUE(file_util::PathExists(source_icon));
+  ASSERT_TRUE(base::PathExists(source_icon));
 
   // Set up the temporary extension directory.
   base::ScopedTempDir temp;
@@ -2345,7 +2398,7 @@
   base::FilePath manifest = extension_path.Append(
       extensions::kManifestFilename);
   base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
-  file_util::CopyFile(source_manifest, manifest);
+  base::CopyFile(source_manifest, manifest);
   file_util::CreateSymbolicLink(source_icon, icon_symlink);
 
   // Load extension.
@@ -2789,7 +2842,7 @@
   base::FilePath extension_path = temp.path();
   base::FilePath manifest_path =
       extension_path.Append(extensions::kManifestFilename);
-  ASSERT_FALSE(file_util::PathExists(manifest_path));
+  ASSERT_FALSE(base::PathExists(manifest_path));
 
   // Start with version 2.0.
   DictionaryValue manifest;
@@ -3410,7 +3463,9 @@
   // Reloading extensions should find our externally registered extension
   // and install it.
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
 
   // Extension should be installed despite blacklist.
   ASSERT_EQ(1u, service_->extensions()->size());
@@ -3588,7 +3643,11 @@
 
   // Providers are set up. Let them run.
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+
+  int count = 2;
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      base::Bind(&WaitForCountNotificationsCallback, &count)).Wait();
 
   ASSERT_EQ(2u, service_->extensions()->size());
   EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
@@ -3628,14 +3687,15 @@
 
   ASSERT_EQ(0u, service_->extensions()->size());
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
 
   ASSERT_EQ(1u, service_->extensions()->size());
   EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
   const Extension* extension = service_->GetExtensionById(good_crx, false);
   EXPECT_TRUE(extension->from_webstore());
   EXPECT_TRUE(extension->was_installed_by_default());
-
 }
 #endif
 
@@ -4001,7 +4061,7 @@
       .AddExtension(FILE_PATH_LITERAL(".localstorage"));
   EXPECT_TRUE(file_util::CreateDirectory(lso_dir_path));
   EXPECT_EQ(0, file_util::WriteFile(lso_file_path, NULL, 0));
-  EXPECT_TRUE(file_util::PathExists(lso_file_path));
+  EXPECT_TRUE(base::PathExists(lso_file_path));
 
   // Create indexed db. Similarly, it is enough to only simulate this by
   // creating the directory on the disk.
@@ -4012,7 +4072,7 @@
       base::MessageLoop::current()->message_loop_proxy().get());
   base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
   EXPECT_TRUE(file_util::CreateDirectory(idb_path));
-  EXPECT_TRUE(file_util::DirectoryExists(idb_path));
+  EXPECT_TRUE(base::DirectoryExists(idb_path));
 
   // Uninstall the extension.
   service_->UninstallExtension(good_crx, false, NULL);
@@ -4032,10 +4092,10 @@
   EXPECT_EQ(0U, origins.size());
 
   // Check that the LSO file has been removed.
-  EXPECT_FALSE(file_util::PathExists(lso_file_path));
+  EXPECT_FALSE(base::PathExists(lso_file_path));
 
   // Check if the indexed db has disappeared too.
-  EXPECT_FALSE(file_util::DirectoryExists(idb_path));
+  EXPECT_FALSE(base::DirectoryExists(idb_path));
 }
 
 // Verifies app state is removed upon uninstall.
@@ -4118,7 +4178,7 @@
       .AddExtension(FILE_PATH_LITERAL(".localstorage"));
   EXPECT_TRUE(file_util::CreateDirectory(lso_dir_path));
   EXPECT_EQ(0, file_util::WriteFile(lso_file_path, NULL, 0));
-  EXPECT_TRUE(file_util::PathExists(lso_file_path));
+  EXPECT_TRUE(base::PathExists(lso_file_path));
 
   // Create indexed db. Similarly, it is enough to only simulate this by
   // creating the directory on the disk.
@@ -4129,7 +4189,7 @@
       base::MessageLoop::current()->message_loop_proxy().get());
   base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
   EXPECT_TRUE(file_util::CreateDirectory(idb_path));
-  EXPECT_TRUE(file_util::DirectoryExists(idb_path));
+  EXPECT_TRUE(base::DirectoryExists(idb_path));
 
   // Uninstall one of them, unlimited storage should still be granted
   // to the origin.
@@ -4166,10 +4226,10 @@
   EXPECT_EQ(0U, origins.size());
 
   // Check that the LSO file has been removed.
-  EXPECT_FALSE(file_util::PathExists(lso_file_path));
+  EXPECT_FALSE(base::PathExists(lso_file_path));
 
   // Check if the indexed db has disappeared too.
-  EXPECT_FALSE(file_util::DirectoryExists(idb_path));
+  EXPECT_FALSE(base::DirectoryExists(idb_path));
 }
 
 // Tests loading single extensions (like --load-extension)
@@ -4253,7 +4313,9 @@
   // Reloading extensions should find our externally registered extension
   // and install it.
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
 
   ASSERT_EQ(0u, GetErrors().size());
   ASSERT_EQ(1u, loaded_.size());
@@ -4280,7 +4342,9 @@
 
   loaded_.clear();
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
   ASSERT_EQ(0u, GetErrors().size());
   ASSERT_EQ(1u, loaded_.size());
   ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
@@ -4299,10 +4363,10 @@
   base::FilePath install_path = extensions_install_dir_.AppendASCII(id);
   if (no_uninstall) {
     // Policy controlled extensions should not have been touched by uninstall.
-    ASSERT_TRUE(file_util::PathExists(install_path));
+    ASSERT_TRUE(base::PathExists(install_path));
   } else {
     // The extension should also be gone from the install directory.
-    ASSERT_FALSE(file_util::PathExists(install_path));
+    ASSERT_FALSE(base::PathExists(install_path));
     loaded_.clear();
     service_->CheckForExternalUpdates();
     loop_.RunUntilIdle();
@@ -4317,7 +4381,9 @@
 
     loaded_.clear();
     service_->CheckForExternalUpdates();
-    loop_.RunUntilIdle();
+    content::WindowedNotificationObserver(
+        chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+        content::NotificationService::AllSources()).Wait();
     ASSERT_EQ(1u, loaded_.size());
   }
   ValidatePrefKeyCount(1);
@@ -4338,13 +4404,15 @@
     ValidatePrefKeyCount(0);
 
     // The extension should also be gone from the install directory.
-    ASSERT_FALSE(file_util::PathExists(install_path));
+    ASSERT_FALSE(base::PathExists(install_path));
 
     // Now test the case where user uninstalls and then the extension is removed
     // from the external provider.
     provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
     service_->CheckForExternalUpdates();
-    loop_.RunUntilIdle();
+    content::WindowedNotificationObserver(
+        chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+        content::NotificationService::AllSources()).Wait();
 
     ASSERT_EQ(1u, loaded_.size());
     ASSERT_EQ(0u, GetErrors().size());
@@ -4495,7 +4563,9 @@
   provider->set_visit_count(0);
   service_->CheckForExternalUpdates();
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
   EXPECT_EQ(2, provider->visit_count());
   ASSERT_EQ(0u, GetErrors().size());
   ASSERT_EQ(1u, loaded_.size());
@@ -4954,6 +5024,100 @@
   };
 }
 
+TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) {
+  InitializeEmptyExtensionService();
+
+  bool flare_was_called = false;
+  syncer::ModelType triggered_type(syncer::UNSPECIFIED);
+  base::WeakPtrFactory<ExtensionServiceTest> factory(this);
+  service_->SetSyncStartFlare(
+      base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
+                 factory.GetWeakPtr(),
+                 &flare_was_called,  // Safe due to WeakPtrFactory scope.
+                 &triggered_type));  // Safe due to WeakPtrFactory scope.
+
+  // Install a component extension.
+  base::FilePath path = data_dir_
+      .AppendASCII("good")
+      .AppendASCII("Extensions")
+      .AppendASCII(good0)
+      .AppendASCII("1.0.0.0");
+  std::string manifest;
+  ASSERT_TRUE(file_util::ReadFileToString(
+      path.Append(extensions::kManifestFilename), &manifest));
+  service_->component_loader()->Add(manifest, path);
+  ASSERT_FALSE(service_->is_ready());
+  service_->Init();
+  ASSERT_TRUE(service_->is_ready());
+
+  // Extensions added before service is_ready() don't trigger sync startup.
+  EXPECT_FALSE(flare_was_called);
+  ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
+}
+
+TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) {
+  // Initialize the test dir with a good Preferences/extensions.
+  base::FilePath source_install_dir = data_dir_
+      .AppendASCII("good")
+      .AppendASCII("Extensions");
+  base::FilePath pref_path = source_install_dir
+      .DirName()
+      .AppendASCII("Preferences");
+  InitializeInstalledExtensionService(pref_path, source_install_dir);
+
+  bool flare_was_called = false;
+  syncer::ModelType triggered_type(syncer::UNSPECIFIED);
+  base::WeakPtrFactory<ExtensionServiceTest> factory(this);
+  service_->SetSyncStartFlare(
+      base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
+                 factory.GetWeakPtr(),
+                 &flare_was_called,  // Safe due to WeakPtrFactory scope.
+                 &triggered_type));  // Safe due to WeakPtrFactory scope.
+
+  ASSERT_FALSE(service_->is_ready());
+  service_->Init();
+  ASSERT_TRUE(service_->is_ready());
+
+  // Extensions added before service is_ready() don't trigger sync startup.
+  EXPECT_FALSE(flare_was_called);
+  ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
+}
+
+TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) {
+  InitializeEmptyExtensionService();
+  service_->Init();
+  ASSERT_TRUE(service_->is_ready());
+
+  bool flare_was_called = false;
+  syncer::ModelType triggered_type(syncer::UNSPECIFIED);
+  base::WeakPtrFactory<ExtensionServiceTest> factory(this);
+  service_->SetSyncStartFlare(
+      base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
+                 factory.GetWeakPtr(),
+                 &flare_was_called,  // Safe due to WeakPtrFactory scope.
+                 &triggered_type));  // Safe due to WeakPtrFactory scope.
+
+  base::FilePath path = data_dir_.AppendASCII("good.crx");
+  InstallCRX(path, INSTALL_NEW);
+
+  EXPECT_TRUE(flare_was_called);
+  EXPECT_EQ(syncer::EXTENSIONS, triggered_type);
+
+  // Reset.
+  flare_was_called = false;
+  triggered_type = syncer::UNSPECIFIED;
+
+  // Once sync starts, flare should no longer be invoked.
+  service_->MergeDataAndStartSyncing(
+      syncer::EXTENSIONS, syncer::SyncDataList(),
+      scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
+      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
+  path = data_dir_.AppendASCII("page_action.crx");
+  InstallCRX(path, INSTALL_NEW);
+  EXPECT_FALSE(flare_was_called);
+  ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
+}
+
 TEST_F(ExtensionServiceTest, GetSyncData) {
   InitializeEmptyExtensionService();
   InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
@@ -5888,7 +6052,7 @@
   ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
   ASSERT_FALSE(IsCrxInstalled());
 
-  // Another request from sync should be ignorred.
+  // Another request from sync should be ignored.
   EXPECT_FALSE(AddPendingSyncInstall());
   ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
   ASSERT_FALSE(IsCrxInstalled());
@@ -5975,7 +6139,9 @@
                                  data_dir_.AppendASCII("hosted_app.crx"));
 
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
   EXPECT_FALSE(extensions::HasExternalInstallError(service_));
 
   // Another normal extension, but installed externally.
@@ -5984,7 +6150,9 @@
                                  data_dir_.AppendASCII("page_action.crx"));
 
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
   EXPECT_TRUE(extensions::HasExternalInstallError(service_));
 }
 
@@ -6003,7 +6171,9 @@
                                  data_dir_.AppendASCII("page_action.crx"));
 
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
   EXPECT_TRUE(extensions::HasExternalInstallError(service_));
   EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
 
@@ -6035,7 +6205,10 @@
                                  data_dir_.AppendASCII("theme.crx"));
 
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  int count = 3;
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      base::Bind(&WaitForCountNotificationsCallback, &count)).Wait();
   EXPECT_TRUE(extensions::HasExternalInstallError(service_));
   EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
   EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
@@ -6073,7 +6246,9 @@
   provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
 
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
   EXPECT_TRUE(extensions::HasExternalInstallError(service_));
   EXPECT_TRUE(extensions::HasExternalInstallBubble(service_));
   EXPECT_FALSE(service_->IsExtensionEnabled(updates_from_webstore));
@@ -6097,7 +6272,9 @@
   provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
 
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
   EXPECT_TRUE(extensions::HasExternalInstallError(service_));
   EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
   EXPECT_FALSE(service_->IsExtensionEnabled(updates_from_webstore));
diff --git a/chrome/browser/extensions/extension_service_unittest.h b/chrome/browser/extensions/extension_service_unittest.h
index 1c09479..e6d70c8 100644
--- a/chrome/browser/extensions/extension_service_unittest.h
+++ b/chrome/browser/extensions/extension_service_unittest.h
@@ -60,6 +60,7 @@
   static void SetUpTestCase();
 
   virtual void SetUp() OVERRIDE;
+  virtual void TearDown() OVERRIDE;
 
   void set_extensions_enabled(bool enabled) {
     service_->set_extensions_enabled(enabled);
diff --git a/chrome/browser/extensions/extension_sorting.cc b/chrome/browser/extensions/extension_sorting.cc
index ec2ba25..1af6640 100644
--- a/chrome/browser/extensions/extension_sorting.cc
+++ b/chrome/browser/extensions/extension_sorting.cc
@@ -7,9 +7,9 @@
 #include <algorithm>
 #include <vector>
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_scoped_prefs.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/extensions/extension_special_storage_policy.h b/chrome/browser/extensions/extension_special_storage_policy.h
index 9b056e3..494c65a 100644
--- a/chrome/browser/extensions/extension_special_storage_policy.h
+++ b/chrome/browser/extensions/extension_special_storage_policy.h
@@ -10,7 +10,7 @@
 
 #include "base/synchronization/lock.h"
 #include "chrome/common/extensions/extension_set.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 #include "webkit/browser/quota/special_storage_policy.h"
 
 class CookieSettings;
diff --git a/chrome/browser/extensions/extension_startup_browsertest.cc b/chrome/browser/extensions/extension_startup_browsertest.cc
index 43519a9..300f023 100644
--- a/chrome/browser/extensions/extension_startup_browsertest.cc
+++ b/chrome/browser/extensions/extension_startup_browsertest.cc
@@ -9,13 +9,13 @@
 #include "base/files/file_path.h"
 #include "base/path_service.h"
 #include "base/strings/string_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/user_script_master.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/feature_switch.h"
@@ -70,20 +70,19 @@
       PathService::Get(chrome::DIR_TEST_DATA, &src_dir);
       src_dir = src_dir.AppendASCII("extensions").AppendASCII("good");
 
-      file_util::CopyFile(src_dir.AppendASCII("Preferences"),
-                          preferences_file_);
-      file_util::CopyDirectory(src_dir.AppendASCII("Extensions"),
-                               profile_dir, true);  // recursive
+      base::CopyFile(src_dir.AppendASCII("Preferences"), preferences_file_);
+      base::CopyDirectory(src_dir.AppendASCII("Extensions"),
+                          profile_dir, true);  // recursive
     }
     return true;
   }
 
   virtual void TearDown() {
-    EXPECT_TRUE(base::Delete(preferences_file_, false));
+    EXPECT_TRUE(base::DeleteFile(preferences_file_, false));
 
     // TODO(phajdan.jr): Check return values of the functions below, carefully.
-    base::Delete(user_scripts_dir_, true);
-    base::Delete(extensions_dir_, true);
+    base::DeleteFile(user_scripts_dir_, true);
+    base::DeleteFile(extensions_dir_, true);
 
     InProcessBrowserTest::TearDown();
   }
diff --git a/chrome/browser/extensions/extension_sync_bundle.cc b/chrome/browser/extensions/extension_sync_bundle.cc
index ef53054..893b69c 100644
--- a/chrome/browser/extensions/extension_sync_bundle.cc
+++ b/chrome/browser/extensions/extension_sync_bundle.cc
@@ -122,9 +122,8 @@
   pending_sync_data_[id] = extension_sync_data;
 }
 
-bool ExtensionSyncBundle::HandlesExtension(const Extension& extension) const {
-  return sync_processor_ != NULL &&
-      sync_helper::IsSyncableExtension(&extension);
+bool ExtensionSyncBundle::IsSyncing() const {
+  return sync_processor_ != NULL;
 }
 
 std::vector<ExtensionSyncData> ExtensionSyncBundle::GetPendingData() const {
@@ -148,7 +147,7 @@
     // If we have pending extension data for this extension, then this
     // version is out of date.  We'll sync back the version we got from
     // sync.
-    if (HandlesExtension(extension) &&
+    if (IsSyncing() && sync_helper::IsSyncableExtension(&extension) &&
         !HasPendingExtensionId(extension.id())) {
       sync_data_list->push_back(
           extension_service_->GetExtensionSyncData(extension));
diff --git a/chrome/browser/extensions/extension_sync_bundle.h b/chrome/browser/extensions/extension_sync_bundle.h
index e621777..d9fdb4b 100644
--- a/chrome/browser/extensions/extension_sync_bundle.h
+++ b/chrome/browser/extensions/extension_sync_bundle.h
@@ -72,9 +72,6 @@
   void AddPendingExtension(const std::string& id,
                            const ExtensionSyncData& extension_sync_data);
 
-  // Returns true if |extension| should be handled by this sync bundle.
-  bool HandlesExtension(const Extension& extension) const;
-
   // Returns a vector of all the pending sync data.
   std::vector<ExtensionSyncData> GetPendingData() const;
 
@@ -83,6 +80,9 @@
       const ExtensionSet& extensions,
       std::vector<extensions::ExtensionSyncData>* sync_data_list) const;
 
+  // Returns true if SetupSync has been called, false otherwise.
+  bool IsSyncing() const;
+
  private:
   // Add a synced extension.
   void AddExtension(const std::string& id);
diff --git a/chrome/browser/extensions/extension_sync_data.h b/chrome/browser/extensions/extension_sync_data.h
index cf8ac6d..8fbe73a 100644
--- a/chrome/browser/extensions/extension_sync_data.h
+++ b/chrome/browser/extensions/extension_sync_data.h
@@ -8,8 +8,8 @@
 #include <string>
 
 #include "base/version.h"
-#include "googleurl/src/gurl.h"
 #include "sync/api/sync_change.h"
+#include "url/gurl.h"
 
 namespace syncer {
 class SyncData;
diff --git a/chrome/browser/extensions/extension_sync_data_unittest.cc b/chrome/browser/extensions/extension_sync_data_unittest.cc
index f7bad7e..637137d 100644
--- a/chrome/browser/extensions/extension_sync_data_unittest.cc
+++ b/chrome/browser/extensions/extension_sync_data_unittest.cc
@@ -7,10 +7,10 @@
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/version.h"
-#include "googleurl/src/gurl.h"
 #include "sync/protocol/extension_specifics.pb.h"
 #include "sync/protocol/sync.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/extensions/extension_system.cc b/chrome/browser/extensions/extension_system.cc
index c65ec53..117d907 100644
--- a/chrome/browser/extensions/extension_system.cc
+++ b/chrome/browser/extensions/extension_system.cc
@@ -34,6 +34,7 @@
 #include "chrome/browser/extensions/user_script_master.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/sync/glue/sync_start_util.h"
 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
@@ -138,6 +139,8 @@
       autoupdate_enabled,
       extensions_enabled,
       &ready_));
+  extension_service_->SetSyncStartFlare(
+      sync_start_util::GetFlareForSyncableService(profile_->GetPath()));
 
   // These services must be registered before the ExtensionService tries to
   // load any extensions.
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc
index e8e50b0..9f6fd69 100644
--- a/chrome/browser/extensions/extension_tab_util.cc
+++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -28,7 +28,7 @@
 #include "content/public/browser/favicon_status.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace keys = extensions::tabs_constants;
 namespace tabs = extensions::api::tabs;
diff --git a/chrome/browser/extensions/extension_tab_util_android.cc b/chrome/browser/extensions/extension_tab_util_android.cc
index 6167685..671f862 100644
--- a/chrome/browser/extensions/extension_tab_util_android.cc
+++ b/chrome/browser/extensions/extension_tab_util_android.cc
@@ -6,7 +6,7 @@
 
 #include "base/logging.h"
 #include "chrome/browser/sessions/session_id.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using base::DictionaryValue;
 using base::ListValue;
diff --git a/chrome/browser/extensions/extension_test_message_listener.cc b/chrome/browser/extensions/extension_test_message_listener.cc
index f548ac1..9314723 100644
--- a/chrome/browser/extensions/extension_test_message_listener.cc
+++ b/chrome/browser/extensions/extension_test_message_listener.cc
@@ -5,8 +5,9 @@
 #include "chrome/browser/extensions/extension_test_message_listener.h"
 
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/test/test_api.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/extensions/extension_toolbar_model.cc b/chrome/browser/extensions/extension_toolbar_model.cc
index 7805832..8d23097 100644
--- a/chrome/browser/extensions/extension_toolbar_model.cc
+++ b/chrome/browser/extensions/extension_toolbar_model.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/extensions/extension_toolbar_model.h"
 
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
 #include "chrome/browser/extensions/browser_event_router.h"
 #include "chrome/browser/extensions/extension_action.h"
@@ -16,7 +17,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/feature_switch.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/extensions/extension_uninstall_dialog.cc b/chrome/browser/extensions/extension_uninstall_dialog.cc
index f7881a5..e91fbff 100644
--- a/chrome/browser/extensions/extension_uninstall_dialog.cc
+++ b/chrome/browser/extensions/extension_uninstall_dialog.cc
@@ -7,9 +7,9 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/image_loader.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/extension_icon_set.h"
diff --git a/chrome/browser/extensions/extension_url_rewrite_browsertest.cc b/chrome/browser/extensions/extension_url_rewrite_browsertest.cc
index 8e8e1df..0764187 100644
--- a/chrome/browser/extensions/extension_url_rewrite_browsertest.cc
+++ b/chrome/browser/extensions/extension_url_rewrite_browsertest.cc
@@ -20,7 +20,7 @@
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::NavigationEntry;
 
diff --git a/chrome/browser/extensions/extension_warning_service.cc b/chrome/browser/extensions/extension_warning_service.cc
index 3eae70b..d59c76e 100644
--- a/chrome/browser/extensions/extension_warning_service.cc
+++ b/chrome/browser/extensions/extension_warning_service.cc
@@ -6,11 +6,11 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/extensions/extension_warning_set.cc b/chrome/browser/extensions/extension_warning_set.cc
index 0e8879c..662e09c 100644
--- a/chrome/browser/extensions/extension_warning_set.cc
+++ b/chrome/browser/extensions/extension_warning_set.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/extensions/extension_warning_set.h"
 
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_set.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/extensions/extension_warning_set.h b/chrome/browser/extensions/extension_warning_set.h
index e68cfce..c0510f1 100644
--- a/chrome/browser/extensions/extension_warning_set.h
+++ b/chrome/browser/extensions/extension_warning_set.h
@@ -9,7 +9,7 @@
 #include <string>
 #include <vector>
 
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 // TODO(battre) Remove the Extension prefix.
 
diff --git a/chrome/browser/extensions/extension_web_ui.cc b/chrome/browser/extensions/extension_web_ui.cc
index b62af29..3ea194b 100644
--- a/chrome/browser/extensions/extension_web_ui.cc
+++ b/chrome/browser/extensions/extension_web_ui.cc
@@ -164,7 +164,7 @@
 // chrome:// URL overrides
 
 // static
-void ExtensionWebUI::RegisterUserPrefs(
+void ExtensionWebUI::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterDictionaryPref(
       kExtensionURLOverrides,
diff --git a/chrome/browser/extensions/extension_web_ui.h b/chrome/browser/extensions/extension_web_ui.h
index 1c34394..0153f69 100644
--- a/chrome/browser/extensions/extension_web_ui.h
+++ b/chrome/browser/extensions/extension_web_ui.h
@@ -60,7 +60,7 @@
                                           const base::Value* override);
 
   // Called from BrowserPrefs
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Get the favicon for the extension by getting an icon from the manifest.
   // Note. |callback| is always run asynchronously.
diff --git a/chrome/browser/extensions/extension_web_ui_override_registrar.cc b/chrome/browser/extensions/extension_web_ui_override_registrar.cc
index fcf5276..aab0a03 100644
--- a/chrome/browser/extensions/extension_web_ui_override_registrar.cc
+++ b/chrome/browser/extensions/extension_web_ui_override_registrar.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/extensions/extension_web_ui_override_registrar.h"
 
 #include "base/lazy_instance.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_web_ui.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/extensions/external_install_ui.cc b/chrome/browser/extensions/external_install_ui.cc
index dd25bf6..fe7fc25 100644
--- a/chrome/browser/extensions/external_install_ui.cc
+++ b/chrome/browser/extensions/external_install_ui.cc
@@ -14,6 +14,7 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_install_prompt.h"
 #include "chrome/browser/extensions/extension_install_ui.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/ui/global_error/global_error_service.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "chrome/browser/ui/host_desktop.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/manifest_url_handler.h"
@@ -84,8 +84,8 @@
   scoped_ptr<ExtensionInstallPrompt> install_ui_;
 
   Browser* browser_;
-  ExtensionService* service_;
-  const Extension* extension_;
+  base::WeakPtr<ExtensionService> service_weak_;
+  const std::string extension_id_;
 };
 
 // Only shows a menu item, no bubble. Clicking the menu item shows
@@ -194,7 +194,9 @@
     ExtensionService* service,
     const Extension* extension,
     bool use_global_error)
-    : browser_(browser), service_(service), extension_(extension) {
+    : browser_(browser),
+      service_weak_(service->AsWeakPtr()),
+      extension_id_(extension->id()) {
   AddRef();  // Balanced in Proceed or Abort.
 
   install_ui_.reset(
@@ -203,21 +205,33 @@
   const ExtensionInstallPrompt::ShowDialogCallback callback =
       use_global_error ?
       base::Bind(&CreateExternalInstallGlobalError,
-                 service->AsWeakPtr(), extension->id()) :
+                 service_weak_, extension_id_) :
       ExtensionInstallPrompt::GetDefaultShowDialogCallback();
-  install_ui_->ConfirmExternalInstall(this, extension_, callback);
+  install_ui_->ConfirmExternalInstall(this, extension, callback);
 }
 
 ExternalInstallDialogDelegate::~ExternalInstallDialogDelegate() {
 }
 
 void ExternalInstallDialogDelegate::InstallUIProceed() {
-  service_->GrantPermissionsAndEnableExtension(extension_);
+  if (!service_weak_.get())
+    return;
+  const Extension* extension =
+      service_weak_->GetInstalledExtension(extension_id_);
+  if (!extension)
+    return;
+  service_weak_->GrantPermissionsAndEnableExtension(extension);
   Release();
 }
 
 void ExternalInstallDialogDelegate::InstallUIAbort(bool user_initiated) {
-  service_->UninstallExtension(extension_->id(), false, NULL);
+  if (!service_weak_.get())
+    return;
+  const Extension* extension =
+      service_weak_->GetInstalledExtension(extension_id_);
+  if (!extension)
+    return;
+  service_weak_->UninstallExtension(extension_id_, false, NULL);
   Release();
 }
 
diff --git a/chrome/browser/extensions/external_policy_loader.cc b/chrome/browser/extensions/external_policy_loader.cc
index 931ae45..61c8363 100644
--- a/chrome/browser/extensions/external_policy_loader.cc
+++ b/chrome/browser/extensions/external_policy_loader.cc
@@ -9,9 +9,9 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/external_provider_impl.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/extensions/external_pref_loader.cc b/chrome/browser/extensions/external_pref_loader.cc
index 849829a..567fdb2 100644
--- a/chrome/browser/extensions/external_pref_loader.cc
+++ b/chrome/browser/extensions/external_pref_loader.cc
@@ -31,7 +31,7 @@
 
   std::set<base::FilePath> external_extension_paths;
 
-  if (!file_util::PathExists(external_extension_search_path)) {
+  if (!base::PathExists(external_extension_search_path)) {
     // Does not have to exist.
     return external_extension_paths;
   }
@@ -156,7 +156,7 @@
 
   base::FilePath json_file = base_path_.Append(kExternalExtensionJson);
 
-  if (!file_util::PathExists(json_file)) {
+  if (!base::PathExists(json_file)) {
     // This is not an error.  The file does not exist by default.
     return;
   }
diff --git a/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc b/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc
index fcb6d2c..20bd554 100644
--- a/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc
+++ b/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc
@@ -7,10 +7,13 @@
 #include "base/command_line.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/test/scoped_path_override.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service_unittest.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/test/test_utils.h"
 
 namespace extensions {
 
@@ -60,7 +63,9 @@
   InitServiceWithExternalProviders();
 
   service_->CheckForExternalUpdates();
-  loop_.RunUntilIdle();
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources()).Wait();
 
   EXPECT_TRUE(service_->GetInstalledExtension(kExternalAppId));
 }
diff --git a/chrome/browser/extensions/external_registry_loader_win.cc b/chrome/browser/extensions/external_registry_loader_win.cc
index 47cf902..cf446c0 100644
--- a/chrome/browser/extensions/external_registry_loader_win.cc
+++ b/chrome/browser/extensions/external_registry_loader_win.cc
@@ -100,7 +100,7 @@
       continue;
     }
 
-    if (!file_util::PathExists(extension_path)) {
+    if (!base::PathExists(extension_path)) {
       LOG(ERROR) << "File " << extension_path_str
                  << " for key " << key_path
                  << " does not exist or is not readable.";
diff --git a/chrome/browser/extensions/gtalk_extension_browsertest.cc b/chrome/browser/extensions/gtalk_extension_browsertest.cc
index 383a0e7..94a5ecd 100644
--- a/chrome/browser/extensions/gtalk_extension_browsertest.cc
+++ b/chrome/browser/extensions/gtalk_extension_browsertest.cc
@@ -5,6 +5,7 @@
 #include "base/bind.h"
 #include "base/process_util.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
@@ -13,7 +14,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
diff --git a/chrome/browser/extensions/image_loader.cc b/chrome/browser/extensions/image_loader.cc
index 9d775dd..439df3c 100644
--- a/chrome/browser/extensions/image_loader.cc
+++ b/chrome/browser/extensions/image_loader.cc
@@ -4,9 +4,13 @@
 
 #include "chrome/browser/extensions/image_loader.h"
 
+#include <map>
+#include <vector>
+
 #include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/file_util.h"
+#include "base/lazy_instance.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/threading/sequenced_worker_pool.h"
@@ -23,7 +27,7 @@
 #include "ui/gfx/image/image_skia.h"
 
 #if defined(USE_AURA)
-#include "grit/keyboard_resources.h"
+#include "ui/keyboard/keyboard_util.h"
 #endif
 
 using content::BrowserThread;
@@ -94,6 +98,23 @@
   gfx::PNGCodec::Decode(data, file_contents.length(), bitmap);
 }
 
+// Add the resources from |entries| (there are |size| of them) to
+// |path_to_resource_id| after normalizing separators.
+void AddComponentResourceEntries(
+    std::map<base::FilePath, int>* path_to_resource_id,
+    const GritResourceMap* entries,
+    size_t size) {
+  for (size_t i = 0; i < size; ++i) {
+    base::FilePath resource_path = base::FilePath().AppendASCII(
+        entries[i].name);
+    resource_path = resource_path.NormalizePathSeparators();
+
+    DCHECK(path_to_resource_id->find(resource_path) ==
+        path_to_resource_id->end());
+    (*path_to_resource_id)[resource_path] = entries[i].value;
+  }
+}
+
 }  // namespace
 
 namespace extensions {
@@ -156,6 +177,11 @@
   return ImageLoaderFactory::GetForProfile(profile);
 }
 
+// A map from a resource path to the resource ID.  Used only by
+// IsComponentExtensionResource below.
+static base::LazyInstance<std::map<base::FilePath, int> > path_to_resource_id =
+    LAZY_INSTANCE_INITIALIZER;
+
 // static
 bool ImageLoader::IsComponentExtensionResource(
     const base::FilePath& extension_path,
@@ -172,30 +198,27 @@
     {"settings_app/settings_app_icon_32.png", IDR_SETTINGS_APP_ICON_32},
     {"settings_app/settings_app_icon_48.png", IDR_SETTINGS_APP_ICON_48},
 #endif
-#if defined(USE_AURA)
-    {"keyboard/api_adapter.js", IDR_KEYBOARD_API_ADAPTER_JS},
-    {"keyboard/constants.js", IDR_KEYBOARD_CONSTANTS_JS},
-    {"keyboard/elements/kb-accent-container.html",
-        IDR_KEYBOARD_ELEMENTS_ACCENT_CONTAINER},
-    {"keyboard/elements/kb-accent-key.html", IDR_KEYBOARD_ELEMENTS_ACCENT_KEY},
-    {"keyboard/elements/kb-accent-set.html", IDR_KEYBOARD_ELEMENTS_ACCENT_SET},
-    {"keyboard/elements/kb-key.html", IDR_KEYBOARD_ELEMENTS_KEY},
-    {"keyboard/elements/kb-keyboard.html", IDR_KEYBOARD_ELEMENTS_KEYBOARD},
-    {"keyboard/elements/kb-keyset.html", IDR_KEYBOARD_ELEMENTS_KEYSET},
-    {"keyboard/elements/kb-row.html", IDR_KEYBOARD_ELEMENTS_ROW},
-    {"keyboard/images/keyboard.svg", IDR_KEYBOARD_IMAGES_KEYBOARD},
-    {"keyboard/images/mic.svg", IDR_KEYBOARD_IMAGES_MIC},
-    {"keyboard/images/mic-green.svg", IDR_KEYBOARD_IMAGES_MIC_GREEN},
-    {"keyboard/index.html", IDR_KEYBOARD_INDEX},
-    {"keyboard/keysets.html", IDR_KEYBOARD_KEYSETS},
-    {"keyboard/main.css", IDR_KEYBOARD_MAIN_CSS},
-    {"keyboard/main.js", IDR_KEYBOARD_MAIN_JS},
-    {"keyboard/polymer.min.js", IDR_KEYBOARD_POLYMER},
-    {"keyboard/voice_input.js", IDR_KEYBOARD_VOICE_INPUT_JS},
-#endif
   };
-  static const size_t kExtraComponentExtensionResourcesSize =
-      arraysize(kExtraComponentExtensionResources);
+
+  if (path_to_resource_id.Get().empty()) {
+    AddComponentResourceEntries(
+        path_to_resource_id.Pointer(),
+        kComponentExtensionResources,
+        kComponentExtensionResourcesSize);
+    AddComponentResourceEntries(
+        path_to_resource_id.Pointer(),
+        kExtraComponentExtensionResources,
+        arraysize(kExtraComponentExtensionResources));
+#if defined(USE_AURA)
+    if (keyboard::IsKeyboardEnabled()) {
+      size_t size;
+      const GritResourceMap* keyboard_resources =
+          keyboard::GetKeyboardExtensionResources(&size);
+      AddComponentResourceEntries(
+          path_to_resource_id.Pointer(), keyboard_resources, size);
+    }
+#endif
+  }
 
   base::FilePath directory_path = extension_path;
   base::FilePath resources_dir;
@@ -207,30 +230,12 @@
   relative_path = relative_path.Append(resource_path);
   relative_path = relative_path.NormalizePathSeparators();
 
-  // TODO(tc): Make a map of base::FilePath -> resource ids so we don't have to
-  // covert to FilePaths all the time.  This will be more useful as we add
-  // more resources.
-  for (size_t i = 0; i < kComponentExtensionResourcesSize; ++i) {
-    base::FilePath resource_path =
-        base::FilePath().AppendASCII(kComponentExtensionResources[i].name);
-    resource_path = resource_path.NormalizePathSeparators();
+  std::map<base::FilePath, int>::const_iterator entry =
+      path_to_resource_id.Get().find(relative_path);
+  if (entry != path_to_resource_id.Get().end())
+    *resource_id = entry->second;
 
-    if (relative_path == resource_path) {
-      *resource_id = kComponentExtensionResources[i].value;
-      return true;
-    }
-  }
-  for (size_t i = 0; i < kExtraComponentExtensionResourcesSize; ++i) {
-    base::FilePath resource_path =
-        base::FilePath().AppendASCII(kExtraComponentExtensionResources[i].name);
-    resource_path = resource_path.NormalizePathSeparators();
-
-    if (relative_path == resource_path) {
-      *resource_id = kExtraComponentExtensionResources[i].value;
-      return true;
-    }
-  }
-  return false;
+  return entry != path_to_resource_id.Get().end();
 }
 
 void ImageLoader::LoadImageAsync(
diff --git a/chrome/browser/extensions/image_loader.h b/chrome/browser/extensions/image_loader.h
index de2b1d3..5e6bc3e 100644
--- a/chrome/browser/extensions/image_loader.h
+++ b/chrome/browser/extensions/image_loader.h
@@ -5,7 +5,6 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_IMAGE_LOADER_H_
 #define CHROME_BROWSER_EXTENSIONS_IMAGE_LOADER_H_
 
-#include <map>
 #include <set>
 
 #include "base/callback_forward.h"
diff --git a/chrome/browser/extensions/image_loader_unittest.cc b/chrome/browser/extensions/image_loader_unittest.cc
index b3213bb..4d50f6b 100644
--- a/chrome/browser/extensions/image_loader_unittest.cc
+++ b/chrome/browser/extensions/image_loader_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/json/json_file_value_serializer.h"
 #include "base/message_loop.h"
 #include "base/path_service.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
diff --git a/chrome/browser/extensions/install_observer.h b/chrome/browser/extensions/install_observer.h
index 422efbd..95370da 100644
--- a/chrome/browser/extensions/install_observer.h
+++ b/chrome/browser/extensions/install_observer.h
@@ -28,8 +28,9 @@
   virtual void OnInstallFailure(const std::string& extension_id) = 0;
 
   virtual void OnExtensionInstalled(const Extension* extension) = 0;
+  virtual void OnExtensionLoaded(const Extension* extension) = 0;
+  virtual void OnExtensionUnloaded(const Extension* extension) = 0;
   virtual void OnExtensionUninstalled(const Extension* extension) = 0;
-  virtual void OnExtensionDisabled(const Extension* extension) = 0;
   virtual void OnAppsReordered() = 0;
   virtual void OnAppInstalledToAppList(const std::string& extension_id) = 0;
 
diff --git a/chrome/browser/extensions/install_tracker.cc b/chrome/browser/extensions/install_tracker.cc
index f7a07d8..ea0e6aa 100644
--- a/chrome/browser/extensions/install_tracker.cc
+++ b/chrome/browser/extensions/install_tracker.cc
@@ -5,8 +5,8 @@
 #include "chrome/browser/extensions/install_tracker.h"
 
 #include "base/bind.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_prefs.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
 
@@ -16,10 +16,14 @@
                                extensions::ExtensionPrefs* prefs) {
   ExtensionSorting* sorting = prefs->extension_sorting();
 
+  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
+      content::Source<Profile>(profile));
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
       content::Source<Profile>(profile));
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
       content::Source<Profile>(profile));
+  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
+      content::Source<Profile>(profile));
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED,
       content::Source<ExtensionSorting>(sorting));
   registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST,
@@ -76,24 +80,34 @@
                              const content::NotificationSource& source,
                              const content::NotificationDetails& details) {
   switch (type) {
-    case chrome::NOTIFICATION_EXTENSION_LOADED: {
+    case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
       const Extension* extension =
           content::Details<const Extension>(details).ptr();
       FOR_EACH_OBSERVER(InstallObserver, observers_,
                         OnExtensionInstalled(extension));
       break;
     }
+    case chrome::NOTIFICATION_EXTENSION_LOADED: {
+      const Extension* extension =
+          content::Details<const Extension>(details).ptr();
+      FOR_EACH_OBSERVER(InstallObserver, observers_,
+                        OnExtensionLoaded(extension));
+      break;
+    }
     case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
       const content::Details<extensions::UnloadedExtensionInfo>& unload_info(
           details);
       const Extension* extension = unload_info->extension;
-      if (unload_info->reason == extension_misc::UNLOAD_REASON_UNINSTALL) {
-        FOR_EACH_OBSERVER(InstallObserver, observers_,
-                          OnExtensionUninstalled(extension));
-      } else {
-        FOR_EACH_OBSERVER(InstallObserver, observers_,
-                          OnExtensionDisabled(extension));
-      }
+      FOR_EACH_OBSERVER(InstallObserver, observers_,
+                        OnExtensionUnloaded(extension));
+      break;
+    }
+    case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
+      const Extension* extension =
+          content::Details<const Extension>(details).ptr();
+
+      FOR_EACH_OBSERVER(InstallObserver, observers_,
+                        OnExtensionUninstalled(extension));
       break;
     }
     case chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED: {
diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc
index ba6f7de..47c4672 100644
--- a/chrome/browser/extensions/lazy_background_page_apitest.cc
+++ b/chrome/browser/extensions/lazy_background_page_apitest.cc
@@ -8,6 +8,7 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/browser_action_test_util.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_host.h"
@@ -20,7 +21,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/omnibox/location_bar.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/url_constants.h"
@@ -28,9 +28,9 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "url/gurl.h"
 
 using extensions::Extension;
 
diff --git a/chrome/browser/extensions/lazy_background_page_test_util.h b/chrome/browser/extensions/lazy_background_page_test_util.h
index be6de4e..cf5f540 100644
--- a/chrome/browser/extensions/lazy_background_page_test_util.h
+++ b/chrome/browser/extensions/lazy_background_page_test_util.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_LAZY_BACKGROUND_PAGE_TEST_UTIL_H_
 #define CHROME_BROWSER_EXTENSIONS_LAZY_BACKGROUND_PAGE_TEST_UTIL_H_
 
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/test/test_utils.h"
 
diff --git a/chrome/browser/extensions/lazy_background_task_queue.cc b/chrome/browser/extensions/lazy_background_task_queue.cc
index 7215ff9..7df7779 100644
--- a/chrome/browser/extensions/lazy_background_task_queue.cc
+++ b/chrome/browser/extensions/lazy_background_task_queue.cc
@@ -5,13 +5,13 @@
 #include "chrome/browser/extensions/lazy_background_task_queue.h"
 
 #include "base/callback.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/process_map.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_messages.h"
diff --git a/chrome/browser/extensions/media_galleries_handler.cc b/chrome/browser/extensions/media_galleries_handler.cc
deleted file mode 100644
index a1a361a..0000000
--- a/chrome/browser/extensions/media_galleries_handler.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/media_galleries_handler.h"
-
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/extension_manifest_constants.h"
-#include "chrome/common/extensions/manifest.h"
-#include "extensions/common/error_utils.h"
-
-namespace keys = extension_manifest_keys;
-namespace errors = extension_manifest_errors;
-
-namespace {
-
-// Stored on the Extension.
-struct MediaGalleriesHandlerInfo : public extensions::Extension::ManifestData {
-  MediaGalleriesHandler::List media_galleries_handlers;
-
-  MediaGalleriesHandlerInfo();
-  virtual ~MediaGalleriesHandlerInfo();
-};
-
-MediaGalleriesHandlerInfo::MediaGalleriesHandlerInfo() {
-}
-
-MediaGalleriesHandlerInfo::~MediaGalleriesHandlerInfo() {
-}
-
-MediaGalleriesHandler* LoadMediaGalleriesHandler(
-    const std::string& extension_id,
-    const DictionaryValue* media_galleries_handler,
-    string16* error) {
-  scoped_ptr<MediaGalleriesHandler> result(new MediaGalleriesHandler());
-  result->set_extension_id(extension_id);
-
-  std::string handler_id;
-  // Read the file action |id| (mandatory).
-  if (!media_galleries_handler->HasKey(keys::kPageActionId) ||
-      !media_galleries_handler->GetString(keys::kPageActionId, &handler_id)) {
-    *error = ASCIIToUTF16(errors::kInvalidPageActionId);
-    return NULL;
-  }
-  result->set_id(handler_id);
-
-  // Read the page action title from |default_title| (mandatory).
-  std::string title;
-  if (!media_galleries_handler->HasKey(keys::kPageActionDefaultTitle) ||
-      !media_galleries_handler->GetString(keys::kPageActionDefaultTitle,
-                                          &title)) {
-    *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle);
-    return NULL;
-  }
-  result->set_title(title);
-
-  std::string default_icon;
-  // Read the media galleries action |default_icon| (optional).
-  if (media_galleries_handler->HasKey(keys::kPageActionDefaultIcon)) {
-    if (!media_galleries_handler->GetString(
-            keys::kPageActionDefaultIcon, &default_icon) ||
-        default_icon.empty()) {
-      *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath);
-      return NULL;
-    }
-    result->set_icon_path(default_icon);
-  }
-
-  return result.release();
-}
-
-// Loads MediaGalleriesHandlers from |extension_actions| into a list in
-// |result|.
-bool LoadMediaGalleriesHandlers(
-    const std::string& extension_id,
-    const base::ListValue* extension_actions,
-    MediaGalleriesHandler::List* result,
-    string16* error) {
-  for (base::ListValue::const_iterator iter = extension_actions->begin();
-       iter != extension_actions->end();
-       ++iter) {
-    if (!(*iter)->IsType(Value::TYPE_DICTIONARY)) {
-      *error = ASCIIToUTF16(errors::kInvalidMediaGalleriesHandler);
-      return false;
-    }
-    scoped_ptr<MediaGalleriesHandler> action(
-        LoadMediaGalleriesHandler(
-            extension_id, reinterpret_cast<DictionaryValue*>(*iter), error));
-    if (!action)
-      return false;  // Failed to parse media galleries action definition.
-    result->push_back(linked_ptr<MediaGalleriesHandler>(action.release()));
-  }
-  return true;
-}
-
-}  // namespace
-
-MediaGalleriesHandler::MediaGalleriesHandler() {
-}
-
-MediaGalleriesHandler::~MediaGalleriesHandler() {
-}
-
-// static
-MediaGalleriesHandler::List*
-MediaGalleriesHandler::GetHandlers(const extensions::Extension* extension) {
-  MediaGalleriesHandlerInfo* info = static_cast<MediaGalleriesHandlerInfo*>(
-      extension->GetManifestData(keys::kMediaGalleriesHandlers));
-  if (info)
-    return &info->media_galleries_handlers;
-  return NULL;
-}
-
-MediaGalleriesHandlerParser::MediaGalleriesHandlerParser() {
-}
-
-MediaGalleriesHandlerParser::~MediaGalleriesHandlerParser() {
-}
-
-bool MediaGalleriesHandlerParser::Parse(extensions::Extension* extension,
-                                        string16* error) {
-  const base::ListValue* media_galleries_handlers_value = NULL;
-  if (!extension->manifest()->GetList(keys::kMediaGalleriesHandlers,
-                                      &media_galleries_handlers_value)) {
-    *error = ASCIIToUTF16(errors::kInvalidMediaGalleriesHandler);
-    return false;
-  }
-  scoped_ptr<MediaGalleriesHandlerInfo> info(new MediaGalleriesHandlerInfo);
-  if (!LoadMediaGalleriesHandlers(extension->id(),
-                                  media_galleries_handlers_value,
-                                  &info->media_galleries_handlers,
-                                  error)) {
-    return false;  // Failed to parse media galleries actions definition.
-  }
-
-  extension->SetManifestData(keys::kMediaGalleriesHandlers, info.release());
-  return true;
-}
-
-const std::vector<std::string> MediaGalleriesHandlerParser::Keys() const {
-  return SingleKey(keys::kMediaGalleriesHandlers);
-}
diff --git a/chrome/browser/extensions/media_galleries_handler.h b/chrome/browser/extensions/media_galleries_handler.h
deleted file mode 100644
index 99a5563..0000000
--- a/chrome/browser/extensions/media_galleries_handler.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_MEDIA_GALLERIES_HANDLER_H_
-#define CHROME_BROWSER_EXTENSIONS_MEDIA_GALLERIES_HANDLER_H_
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/manifest_handler.h"
-
-class URLPattern;
-
-// Encapsulates the state of a media gallery handler.
-class MediaGalleriesHandler {
- public:
-  typedef std::vector<linked_ptr<MediaGalleriesHandler> > List;
-
-  MediaGalleriesHandler();
-  ~MediaGalleriesHandler();
-
-  std::string extension_id() const { return extension_id_; }
-  void set_extension_id(const std::string& extension_id) {
-    extension_id_ = extension_id;
-  }
-
-  const std::string& id() const { return id_; }
-  void set_id(const std::string& id) { id_ = id; }
-
-  // Default title.
-  const std::string& title() const { return title_; }
-  void set_title(const std::string& title) { title_ = title; }
-
-  // Action icon path.
-  const std::string icon_path() const { return default_icon_path_; }
-  void set_icon_path(const std::string& path) {
-    default_icon_path_ = path;
-  }
-
-  // Returns the media galleries handlers associated with the |extension|.
-  static List* GetHandlers(const extensions::Extension* extension);
-
- private:
-  // The id for the extension this action belongs to (as defined in the
-  // extension manifest).
-  std::string extension_id_;
-  std::string title_;
-  std::string default_icon_path_;
-  // The id for the MediaGalleriesHandler, for example: "ImportToDrive".
-  std::string id_;
-};
-
-// Parses the "media_galleries_handlers" extension manifest key.
-class MediaGalleriesHandlerParser : public extensions::ManifestHandler {
- public:
-  MediaGalleriesHandlerParser();
-  virtual ~MediaGalleriesHandlerParser();
-
-  virtual bool Parse(extensions::Extension* extension,
-                     string16* error) OVERRIDE;
-
- private:
-  virtual const std::vector<std::string> Keys() const OVERRIDE;
-};
-
-#endif  // CHROME_BROWSER_EXTENSIONS_MEDIA_GALLERIES_HANDLER_H_
diff --git a/chrome/browser/extensions/menu_manager.cc b/chrome/browser/extensions/menu_manager.cc
index cb2ce0e..2091db8 100644
--- a/chrome/browser/extensions/menu_manager.cc
+++ b/chrome/browser/extensions/menu_manager.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_names.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -20,7 +21,6 @@
 #include "chrome/browser/extensions/state_store.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/extensions/menu_manager_unittest.cc b/chrome/browser/extensions/menu_manager_unittest.cc
index 73c8357..40dfeed 100644
--- a/chrome/browser/extensions/menu_manager_unittest.cc
+++ b/chrome/browser/extensions/menu_manager_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/event_names.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_system_factory.h"
@@ -19,7 +20,6 @@
 #include "chrome/browser/extensions/test_extension_prefs.h"
 #include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
diff --git a/chrome/browser/extensions/mock_extension_special_storage_policy.h b/chrome/browser/extensions/mock_extension_special_storage_policy.h
index 6417368..5fb958d 100644
--- a/chrome/browser/extensions/mock_extension_special_storage_policy.h
+++ b/chrome/browser/extensions/mock_extension_special_storage_policy.h
@@ -9,7 +9,7 @@
 #include <string>
 
 #include "chrome/browser/extensions/extension_special_storage_policy.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 // This class is the same as MockSpecialStoragePolicy (in
 // webkit/browser/quota/mock_special_storage_policy.h), but it inherits
diff --git a/chrome/browser/extensions/pack_extension_unittest.cc b/chrome/browser/extensions/pack_extension_unittest.cc
index 5198be2..dddfe4d 100644
--- a/chrome/browser/extensions/pack_extension_unittest.cc
+++ b/chrome/browser/extensions/pack_extension_unittest.cc
@@ -31,7 +31,7 @@
   bool TestPackExtension(const base::FilePath& path) {
     base::ScopedTempDir temp_dir;
     EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
-    EXPECT_TRUE(file_util::CopyDirectory(path, temp_dir.path(), true));
+    EXPECT_TRUE(base::CopyDirectory(path, temp_dir.path(), true));
     CommandLine command_line(CommandLine::NO_PROGRAM);
     command_line.AppendSwitchPath(switches::kPackExtension,
                                   temp_dir.path().Append(path.BaseName()));
diff --git a/chrome/browser/extensions/page_action_controller.cc b/chrome/browser/extensions/page_action_controller.cc
index 979518b..62dab8f 100644
--- a/chrome/browser/extensions/page_action_controller.cc
+++ b/chrome/browser/extensions/page_action_controller.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/extensions/page_action_controller.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/browser_event_router.h"
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/extensions/extension_action.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_id.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_set.h"
 #include "content/public/browser/invalidate_type.h"
 #include "content/public/browser/navigation_details.h"
diff --git a/chrome/browser/extensions/pending_extension_info.h b/chrome/browser/extensions/pending_extension_info.h
index b30e9d1..dbcf1bd 100644
--- a/chrome/browser/extensions/pending_extension_info.h
+++ b/chrome/browser/extensions/pending_extension_info.h
@@ -10,7 +10,7 @@
 #include "base/version.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/manifest.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 FORWARD_DECLARE_TEST(ExtensionServiceTest, AddPendingExtensionFromSync);
 
diff --git a/chrome/browser/extensions/pending_extension_manager.cc b/chrome/browser/extensions/pending_extension_manager.cc
index fcf1660..b27b6ca 100644
--- a/chrome/browser/extensions/pending_extension_manager.cc
+++ b/chrome/browser/extensions/pending_extension_manager.cc
@@ -10,7 +10,7 @@
 #include "base/version.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
diff --git a/chrome/browser/extensions/permissions_updater.cc b/chrome/browser/extensions/permissions_updater.cc
index a985332..e52af60 100644
--- a/chrome/browser/extensions/permissions_updater.cc
+++ b/chrome/browser/extensions/permissions_updater.cc
@@ -7,12 +7,12 @@
 #include "base/json/json_writer.h"
 #include "base/memory/ref_counted.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/permissions/permissions_api_helpers.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/permissions.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_messages.h"
diff --git a/chrome/browser/extensions/permissions_updater_unittest.cc b/chrome/browser/extensions/permissions_updater_unittest.cc
index cf55dc7..315f46b 100644
--- a/chrome/browser/extensions/permissions_updater_unittest.cc
+++ b/chrome/browser/extensions/permissions_updater_unittest.cc
@@ -8,10 +8,10 @@
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_service_unittest.h"
 #include "chrome/browser/extensions/permissions_updater.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_test_util.h"
diff --git a/chrome/browser/extensions/platform_app_browsertest.cc b/chrome/browser/extensions/platform_app_browsertest.cc
index 28168bb..e301d3d 100644
--- a/chrome/browser/extensions/platform_app_browsertest.cc
+++ b/chrome/browser/extensions/platform_app_browsertest.cc
@@ -13,6 +13,7 @@
 #include "base/threading/platform_thread.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/automation/automation_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/api/permissions/permissions_api.h"
 #include "chrome/browser/extensions/component_loader.h"
@@ -31,7 +32,6 @@
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/extensions/native_app_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -43,7 +43,7 @@
 #include "content/public/browser/web_contents_view.h"
 #include "content/public/test/test_utils.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using apps::ShellWindow;
 using content::WebContents;
@@ -111,7 +111,7 @@
     const char* filename) {
   base::FilePath path = temp_dir.AppendASCII(
       filename).NormalizePathSeparators();
-  if (!(file_util::CopyFile(test_data_file, path)))
+  if (!(base::CopyFile(test_data_file, path)))
     return false;
 
   CommandLine* command_line = CommandLine::ForCurrentProcess();
diff --git a/chrome/browser/extensions/platform_app_browsertest_util.cc b/chrome/browser/extensions/platform_app_browsertest_util.cc
index 2d1cdd0..a2634c7 100644
--- a/chrome/browser/extensions/platform_app_browsertest_util.cc
+++ b/chrome/browser/extensions/platform_app_browsertest_util.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/extensions/platform_app_browsertest_util.h"
 
+#include "apps/app_window_contents.h"
 #include "base/command_line.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/extensions/api/tabs/tabs_api.h"
@@ -146,17 +147,19 @@
 
 ShellWindow* PlatformAppBrowserTest::CreateShellWindow(
     const Extension* extension) {
-  ShellWindow::CreateParams params;
-  return ShellWindow::Create(
-      browser()->profile(), new chrome::ChromeShellWindowDelegate(),
-      extension, GURL(std::string()), params);
+  return CreateShellWindowFromParams(extension, ShellWindow::CreateParams());
 }
 
 ShellWindow* PlatformAppBrowserTest::CreateShellWindowFromParams(
     const Extension* extension, const ShellWindow::CreateParams& params) {
-  return ShellWindow::Create(
-      browser()->profile(), new chrome::ChromeShellWindowDelegate(),
-      extension, GURL(std::string()), params);
+  ShellWindow* window = new ShellWindow(
+      browser()->profile(),
+      new chrome::ChromeShellWindowDelegate(),
+      extension);
+  window->Init(GURL(std::string()),
+               new apps::AppWindowContents(window),
+               params);
+  return window;
 }
 
 void PlatformAppBrowserTest::CloseShellWindow(ShellWindow* window) {
diff --git a/chrome/browser/extensions/platform_app_launcher.cc b/chrome/browser/extensions/platform_app_launcher.cc
index 03d914b..66d1133 100644
--- a/chrome/browser/extensions/platform_app_launcher.cc
+++ b/chrome/browser/extensions/platform_app_launcher.cc
@@ -146,8 +146,8 @@
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
 
     // If the file doesn't exist, or is a directory, launch with no launch data.
-    if (!file_util::PathExists(file_path_) ||
-        file_util::DirectoryExists(file_path_)) {
+    if (!base::PathExists(file_path_) ||
+        base::DirectoryExists(file_path_)) {
       LOG(WARNING) << "No file exists with path " << file_path_.value();
       BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
               &PlatformAppPathLauncher::LaunchWithNoLaunchData, this));
diff --git a/chrome/browser/extensions/plugin_manager.cc b/chrome/browser/extensions/plugin_manager.cc
index 1671fd8..f797cda 100644
--- a/chrome/browser/extensions/plugin_manager.cc
+++ b/chrome/browser/extensions/plugin_manager.cc
@@ -6,10 +6,10 @@
 #include "base/lazy_instance.h"
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/plugin_manager.h"
 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
 #include "chrome/common/extensions/extension.h"
@@ -17,7 +17,7 @@
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/common/pepper_plugin_info.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::PluginService;
 
diff --git a/chrome/browser/extensions/sandboxed_unpacker.cc b/chrome/browser/extensions/sandboxed_unpacker.cc
index 91b4cbc..cb40deb 100644
--- a/chrome/browser/extensions/sandboxed_unpacker.cc
+++ b/chrome/browser/extensions/sandboxed_unpacker.cc
@@ -18,18 +18,21 @@
 #include "base/path_service.h"
 #include "base/sequenced_task_runner.h"
 #include "base/strings/utf_string_conversions.h"  // TODO(viettrungluu): delete me.
+#include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_utility_messages.h"
 #include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/extension_file_util.h"
 #include "chrome/common/extensions/extension_l10n_util.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
-#include "chrome/common/extensions/unpacker.h"
+#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/utility_process_host.h"
+#include "content/public/common/common_param_traits.h"
 #include "crypto/signature_verifier.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/crx_file.h"
@@ -56,6 +59,7 @@
 #define UNPACK_RATE_HISTOGRAM(name, rate) \
     UMA_HISTOGRAM_CUSTOM_COUNTS(name, rate, 1, 100000, 100);
 
+namespace extensions {
 namespace {
 
 void RecordSuccessfulUnpackTimeHistograms(
@@ -141,7 +145,7 @@
     *temp_dir = normalized_temp_file.DirName();
   }
   // Clean up the temp file.
-  base::Delete(temp_file, false);
+  base::DeleteFile(temp_file, false);
 
   return normalized;
 }
@@ -172,20 +176,48 @@
   return false;
 }
 
-}  // namespace
+// Read the decoded images back from the file we saved them to.
+// |extension_path| is the path to the extension we unpacked that wrote the
+// data. Returns true on success.
+bool ReadImagesFromFile(const base::FilePath& extension_path,
+                        DecodedImages* images) {
+  base::FilePath path =
+      extension_path.AppendASCII(extension_filenames::kDecodedImagesFilename);
+  std::string file_str;
+  if (!file_util::ReadFileToString(path, &file_str))
+    return false;
 
-namespace extensions {
+  IPC::Message pickle(file_str.data(), file_str.size());
+  PickleIterator iter(pickle);
+  return IPC::ReadParam(&pickle, &iter, images);
+}
+
+// Read the decoded message catalogs back from the file we saved them to.
+// |extension_path| is the path to the extension we unpacked that wrote the
+// data. Returns true on success.
+bool ReadMessageCatalogsFromFile(const base::FilePath& extension_path,
+                                 base::DictionaryValue* catalogs) {
+  base::FilePath path = extension_path.AppendASCII(
+      extension_filenames::kDecodedMessageCatalogsFilename);
+  std::string file_str;
+  if (!file_util::ReadFileToString(path, &file_str))
+    return false;
+
+  IPC::Message pickle(file_str.data(), file_str.size());
+  PickleIterator iter(pickle);
+  return IPC::ReadParam(&pickle, &iter, catalogs);
+}
+
+}  // namespace
 
 SandboxedUnpacker::SandboxedUnpacker(
     const base::FilePath& crx_path,
-    bool run_out_of_process,
     Manifest::Location location,
     int creation_flags,
     const base::FilePath& extensions_dir,
     base::SequencedTaskRunner* unpacker_io_task_runner,
     SandboxedUnpackerClient* client)
     : crx_path_(crx_path),
-      run_out_of_process_(run_out_of_process),
       client_(client),
       extensions_dir_(extensions_dir),
       got_response_(false),
@@ -246,7 +278,7 @@
   PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackTempCrxPathLength",
                         temp_crx_path);
 
-  if (!file_util::CopyFile(crx_path_, temp_crx_path)) {
+  if (!base::CopyFile(crx_path_, temp_crx_path)) {
     // Failed to copy extension file to temporary directory.
     ReportFailure(
         FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY,
@@ -256,46 +288,29 @@
     return;
   }
 
-  // If we are supposed to use a subprocess, kick off the subprocess.
-  //
-  // TODO(asargent) we shouldn't need to do this branch here - instead
-  // UtilityProcessHost should handle it for us. (http://crbug.com/19192)
-  bool use_utility_process = run_out_of_process_ &&
-      !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess);
-  if (use_utility_process) {
-    // The utility process will have access to the directory passed to
-    // SandboxedUnpacker.  That directory should not contain a symlink or NTFS
-    // reparse point.  When the path is used, following the link/reparse point
-    // will cause file system access outside the sandbox path, and the sandbox
-    // will deny the operation.
-    base::FilePath link_free_crx_path;
-    if (!file_util::NormalizeFilePath(temp_crx_path, &link_free_crx_path)) {
-      LOG(ERROR) << "Could not get the normalized path of "
-                 << temp_crx_path.value();
-      ReportFailure(
-          COULD_NOT_GET_SANDBOX_FRIENDLY_PATH,
-          l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED));
-      return;
-    }
-    PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackLinkFreeCrxPathLength",
-                          link_free_crx_path);
-
-    BrowserThread::PostTask(
-        BrowserThread::IO, FROM_HERE,
-        base::Bind(
-            &SandboxedUnpacker::StartProcessOnIOThread,
-            this,
-            link_free_crx_path));
-  } else {
-    // Otherwise, unpack the extension in this process.
-    Unpacker unpacker(temp_crx_path, extension_id_, location_, creation_flags_);
-    if (unpacker.Run() && unpacker.DumpImagesToFile() &&
-        unpacker.DumpMessageCatalogsToFile()) {
-      OnUnpackExtensionSucceeded(*unpacker.parsed_manifest());
-    } else {
-      OnUnpackExtensionFailed(unpacker.error_message());
-    }
+  // The utility process will have access to the directory passed to
+  // SandboxedUnpacker.  That directory should not contain a symlink or NTFS
+  // reparse point.  When the path is used, following the link/reparse point
+  // will cause file system access outside the sandbox path, and the sandbox
+  // will deny the operation.
+  base::FilePath link_free_crx_path;
+  if (!file_util::NormalizeFilePath(temp_crx_path, &link_free_crx_path)) {
+    LOG(ERROR) << "Could not get the normalized path of "
+               << temp_crx_path.value();
+    ReportFailure(
+        COULD_NOT_GET_SANDBOX_FRIENDLY_PATH,
+        l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED));
+    return;
   }
+  PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackLinkFreeCrxPathLength",
+                        link_free_crx_path);
+
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::Bind(
+          &SandboxedUnpacker::StartProcessOnIOThread,
+          this,
+          link_free_crx_path));
 }
 
 SandboxedUnpacker::~SandboxedUnpacker() {
@@ -381,13 +396,14 @@
     return;
   }
 
-  if (!RewriteImageFiles())
+  SkBitmap install_icon;
+  if (!RewriteImageFiles(&install_icon))
     return;
 
   if (!RewriteCatalogFiles())
     return;
 
-  ReportSuccess(manifest);
+  ReportSuccess(manifest, install_icon);
 }
 
 void SandboxedUnpacker::OnUnpackExtensionFailed(const string16& error) {
@@ -573,7 +589,8 @@
 }
 
 void SandboxedUnpacker::ReportSuccess(
-    const DictionaryValue& original_manifest) {
+    const DictionaryValue& original_manifest,
+    const SkBitmap& install_icon) {
   UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccess", 1);
 
   RecordSuccessfulUnpackTimeHistograms(
@@ -581,7 +598,8 @@
 
   // Client takes ownership of temporary directory and extension.
   client_->OnUnpackSuccess(
-      temp_dir_.Take(), extension_root_, &original_manifest, extension_.get());
+      temp_dir_.Take(), extension_root_, &original_manifest, extension_.get(),
+      install_icon);
   extension_ = NULL;
 }
 
@@ -622,9 +640,9 @@
   return final_manifest.release();
 }
 
-bool SandboxedUnpacker::RewriteImageFiles() {
-  Unpacker::DecodedImages images;
-  if (!Unpacker::ReadImagesFromFile(temp_dir_.path(), &images)) {
+bool SandboxedUnpacker::RewriteImageFiles(SkBitmap* install_icon) {
+  DecodedImages images;
+  if (!ReadImagesFromFile(temp_dir_.path(), &images)) {
     // Couldn't read image data from disk.
     ReportFailure(
         COULD_NOT_READ_IMAGE_DATA_FROM_DISK,
@@ -661,7 +679,7 @@
               ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE")));
       return false;
     }
-    if (!base::Delete(extension_root_.Append(path), false)) {
+    if (!base::DeleteFile(extension_root_.Append(path), false)) {
       // Error removing old image file.
       ReportFailure(
           ERROR_REMOVING_OLD_IMAGE_FILE,
@@ -672,10 +690,27 @@
     }
   }
 
+  std::string install_icon_path = IconsInfo::GetIcons(extension_).Get(
+      extension_misc::EXTENSION_ICON_LARGE,
+      ExtensionIconSet::MATCH_BIGGER);
+
   // Write our parsed images back to disk as well.
   for (size_t i = 0; i < images.size(); ++i) {
+    if (BrowserThread::GetBlockingPool()->IsShutdownInProgress()) {
+      // Abort package installation if shutdown was initiated, crbug.com/235525
+      ReportFailure(
+          ABORTED_DUE_TO_SHUTDOWN,
+          l10n_util::GetStringFUTF16(
+              IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+              ASCIIToUTF16("ABORTED_DUE_TO_SHUTDOWN")));
+      return false;
+    }
+
     const SkBitmap& image = images[i].a;
     base::FilePath path_suffix = images[i].b;
+    if (path_suffix.MaybeAsASCII() == install_icon_path)
+      *install_icon = image;
+
     if (path_suffix.IsAbsolute() || path_suffix.ReferencesParent()) {
       // Invalid path for bitmap image.
       ReportFailure(
@@ -720,7 +755,7 @@
 
 bool SandboxedUnpacker::RewriteCatalogFiles() {
   DictionaryValue catalogs;
-  if (!Unpacker::ReadMessageCatalogsFromFile(temp_dir_.path(), &catalogs)) {
+  if (!ReadMessageCatalogsFromFile(temp_dir_.path(), &catalogs)) {
     // Could not read catalog data from disk.
     ReportFailure(
         COULD_NOT_READ_CATALOG_DATA_FROM_DISK,
diff --git a/chrome/browser/extensions/sandboxed_unpacker.h b/chrome/browser/extensions/sandboxed_unpacker.h
index 4a694c8..07031da 100644
--- a/chrome/browser/extensions/sandboxed_unpacker.h
+++ b/chrome/browser/extensions/sandboxed_unpacker.h
@@ -14,6 +14,8 @@
 #include "chrome/common/extensions/manifest.h"
 #include "content/public/browser/utility_process_host_client.h"
 
+class SkBitmap;
+
 namespace base {
 class DictionaryValue;
 class SequencedTaskRunner;
@@ -35,10 +37,13 @@
   //
   // extension - The extension that was unpacked. The client is responsible
   // for deleting this memory.
+  //
+  // install_icon - The icon we will display in the installation UI, if any.
   virtual void OnUnpackSuccess(const base::FilePath& temp_dir,
                                const base::FilePath& extension_root,
                                const base::DictionaryValue* original_manifest,
-                               const Extension* extension) = 0;
+                               const Extension* extension,
+                               const SkBitmap& install_icon) = 0;
   virtual void OnUnpackFailure(const string16& error) = 0;
 
  protected:
@@ -74,7 +79,6 @@
   // |client| with the result. If |run_out_of_process| is provided, unpacking
   // is done in a sandboxed subprocess. Otherwise, it is done in-process.
   SandboxedUnpacker(const base::FilePath& crx_path,
-                    bool run_out_of_process,
                     Manifest::Location location,
                     int creation_flags,
                     const base::FilePath& extensions_dir,
@@ -134,6 +138,7 @@
     INVALID_PATH_FOR_BITMAP_IMAGE,
     ERROR_RE_ENCODING_THEME_IMAGE,
     ERROR_SAVING_THEME_IMAGE,
+    ABORTED_DUE_TO_SHUTDOWN,
 
     // SandboxedUnpacker::RewriteCatalogFiles()
     COULD_NOT_READ_CATALOG_DATA_FROM_DISK,
@@ -177,7 +182,8 @@
   void OnUnpackExtensionFailed(const string16& error_message);
 
   void ReportFailure(FailureReason reason, const string16& message);
-  void ReportSuccess(const base::DictionaryValue& original_manifest);
+  void ReportSuccess(const base::DictionaryValue& original_manifest,
+                     const SkBitmap& install_icon);
 
   // Overwrites original manifest with safe result from utility process.
   // Returns NULL on error. Caller owns the returned object.
@@ -186,7 +192,7 @@
 
   // Overwrites original files with safe results from utility process.
   // Reports error and returns false if it fails.
-  bool RewriteImageFiles();
+  bool RewriteImageFiles(SkBitmap* install_icon);
   bool RewriteCatalogFiles();
 
   // Cleans up temp directory artifacts.
@@ -195,9 +201,6 @@
   // The path to the CRX to unpack.
   base::FilePath crx_path_;
 
-  // True if unpacking should be done by the utility process.
-  bool run_out_of_process_;
-
   // Our client.
   scoped_refptr<SandboxedUnpackerClient> client_;
 
diff --git a/chrome/browser/extensions/sandboxed_unpacker_unittest.cc b/chrome/browser/extensions/sandboxed_unpacker_unittest.cc
index 092f8f4..55fe555 100644
--- a/chrome/browser/extensions/sandboxed_unpacker_unittest.cc
+++ b/chrome/browser/extensions/sandboxed_unpacker_unittest.cc
@@ -2,78 +2,76 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/bind.h"
 #include "base/file_util.h"
-#include "base/files/file_enumerator.h"
-#include "base/files/scoped_temp_dir.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop.h"
 #include "base/path_service.h"
+#include "base/run_loop.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
 #include "chrome/browser/extensions/sandboxed_unpacker.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/unpacker.h"
-#include "content/public/test/test_browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_utils.h"
 #include "extensions/common/constants.h"
-#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
-using content::BrowserThread;
-using testing::_;
-using testing::Invoke;
-
-namespace {
-
-void OnUnpackSuccess(const base::FilePath& temp_dir,
-                     const base::FilePath& extension_root,
-                     const DictionaryValue* original_manifest,
-                     const extensions::Extension* extension) {
-  // Don't delete temp_dir here, we need to do some post op checking.
-}
-
-}  // namespace
-
 namespace extensions {
 
 class MockSandboxedUnpackerClient : public SandboxedUnpackerClient {
  public:
-  MOCK_METHOD4(OnUnpackSuccess,
-               void(const base::FilePath& temp_dir,
-                    const base::FilePath& extension_root,
-                    const DictionaryValue* original_manifest,
-                    const Extension* extension));
 
-  MOCK_METHOD1(OnUnpackFailure,
-               void(const string16& error));
-
-  void DelegateToFake() {
-    ON_CALL(*this, OnUnpackSuccess(_, _, _, _))
-        .WillByDefault(Invoke(::OnUnpackSuccess));
+  void WaitForUnpack() {
+    scoped_refptr<content::MessageLoopRunner> runner =
+        new content::MessageLoopRunner;
+    quit_closure_ = runner->QuitClosure();
+    runner->Run();
   }
 
- protected:
+  base::FilePath temp_dir() const { return temp_dir_; }
+
+ private:
   virtual ~MockSandboxedUnpackerClient() {}
+
+  virtual void OnUnpackSuccess(const base::FilePath& temp_dir,
+                               const base::FilePath& extension_root,
+                               const base::DictionaryValue* original_manifest,
+                               const Extension* extension,
+                               const SkBitmap& install_icon) OVERRIDE {
+    temp_dir_ = temp_dir;
+    quit_closure_.Run();
+
+  }
+
+  virtual void OnUnpackFailure(const string16& error) OVERRIDE {
+    ASSERT_TRUE(false);
+  }
+
+  base::Closure quit_closure_;
+  base::FilePath temp_dir_;
 };
 
 class SandboxedUnpackerTest : public testing::Test {
  public:
   virtual void SetUp() {
-   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    ASSERT_TRUE(extensions_dir_.CreateUniqueTempDir());
-    file_thread_.reset(new content::TestBrowserThread(BrowserThread::FILE,
-                                                      &loop_));
+    browser_threads_.reset(new content::TestBrowserThreadBundle(
+        content::TestBrowserThreadBundle::IO_MAINLOOP));
     // It will delete itself.
     client_ = new MockSandboxedUnpackerClient;
-    client_->DelegateToFake();
+    content::RenderProcessHost::SetRunRendererInProcess(true);
   }
 
   virtual void TearDown() {
     // Need to destruct SandboxedUnpacker before the message loop since
     // it posts a task to it.
     sandboxed_unpacker_ = NULL;
-    loop_.RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
+    content::RenderProcessHost::SetRunRendererInProcess(false);
   }
 
   void SetupUnpacker(const std::string& crx_name) {
@@ -82,143 +80,48 @@
     original_path = original_path.AppendASCII("extensions")
         .AppendASCII("unpacker")
         .AppendASCII(crx_name);
-    ASSERT_TRUE(file_util::PathExists(original_path)) << original_path.value();
-
-    // Try bots won't let us write into DIR_TEST_DATA, so we have to write the
-    // CRX to the temp directory, and create a subdirectory into which to
-    // unpack it.
-    base::FilePath crx_path = temp_dir_.path().AppendASCII(crx_name);
-    ASSERT_TRUE(file_util::CopyFile(original_path, crx_path)) <<
-        "Original path: " << original_path.value() <<
-        ", Crx path: " << crx_path.value();
-
-    unpacker_.reset(new Unpacker(
-        crx_path, std::string(), Manifest::INTERNAL, Extension::NO_FLAGS));
-
-    // Build a temp area where the extension will be unpacked.
-    temp_path_ =
-        temp_dir_.path().AppendASCII("sandboxed_unpacker_test_Temp");
-    ASSERT_TRUE(file_util::CreateDirectory(temp_path_));
+    ASSERT_TRUE(base::PathExists(original_path)) << original_path.value();
 
     sandboxed_unpacker_ = new SandboxedUnpacker(
-        crx_path,
-        false,
+        original_path,
         Manifest::INTERNAL,
         Extension::NO_FLAGS,
         extensions_dir_.path(),
-        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(),
+        base::MessageLoopProxy::current(),
         client_);
 
-    EXPECT_TRUE(PrepareUnpackerEnv());
-  }
-
-  bool PrepareUnpackerEnv() {
-    sandboxed_unpacker_->extension_root_ =
-      temp_dir_.path().AppendASCII(extension_filenames::kTempExtensionName);
-
-    if (!sandboxed_unpacker_->temp_dir_.Set(temp_dir_.path()))
-      return false;
-    sandboxed_unpacker_->public_key_ =
-      "ocnapchkplbmjmpfehjocmjnipfmogkh";
-    return true;
-  }
-
-  void OnUnpackSucceeded() {
-    sandboxed_unpacker_->OnUnpackExtensionSucceeded(
-        *unpacker_->parsed_manifest());
+    base::MessageLoopProxy::current()->PostTask(
+        FROM_HERE,
+        base::Bind(&SandboxedUnpacker::Start, sandboxed_unpacker_.get()));
+    client_->WaitForUnpack();
   }
 
   base::FilePath GetInstallPath() {
-    return temp_dir_.path().AppendASCII(
+    return client_->temp_dir().AppendASCII(
         extension_filenames::kTempExtensionName);
   }
 
-  bool TempFilesRemoved() {
-    // Check that temporary files were cleaned up.
-    int files_and_dirs = base::FileEnumerator::DIRECTORIES |
-        base::FileEnumerator::FILES;
-
-    base::FileEnumerator temp_iterator(
-      temp_path_,
-      true,  // recursive
-      files_and_dirs
-    );
-    int items_not_removed = 0;
-    base::FilePath item_in_temp;
-    item_in_temp = temp_iterator.Next();
-    while (!item_in_temp.value().empty()) {
-      items_not_removed++;
-      EXPECT_STREQ(FILE_PATH_LITERAL(""), item_in_temp.value().c_str())
-        << "File was not removed on success.";
-      item_in_temp = temp_iterator.Next();
-    }
-    return (items_not_removed == 0);
-  }
-
  protected:
-  base::ScopedTempDir temp_dir_;
   base::ScopedTempDir extensions_dir_;
-  base::FilePath temp_path_;
   MockSandboxedUnpackerClient* client_;
-  scoped_ptr<Unpacker> unpacker_;
   scoped_refptr<SandboxedUnpacker> sandboxed_unpacker_;
-  base::MessageLoop loop_;
-  scoped_ptr<content::TestBrowserThread> file_thread_;
+  scoped_ptr<content::TestBrowserThreadBundle> browser_threads_;
 };
 
 TEST_F(SandboxedUnpackerTest, NoCatalogsSuccess) {
-  EXPECT_CALL(*client_, OnUnpackSuccess(_, _, _, _));
-  EXPECT_CALL(*client_, OnUnpackFailure(_)).Times(0);
-
   SetupUnpacker("no_l10n.crx");
-  ASSERT_TRUE(unpacker_->Run());
-  ASSERT_TRUE(unpacker_->DumpImagesToFile());
-  ASSERT_TRUE(unpacker_->DumpMessageCatalogsToFile());
-
   // Check that there is no _locales folder.
   base::FilePath install_path =
-    GetInstallPath().Append(kLocaleFolder);
-  EXPECT_FALSE(file_util::PathExists(install_path));
-
-  OnUnpackSucceeded();
-
-  // Check that there still is no _locales folder.
-  EXPECT_FALSE(file_util::PathExists(install_path));
-
-  ASSERT_TRUE(TempFilesRemoved());
+      GetInstallPath().Append(kLocaleFolder);
+  EXPECT_FALSE(base::PathExists(install_path));
 }
 
 TEST_F(SandboxedUnpackerTest, WithCatalogsSuccess) {
-  EXPECT_CALL(*client_, OnUnpackSuccess(_, _, _, _));
-  EXPECT_CALL(*client_, OnUnpackFailure(_)).Times(0);
-
   SetupUnpacker("good_l10n.crx");
-  ASSERT_TRUE(unpacker_->Run());
-  ASSERT_TRUE(unpacker_->DumpImagesToFile());
-  ASSERT_TRUE(unpacker_->DumpMessageCatalogsToFile());
-
-  // Set timestamp on _locales/en_US/messages.json into the past.
-  base::FilePath messages_file;
-  messages_file = GetInstallPath().Append(kLocaleFolder)
-      .AppendASCII("en_US")
-      .Append(kMessagesFilename);
-  base::PlatformFileInfo old_info;
-  EXPECT_TRUE(file_util::GetFileInfo(messages_file, &old_info));
-  base::Time old_time =
-      old_info.last_modified - base::TimeDelta::FromSeconds(2);
-  EXPECT_TRUE(file_util::SetLastModifiedTime(messages_file, old_time));
-  // Refresh old_info, just to be sure.
-  EXPECT_TRUE(file_util::GetFileInfo(messages_file, &old_info));
-
-  OnUnpackSucceeded();
-
-  // Check that there is newer _locales/en_US/messages.json file.
-  base::PlatformFileInfo new_info;
-  EXPECT_TRUE(file_util::GetFileInfo(messages_file, &new_info));
-
-  EXPECT_TRUE(new_info.last_modified > old_info.last_modified);
-
-  ASSERT_TRUE(TempFilesRemoved());
+  // Check that there is _locales folder.
+  base::FilePath install_path =
+      GetInstallPath().Append(kLocaleFolder);
+  EXPECT_TRUE(base::PathExists(install_path));
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/script_badge_controller.cc b/chrome/browser/extensions/script_badge_controller.cc
index ab60b52..43aebb1 100644
--- a/chrome/browser/extensions/script_badge_controller.cc
+++ b/chrome/browser/extensions/script_badge_controller.cc
@@ -7,6 +7,7 @@
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/browser_event_router.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_id.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_messages.h"
 #include "chrome/common/extensions/extension_set.h"
@@ -24,9 +24,9 @@
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
 #include "ipc/ipc_message.h"
 #include "ipc/ipc_message_macros.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/script_badge_controller_unittest.cc b/chrome/browser/extensions/script_badge_controller_unittest.cc
index 1e5c90f..6eed1ad 100644
--- a/chrome/browser/extensions/script_badge_controller_unittest.cc
+++ b/chrome/browser/extensions/script_badge_controller_unittest.cc
@@ -8,12 +8,12 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/script_badge_controller.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/extensions/test_extension_system.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/extensions/extension.h"
diff --git a/chrome/browser/extensions/startup_helper.cc b/chrome/browser/extensions/startup_helper.cc
index 252f686..7bc9524 100644
--- a/chrome/browser/extensions/startup_helper.cc
+++ b/chrome/browser/extensions/startup_helper.cc
@@ -107,7 +107,8 @@
   virtual void OnUnpackSuccess(const base::FilePath& temp_dir,
                                const base::FilePath& extension_root,
                                const base::DictionaryValue* original_manifest,
-                               const Extension* extension) OVERRIDE {
+                               const Extension* extension,
+                               const SkBitmap& install_icon) OVERRIDE {
     finished_ = true;
     success_ = true;
     BrowserThread::PostTask(BrowserThread::UI,
@@ -139,7 +140,6 @@
 
     scoped_refptr<SandboxedUnpacker> unpacker(
         new SandboxedUnpacker(crx_file_,
-                              true /* out of process */,
                               Manifest::INTERNAL,
                               0, /* no special creation flags */
                               temp_dir_,
diff --git a/chrome/browser/extensions/state_store.cc b/chrome/browser/extensions/state_store.cc
index f1d09bc..c89cfc3 100644
--- a/chrome/browser/extensions/state_store.cc
+++ b/chrome/browser/extensions/state_store.cc
@@ -6,7 +6,7 @@
 
 #include "base/bind.h"
 #include "base/message_loop.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
diff --git a/chrome/browser/extensions/stubs_apitest.cc b/chrome/browser/extensions/stubs_apitest.cc
index 982d317..24c4d89 100644
--- a/chrome/browser/extensions/stubs_apitest.cc
+++ b/chrome/browser/extensions/stubs_apitest.cc
@@ -5,8 +5,8 @@
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "url/gurl.h"
 
 // Tests that we throw errors when you try using extension APIs that aren't
 // supported in content scripts.
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc
index 059ccc9..cfd07b7 100644
--- a/chrome/browser/extensions/tab_helper.cc
+++ b/chrome/browser/extensions/tab_helper.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/extensions/tab_helper.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/activity_log/activity_log.h"
 #include "chrome/browser/extensions/api/declarative/rules_registry_service.h"
 #include "chrome/browser/extensions/api/declarative_content/content_rules_registry.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/web_applications/web_app_ui.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/extension_icon_set.h"
@@ -408,13 +408,8 @@
                                         int return_route_id,
                                         bool success,
                                         const std::string& error) {
-  if (success) {
-    Send(new ExtensionMsg_InlineWebstoreInstallResponse(
-        return_route_id, install_id, true, std::string()));
-  } else {
-    Send(new ExtensionMsg_InlineWebstoreInstallResponse(
-        return_route_id, install_id, false, error));
-  }
+  Send(new ExtensionMsg_InlineWebstoreInstallResponse(
+      return_route_id, install_id, success, success ? std::string() : error));
 }
 
 WebContents* TabHelper::GetAssociatedWebContents() const {
diff --git a/chrome/browser/extensions/test_extension_dir.cc b/chrome/browser/extensions/test_extension_dir.cc
new file mode 100644
index 0000000..039fbe8
--- /dev/null
+++ b/chrome/browser/extensions/test_extension_dir.cc
@@ -0,0 +1,68 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/test_extension_dir.h"
+
+#include "base/file_util.h"
+#include "base/json/json_writer.h"
+#include "base/safe_numerics.h"
+#include "base/test/values_test_util.h"
+#include "chrome/browser/extensions/extension_creator.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+TestExtensionDir::TestExtensionDir() {
+  EXPECT_TRUE(dir_.CreateUniqueTempDir());
+  EXPECT_TRUE(crx_dir_.CreateUniqueTempDir());
+}
+
+TestExtensionDir::~TestExtensionDir() {
+}
+
+void TestExtensionDir::WriteManifest(base::StringPiece manifest) {
+  // TODO(kalman): Write some more convenient way to specify a manifest than
+  // via JSON, which requires awkwardly escaping all quotes. E.g. add a feature
+  // to JSONReader that can parse '' literals rather than "".
+  WriteFile(FILE_PATH_LITERAL("manifest.json"), manifest);
+}
+
+void TestExtensionDir::WriteFile(const base::FilePath::StringType& filename,
+                                 base::StringPiece contents) {
+  EXPECT_EQ(
+      base::checked_numeric_cast<int>(contents.size()),
+      file_util::WriteFile(
+          dir_.path().Append(filename), contents.data(), contents.size()));
+}
+
+// This function packs the extension into a .crx, and returns the path to that
+// .crx. Multiple calls to Pack() will produce extensions with the same ID.
+base::FilePath TestExtensionDir::Pack() {
+  ExtensionCreator creator;
+  base::FilePath crx_path =
+      crx_dir_.path().Append(FILE_PATH_LITERAL("ext.crx"));
+  base::FilePath pem_path =
+      crx_dir_.path().Append(FILE_PATH_LITERAL("ext.pem"));
+  base::FilePath pem_in_path, pem_out_path;
+  if (base::PathExists(pem_path))
+    pem_in_path = pem_path;
+  else
+    pem_out_path = pem_path;
+  if (!creator.Run(dir_.path(),
+                   crx_path,
+                   pem_in_path,
+                   pem_out_path,
+                   ExtensionCreator::kOverwriteCRX)) {
+    ADD_FAILURE()
+        << "ExtensionCreator::Run() failed: " << creator.error_message();
+    return base::FilePath();
+  }
+  if (!base::PathExists(crx_path)) {
+    ADD_FAILURE() << crx_path.value() << " was not created.";
+    return base::FilePath();
+  }
+  return crx_path;
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/test_extension_dir.h b/chrome/browser/extensions/test_extension_dir.h
new file mode 100644
index 0000000..df1d731
--- /dev/null
+++ b/chrome/browser/extensions/test_extension_dir.h
@@ -0,0 +1,50 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_TEST_EXTENSION_DIR_H_
+#define CHROME_BROWSER_EXTENSIONS_TEST_EXTENSION_DIR_H_
+
+#include "base/files/file_path.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/strings/string_piece.h"
+
+namespace extensions {
+
+// Provides a temporary directory to build an extension into.  This lets all of
+// an extension's code live inside the test instead of in a separate directory.
+class TestExtensionDir {
+ public:
+  TestExtensionDir();
+
+  ~TestExtensionDir();
+
+  // Writes |manifest| to manifest.json within the unpacked dir.  No validation
+  // is performed. If desired this should be done on extension installation.
+  void WriteManifest(base::StringPiece manifest);
+
+  // Writes |contents| to |filename| within the unpacked dir, overwriting
+  // anything that was already there.
+  void WriteFile(const base::FilePath::StringType& filename,
+                 base::StringPiece contents);
+
+  // Packs the extension into a .crx, and returns the path to that
+  // .crx. Multiple calls to Pack() will produce extensions with the same ID.
+  base::FilePath Pack();
+
+  // Returns the path to the unpacked directory.
+  base::FilePath unpacked_path() {
+    return dir_.path();
+  }
+
+ private:
+  // Stores files that make up the extension.
+  base::ScopedTempDir dir_;
+
+  // Stores the generated .crx and .pem.
+  base::ScopedTempDir crx_dir_;
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_TEST_EXTENSION_DIR_H_
diff --git a/chrome/browser/extensions/test_extension_prefs.cc b/chrome/browser/extensions/test_extension_prefs.cc
index 2a53a99..6c21f20 100644
--- a/chrome/browser/extensions/test_extension_prefs.cc
+++ b/chrome/browser/extensions/test_extension_prefs.cc
@@ -82,7 +82,7 @@
 
 void TestExtensionPrefs::ResetPrefRegistry() {
   pref_registry_ = new user_prefs::PrefRegistrySyncable;
-  ExtensionPrefs::RegisterUserPrefs(pref_registry_.get());
+  ExtensionPrefs::RegisterProfilePrefs(pref_registry_.get());
 }
 
 void TestExtensionPrefs::RecreateExtensionPrefs() {
diff --git a/chrome/browser/extensions/test_extension_system.h b/chrome/browser/extensions/test_extension_system.h
index 8701af4..3f30622 100644
--- a/chrome/browser/extensions/test_extension_system.h
+++ b/chrome/browser/extensions/test_extension_system.h
@@ -66,6 +66,11 @@
   virtual Blacklist* blacklist() OVERRIDE;
   virtual const OneShotEvent& ready() const OVERRIDE;
 
+  void SetReady() {
+    LOG(INFO) << "SetReady()";
+    ready_.Signal();
+  }
+
   // Factory method for tests to use with SetTestingProfile.
   static BrowserContextKeyedService* Build(content::BrowserContext* profile);
 
diff --git a/chrome/browser/extensions/theme_installed_infobar_delegate.cc b/chrome/browser/extensions/theme_installed_infobar_delegate.cc
index deb28c2..3a0ae75 100644
--- a/chrome/browser/extensions/theme_installed_infobar_delegate.cc
+++ b/chrome/browser/extensions/theme_installed_infobar_delegate.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/generated_resources.h"
@@ -28,25 +28,31 @@
     Profile* profile,
     const std::string& previous_theme_id,
     bool previous_using_native_theme) {
+  DCHECK(new_theme);
   if (!new_theme->is_theme())
     return;
 
-  // Get last active tabbed browser of profile.
-  Browser* browser = chrome::FindTabbedBrowser(profile,
-                                               true,
-                                               chrome::GetActiveDesktop());
+  // Create the new infobar.
+  // FindTabbedBrowser() is called with |match_original_profiles| true because a
+  // theme install in either a normal or incognito window for a profile affects
+  // all normal and incognito windows for that profile.
+  Browser* browser =
+      chrome::FindTabbedBrowser(profile, true, chrome::GetActiveDesktop());
   if (!browser)
     return;
-
   content::WebContents* web_contents =
       browser->tab_strip_model()->GetActiveWebContents();
   if (!web_contents)
     return;
   InfoBarService* infobar_service =
       InfoBarService::FromWebContents(web_contents);
+  ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile);
+  scoped_ptr<InfoBarDelegate> new_infobar(new ThemeInstalledInfoBarDelegate(
+      infobar_service, profile->GetExtensionService(), theme_service, new_theme,
+      previous_theme_id, previous_using_native_theme));
 
-  // First find any previous theme preview infobars.
-  InfoBarDelegate* old_delegate = NULL;
+  // If there's a previous theme infobar, just replace that instead of adding a
+  // new one.
   for (size_t i = 0; i < infobar_service->infobar_count(); ++i) {
     InfoBarDelegate* delegate = infobar_service->infobar_at(i);
     ThemeInstalledInfoBarDelegate* theme_infobar =
@@ -55,27 +61,17 @@
       // If the user installed the same theme twice, ignore the second install
       // and keep the first install info bar, so that they can easily undo to
       // get back the previous theme.
-      if (theme_infobar->theme_id_ == new_theme->id())
-        return;
-      old_delegate = delegate;
-      break;
+      if (theme_infobar->theme_id_ != new_theme->id()) {
+        infobar_service->ReplaceInfoBar(delegate, new_infobar.Pass());
+        theme_service->OnInfobarDisplayed();
+      }
+      return;
     }
   }
 
-  // Then either replace that old one or add a new one.
-  scoped_ptr<InfoBarDelegate> new_delegate(
-      new ThemeInstalledInfoBarDelegate(
-          infobar_service,
-          profile->GetExtensionService(),
-          ThemeServiceFactory::GetForProfile(profile),
-          new_theme,
-          previous_theme_id,
-          previous_using_native_theme));
-
-  if (old_delegate)
-    infobar_service->ReplaceInfoBar(old_delegate, new_delegate.Pass());
-  else
-    infobar_service->AddInfoBar(new_delegate.Pass());
+  // No previous theme infobar, so add this.
+  infobar_service->AddInfoBar(new_infobar.Pass());
+  theme_service->OnInfobarDisplayed();
 }
 
 ThemeInstalledInfoBarDelegate::ThemeInstalledInfoBarDelegate(
@@ -92,7 +88,6 @@
       theme_id_(new_theme->id()),
       previous_theme_id_(previous_theme_id),
       previous_using_native_theme_(previous_using_native_theme) {
-  theme_service_->OnInfobarDisplayed();
   registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
                  content::Source<ThemeService>(theme_service_));
 }
diff --git a/chrome/browser/extensions/token_cache/token_cache_service.cc b/chrome/browser/extensions/token_cache/token_cache_service.cc
index d07ebf8..9d5aabd 100644
--- a/chrome/browser/extensions/token_cache/token_cache_service.cc
+++ b/chrome/browser/extensions/token_cache/token_cache_service.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/extensions/token_cache/token_cache_service.h"
 
 #include "base/logging.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 
 using base::Time;
diff --git a/chrome/browser/extensions/token_cache/token_cache_service_unittest.cc b/chrome/browser/extensions/token_cache/token_cache_service_unittest.cc
index fb42678..fe54931 100644
--- a/chrome/browser/extensions/token_cache/token_cache_service_unittest.cc
+++ b/chrome/browser/extensions/token_cache/token_cache_service_unittest.cc
@@ -5,8 +5,8 @@
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/token_cache/token_cache_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/extensions/updater/extension_downloader.cc b/chrome/browser/extensions/updater/extension_downloader.cc
index 0af857d..0c114f7 100644
--- a/chrome/browser/extensions/updater/extension_downloader.cc
+++ b/chrome/browser/extensions/updater/extension_downloader.cc
@@ -19,10 +19,10 @@
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "base/version.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/updater/request_queue_impl.h"
 #include "chrome/browser/extensions/updater/safe_manifest_parser.h"
 #include "chrome/browser/metrics/metrics_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/extensions/extension_constants.h"
diff --git a/chrome/browser/extensions/updater/extension_downloader.h b/chrome/browser/extensions/updater/extension_downloader.h
index 29c2fc5..645bba4 100644
--- a/chrome/browser/extensions/updater/extension_downloader.h
+++ b/chrome/browser/extensions/updater/extension_downloader.h
@@ -9,8 +9,8 @@
 #include <map>
 #include <set>
 #include <string>
-#include <vector>
 #include <utility>
+#include <vector>
 
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
@@ -23,8 +23,8 @@
 #include "chrome/browser/extensions/updater/request_queue.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/update_manifest.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_fetcher_delegate.h"
+#include "url/gurl.h"
 
 namespace net {
 class URLFetcher;
diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc
index 1a861ae..b66f548 100644
--- a/chrome/browser/extensions/updater/extension_updater.cc
+++ b/chrome/browser/extensions/updater/extension_updater.cc
@@ -16,6 +16,7 @@
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/module/module.h"
 #include "chrome/browser/extensions/blacklist.h"
 #include "chrome/browser/extensions/crx_installer.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/extensions/pending_extension_manager.h"
 #include "chrome/browser/extensions/updater/extension_downloader.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_set.h"
 #include "chrome/common/extensions/manifest.h"
diff --git a/chrome/browser/extensions/updater/extension_updater.h b/chrome/browser/extensions/updater/extension_updater.h
index 94e0176..3a40f7e 100644
--- a/chrome/browser/extensions/updater/extension_updater.h
+++ b/chrome/browser/extensions/updater/extension_updater.h
@@ -23,7 +23,7 @@
 #include "chrome/browser/extensions/updater/manifest_fetch_data.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class ExtensionServiceInterface;
 class ExtensionSet;
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc
index f0e4330..07599e1 100644
--- a/chrome/browser/extensions/updater/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -23,6 +23,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/threading/thread.h"
 #include "base/version.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/blacklist.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_error_reporter.h"
@@ -39,7 +40,6 @@
 #include "chrome/browser/extensions/updater/request_queue_impl.h"
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "chrome/common/omaha_query_params/omaha_query_params.h"
@@ -50,7 +50,9 @@
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
-#include "content/public/test/test_browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_utils.h"
 #include "extensions/common/id_util.h"
 #include "libxml/globals.h"
 #include "net/base/backoff_entry.h"
@@ -71,6 +73,7 @@
 using base::TimeDelta;
 using content::BrowserThread;
 using testing::DoAll;
+using testing::InvokeWithoutArgs;
 using testing::Mock;
 using testing::Return;
 using testing::SetArgPointee;
@@ -142,6 +145,21 @@
   MOCK_METHOD1(IsExtensionPending, bool(const std::string&));
   MOCK_METHOD2(GetExtensionExistingVersion,
                bool(const std::string&, std::string*));
+
+  void Wait() {
+    scoped_refptr<content::MessageLoopRunner> runner =
+        new content::MessageLoopRunner;
+    quit_closure_ = runner->QuitClosure();
+    runner->Run();
+    quit_closure_.Reset();
+  }
+
+  void Quit() {
+    quit_closure_.Run();
+  }
+
+ private:
+  base::Closure quit_closure_;
 };
 
 const int kNotificationsObserved[] = {
@@ -177,10 +195,20 @@
     return updated_.find(id) != updated_.end();
   }
 
+  void Wait() {
+    scoped_refptr<content::MessageLoopRunner> runner =
+        new content::MessageLoopRunner;
+    quit_closure_ = runner->QuitClosure();
+    runner->Run();
+    quit_closure_.Reset();
+  }
+
  private:
   virtual void Observe(int type,
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE {
+    if (!quit_closure_.is_null())
+      quit_closure_.Run();
     for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
       if (kNotificationsObserved[i] == type) {
         count_[i]++;
@@ -197,6 +225,7 @@
   content::NotificationRegistrar registrar_;
   size_t count_[arraysize(kNotificationsObserved)];
   std::set<std::string> updated_;
+  base::Closure quit_closure_;
 
   DISALLOW_COPY_AND_ASSIGN(NotificationsObserver);
 };
@@ -469,16 +498,16 @@
 class ExtensionUpdaterTest : public testing::Test {
  public:
   ExtensionUpdaterTest()
-      : ui_thread_(BrowserThread::UI, &loop_),
-        file_thread_(BrowserThread::FILE, &loop_),
-        io_thread_(BrowserThread::IO, &loop_) {
+      : test_browser_thread_bundle_(
+            content::TestBrowserThreadBundle::IO_MAINLOOP) {
   }
 
   virtual ~ExtensionUpdaterTest() {
   }
 
   virtual void SetUp() OVERRIDE {
-    prefs_.reset(new TestExtensionPrefs(loop_.message_loop_proxy().get()));
+    prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
+    content::RenderProcessHost::SetRunRendererInProcess(true);
   }
 
   virtual void TearDown() OVERRIDE {
@@ -487,11 +516,12 @@
     // those objects are released.
     RunUntilIdle();
     prefs_.reset();
+    content::RenderProcessHost::SetRunRendererInProcess(false);
   }
 
   void RunUntilIdle() {
     prefs_->pref_service()->CommitPendingWrite();
-    loop_.RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 
   void SimulateTimerFired(ExtensionUpdater* updater) {
@@ -852,13 +882,15 @@
     EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
     EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
     EXPECT_CALL(delegate, OnExtensionDownloadFailed(
-        "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _));
+        "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _))
+        .WillOnce(InvokeWithoutArgs(&delegate,
+                                    &MockExtensionDownloaderDelegate::Quit));
     fetcher->set_url(kUpdateUrl);
     fetcher->set_status(net::URLRequestStatus());
     fetcher->set_response_code(200);
     fetcher->SetResponseString(kInvalidXml);
     fetcher->delegate()->OnURLFetchComplete(fetcher);
-    RunUntilIdle();
+    delegate.Wait();
     Mock::VerifyAndClearExpectations(&delegate);
 
     // The third fetcher doesn't have an update available.
@@ -879,13 +911,15 @@
         .WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"),
                         Return(true)));
     EXPECT_CALL(delegate, OnExtensionDownloadFailed(
-        "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _));
+        "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _))
+        .WillOnce(InvokeWithoutArgs(&delegate,
+                                    &MockExtensionDownloaderDelegate::Quit));
     fetcher->set_url(kUpdateUrl);
     fetcher->set_status(net::URLRequestStatus());
     fetcher->set_response_code(200);
     fetcher->SetResponseString(kNoUpdate);
     fetcher->delegate()->OnURLFetchComplete(fetcher);
-    RunUntilIdle();
+    delegate.Wait();
     Mock::VerifyAndClearExpectations(&delegate);
 
     // The last fetcher has an update.
@@ -910,7 +944,7 @@
     fetcher->set_response_code(200);
     fetcher->SetResponseString(kUpdateAvailable);
     fetcher->delegate()->OnURLFetchComplete(fetcher);
-    RunUntilIdle();
+    observer.Wait();
     Mock::VerifyAndClearExpectations(&delegate);
 
     // Verify that the downloader decided to update this extension.
@@ -1308,7 +1342,7 @@
 
     // Set up 2 mock extensions, one with a google.com update url and one
     // without.
-    prefs_.reset(new TestExtensionPrefs(loop_.message_loop_proxy().get()));
+    prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
     ServiceForManifestTests service(prefs_.get());
     ExtensionList tmp;
     GURL url1("http://clients2.google.com/service/update2/crx");
@@ -1468,10 +1502,7 @@
   scoped_ptr<TestExtensionPrefs> prefs_;
 
  private:
-  base::MessageLoop loop_;
-  content::TestBrowserThread ui_thread_;
-  content::TestBrowserThread file_thread_;
-  content::TestBrowserThread io_thread_;
+  content::TestBrowserThreadBundle test_browser_thread_bundle_;
 
 #if defined OS_CHROMEOS
   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
diff --git a/chrome/browser/extensions/updater/manifest_fetch_data.h b/chrome/browser/extensions/updater/manifest_fetch_data.h
index e830baa..744299b 100644
--- a/chrome/browser/extensions/updater/manifest_fetch_data.h
+++ b/chrome/browser/extensions/updater/manifest_fetch_data.h
@@ -10,7 +10,7 @@
 #include <string>
 
 #include "base/basictypes.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/updater/safe_manifest_parser.cc b/chrome/browser/extensions/updater/safe_manifest_parser.cc
index ae571c7..c947287 100644
--- a/chrome/browser/extensions/updater/safe_manifest_parser.cc
+++ b/chrome/browser/extensions/updater/safe_manifest_parser.cc
@@ -10,7 +10,6 @@
 #include "base/logging.h"
 #include "chrome/common/chrome_utility_messages.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/resource_dispatcher_host.h"
 #include "content/public/browser/utility_process_host.h"
 #include "content/public/common/content_switches.h"
 #include "ipc/ipc_message_macros.h"
@@ -45,36 +44,11 @@
 void SafeManifestParser::ParseInSandbox() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
-  // TODO(asargent) we shouldn't need to do this branch here - instead
-  // UtilityProcessHost should handle it for us. (http://crbug.com/19192)
-  bool use_utility_process = content::ResourceDispatcherHost::Get() &&
-      !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess);
-  if (use_utility_process) {
-    content::UtilityProcessHost* host = content::UtilityProcessHost::Create(
-        this,
-        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get());
-    host->EnableZygote();
-    host->Send(new ChromeUtilityMsg_ParseUpdateManifest(xml_));
-  } else {
-    UpdateManifest manifest;
-    if (manifest.Parse(xml_)) {
-      if (!BrowserThread::PostTask(
-              BrowserThread::UI, FROM_HERE,
-              base::Bind(
-                  &SafeManifestParser::OnParseUpdateManifestSucceeded, this,
-                  manifest.results()))) {
-        NOTREACHED();
-      }
-    } else {
-      if (!BrowserThread::PostTask(
-              BrowserThread::UI, FROM_HERE,
-              base::Bind(
-                  &SafeManifestParser::OnParseUpdateManifestFailed, this,
-                  manifest.errors()))) {
-        NOTREACHED();
-      }
-    }
-  }
+  content::UtilityProcessHost* host = content::UtilityProcessHost::Create(
+      this,
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get());
+  host->EnableZygote();
+  host->Send(new ChromeUtilityMsg_ParseUpdateManifest(xml_));
 }
 
 bool SafeManifestParser::OnMessageReceived(const IPC::Message& message) {
diff --git a/chrome/browser/extensions/user_script_listener.cc b/chrome/browser/extensions/user_script_listener.cc
index 229aa40..1e2c587 100644
--- a/chrome/browser/extensions/user_script_listener.cc
+++ b/chrome/browser/extensions/user_script_listener.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/extensions/user_script_listener.h"
 
 #include "base/bind.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/extensions/user_script_listener_unittest.cc b/chrome/browser/extensions/user_script_listener_unittest.cc
index 18d899a..23ea469 100644
--- a/chrome/browser/extensions/user_script_listener_unittest.cc
+++ b/chrome/browser/extensions/user_script_listener_unittest.cc
@@ -6,10 +6,10 @@
 #include "base/json/json_file_value_serializer.h"
 #include "base/message_loop.h"
 #include "base/threading/thread.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service_unittest.h"
 #include "chrome/browser/extensions/unpacked_installer.h"
 #include "chrome/browser/extensions/user_script_listener.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/extension_file_util.h"
 #include "chrome/test/base/testing_profile.h"
@@ -79,7 +79,7 @@
 // Yoinked from extension_manifest_unittest.cc.
 DictionaryValue* LoadManifestFile(const base::FilePath path,
                                   std::string* error) {
-  EXPECT_TRUE(file_util::PathExists(path));
+  EXPECT_TRUE(base::PathExists(path));
   JSONFileValueSerializer serializer(path);
   return static_cast<DictionaryValue*>(serializer.Deserialize(NULL, error));
 }
diff --git a/chrome/browser/extensions/user_script_master.cc b/chrome/browser/extensions/user_script_master.cc
index dd785e8..64f892b 100644
--- a/chrome/browser/extensions/user_script_master.cc
+++ b/chrome/browser/extensions/user_script_master.cc
@@ -16,11 +16,11 @@
 #include "base/strings/string_util.h"
 #include "base/threading/thread.h"
 #include "base/version.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/image_loader.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/i18n/default_locale_handler.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_file_util.h"
diff --git a/chrome/browser/extensions/user_script_master.h b/chrome/browser/extensions/user_script_master.h
index 166244c..b805f7c 100644
--- a/chrome/browser/extensions/user_script_master.h
+++ b/chrome/browser/extensions/user_script_master.h
@@ -12,7 +12,7 @@
 #include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/shared_memory.h"
+#include "base/memory/shared_memory.h"
 #include "base/strings/string_piece.h"
 #include "chrome/browser/extensions/extension_info_map.h"
 #include "chrome/common/extensions/extension_messages.h"
diff --git a/chrome/browser/extensions/user_script_master_unittest.cc b/chrome/browser/extensions/user_script_master_unittest.cc
index 67fbf3d..d072c30 100644
--- a/chrome/browser/extensions/user_script_master_unittest.cc
+++ b/chrome/browser/extensions/user_script_master_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/message_loop.h"
 #include "base/path_service.h"
 #include "base/strings/string_util.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/extensions/web_view_browsertest.cc b/chrome/browser/extensions/web_view_browsertest.cc
index d3400ae..3f56d70 100644
--- a/chrome/browser/extensions/web_view_browsertest.cc
+++ b/chrome/browser/extensions/web_view_browsertest.cc
@@ -30,9 +30,17 @@
 using prerender::PrerenderLinkManagerFactory;
 
 namespace {
+  const char kEmptyResponsePath[] = "/close-socket";
   const char kRedirectResponsePath[] = "/server-redirect";
   const char kRedirectResponseFullPath[] =
       "/extensions/platform_apps/web_view/shim/guest_redirect.html";
+
+  class EmptyHttpResponse : public net::test_server::HttpResponse {
+  public:
+    virtual std::string ToResponseString() const OVERRIDE {
+      return std::string();
+    }
+  };
 }  // namespace
 
 // This class intercepts media access request from the embedder. The request
@@ -376,6 +384,18 @@
     return http_response.PassAs<net::test_server::HttpResponse>();
   }
 
+  // Handles |request| by serving an empty response.
+  static scoped_ptr<net::test_server::HttpResponse> EmptyResponseHandler(
+      const std::string& path,
+      const net::test_server::HttpRequest& request) {
+    if (StartsWithASCII(path, request.relative_url, true)) {
+      return scoped_ptr<net::test_server::HttpResponse>(
+          new EmptyHttpResponse);
+    }
+
+    return scoped_ptr<net::test_server::HttpResponse>();
+  }
+
   void TestHelper(const std::string& test_name,
                   const std::string& test_passed_msg,
                   const std::string& test_failed_msg,
@@ -390,6 +410,9 @@
                    kRedirectResponsePath,
                    embedded_test_server()->GetURL(kRedirectResponseFullPath)));
 
+    embedded_test_server()->RegisterRequestHandler(
+        base::Bind(&WebViewTest::EmptyResponseHandler, kEmptyResponsePath));
+
     content::WebContents* embedder_web_contents =
         GetFirstShellWindowWebContents();
     ASSERT_TRUE(embedder_web_contents);
@@ -594,6 +617,34 @@
              "web_view/shim");
 }
 
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortEmptyResponse) {
+  TestHelper("testLoadAbortEmptyResponse",
+             "DoneShimTest.PASSED",
+             "DoneShimTest.FAILED",
+             "web_view/shim");
+}
+
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortIllegalChromeURL) {
+  TestHelper("testLoadAbortIllegalChromeURL",
+             "DoneShimTest.PASSED",
+             "DoneShimTest.FAILED",
+             "web_view/shim");
+}
+
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortIllegalFileURL) {
+  TestHelper("testLoadAbortIllegalFileURL",
+             "DoneShimTest.PASSED",
+             "DoneShimTest.FAILED",
+             "web_view/shim");
+}
+
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestReload) {
+  TestHelper("testReload",
+             "DoneShimTest.PASSED",
+             "DoneShimTest.FAILED",
+             "web_view/shim");
+}
+
 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestGetProcessId) {
   TestHelper("testGetProcessId",
              "DoneShimTest.PASSED",
@@ -601,6 +652,57 @@
              "web_view/shim");
 }
 
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestRemoveWebviewOnExit) {
+  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
+
+  // Launch the app and wait until it's ready to load a test.
+  ExtensionTestMessageListener launched_listener("Launched", false);
+  LoadAndLaunchPlatformApp("web_view/shim");
+  ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
+
+  content::WebContents* embedder_web_contents =
+      GetFirstShellWindowWebContents();
+  ASSERT_TRUE(embedder_web_contents);
+
+  GURL::Replacements replace_host;
+  std::string host_str("localhost");  // Must stay in scope with replace_host.
+  replace_host.SetHostStr(host_str);
+
+  std::string guest_path(
+      "/extensions/platform_apps/web_view/shim/empty_guest.html");
+  GURL guest_url = embedded_test_server()->GetURL(guest_path);
+  guest_url = guest_url.ReplaceComponents(replace_host);
+
+  ui_test_utils::UrlLoadObserver guest_observer(
+      guest_url, content::NotificationService::AllSources());
+
+  // Run the test and wait until the guest WebContents is available and has
+  // finished loading.
+  ExtensionTestMessageListener guest_loaded_listener("guest-loaded", false);
+  EXPECT_TRUE(content::ExecuteScript(
+                  embedder_web_contents,
+                  "runTest('testRemoveWebviewOnExit')"));
+  guest_observer.Wait();
+
+  content::Source<content::NavigationController> source =
+      guest_observer.source();
+  EXPECT_TRUE(source->GetWebContents()->GetRenderProcessHost()->IsGuest());
+
+  ASSERT_TRUE(guest_loaded_listener.WaitUntilSatisfied());
+
+  content::WindowedNotificationObserver observer(
+      content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
+      content::Source<content::WebContents>(source->GetWebContents()));
+
+  // Tell the embedder to kill the guest.
+  EXPECT_TRUE(content::ExecuteScript(
+                  embedder_web_contents,
+                  "removeWebviewOnExitDoCrash();"));
+
+  // Wait until the guest WebContents is destroyed.
+  observer.Wait();
+}
+
 IN_PROC_BROWSER_TEST_F(WebViewTest, ShimSrcAttribute) {
   ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/src_attribute"))
       << message_;
@@ -1202,11 +1304,11 @@
         "platform_apps/web_view/geolocation/cancel_request")) << message_;
 }
 
-IN_PROC_BROWSER_TEST_F(WebViewTest, Navigation) {
-  TestHelper("testNavigation",
-             "DoneNavigationTest.PASSED",
-             "DoneNavigationTest.FAILED",
-             "web_view/navigation");
+IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationRequestGone) {
+  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
+  ASSERT_TRUE(RunPlatformAppTest(
+        "platform_apps/web_view/geolocation/geolocation_request_gone"))
+            << message_;
 }
 
 IN_PROC_BROWSER_TEST_F(WebViewTest, ConsoleMessage) {
@@ -1275,3 +1377,8 @@
   ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/document_ready"))
                   << message_;
 }
+
+IN_PROC_BROWSER_TEST_F(WebViewTest, SetPropertyOnDocumentInteractive) {
+  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/document_interactive"))
+                  << message_;
+}
diff --git a/chrome/browser/extensions/web_view_interactive_browsertest.cc b/chrome/browser/extensions/web_view_interactive_browsertest.cc
index 69b5cbc..04d6e4b 100644
--- a/chrome/browser/extensions/web_view_interactive_browsertest.cc
+++ b/chrome/browser/extensions/web_view_interactive_browsertest.cc
@@ -17,6 +17,7 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_view.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "ui/base/keycodes/keyboard_codes.h"
@@ -52,6 +53,11 @@
     SendMouseEvent(button, ui_controls::UP);
   }
 
+  void MoveMouseInsideWindow(const gfx::Point& point) {
+    ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
+        gfx::Point(corner_.x() + point.x(), corner_.y() + point.y())));
+  }
+
   gfx::NativeWindow GetPlatformAppWindow() {
     const extensions::ShellWindowRegistry::ShellWindowList& shell_windows =
         extensions::ShellWindowRegistry::Get(
@@ -90,20 +96,48 @@
 #endif
   }
 
-  void SendMouseEvent(ui_controls::MouseButton button,
-                      ui_controls::MouseButtonState state) {
-   if (first_click_) {
-     mouse_click_result_ = ui_test_utils::SendMouseEventsSync(button,
-                                                              state);
-     first_click_ = false;
-   } else {
-     ASSERT_EQ(mouse_click_result_, ui_test_utils::SendMouseEventsSync(
-         button, state));
-   }
+  void SendBackShortcutToPlatformApp() {
+#if defined(OS_MACOSX)
+    // Send Cmd+[ on MacOSX.
+    ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
+        GetPlatformAppWindow(), ui::VKEY_OEM_4, false, false, false, true));
+#else
+    // Send browser back key on Linux/Windows.
+    ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
+        GetPlatformAppWindow(), ui::VKEY_BROWSER_BACK,
+        false, false, false, false));
+#endif
   }
 
-  void NewWindowTestHelper(const std::string& test_name,
-                           const std::string& app_location) {
+  void SendForwardShortcutToPlatformApp() {
+#if defined(OS_MACOSX)
+    // Send Cmd+] on MacOSX.
+    ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
+        GetPlatformAppWindow(), ui::VKEY_OEM_6, false, false, false, true));
+#else
+    // Send browser back key on Linux/Windows.
+    ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
+        GetPlatformAppWindow(), ui::VKEY_BROWSER_FORWARD,
+        false, false, false, false));
+#endif
+  }
+
+  void SendMouseEvent(ui_controls::MouseButton button,
+                      ui_controls::MouseButtonState state) {
+    if (first_click_) {
+      mouse_click_result_ = ui_test_utils::SendMouseEventsSync(button,
+                                                                state);
+      first_click_ = false;
+    } else {
+      ASSERT_EQ(mouse_click_result_, ui_test_utils::SendMouseEventsSync(
+          button, state));
+    }
+  }
+
+  void TestHelper(const std::string& test_name,
+                  const std::string& test_passed_msg,
+                  const std::string& test_failed_msg,
+                  const std::string& app_location) {
     ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
     ExtensionTestMessageListener launched_listener("Launched", false);
     LoadAndLaunchPlatformApp(app_location.c_str());
@@ -113,13 +147,11 @@
         GetFirstShellWindowWebContents();
     ASSERT_TRUE(embedder_web_contents);
 
-    ExtensionTestMessageListener done_listener("DoneNewWindowTest.PASSED",
-                                               false);
-    done_listener.AlsoListenForFailureMessage("DoneNewWindowTest.FAILED");
+    ExtensionTestMessageListener done_listener(test_passed_msg, false);
+    done_listener.AlsoListenForFailureMessage(test_failed_msg);
     EXPECT_TRUE(content::ExecuteScript(
                     embedder_web_contents,
-                    base::StringPrintf("runNewWindowTest('%s')",
-                                       test_name.c_str())));
+                    base::StringPrintf("runTest('%s')", test_name.c_str())));
     ASSERT_TRUE(done_listener.WaitUntilSatisfied());
   }
 
@@ -154,6 +186,16 @@
     gfx::Rect offset;
     embedder_web_contents_->GetView()->GetContainerBounds(&offset);
     corner_ = gfx::Point(offset.x(), offset.y());
+
+    const testing::TestInfo* const test_info =
+            testing::UnitTest::GetInstance()->current_test_info();
+    const std::string& prefix = "DragDropWithinWebView";
+    if (!strncmp(test_info->name(), prefix.c_str(), prefix.size())) {
+      // In the drag drop test we add 20px padding to the page body because on
+      // windows if we get too close to the edge of the window the resize cursor
+      // appears and we start dragging the window edge.
+      corner_.Offset(20, 20);
+    }
   }
 
   content::WebContents* guest_web_contents() {
@@ -278,12 +320,66 @@
     WaitForTitle("PASSED3");
   }
 
- private:
+  void DragTestStep1() {
+    // Move mouse to start of text.
+    MoveMouseInsideWindow(gfx::Point(45, 8));
+    SendMouseEvent(ui_controls::LEFT, ui_controls::DOWN);
+    MoveMouseInsideWindow(gfx::Point(76, 12));
+
+    // Now wait a bit before moving mouse to initiate drag/drop.
+    base::MessageLoop::current()->PostDelayedTask(
+        FROM_HERE,
+        base::Bind(&WebViewInteractiveTest::DragTestStep2,
+                   base::Unretained(this)),
+        base::TimeDelta::FromMilliseconds(200));
+  }
+
+  void DragTestStep2() {
+    // Drag source over target.
+    MoveMouseInsideWindow(gfx::Point(76, 76));
+
+    // Create a second mouse over the source to trigger the drag over event.
+    MoveMouseInsideWindow(gfx::Point(76, 77));
+
+    // Release mouse to drop.
+    SendMouseEvent(ui_controls::LEFT, ui_controls::UP);
+    SendMouseClick(ui_controls::LEFT);
+
+    quit_closure_.Run();
+
+    // Note that following ExtensionTestMessageListener and ExecuteScript*
+    // call must be after we quit |quit_closure_|. Otherwise the class
+    // here won't be able to receive messages sent by chrome.test.sendMessage.
+    // This is because of the nature of drag and drop code (esp. the
+    // MessageLoop) in it.
+
+    // Now verify we got a drop and correct drop data.
+    ExtensionTestMessageListener drop_listener("guest-got-drop", false);
+    EXPECT_TRUE(content::ExecuteScript(guest_web_contents_,
+                                       "window.pingEmbedder()"));
+    EXPECT_TRUE(drop_listener.WaitUntilSatisfied());
+
+    std::string last_drop_data;
+    EXPECT_TRUE(content::ExecuteScriptAndExtractString(
+        embedder_web_contents_,
+        "window.domAutomationController.send(getLastDropData())",
+        &last_drop_data));
+    EXPECT_EQ(last_drop_data, "Drop me");
+  }
+
+ protected:
+  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+    command_line->AppendSwitch(switches::kEnableBrowserPluginDragDrop);
+    extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line);
+  }
+
   content::WebContents* guest_web_contents_;
   content::WebContents* embedder_web_contents_;
   gfx::Point corner_;
   bool mouse_click_result_;
   bool first_click_;
+  // Only used in drag/drop test.
+  base::Closure quit_closure_;
 };
 
 // ui_test_utils::SendMouseMoveSync doesn't seem to work on OS_MACOSX, and
@@ -410,32 +506,53 @@
 
 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
                        NewWindow_NewWindowNameTakesPrecedence) {
-  NewWindowTestHelper("testNewWindowNameTakesPrecedence", "web_view/newwindow");
+  TestHelper("testNewWindowNameTakesPrecedence",
+             "DoneNewWindowTest.PASSED",
+             "DoneNewWindowTest.FAILED",
+             "web_view/newwindow");
 }
 
 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
                        NewWindow_WebViewNameTakesPrecedence) {
-  NewWindowTestHelper("testWebViewNameTakesPrecedence", "web_view/newwindow");
+  TestHelper("testWebViewNameTakesPrecedence",
+             "DoneNewWindowTest.PASSED",
+             "DoneNewWindowTest.FAILED",
+             "web_view/newwindow");
 }
 
 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_NoName) {
-  NewWindowTestHelper("testNoName", "web_view/newwindow");
+  TestHelper("testNoName",
+             "DoneNewWindowTest.PASSED",
+             "DoneNewWindowTest.FAILED",
+             "web_view/newwindow");
 }
 
 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_Redirect) {
-  NewWindowTestHelper("testNewWindowRedirect", "web_view/newwindow");
+  TestHelper("testNewWindowRedirect",
+             "DoneNewWindowTest.PASSED",
+             "DoneNewWindowTest.FAILED",
+             "web_view/newwindow");
 }
 
 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_Close) {
-  NewWindowTestHelper("testNewWindowClose", "web_view/newwindow");
+  TestHelper("testNewWindowClose",
+             "DoneNewWindowTest.PASSED",
+             "DoneNewWindowTest.FAILED",
+             "web_view/newwindow");
 }
 
 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_ExecuteScript) {
-  NewWindowTestHelper("testNewWindowExecuteScript", "web_view/newwindow");
+  TestHelper("testNewWindowExecuteScript",
+             "DoneNewWindowTest.PASSED",
+             "DoneNewWindowTest.FAILED",
+             "web_view/newwindow");
 }
 
 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_WebRequest) {
-  NewWindowTestHelper("testNewWindowWebRequest", "web_view/newwindow");
+  TestHelper("testNewWindowWebRequest",
+             "DoneNewWindowTest.PASSED",
+             "DoneNewWindowTest.FAILED",
+             "web_view/newwindow");
 }
 
 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, ExecuteCode) {
@@ -444,7 +561,9 @@
       "platform_apps/web_view/common", "execute_code")) << message_;
 }
 
-IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, PopupPositioning) {
+// This test used the old Autofill UI, which has been removed.
+// See crbug.com/259438
+IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DISABLED_PopupPositioning) {
   SetupTest(
       "web_view/popup_positioning",
       "/extensions/platform_apps/web_view/popup_positioning/guest.html");
@@ -470,3 +589,68 @@
 
   PopupTestHelper(gfx::Point(20, 0));
 }
+
+// Drag and drop inside a webview is currently only enabled for linux and mac,
+// but the tests don't work on anything except chromeos for now. This is because
+// of simulating mouse drag code's dependency on platforms.
+#if defined(OS_CHROMEOS)
+IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DragDropWithinWebView) {
+  SetupTest(
+      "web_view/dnd_within_webview",
+      "/extensions/platform_apps/web_view/dnd_within_webview/guest.html");
+  ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow()));
+
+  // Flush any pending events to make sure we start with a clean slate.
+  content::RunAllPendingInMessageLoop();
+  base::RunLoop run_loop;
+  quit_closure_ = run_loop.QuitClosure();
+  base::MessageLoop::current()->PostTask(
+      FROM_HERE,
+      base::Bind(&WebViewInteractiveTest::DragTestStep1,
+                 base::Unretained(this)));
+  run_loop.Run();
+}
+#endif  // (defined(OS_CHROMEOS))
+
+IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Navigation) {
+  TestHelper("testNavigation",
+             "DoneNavigationTest.PASSED",
+             "DoneNavigationTest.FAILED",
+             "web_view/navigation");
+}
+
+IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Navigation_BackForwardKeys) {
+  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
+  ExtensionTestMessageListener launched_listener("Launched", false);
+  LoadAndLaunchPlatformApp("web_view/navigation");
+  ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
+
+  ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
+      GetPlatformAppWindow()));
+  // Flush any pending events to make sure we start with a clean slate.
+  content::RunAllPendingInMessageLoop();
+
+  content::WebContents* embedder_web_contents =
+      GetFirstShellWindowWebContents();
+  ASSERT_TRUE(embedder_web_contents);
+
+  ExtensionTestMessageListener done_listener(
+      "DoneNavigationTest.PASSED", false);
+  done_listener.AlsoListenForFailureMessage("DoneNavigationTest.FAILED");
+  ExtensionTestMessageListener ready_back_key_listener(
+      "ReadyForBackKey", false);
+  ExtensionTestMessageListener ready_forward_key_listener(
+      "ReadyForForwardKey", false);
+
+  EXPECT_TRUE(content::ExecuteScript(
+                  embedder_web_contents,
+                  "runTest('testBackForwardKeys')"));
+
+  ASSERT_TRUE(ready_back_key_listener.WaitUntilSatisfied());
+  SendBackShortcutToPlatformApp();
+
+  ASSERT_TRUE(ready_forward_key_listener.WaitUntilSatisfied());
+  SendForwardShortcutToPlatformApp();
+
+  ASSERT_TRUE(done_listener.WaitUntilSatisfied());
+}
diff --git a/chrome/browser/extensions/webstore_data_fetcher.h b/chrome/browser/extensions/webstore_data_fetcher.h
index e8119e1..fb8aafd 100644
--- a/chrome/browser/extensions/webstore_data_fetcher.h
+++ b/chrome/browser/extensions/webstore_data_fetcher.h
@@ -9,8 +9,8 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_fetcher_delegate.h"
+#include "url/gurl.h"
 
 namespace base {
 class Value;
diff --git a/chrome/browser/extensions/webstore_inline_installer_unittest.cc b/chrome/browser/extensions/webstore_inline_installer_unittest.cc
index 70e4ba1..a9d2804 100644
--- a/chrome/browser/extensions/webstore_inline_installer_unittest.cc
+++ b/chrome/browser/extensions/webstore_inline_installer_unittest.cc
@@ -9,8 +9,8 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/test_browser_thread.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/webstore_install_helper.h b/chrome/browser/extensions/webstore_install_helper.h
index 5d5c83f..370ce9c 100644
--- a/chrome/browser/extensions/webstore_install_helper.h
+++ b/chrome/browser/extensions/webstore_install_helper.h
@@ -10,9 +10,9 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "content/public/browser/utility_process_host_client.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "url/gurl.h"
 
 class SkBitmap;
 
diff --git a/chrome/browser/extensions/webstore_installer.cc b/chrome/browser/extensions/webstore_installer.cc
index bd40ef5..44b6450 100644
--- a/chrome/browser/extensions/webstore_installer.cc
+++ b/chrome/browser/extensions/webstore_installer.cc
@@ -14,6 +14,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_crx_util.h"
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/download/download_util.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
@@ -41,8 +41,8 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/escape.h"
+#include "url/gurl.h"
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/drive/file_system_util.h"
@@ -88,7 +88,7 @@
 
   // Ensure the download directory exists. TODO(asargent) - make this use
   // common code from the downloads system.
-  if (!file_util::DirectoryExists(directory)) {
+  if (!base::DirectoryExists(directory)) {
     if (!file_util::CreateDirectory(directory)) {
       BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                               base::Bind(callback, base::FilePath()));
@@ -161,7 +161,8 @@
     : profile(NULL),
       use_app_installed_bubble(false),
       skip_post_install_ui(false),
-      skip_install_dialog(false) {
+      skip_install_dialog(false),
+      enable_launcher(false) {
 }
 
 scoped_ptr<WebstoreInstaller::Approval>
diff --git a/chrome/browser/extensions/webstore_installer.h b/chrome/browser/extensions/webstore_installer.h
index 18b972e..0f9727f 100644
--- a/chrome/browser/extensions/webstore_installer.h
+++ b/chrome/browser/extensions/webstore_installer.h
@@ -18,9 +18,9 @@
 #include "content/public/browser/download_item.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/net_errors.h"
 #include "ui/gfx/image/image_skia.h"
+#include "url/gurl.h"
 
 class Profile;
 
diff --git a/chrome/browser/extensions/webstore_standalone_installer.cc b/chrome/browser/extensions/webstore_standalone_installer.cc
index 70e61ce..db3eca0 100644
--- a/chrome/browser/extensions/webstore_standalone_installer.cc
+++ b/chrome/browser/extensions/webstore_standalone_installer.cc
@@ -13,7 +13,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::WebContents;
 
diff --git a/chrome/browser/extensions/webstore_startup_installer.h b/chrome/browser/extensions/webstore_startup_installer.h
index 2fcd794..b89195b 100644
--- a/chrome/browser/extensions/webstore_startup_installer.h
+++ b/chrome/browser/extensions/webstore_startup_installer.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_WEBSTORE_STARTUP_INSTALLER_H_
 #define CHROME_BROWSER_EXTENSIONS_WEBSTORE_STARTUP_INSTALLER_H_
 
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 #include "webstore_standalone_installer.h"
 
 namespace content {
diff --git a/chrome/browser/extensions/webstore_startup_installer_browsertest.cc b/chrome/browser/extensions/webstore_startup_installer_browsertest.cc
index 019acee..6b727f4 100644
--- a/chrome/browser/extensions/webstore_startup_installer_browsertest.cc
+++ b/chrome/browser/extensions/webstore_startup_installer_browsertest.cc
@@ -5,6 +5,7 @@
 #include "base/command_line.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_install_ui.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_builder.h"
 #include "chrome/common/extensions/value_builder.h"
@@ -29,9 +29,9 @@
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/host_port_pair.h"
 #include "net/dns/mock_host_resolver.h"
+#include "url/gurl.h"
 
 using content::WebContents;
 using extensions::DictionaryBuilder;
@@ -151,14 +151,9 @@
   RunTest("runTest");
 }
 
-// Crashes at random intervals on MacOS: http://crbug.com/95713.
-// Flakes on Windows: http://crbug.com/229947
-#if defined(OS_MACOSX) || defined(OS_WIN)
-#define Maybe_ArgumentValidation DISABLED_ArgumentValidation
-#else
-#define Maybe_ArgumentValidation ArgumentValidation
-#endif
-IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallerTest, Maybe_ArgumentValidation) {
+// Flakes on all platforms: http://crbug.com/95713, http://crbug.com/229947
+IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallerTest,
+                       DISABLED_ArgumentValidation) {
   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
       switches::kAppsGalleryInstallAutoConfirmForTests, "cancel");
 
diff --git a/chrome/browser/fast_shutdown_browsertest.cc b/chrome/browser/fast_shutdown_browsertest.cc
index 5b7c3fb..949f0e6 100644
--- a/chrome/browser/fast_shutdown_browsertest.cc
+++ b/chrome/browser/fast_shutdown_browsertest.cc
@@ -5,13 +5,13 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/favicon/DEPS b/chrome/browser/favicon/DEPS
index 2ed7139..0496456 100644
--- a/chrome/browser/favicon/DEPS
+++ b/chrome/browser/favicon/DEPS
@@ -3,6 +3,7 @@
   # three basic rules followed by temporary exceptions.  Please don't
   # add to the list of exceptions!
   "-chrome/browser",
+  "+chrome/browser/chrome_notification_types.h",
   "+chrome/browser/common",
   "+chrome/browser/favicon",
 
diff --git a/chrome/browser/favicon/favicon_tab_helper.cc b/chrome/browser/favicon/favicon_tab_helper.cc
index 93af404..103bda5 100644
--- a/chrome/browser/favicon/favicon_tab_helper.cc
+++ b/chrome/browser/favicon/favicon_tab_helper.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/favicon/favicon_tab_helper.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_handler.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/favicon/favicon_util.h"
@@ -12,7 +13,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/favicon_status.h"
 #include "content/public/browser/invalidate_type.h"
diff --git a/chrome/browser/favicon/favicon_util.cc b/chrome/browser/favicon/favicon_util.cc
index 21c9d75..e53a71c 100644
--- a/chrome/browser/favicon/favicon_util.cc
+++ b/chrome/browser/favicon/favicon_util.cc
@@ -6,8 +6,6 @@
 
 #include "chrome/browser/favicon/favicon_types.h"
 #include "chrome/browser/history/select_favicon_frames.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/child/image_decoder_utils.h"
 #include "skia/ext/image_operations.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/codec/png_codec.h"
@@ -15,7 +13,6 @@
 #include "ui/gfx/image/image_png_rep.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/size.h"
-#include "url/gurl.h"
 
 #if defined(OS_MACOSX) && !defined(OS_IOS)
 #include "base/mac/mac_util.h"
@@ -200,30 +197,3 @@
   DCHECK_EQ(1u, selected_bitmap_indices.size());
   return selected_bitmap_indices[0];
 }
-
-// static
-bool FaviconUtil::ReencodeFavicon(const unsigned char* src_data,
-                                  size_t src_len,
-                                  std::vector<unsigned char>* png_data) {
-  // Decode the favicon using WebKit's image decoder.
-  SkBitmap decoded = content::DecodeImage(
-      src_data,
-      gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize),
-      src_len);
-  if (decoded.empty())
-    return false;  // Unable to decode.
-
-  if (decoded.width() != gfx::kFaviconSize ||
-      decoded.height() != gfx::kFaviconSize) {
-    // The bitmap is not the correct size, re-sample.
-    int new_width = decoded.width();
-    int new_height = decoded.height();
-    gfx::CalculateFaviconTargetSize(&new_width, &new_height);
-    decoded = skia::ImageOperations::Resize(
-        decoded, skia::ImageOperations::RESIZE_LANCZOS3, new_width, new_height);
-  }
-
-  // Encode our bitmap as a PNG.
-  gfx::PNGCodec::EncodeBGRASkBitmap(decoded, false, png_data);
-  return true;
-}
diff --git a/chrome/browser/favicon/favicon_util.h b/chrome/browser/favicon/favicon_util.h
index 89474e9..3bc3add 100644
--- a/chrome/browser/favicon/favicon_util.h
+++ b/chrome/browser/favicon/favicon_util.h
@@ -9,16 +9,10 @@
 
 #include "ui/base/layout.h"
 
-class GURL;
-
 namespace chrome {
 struct FaviconBitmapResult;
 }
 
-namespace content {
-class RenderViewHost;
-}
-
 namespace gfx {
 class Image;
 }
@@ -52,13 +46,6 @@
       const std::vector<SkBitmap>& bitmaps,
       const std::vector<ui::ScaleFactor>& scale_factors,
       int desired_size);
-
-  // Given raw image data, decodes the icon, re-sampling to the correct size as
-  // necessary, and re-encodes as PNG data in the given output vector. Returns
-  // true on success.
-  static bool ReencodeFavicon(const unsigned char* src_data,
-                              size_t src_len,
-                              std::vector<unsigned char>* png_data);
 };
 
 #endif  // CHROME_BROWSER_FAVICON_FAVICON_UTIL_H_
diff --git a/chrome/browser/feedback/feedback_util.h b/chrome/browser/feedback/feedback_util.h
index 5d103b4..0c0cec6 100644
--- a/chrome/browser/feedback/feedback_util.h
+++ b/chrome/browser/feedback/feedback_util.h
@@ -21,8 +21,6 @@
 #include "base/sys_info.h"
 #elif defined(OS_WIN)
 #include "base/win/windows_version.h"
-#elif defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #endif
 
 class Profile;
diff --git a/chrome/browser/file_select_helper.cc b/chrome/browser/file_select_helper.cc
index 6c44527..ef84e7c 100644
--- a/chrome/browser/file_select_helper.cc
+++ b/chrome/browser/file_select_helper.cc
@@ -5,11 +5,11 @@
 #include "chrome/browser/file_select_helper.h"
 
 #include <string>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/file_util.h"
 #include "base/files/file_enumerator.h"
-#include "base/platform_file.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -46,27 +46,8 @@
 
 void NotifyRenderViewHost(RenderViewHost* render_view_host,
                           const std::vector<ui::SelectedFileInfo>& files,
-                          ui::SelectFileDialog::Type dialog_type) {
-  const int kReadFilePermissions =
-      base::PLATFORM_FILE_OPEN |
-      base::PLATFORM_FILE_READ |
-      base::PLATFORM_FILE_EXCLUSIVE_READ |
-      base::PLATFORM_FILE_ASYNC;
-
-  const int kWriteFilePermissions =
-      base::PLATFORM_FILE_CREATE |
-      base::PLATFORM_FILE_CREATE_ALWAYS |
-      base::PLATFORM_FILE_OPEN |
-      base::PLATFORM_FILE_OPEN_ALWAYS |
-      base::PLATFORM_FILE_OPEN_TRUNCATED |
-      base::PLATFORM_FILE_WRITE |
-      base::PLATFORM_FILE_WRITE_ATTRIBUTES |
-      base::PLATFORM_FILE_ASYNC;
-
-  int permissions = kReadFilePermissions;
-  if (dialog_type == ui::SelectFileDialog::SELECT_SAVEAS_FILE)
-    permissions = kWriteFilePermissions;
-  render_view_host->FilesSelectedInChooser(files, permissions);
+                          FileChooserParams::Mode dialog_mode) {
+  render_view_host->FilesSelectedInChooser(files, dialog_mode);
 }
 
 // Converts a list of FilePaths to a list of ui::SelectedFileInfo.
@@ -97,7 +78,8 @@
       web_contents_(NULL),
       select_file_dialog_(),
       select_file_types_(),
-      dialog_type_(ui::SelectFileDialog::SELECT_OPEN_FILE) {
+      dialog_type_(ui::SelectFileDialog::SELECT_OPEN_FILE),
+      dialog_mode_(FileChooserParams::Open) {
 }
 
 FileSelectHelper::~FileSelectHelper() {
@@ -148,7 +130,7 @@
 
   std::vector<ui::SelectedFileInfo> files;
   files.push_back(file);
-  NotifyRenderViewHost(render_view_host_, files, dialog_type_);
+  NotifyRenderViewHost(render_view_host_, files, dialog_mode_);
 
   // No members should be accessed from here on.
   RunFileChooserEnd();
@@ -171,7 +153,7 @@
   if (!render_view_host_)
     return;
 
-  NotifyRenderViewHost(render_view_host_, files, dialog_type_);
+  NotifyRenderViewHost(render_view_host_, files, dialog_mode_);
 
   // No members should be accessed from here on.
   RunFileChooserEnd();
@@ -185,7 +167,7 @@
   // empty vector.
   NotifyRenderViewHost(
       render_view_host_, std::vector<ui::SelectedFileInfo>(),
-      dialog_type_);
+      dialog_mode_);
 
   // No members should be accessed from here on.
   RunFileChooserEnd();
@@ -241,7 +223,7 @@
       FilePathListToSelectedFileInfoList(entry->results_);
 
   if (id == kFileSelectEnumerationId)
-    NotifyRenderViewHost(entry->rvh_, selected_files, dialog_type_);
+    NotifyRenderViewHost(entry->rvh_, selected_files, dialog_mode_);
   else
     entry->rvh_->DirectoryEnumerationFinished(id, entry->results_);
 
@@ -387,6 +369,7 @@
   select_file_dialog_ = ui::SelectFileDialog::Create(
       this, new ChromeSelectFilePolicy(web_contents_));
 
+  dialog_mode_ = params.mode;
   switch (params.mode) {
     case FileChooserParams::Open:
       dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE;
@@ -415,8 +398,8 @@
 
 #if defined(OS_ANDROID)
   // Android needs the original MIME types and an additional capture value.
-  std::vector<string16> accept_types(params.accept_types);
-  accept_types.push_back(params.capture);
+  std::pair<std::vector<string16>, bool> accept_types =
+      std::make_pair(params.accept_types, params.capture);
 #endif
 
   select_file_dialog_->SelectFile(
diff --git a/chrome/browser/file_select_helper.h b/chrome/browser/file_select_helper.h
index 89f769f..0c2c9b4 100644
--- a/chrome/browser/file_select_helper.h
+++ b/chrome/browser/file_select_helper.h
@@ -12,6 +12,7 @@
 #include "base/gtest_prod_util.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
+#include "content/public/common/file_chooser_params.h"
 #include "net/base/directory_lister.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
 
@@ -20,7 +21,6 @@
 namespace content {
 class RenderViewHost;
 class WebContents;
-struct FileChooserParams;
 }
 
 namespace ui {
@@ -148,6 +148,9 @@
   // The type of file dialog last shown.
   ui::SelectFileDialog::Type dialog_type_;
 
+  // The mode of file dialog last shown.
+  content::FileChooserParams::Mode dialog_mode_;
+
   // Maintain a list of active directory enumerations.  These could come from
   // the file select dialog or from drag-and-drop of directories, so there could
   // be more than one going on at a time.
diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc
index 4216528..9cb785b 100644
--- a/chrome/browser/first_run/first_run.cc
+++ b/chrome/browser/first_run/first_run.cc
@@ -18,14 +18,15 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/updater/extension_updater.h"
 #include "chrome/browser/first_run/first_run_internal.h"
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/importer/external_process_importer_host.h"
-#include "chrome/browser/importer/importer_creator.h"
 #include "chrome/browser/importer/importer_list.h"
 #include "chrome/browser/importer/importer_progress_observer.h"
+#include "chrome/browser/importer/importer_uma.h"
 #include "chrome/browser/importer/profile_writer.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/search_engines/template_url_service.h"
@@ -41,7 +42,6 @@
 #include "chrome/browser/ui/sync/sync_promo_ui.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -169,7 +169,7 @@
   base::FilePath default_pref_dir =
       ProfileManager::GetDefaultProfileDir(user_data_dir);
   if (create_profile_dir) {
-    if (!file_util::PathExists(default_pref_dir)) {
+    if (!base::PathExists(default_pref_dir)) {
       if (!file_util::CreateDirectory(default_pref_dir))
         return base::FilePath();
     }
@@ -334,7 +334,7 @@
 
   // The master prefs are regular prefs so we can just copy the file
   // to the default place and they just work.
-  return file_util::CopyFile(master_prefs_path, user_prefs);
+  return base::CopyFile(master_prefs_path, user_prefs);
 }
 
 void SetupMasterPrefsFromInstallPrefs(
@@ -470,7 +470,7 @@
 
   base::FilePath first_run_sentinel;
   if (!internal::GetFirstRunSentinelFilePath(&first_run_sentinel) ||
-      file_util::PathExists(first_run_sentinel)) {
+      base::PathExists(first_run_sentinel)) {
     internal::first_run_ = internal::FIRST_RUN_FALSE;
     return false;
   }
@@ -491,7 +491,7 @@
                             installer::master_preferences::kDistroPingDelay);
 }
 
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       GetPingDelayPrefName().c_str(),
       0,
@@ -502,7 +502,7 @@
   base::FilePath first_run_sentinel;
   if (!internal::GetFirstRunSentinelFilePath(&first_run_sentinel))
     return false;
-  return base::Delete(first_run_sentinel, false);
+  return base::DeleteFile(first_run_sentinel, false);
 }
 
 bool SetShowFirstRunBubblePref(FirstRunBubbleOptions show_bubble_option) {
@@ -677,7 +677,7 @@
 
   base::FilePath local_state_path;
   PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path);
-  bool local_state_file_exists = file_util::PathExists(local_state_path);
+  bool local_state_file_exists = base::PathExists(local_state_path);
 
   scoped_refptr<ImporterList> importer_list(new ImporterList());
   importer_list->DetectSourceProfilesHack(
diff --git a/chrome/browser/first_run/first_run.h b/chrome/browser/first_run/first_run.h
index 91e5cda..7be708f 100644
--- a/chrome/browser/first_run/first_run.h
+++ b/chrome/browser/first_run/first_run.h
@@ -99,7 +99,7 @@
 std::string GetPingDelayPrefName();
 
 // Register user preferences used by the MasterPrefs structure.
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
 // Removes the sentinel file created in ConfigDone(). Returns false if the
 // sentinel file could not be removed.
diff --git a/chrome/browser/first_run/first_run_browsertest.cc b/chrome/browser/first_run/first_run_browsertest.cc
index 437f691..b6fd6fd 100644
--- a/chrome/browser/first_run/first_run_browsertest.cc
+++ b/chrome/browser/first_run/first_run_browsertest.cc
@@ -93,7 +93,7 @@
   }
 
   virtual void TearDown() OVERRIDE {
-    EXPECT_TRUE(base::Delete(prefs_file_, false));
+    EXPECT_TRUE(base::DeleteFile(prefs_file_, false));
     InProcessBrowserTest::TearDown();
   }
 
diff --git a/chrome/browser/first_run/first_run_internal_posix.cc b/chrome/browser/first_run/first_run_internal_posix.cc
index ce26df8..51f942a 100644
--- a/chrome/browser/first_run/first_run_internal_posix.cc
+++ b/chrome/browser/first_run/first_run_internal_posix.cc
@@ -28,7 +28,7 @@
 #if !defined(USE_AURA)
   base::FilePath local_state_path;
   PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path);
-  bool local_state_file_exists = file_util::PathExists(local_state_path);
+  bool local_state_file_exists = base::PathExists(local_state_path);
   // Launch the first run dialog only for certain builds, and only if the user
   // has not already set preferences.
   if (internal::IsOrganicFirstRun() && !local_state_file_exists) {
diff --git a/chrome/browser/first_run/first_run_internal_win.cc b/chrome/browser/first_run/first_run_internal_win.cc
index 6004248..5cb5228 100644
--- a/chrome/browser/first_run/first_run_internal_win.cc
+++ b/chrome/browser/first_run/first_run_internal_win.cc
@@ -9,10 +9,10 @@
 
 #include "base/base_paths.h"
 #include "base/callback.h"
+#include "base/command_line.h"
 #include "base/file_util.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
-#include "base/prefs/pref_service.h"
 #include "base/process.h"
 #include "base/process_util.h"
 #include "base/threading/sequenced_worker_pool.h"
@@ -27,7 +27,6 @@
 #include "chrome/installer/util/master_preferences_constants.h"
 #include "chrome/installer/util/util_constants.h"
 #include "content/public/browser/browser_thread.h"
-#include "google_update/google_update_idl.h"
 #include "grit/locale_settings.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/win/shell.h"
@@ -69,14 +68,12 @@
                              SEE_MASK_FLAG_LOG_USAGE | SEE_MASK_FLAG_NO_UI);
     return false;
   } else {
-    base::LaunchOptions launch_options;
-    launch_options.wait = true;
     CommandLine setup_path(exe_path);
     setup_path.AppendArguments(cl, false);
 
-    DWORD exit_code = 0;
-    if (!base::LaunchProcess(setup_path, launch_options, &ph) ||
-        !::GetExitCodeProcess(ph, &exit_code)) {
+    int exit_code = 0;
+    if (!base::LaunchProcess(setup_path, base::LaunchOptions(), &ph) ||
+        !base::WaitForExitCode(ph, &exit_code)) {
       return false;
     }
 
@@ -115,7 +112,7 @@
     // Be conservative and show the EULA if the path to the sentinel can't be
     // determined.
     if (!GetEULASentinelFilePath(&eula_sentinel) ||
-        !file_util::PathExists(eula_sentinel)) {
+        !base::PathExists(eula_sentinel)) {
       return true;
     }
   }
@@ -126,14 +123,9 @@
 // true if successful.
 bool WriteEULAtoTempFile(base::FilePath* eula_path) {
   std::string terms = l10n_util::GetStringUTF8(IDS_TERMS_HTML);
-  if (terms.empty())
-    return false;
-  FILE *file = file_util::CreateAndOpenTemporaryFile(eula_path);
-  if (!file)
-    return false;
-  bool good = fwrite(terms.data(), terms.size(), 1, file) == 1;
-  fclose(file);
-  return good;
+  return (!terms.empty() &&
+          file_util::CreateTemporaryFile(eula_path) &&
+          file_util::WriteFile(*eula_path, terms.data(), terms.size()) != -1);
 }
 
 // Creates the sentinel indicating that the EULA was required and has been
diff --git a/chrome/browser/first_run/first_run_unittest.cc b/chrome/browser/first_run/first_run_unittest.cc
index 8cd1edf..0e0edcb 100644
--- a/chrome/browser/first_run/first_run_unittest.cc
+++ b/chrome/browser/first_run/first_run_unittest.cc
@@ -34,10 +34,10 @@
 
 TEST_F(FirstRunTest, RemoveSentinel) {
   EXPECT_TRUE(CreateSentinel());
-  EXPECT_TRUE(file_util::PathExists(sentinel_path_));
+  EXPECT_TRUE(base::PathExists(sentinel_path_));
 
   EXPECT_TRUE(RemoveSentinel());
-  EXPECT_FALSE(file_util::PathExists(sentinel_path_));
+  EXPECT_FALSE(base::PathExists(sentinel_path_));
 }
 
 TEST_F(FirstRunTest, SetupMasterPrefsFromInstallPrefs_VariationsSeed) {
diff --git a/chrome/browser/first_run/upgrade_util_win.cc b/chrome/browser/first_run/upgrade_util_win.cc
index 23b9067..c669aa0 100644
--- a/chrome/browser/first_run/upgrade_util_win.cc
+++ b/chrome/browser/first_run/upgrade_util_win.cc
@@ -174,14 +174,14 @@
   base::FilePath new_chrome_exe;
   if (!GetNewerChromeFile(&new_chrome_exe))
     return false;
-  return file_util::PathExists(new_chrome_exe);
+  return base::PathExists(new_chrome_exe);
 }
 
 bool SwapNewChromeExeIfPresent() {
   base::FilePath new_chrome_exe;
   if (!GetNewerChromeFile(&new_chrome_exe))
     return false;
-  if (!file_util::PathExists(new_chrome_exe))
+  if (!base::PathExists(new_chrome_exe))
     return false;
   base::FilePath cur_chrome_exe;
   if (!PathService::Get(base::FILE_EXE, &cur_chrome_exe))
diff --git a/chrome/browser/fullscreen.h b/chrome/browser/fullscreen.h
index 26ee79f..9c21ec2 100644
--- a/chrome/browser/fullscreen.h
+++ b/chrome/browser/fullscreen.h
@@ -9,4 +9,13 @@
 
 bool IsFullScreenMode();
 
+#if defined(OS_MACOSX)
+namespace chrome {
+namespace mac {
+// Returns true if this system supports Lion-style system fullscreen.
+bool SupportsSystemFullscreen();
+}  // namespace mac
+}  // namespace chrome
+#endif
+
 #endif  // CHROME_BROWSER_FULLSCREEN_H_
diff --git a/chrome/browser/fullscreen_mac.mm b/chrome/browser/fullscreen_mac.mm
index d40ce0a..2d28360 100644
--- a/chrome/browser/fullscreen_mac.mm
+++ b/chrome/browser/fullscreen_mac.mm
@@ -6,6 +6,10 @@
 
 #import <Cocoa/Cocoa.h>
 
+#include "base/command_line.h"
+#include "base/mac/mac_util.h"
+#include "chrome/common/chrome_switches.h"
+
 // Replicate specific 10.7 SDK declarations for building with prior SDKs.
 #if !defined(MAC_OS_X_VERSION_10_7) || \
     MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
@@ -40,3 +44,17 @@
 
   return false;
 }
+
+namespace chrome {
+namespace mac {
+
+bool SupportsSystemFullscreen() {
+  const CommandLine* command_line = CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kDisableSystemFullscreenForTesting))
+    return false;
+
+  return base::mac::IsOSLionOrLater();
+}
+
+}  // namespace mac
+}  // namespace chrome
diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
index f2a5623..e81d950 100644
--- a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
+++ b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
@@ -182,7 +182,7 @@
 }
 
 GeolocationInfoBarQueueController*
-ChromeGeolocationPermissionContext::QueueController() {
+    ChromeGeolocationPermissionContext::QueueController() {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   DCHECK(!shutting_down_);
   if (!geolocation_infobar_queue_controller_)
@@ -191,7 +191,7 @@
 }
 
 GeolocationInfoBarQueueController*
-ChromeGeolocationPermissionContext::CreateQueueController() {
+    ChromeGeolocationPermissionContext::CreateQueueController() {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   return new GeolocationInfoBarQueueController(profile());
 }
diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context_factory.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context_factory.cc
index 7611658..515ed73 100644
--- a/chrome/browser/geolocation/chrome_geolocation_permission_context_factory.cc
+++ b/chrome/browser/geolocation/chrome_geolocation_permission_context_factory.cc
@@ -73,7 +73,7 @@
   return new Service(static_cast<Profile*>(profile));
 }
 
-void ChromeGeolocationPermissionContextFactory::RegisterUserPrefs(
+void ChromeGeolocationPermissionContextFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
 #if defined(OS_ANDROID)
   registry->RegisterBooleanPref(
diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h b/chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h
index 3b03442..0e161a6 100644
--- a/chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h
+++ b/chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h
@@ -31,7 +31,7 @@
   // |BrowserContextKeyedBaseFactory| methods:
   virtual BrowserContextKeyedService*
       BuildServiceInstanceFor(content::BrowserContext* profile) const OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const OVERRIDE;
diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc
index 5350751..c5f7911 100644
--- a/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc
+++ b/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
+
 #include <set>
 #include <string>
 #include <utility>
@@ -10,15 +12,14 @@
 #include "base/containers/hash_tables.h"
 #include "base/memory/scoped_vector.h"
 #include "base/synchronization/waitable_event.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
-#include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
 #include "chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h"
 #include "chrome/browser/geolocation/geolocation_permission_request_id.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar.h"
 #include "chrome/browser/infobars/infobar_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/navigation_details.h"
@@ -337,18 +338,13 @@
   GURL requesting_frame_0("http://www.example.com/geolocation");
   GURL requesting_frame_1("http://www.example-2.com/geolocation");
   EXPECT_EQ(CONTENT_SETTING_ASK,
-      profile()->GetHostContentSettingsMap()->GetContentSetting(
-          requesting_frame_0,
-          requesting_frame_0,
-          CONTENT_SETTINGS_TYPE_GEOLOCATION,
-          std::string()));
+            profile()->GetHostContentSettingsMap()->GetContentSetting(
+                requesting_frame_0, requesting_frame_0,
+                CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
   EXPECT_EQ(CONTENT_SETTING_ASK,
-      profile()->GetHostContentSettingsMap()->GetContentSetting(
-          requesting_frame_1,
-          requesting_frame_0,
-          CONTENT_SETTINGS_TYPE_GEOLOCATION,
-          std::string()));
-
+            profile()->GetHostContentSettingsMap()->GetContentSetting(
+                requesting_frame_1, requesting_frame_0,
+                CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
 
   NavigateAndCommit(requesting_frame_0);
   EXPECT_EQ(0U, infobar_service()->infobar_count());
@@ -393,17 +389,13 @@
   // Ensure the persisted permissions are ok.
   EXPECT_EQ(CONTENT_SETTING_ALLOW,
       profile()->GetHostContentSettingsMap()->GetContentSetting(
-          requesting_frame_0,
-          requesting_frame_0,
-          CONTENT_SETTINGS_TYPE_GEOLOCATION,
-          std::string()));
+          requesting_frame_0, requesting_frame_0,
+          CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
 
   EXPECT_EQ(CONTENT_SETTING_BLOCK,
       profile()->GetHostContentSettingsMap()->GetContentSetting(
-          requesting_frame_1,
-          requesting_frame_0,
-          CONTENT_SETTINGS_TYPE_GEOLOCATION,
-          std::string()));
+          requesting_frame_1, requesting_frame_0,
+          CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
 }
 
 TEST_F(GeolocationPermissionContextTests, PermissionForFileScheme) {
@@ -435,19 +427,14 @@
   GURL requesting_frame_0("http://www.example.com/geolocation");
   GURL requesting_frame_1("http://www.example-2.com/geolocation");
   EXPECT_EQ(CONTENT_SETTING_ASK,
-      profile()->GetHostContentSettingsMap()->GetContentSetting(
-          requesting_frame_0,
-          requesting_frame_0,
-          CONTENT_SETTINGS_TYPE_GEOLOCATION,
-          std::string()));
+            profile()->GetHostContentSettingsMap()->GetContentSetting(
+                requesting_frame_0, requesting_frame_0,
+                CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
 
   EXPECT_EQ(CONTENT_SETTING_ASK,
-      profile()->GetHostContentSettingsMap()->GetContentSetting(
-          requesting_frame_1,
-          requesting_frame_0,
-          CONTENT_SETTINGS_TYPE_GEOLOCATION,
-          std::string()));
-
+            profile()->GetHostContentSettingsMap()->GetContentSetting(
+                requesting_frame_1, requesting_frame_0,
+                CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
 
   NavigateAndCommit(requesting_frame_0);
   EXPECT_EQ(0U, infobar_service()->infobar_count());
@@ -487,18 +474,14 @@
   EXPECT_EQ(0U, infobar_service()->infobar_count());
   // Ensure the persisted permissions are ok.
   EXPECT_EQ(CONTENT_SETTING_ASK,
-      profile()->GetHostContentSettingsMap()->GetContentSetting(
-          requesting_frame_0,
-          requesting_frame_0,
-          CONTENT_SETTINGS_TYPE_GEOLOCATION,
-          std::string()));
+            profile()->GetHostContentSettingsMap()->GetContentSetting(
+                requesting_frame_0, requesting_frame_0,
+                CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
 
   EXPECT_EQ(CONTENT_SETTING_ALLOW,
-      profile()->GetHostContentSettingsMap()->GetContentSetting(
-          requesting_frame_1,
-          requesting_frame_0,
-          CONTENT_SETTINGS_TYPE_GEOLOCATION,
-          std::string()));
+            profile()->GetHostContentSettingsMap()->GetContentSetting(
+                requesting_frame_1, requesting_frame_0,
+                CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
 }
 
 TEST_F(GeolocationPermissionContextTests, InvalidURL) {
@@ -615,21 +598,15 @@
 TEST_F(GeolocationPermissionContextTests, TabDestroyed) {
   GURL requesting_frame_0("http://www.example.com/geolocation");
   GURL requesting_frame_1("http://www.example-2.com/geolocation");
-  EXPECT_EQ(
-      CONTENT_SETTING_ASK,
-      profile()->GetHostContentSettingsMap()->GetContentSetting(
-          requesting_frame_0,
-          requesting_frame_0,
-          CONTENT_SETTINGS_TYPE_GEOLOCATION,
-          std::string()));
+  EXPECT_EQ(CONTENT_SETTING_ASK,
+            profile()->GetHostContentSettingsMap()->GetContentSetting(
+                requesting_frame_0, requesting_frame_0,
+                CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
 
-  EXPECT_EQ(
-      CONTENT_SETTING_ASK,
-      profile()->GetHostContentSettingsMap()->GetContentSetting(
-          requesting_frame_1,
-          requesting_frame_0,
-          CONTENT_SETTINGS_TYPE_GEOLOCATION,
-          std::string()));
+  EXPECT_EQ(CONTENT_SETTING_ASK,
+            profile()->GetHostContentSettingsMap()->GetContentSetting(
+                requesting_frame_1, requesting_frame_0,
+                CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
 
   NavigateAndCommit(requesting_frame_0);
   EXPECT_EQ(0U, infobar_service()->infobar_count());
diff --git a/chrome/browser/geolocation/geolocation_browsertest.cc b/chrome/browser/geolocation/geolocation_browsertest.cc
index 597ce45..f5b8439 100644
--- a/chrome/browser/geolocation/geolocation_browsertest.cc
+++ b/chrome/browser/geolocation/geolocation_browsertest.cc
@@ -8,6 +8,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/geolocation/geolocation_settings_state.h"
@@ -18,7 +19,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/content_settings_pattern.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -49,13 +49,14 @@
 class IFrameLoader : public content::NotificationObserver {
  public:
   IFrameLoader(Browser* browser, int iframe_id, const GURL& url);
+  virtual ~IFrameLoader();
 
   // content::NotificationObserver:
   virtual void Observe(int type,
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
-  GURL iframe_url() const { return iframe_url_; }
+  const GURL& iframe_url() const { return iframe_url_; }
 
  private:
   content::NotificationRegistrar registrar_;
@@ -77,19 +78,19 @@
 IFrameLoader::IFrameLoader(Browser* browser, int iframe_id, const GURL& url)
     : navigation_completed_(false),
       javascript_completed_(false) {
-  NavigationController* controller =
-      &browser->tab_strip_model()->GetActiveWebContents()->GetController();
+  WebContents* web_contents =
+      browser->tab_strip_model()->GetActiveWebContents();
+  NavigationController* controller = &web_contents->GetController();
   registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
-                  content::Source<NavigationController>(controller));
+                 content::Source<NavigationController>(controller));
   registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE,
-                  content::NotificationService::AllSources());
-  std::string script = base::StringPrintf(
+                 content::NotificationService::AllSources());
+  std::string script(base::StringPrintf(
       "window.domAutomationController.setAutomationId(0);"
       "window.domAutomationController.send(addIFrame(%d, \"%s\"));",
-      iframe_id,
-      url.spec().c_str());
-  browser->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost()->
-      ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(script));
+      iframe_id, url.spec().c_str()));
+  web_contents->GetRenderViewHost()->ExecuteJavascriptInWebFrame(
+      string16(), UTF8ToUTF16(script));
   content::RunMessageLoop();
 
   EXPECT_EQ(base::StringPrintf("\"%d\"", iframe_id), javascript_response_);
@@ -98,13 +99,14 @@
   script = base::StringPrintf(
       "window.domAutomationController.send(getIFrameSrc(%d))", iframe_id);
   std::string iframe_src;
-  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      browser->tab_strip_model()->GetActiveWebContents(),
-      script,
-      &iframe_src));
+  EXPECT_TRUE(content::ExecuteScriptAndExtractString(web_contents, script,
+                                                     &iframe_src));
   iframe_url_ = GURL(iframe_src);
 }
 
+IFrameLoader::~IFrameLoader() {
+}
+
 void IFrameLoader::Observe(int type,
                            const content::NotificationSource& source,
                            const content::NotificationDetails& details) {
@@ -128,6 +130,7 @@
   // until the infobar has been displayed; otherwise it will block until the
   // navigation is completed.
   explicit GeolocationNotificationObserver(bool wait_for_infobar);
+  virtual ~GeolocationNotificationObserver();
 
   // content::NotificationObserver:
   virtual void Observe(int type,
@@ -137,6 +140,10 @@
   void AddWatchAndWaitForNotification(content::RenderViewHost* render_view_host,
                                       const std::string& iframe_xpath);
 
+  bool has_infobar() const { return !!infobar_; }
+  InfoBarDelegate* infobar() { return infobar_; }
+
+ private:
   content::NotificationRegistrar registrar_;
   bool wait_for_infobar_;
   InfoBarDelegate* infobar_;
@@ -144,7 +151,6 @@
   bool navigation_completed_;
   std::string javascript_response_;
 
- private:
   DISALLOW_COPY_AND_ASSIGN(GeolocationNotificationObserver);
 };
 
@@ -155,20 +161,23 @@
       navigation_started_(false),
       navigation_completed_(false) {
   registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE,
-                  content::NotificationService::AllSources());
+                 content::NotificationService::AllSources());
   if (wait_for_infobar) {
     registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
-                    content::NotificationService::AllSources());
+                   content::NotificationService::AllSources());
   } else {
     registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
-                    content::NotificationService::AllSources());
+                   content::NotificationService::AllSources());
     registrar_.Add(this, content::NOTIFICATION_LOAD_START,
-                    content::NotificationService::AllSources());
+                   content::NotificationService::AllSources());
     registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
-                    content::NotificationService::AllSources());
+                   content::NotificationService::AllSources());
   }
 }
 
+GeolocationNotificationObserver::~GeolocationNotificationObserver() {
+}
+
 void GeolocationNotificationObserver::Observe(
     int type,
     const content::NotificationSource& source,
@@ -181,21 +190,18 @@
     content::Details<DomOperationNotificationDetails> dom_op_details(details);
     javascript_response_ = dom_op_details->json;
     LOG(WARNING) << "javascript_response " << javascript_response_;
-  } else if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED ||
-              type == content::NOTIFICATION_LOAD_START) {
+  } else if ((type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) ||
+             (type == content::NOTIFICATION_LOAD_START)) {
     navigation_started_ = true;
-  } else if (type == content::NOTIFICATION_LOAD_STOP) {
-    if (navigation_started_) {
-      navigation_started_ = false;
-      navigation_completed_ = true;
-    }
+  } else if ((type == content::NOTIFICATION_LOAD_STOP) && navigation_started_) {
+    navigation_started_ = false;
+    navigation_completed_ = true;
   }
 
   // We're either waiting for just the inforbar, or for both a javascript
   // prompt and response.
-  if (wait_for_infobar_ && infobar_)
-    base::MessageLoopForUI::current()->Quit();
-  else if (navigation_completed_ && !javascript_response_.empty())
+  if ((wait_for_infobar_ && infobar_) ||
+      (navigation_completed_ && !javascript_response_.empty()))
     base::MessageLoopForUI::current()->Quit();
 }
 
@@ -203,20 +209,16 @@
     content::RenderViewHost* render_view_host,
     const std::string& iframe_xpath) {
   LOG(WARNING) << "will add geolocation watch";
-  std::string script =
+  std::string script(
       "window.domAutomationController.setAutomationId(0);"
-      "window.domAutomationController.send(geoStart());";
+      "window.domAutomationController.send(geoStart());");
   render_view_host->ExecuteJavascriptInWebFrame(UTF8ToUTF16(iframe_xpath),
                                                 UTF8ToUTF16(script));
   content::RunMessageLoop();
   registrar_.RemoveAll();
   LOG(WARNING) << "got geolocation watch" << javascript_response_;
   EXPECT_NE("\"0\"", javascript_response_);
-  if (wait_for_infobar_) {
-    EXPECT_TRUE(infobar_);
-  } else {
-    EXPECT_TRUE(navigation_completed_);
-  }
+  EXPECT_TRUE(wait_for_infobar_ ? (infobar_ != NULL) : navigation_completed_);
 }
 
 }  // namespace
@@ -243,23 +245,38 @@
   };
 
   GeolocationBrowserTest();
+  virtual ~GeolocationBrowserTest();
 
   // InProcessBrowserTest:
   virtual void SetUpOnMainThread() OVERRIDE;
   virtual void TearDownInProcessBrowserTestFixture() OVERRIDE;
 
+  Browser* current_browser() { return current_browser_; }
+  void set_html_for_tests(const std::string& html_for_tests) {
+    html_for_tests_ = html_for_tests;
+  }
+  const std::string& iframe_xpath() const { return iframe_xpath_; }
+  void set_iframe_xpath(const std::string& iframe_xpath) {
+    iframe_xpath_ = iframe_xpath;
+  }
+  const GURL& current_url() const { return current_url_; }
+  const GURL& iframe_url(size_t i) const { return iframe_urls_[i]; }
+  double fake_latitude() const { return fake_latitude_; }
+  double fake_longitude() const { return fake_longitude_; }
+
   bool Initialize(InitializationOptions options) WARN_UNUSED_RESULT;
   void LoadIFrames(int number_iframes);
   void AddGeolocationWatch(bool wait_for_infobar);
   void CheckGeoposition(double latitude, double longitude);
-  void SetInfobarResponse(const GURL& requesting_url, bool allowed);
-  void CheckStringValueFromJavascriptForTab(
-      const std::string& expected, const std::string& function,
-      WebContents* web_contents);
-  void CheckStringValueFromJavascript(
-      const std::string& expected, const std::string& function);
+  void SetInfoBarResponse(const GURL& requesting_url, bool allowed);
+  void CheckStringValueFromJavascriptForTab(const std::string& expected,
+                                            const std::string& function,
+                                            WebContents* web_contents);
+  void CheckStringValueFromJavascript(const std::string& expected,
+                                      const std::string& function);
   void NotifyGeoposition(double latitude, double longitude);
 
+ private:
   InfoBarDelegate* infobar_;
   Browser* current_browser_;
   // path element of a URL referencing the html content for this test.
@@ -274,7 +291,6 @@
   double fake_latitude_;
   double fake_longitude_;
 
- private:
   DISALLOW_COPY_AND_ASSIGN(GeolocationBrowserTest);
 };
 
@@ -286,6 +302,9 @@
     fake_longitude_(4.56) {
 }
 
+GeolocationBrowserTest::~GeolocationBrowserTest() {
+}
+
 void GeolocationBrowserTest::SetUpOnMainThread() {
   ui_test_utils::OverrideGeolocation(fake_latitude_, fake_longitude_);
 }
@@ -306,34 +325,27 @@
   if (options == INITIALIZATION_OFFTHERECORD) {
     current_browser_ = ui_test_utils::OpenURLOffTheRecord(
         browser()->profile(), current_url_);
-  } else if (options == INITIALIZATION_NEWTAB) {
-    current_browser_ = browser();
-    chrome::NewTab(current_browser_);
-    ui_test_utils::NavigateToURL(current_browser_, current_url_);
-  } else if (options == INITIALIZATION_IFRAMES) {
-    current_browser_ = browser();
-    ui_test_utils::NavigateToURL(current_browser_, current_url_);
   } else {
     current_browser_ = browser();
+    if (options == INITIALIZATION_NEWTAB)
+      chrome::NewTab(current_browser_);
     ui_test_utils::NavigateToURL(current_browser_, current_url_);
   }
   LOG(WARNING) << "after navigate";
 
   EXPECT_TRUE(current_browser_);
-  if (!current_browser_)
-    return false;
-
-  return true;
+  return !!current_browser_;
 }
 
 void GeolocationBrowserTest::LoadIFrames(int number_iframes) {
-    // Limit to 3 iframes.
-    DCHECK(0 < number_iframes && number_iframes <= 3);
-    iframe_urls_.resize(number_iframes);
-    for (int i = 0; i < number_iframes; ++i) {
-      IFrameLoader loader(current_browser_, i, GURL());
-      iframe_urls_[i] = loader.iframe_url();
-    }
+  // Limit to 3 iframes.
+  DCHECK_LT(0, number_iframes);
+  DCHECK_LE(number_iframes, 3);
+  iframe_urls_.resize(number_iframes);
+  for (int i = 0; i < number_iframes; ++i) {
+    IFrameLoader loader(current_browser_, i, GURL());
+    iframe_urls_[i] = loader.iframe_url();
+  }
 }
 
 void GeolocationBrowserTest::AddGeolocationWatch(bool wait_for_infobar) {
@@ -341,10 +353,10 @@
   notification_observer.AddWatchAndWaitForNotification(
       current_browser_->tab_strip_model()->GetActiveWebContents()->
           GetRenderViewHost(),
-      iframe_xpath_);
+      iframe_xpath());
   if (wait_for_infobar) {
-    EXPECT_TRUE(notification_observer.infobar_);
-    infobar_ = notification_observer.infobar_;
+    EXPECT_TRUE(notification_observer.has_infobar());
+    infobar_ = notification_observer.infobar();
   }
 }
 
@@ -353,12 +365,12 @@
   // Checks we have no error.
   CheckStringValueFromJavascript("0", "geoGetLastError()");
   CheckStringValueFromJavascript(base::DoubleToString(latitude),
-                                  "geoGetLastPositionLatitude()");
+                                 "geoGetLastPositionLatitude()");
   CheckStringValueFromJavascript(base::DoubleToString(longitude),
-                                  "geoGetLastPositionLongitude()");
+                                 "geoGetLastPositionLongitude()");
 }
 
-void GeolocationBrowserTest::SetInfobarResponse(const GURL& requesting_url,
+void GeolocationBrowserTest::SetInfoBarResponse(const GURL& requesting_url,
                                                 bool allowed) {
   WebContents* web_contents =
       current_browser_->tab_strip_model()->GetActiveWebContents();
@@ -372,8 +384,7 @@
   {
     content::WindowedNotificationObserver observer(
         content::NOTIFICATION_LOAD_STOP,
-        content::Source<NavigationController>(
-            &web_contents->GetController()));
+        content::Source<NavigationController>(&web_contents->GetController()));
     if (allowed)
       infobar_->AsConfirmInfoBarDelegate()->Accept();
     else
@@ -385,7 +396,7 @@
   LOG(WARNING) << "infobar response set";
   infobar_ = NULL;
   EXPECT_GT(settings_state.state_map().size(), state_map_size);
-  GURL requesting_origin = requesting_url.GetOrigin();
+  GURL requesting_origin(requesting_url.GetOrigin());
   EXPECT_EQ(1U, settings_state.state_map().count(requesting_origin));
   ContentSetting expected_setting =
         allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
@@ -397,14 +408,11 @@
     const std::string& expected,
     const std::string& function,
     WebContents* web_contents) {
-  std::string script = base::StringPrintf(
-      "window.domAutomationController.send(%s)", function.c_str());
+  std::string script(base::StringPrintf(
+      "window.domAutomationController.send(%s)", function.c_str()));
   std::string result;
   ASSERT_TRUE(content::ExecuteScriptInFrameAndExtractString(
-      web_contents,
-      iframe_xpath_,
-      script,
-      &result));
+      web_contents, iframe_xpath_, script, &result));
   EXPECT_EQ(expected, result);
 }
 
@@ -435,8 +443,8 @@
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, Geoposition) {
   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
   AddGeolocationWatch(true);
-  SetInfobarResponse(current_url_, true);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  SetInfoBarResponse(current_url(), true);
+  CheckGeoposition(fake_latitude(), fake_longitude());
 }
 
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,
@@ -444,7 +452,7 @@
   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
   AddGeolocationWatch(true);
   // Infobar was displayed, deny access and check for error code.
-  SetInfobarResponse(current_url_, false);
+  SetInfoBarResponse(current_url(), false);
   CheckStringValueFromJavascript("1", "geoGetLastError()");
 }
 
@@ -457,14 +465,14 @@
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_NoInfobarForSecondTab) {
   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
   AddGeolocationWatch(true);
-  SetInfobarResponse(current_url_, true);
+  SetInfoBarResponse(current_url(), true);
   // Disables further prompts from this tab.
   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
 
   // Checks infobar will not be created a second tab.
   ASSERT_TRUE(Initialize(INITIALIZATION_NEWTAB));
   AddGeolocationWatch(false);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  CheckGeoposition(fake_latitude(), fake_longitude());
 }
 
 // http://crbug.com/44589. Hangs on Mac, crashes on Windows
@@ -475,12 +483,10 @@
 #endif
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_NoInfobarForDeniedOrigin) {
   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
-  current_browser_->profile()->GetHostContentSettingsMap()->
-      SetContentSetting(ContentSettingsPattern::FromURLNoWildcard(current_url_),
-                        ContentSettingsPattern::FromURLNoWildcard(current_url_),
-                        CONTENT_SETTINGS_TYPE_GEOLOCATION,
-                        std::string(),
-                        CONTENT_SETTING_BLOCK);
+  current_browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+      ContentSettingsPattern::FromURLNoWildcard(current_url()),
+      ContentSettingsPattern::FromURLNoWildcard(current_url()),
+      CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string(), CONTENT_SETTING_BLOCK);
   AddGeolocationWatch(false);
   // Checks we have an error for this denied origin.
   CheckStringValueFromJavascript("1", "geoGetLastError()");
@@ -492,15 +498,13 @@
 
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForAllowedOrigin) {
   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
-  current_browser_->profile()->GetHostContentSettingsMap()->
-      SetContentSetting(ContentSettingsPattern::FromURLNoWildcard(current_url_),
-                        ContentSettingsPattern::FromURLNoWildcard(current_url_),
-                        CONTENT_SETTINGS_TYPE_GEOLOCATION,
-                        std::string(),
-                        CONTENT_SETTING_ALLOW);
+  current_browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
+      ContentSettingsPattern::FromURLNoWildcard(current_url()),
+      ContentSettingsPattern::FromURLNoWildcard(current_url()),
+      CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string(), CONTENT_SETTING_ALLOW);
   // Checks no infobar will be created and there's no error callback.
   AddGeolocationWatch(false);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  CheckGeoposition(fake_latitude(), fake_longitude());
 }
 
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForOffTheRecord) {
@@ -508,14 +512,14 @@
   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
   AddGeolocationWatch(true);
   // Response will be persisted
-  SetInfobarResponse(current_url_, true);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  SetInfoBarResponse(current_url(), true);
+  CheckGeoposition(fake_latitude(), fake_longitude());
   // Disables further prompts from this tab.
   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
   // Go incognito, and checks no infobar will be created.
   ASSERT_TRUE(Initialize(INITIALIZATION_OFFTHERECORD));
   AddGeolocationWatch(false);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  CheckGeoposition(fake_latitude(), fake_longitude());
 }
 
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoLeakFromOffTheRecord) {
@@ -523,46 +527,46 @@
   ASSERT_TRUE(Initialize(INITIALIZATION_OFFTHERECORD));
   AddGeolocationWatch(true);
   // Response won't be persisted.
-  SetInfobarResponse(current_url_, true);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  SetInfoBarResponse(current_url(), true);
+  CheckGeoposition(fake_latitude(), fake_longitude());
   // Disables further prompts from this tab.
   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
   // Go to the regular profile, infobar will be created.
   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
   AddGeolocationWatch(true);
-  SetInfobarResponse(current_url_, false);
+  SetInfoBarResponse(current_url(), false);
   CheckStringValueFromJavascript("1", "geoGetLastError()");
 }
 
 // crbug.com/176291
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,
                        DISABLED_IFramesWithFreshPosition) {
-  html_for_tests_ = "/geolocation/iframes_different_origin.html";
+  set_html_for_tests("/geolocation/iframes_different_origin.html");
   ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
   LoadIFrames(2);
   LOG(WARNING) << "frames loaded";
 
-  iframe_xpath_ = "//iframe[@id='iframe_0']";
+  set_iframe_xpath("//iframe[@id='iframe_0']");
   AddGeolocationWatch(true);
-  SetInfobarResponse(iframe_urls_[0], true);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  SetInfoBarResponse(iframe_url(0), true);
+  CheckGeoposition(fake_latitude(), fake_longitude());
   // Disables further prompts from this iframe.
   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
 
   // Test second iframe from a different origin with a cached geoposition will
   // create the infobar.
-  iframe_xpath_ = "//iframe[@id='iframe_1']";
+  set_iframe_xpath("//iframe[@id='iframe_1']");
   AddGeolocationWatch(true);
 
   // Back to the first frame, enable navigation and refresh geoposition.
-  iframe_xpath_ = "//iframe[@id='iframe_0']";
+  set_iframe_xpath("//iframe[@id='iframe_0']");
   CheckStringValueFromJavascript("1", "geoSetMaxNavigateCount(1)");
   double fresh_position_latitude = 3.17;
   double fresh_position_longitude = 4.23;
   content::WindowedNotificationObserver observer(
       content::NOTIFICATION_LOAD_STOP,
       content::Source<NavigationController>(
-          &current_browser_->tab_strip_model()->GetActiveWebContents()->
+          &current_browser()->tab_strip_model()->GetActiveWebContents()->
               GetController()));
   NotifyGeoposition(fresh_position_latitude, fresh_position_longitude);
   observer.Wait();
@@ -572,9 +576,9 @@
   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
 
   // Now go ahead an authorize the second frame.
-  iframe_xpath_ = "//iframe[@id='iframe_1']";
+  set_iframe_xpath("//iframe[@id='iframe_1']");
   // Infobar was displayed, allow access and check there's no error code.
-  SetInfobarResponse(iframe_urls_[1], true);
+  SetInfoBarResponse(iframe_url(1), true);
   LOG(WARNING) << "Checking position...";
   CheckGeoposition(fresh_position_latitude, fresh_position_longitude);
   LOG(WARNING) << "...done.";
@@ -582,14 +586,14 @@
 
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,
                        IFramesWithCachedPosition) {
-  html_for_tests_ = "/geolocation/iframes_different_origin.html";
+  set_html_for_tests("/geolocation/iframes_different_origin.html");
   ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
   LoadIFrames(2);
 
-  iframe_xpath_ = "//iframe[@id='iframe_0']";
+  set_iframe_xpath("//iframe[@id='iframe_0']");
   AddGeolocationWatch(true);
-  SetInfobarResponse(iframe_urls_[0], true);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  SetInfoBarResponse(iframe_url(0), true);
+  CheckGeoposition(fake_latitude(), fake_longitude());
 
   // Refresh geoposition, but let's not yet create the watch on the second frame
   // so that it'll fetch from cache.
@@ -598,7 +602,7 @@
   content::WindowedNotificationObserver observer(
       content::NOTIFICATION_LOAD_STOP,
       content::Source<NavigationController>(
-          &current_browser_->tab_strip_model()->GetActiveWebContents()->
+          &current_browser()->tab_strip_model()->GetActiveWebContents()->
               GetController()));
   NotifyGeoposition(cached_position_latitude, cached_position_lognitude);
   observer.Wait();
@@ -608,41 +612,41 @@
   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
 
   // Now go ahead an authorize the second frame.
-  iframe_xpath_ = "//iframe[@id='iframe_1']";
+  set_iframe_xpath("//iframe[@id='iframe_1']");
   AddGeolocationWatch(true);
   // WebKit will use its cache, but we also broadcast a position shortly
   // afterwards. We're only interested in the first navigation for the success
   // callback from the cached position.
   CheckStringValueFromJavascript("1", "geoSetMaxNavigateCount(1)");
-  SetInfobarResponse(iframe_urls_[1], true);
+  SetInfoBarResponse(iframe_url(1), true);
   CheckGeoposition(cached_position_latitude, cached_position_lognitude);
 }
 
 // crbug.com/176291
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,
                        DISABLED_CancelPermissionForFrame) {
-  html_for_tests_ = "/geolocation/iframes_different_origin.html";
+  set_html_for_tests("/geolocation/iframes_different_origin.html");
   ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
   LoadIFrames(2);
   LOG(WARNING) << "frames loaded";
 
-  iframe_xpath_ = "//iframe[@id='iframe_0']";
+  set_iframe_xpath("//iframe[@id='iframe_0']");
   AddGeolocationWatch(true);
-  SetInfobarResponse(iframe_urls_[0], true);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  SetInfoBarResponse(iframe_url(0), true);
+  CheckGeoposition(fake_latitude(), fake_longitude());
   // Disables further prompts from this iframe.
   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
 
   // Test second iframe from a different origin with a cached geoposition will
   // create the infobar.
-  iframe_xpath_ = "//iframe[@id='iframe_1']";
+  set_iframe_xpath("//iframe[@id='iframe_1']");
   AddGeolocationWatch(true);
 
   InfoBarService* infobar_service = InfoBarService::FromWebContents(
-      current_browser_->tab_strip_model()->GetActiveWebContents());
+      current_browser()->tab_strip_model()->GetActiveWebContents());
   size_t num_infobars_before_cancel = infobar_service->infobar_count();
   // Change the iframe, and ensure the infobar is gone.
-  IFrameLoader change_iframe_1(current_browser_, 1, current_url_);
+  IFrameLoader change_iframe_1(current_browser(), 1, current_url());
   size_t num_infobars_after_cancel = infobar_service->infobar_count();
   EXPECT_EQ(num_infobars_before_cancel, num_infobars_after_cancel + 1);
 }
@@ -650,40 +654,40 @@
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, InvalidUrlRequest) {
   // Tests that an invalid URL (e.g. from a popup window) is rejected
   // correctly. Also acts as a regression test for http://crbug.com/40478
-  html_for_tests_ = "/geolocation/invalid_request_url.html";
+  set_html_for_tests("/geolocation/invalid_request_url.html");
   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
   WebContents* original_tab =
-      current_browser_->tab_strip_model()->GetActiveWebContents();
+      current_browser()->tab_strip_model()->GetActiveWebContents();
   CheckStringValueFromJavascript("1", "requestGeolocationFromInvalidUrl()");
   CheckStringValueFromJavascriptForTab("1", "isAlive()", original_tab);
 }
 
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfoBarBeforeStart) {
   // See http://crbug.com/42789
-  html_for_tests_ = "/geolocation/iframes_different_origin.html";
+  set_html_for_tests("/geolocation/iframes_different_origin.html");
   ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
   LoadIFrames(2);
   LOG(WARNING) << "frames loaded";
 
   // Access navigator.geolocation, but ensure it won't request permission.
-  iframe_xpath_ = "//iframe[@id='iframe_1']";
+  set_iframe_xpath("//iframe[@id='iframe_1']");
   CheckStringValueFromJavascript("object", "geoAccessNavigatorGeolocation()");
 
-  iframe_xpath_ = "//iframe[@id='iframe_0']";
+  set_iframe_xpath("//iframe[@id='iframe_0']");
   AddGeolocationWatch(true);
-  SetInfobarResponse(iframe_urls_[0], true);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  SetInfoBarResponse(iframe_url(0), true);
+  CheckGeoposition(fake_latitude(), fake_longitude());
   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
 
   // Permission should be requested after adding a watch.
-  iframe_xpath_ = "//iframe[@id='iframe_1']";
+  set_iframe_xpath("//iframe[@id='iframe_1']");
   AddGeolocationWatch(true);
-  SetInfobarResponse(iframe_urls_[1], true);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  SetInfoBarResponse(iframe_url(1), true);
+  CheckGeoposition(fake_latitude(), fake_longitude());
 }
 
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, TwoWatchesInOneFrame) {
-  html_for_tests_ = "/geolocation/two_watches.html";
+  set_html_for_tests("/geolocation/two_watches.html");
   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
   // First, set the JavaScript to navigate when it receives |final_position|.
   double final_position_latitude = 3.17;
@@ -693,22 +697,21 @@
       final_position_latitude, final_position_longitude);
   std::string js_result;
   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
-      current_browser_->tab_strip_model()->GetActiveWebContents(),
-      script,
+      current_browser()->tab_strip_model()->GetActiveWebContents(), script,
       &js_result));
   EXPECT_EQ(js_result, "ok");
 
   // Send a position which both geolocation watches will receive.
   AddGeolocationWatch(true);
-  SetInfobarResponse(current_url_, true);
-  CheckGeoposition(fake_latitude_, fake_longitude_);
+  SetInfoBarResponse(current_url(), true);
+  CheckGeoposition(fake_latitude(), fake_longitude());
 
   // The second watch will now have cancelled. Ensure an update still makes
   // its way through to the first watcher.
   content::WindowedNotificationObserver observer(
       content::NOTIFICATION_LOAD_STOP,
       content::Source<NavigationController>(
-          &current_browser_->tab_strip_model()->GetActiveWebContents()->
+          &current_browser()->tab_strip_model()->GetActiveWebContents()->
               GetController()));
   NotifyGeoposition(final_position_latitude, final_position_longitude);
   observer.Wait();
@@ -717,24 +720,22 @@
 
 // crbug.com/176291
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DISABLED_TabDestroyed) {
-  html_for_tests_ = "/geolocation/tab_destroyed.html";
+  set_html_for_tests("/geolocation/tab_destroyed.html");
   ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
   LoadIFrames(3);
 
-  iframe_xpath_ = "//iframe[@id='iframe_0']";
+  set_iframe_xpath("//iframe[@id='iframe_0']");
   AddGeolocationWatch(true);
 
-  iframe_xpath_ = "//iframe[@id='iframe_1']";
+  set_iframe_xpath("//iframe[@id='iframe_1']");
   AddGeolocationWatch(false);
 
-  iframe_xpath_ = "//iframe[@id='iframe_2']";
+  set_iframe_xpath("//iframe[@id='iframe_2']");
   AddGeolocationWatch(false);
 
   std::string script =
       "window.domAutomationController.send(window.close());";
-  bool result =
-      content::ExecuteScript(
-          current_browser_->tab_strip_model()->GetActiveWebContents(),
-          script);
+  bool result = content::ExecuteScript(
+      current_browser()->tab_strip_model()->GetActiveWebContents(), script);
   EXPECT_EQ(result, true);
 }
diff --git a/chrome/browser/geolocation/geolocation_infobar_delegate.cc b/chrome/browser/geolocation/geolocation_infobar_delegate.cc
index 07caf8a..93f500d 100644
--- a/chrome/browser/geolocation/geolocation_infobar_delegate.cc
+++ b/chrome/browser/geolocation/geolocation_infobar_delegate.cc
@@ -52,6 +52,9 @@
    contents_unique_id_ = committed_entry ? committed_entry->GetUniqueID() : 0;
 }
 
+GeolocationInfoBarDelegate::~GeolocationInfoBarDelegate() {
+}
+
 bool GeolocationInfoBarDelegate::Accept() {
   SetPermission(true, true);
   return true;
@@ -112,11 +115,10 @@
       "https://www.google.com/support/chrome/bin/answer.py?answer=142065";
 #endif
 
-  content::OpenURLParams params(
+  web_contents()->OpenURL(content::OpenURLParams(
       google_util::AppendGoogleLocaleParam(GURL(kGeolocationLearnMoreUrl)),
       content::Referrer(),
       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
-      content::PAGE_TRANSITION_LINK, false);
-  web_contents()->OpenURL(params);
+      content::PAGE_TRANSITION_LINK, false));
   return false;  // Do not dismiss the info bar.
 }
diff --git a/chrome/browser/geolocation/geolocation_infobar_delegate.h b/chrome/browser/geolocation/geolocation_infobar_delegate.h
index d149836..f1656ad 100644
--- a/chrome/browser/geolocation/geolocation_infobar_delegate.h
+++ b/chrome/browser/geolocation/geolocation_infobar_delegate.h
@@ -33,6 +33,7 @@
                              const GeolocationPermissionRequestID& id,
                              const GURL& requesting_frame,
                              const std::string& display_languages);
+  virtual ~GeolocationInfoBarDelegate();
 
   // ConfirmInfoBarDelegate:
   virtual bool Accept() OVERRIDE;
diff --git a/chrome/browser/geolocation/geolocation_infobar_delegate_android.cc b/chrome/browser/geolocation/geolocation_infobar_delegate_android.cc
index 70470cc..062e200 100644
--- a/chrome/browser/geolocation/geolocation_infobar_delegate_android.cc
+++ b/chrome/browser/geolocation/geolocation_infobar_delegate_android.cc
@@ -41,9 +41,7 @@
 
 string16 GeolocationInfoBarDelegateAndroid::GetButtonLabel(
     InfoBarButton button) const {
-  if (button == BUTTON_OK) {
-    return UTF8ToUTF16(
-        google_location_settings_helper_->GetAcceptButtonLabel());
-  }
-  return l10n_util::GetStringUTF16(IDS_GEOLOCATION_DENY_BUTTON);
+  return (button == BUTTON_OK) ?
+      UTF8ToUTF16(google_location_settings_helper_->GetAcceptButtonLabel()) :
+      l10n_util::GetStringUTF16(IDS_GEOLOCATION_DENY_BUTTON);
 }
diff --git a/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc b/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc
index 2721472..6607c25 100644
--- a/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc
+++ b/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc
@@ -5,13 +5,13 @@
 #include "chrome/browser/geolocation/geolocation_infobar_queue_controller.h"
 
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/geolocation/geolocation_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
@@ -99,7 +99,6 @@
   infobar_delegate_ = GeolocationInfoBarDelegate::Create(
       GetInfoBarService(id_), controller, id_, requesting_frame_,
       display_languages);
-
 }
 
 
@@ -269,10 +268,12 @@
     const GeolocationPermissionRequestID& id) {
   for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
        i != pending_infobar_requests_.end(); ) {
-    if (i->id().IsForSameTabAs(id))
+    if (i->id().IsForSameTabAs(id)) {
+      DCHECK(!i->has_infobar_delegate());
       i = pending_infobar_requests_.erase(i);
-    else
+    } else {
       ++i;
+    }
   }
 }
 
diff --git a/chrome/browser/geolocation/geolocation_infobar_queue_controller_unittest.cc b/chrome/browser/geolocation/geolocation_infobar_queue_controller_unittest.cc
index 44a0710..10f563c 100644
--- a/chrome/browser/geolocation/geolocation_infobar_queue_controller_unittest.cc
+++ b/chrome/browser/geolocation/geolocation_infobar_queue_controller_unittest.cc
@@ -2,8 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/synchronization/waitable_event.h"
 #include "chrome/browser/geolocation/geolocation_infobar_queue_controller.h"
+
+#include "base/synchronization/waitable_event.h"
 #include "chrome/browser/geolocation/geolocation_permission_request_id.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
diff --git a/chrome/browser/google/google_update_settings_posix.cc b/chrome/browser/google/google_update_settings_posix.cc
index c4bd2cd..8942024 100644
--- a/chrome/browser/google/google_update_settings_posix.cc
+++ b/chrome/browser/google/google_update_settings_posix.cc
@@ -37,13 +37,13 @@
 bool GoogleUpdateSettings::SetCollectStatsConsent(bool consented) {
   base::FilePath consent_dir;
   PathService::Get(chrome::DIR_USER_DATA, &consent_dir);
-  if (!file_util::DirectoryExists(consent_dir))
+  if (!base::DirectoryExists(consent_dir))
     return false;
 
   base::FilePath consent_file = consent_dir.AppendASCII(kConsentToSendStats);
   if (consented) {
-    if ((!file_util::PathExists(consent_file)) ||
-        (file_util::PathExists(consent_file) &&
+    if ((!base::PathExists(consent_file)) ||
+        (base::PathExists(consent_file) &&
          !google_update::posix_guid().empty())) {
       const char* c_str = google_update::posix_guid().c_str();
       int size = google_update::posix_guid().size();
@@ -51,7 +51,7 @@
     }
   } else {
     google_update::posix_guid().clear();
-    return base::Delete(consent_file, false);
+    return base::DeleteFile(consent_file, false);
   }
   return true;
 }
@@ -60,7 +60,7 @@
   // Make sure that user has consented to send crashes.
   base::FilePath consent_dir;
   PathService::Get(chrome::DIR_USER_DATA, &consent_dir);
-  if (!file_util::DirectoryExists(consent_dir) ||
+  if (!base::DirectoryExists(consent_dir) ||
       !GoogleUpdateSettings::GetCollectStatsConsent())
     return false;
 
diff --git a/chrome/browser/google/google_url_tracker.cc b/chrome/browser/google/google_url_tracker.cc
index 2472417..4ed0c28 100644
--- a/chrome/browser/google/google_url_tracker.cc
+++ b/chrome/browser/google/google_url_tracker.cc
@@ -8,13 +8,13 @@
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_url_tracker_factory.h"
 #include "chrome/browser/google/google_url_tracker_infobar_delegate.h"
 #include "chrome/browser/google/google_url_tracker_navigation_helper.h"
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/navigation_controller.h"
@@ -303,12 +303,12 @@
           infobar_service,
           new GoogleURLTrackerMapEntry(this, infobar_service,
                                        navigation_controller)));
-    } else if (i->second->has_infobar()) {
+    } else if (i->second->has_infobar_delegate()) {
       // This is a new search on a tab where we already have an infobar.
-      i->second->infobar()->set_pending_id(pending_id);
+      i->second->infobar_delegate()->set_pending_id(pending_id);
     }
   } else if (i != entry_map_.end()){
-    if (i->second->has_infobar()) {
+    if (i->second->has_infobar_delegate()) {
       // This is a non-search navigation on a tab with an infobar.  If there was
       // a previous pending search on this tab, this means it won't commit, so
       // undo anything we did in response to seeing that.  Note that if there
@@ -319,7 +319,7 @@
       // owner to expire the infobar if need be.  If it doesn't commit, then
       // simply leaving the infobar as-is will have been the right thing.
       UnregisterForEntrySpecificNotifications(*i->second, false);
-      i->second->infobar()->set_pending_id(0);
+      i->second->infobar_delegate()->set_pending_id(0);
     } else {
       // Non-search navigation on a tab with an entry that has not yet created
       // an infobar.  This means the original search won't commit, so delete the
@@ -340,13 +340,13 @@
   DCHECK(search_url.is_valid());
 
   UnregisterForEntrySpecificNotifications(*map_entry, true);
-  if (map_entry->has_infobar()) {
-    map_entry->infobar()->Update(search_url);
+  if (map_entry->has_infobar_delegate()) {
+    map_entry->infobar_delegate()->Update(search_url);
   } else {
     GoogleURLTrackerInfoBarDelegate* infobar_delegate =
         infobar_creator_.Run(infobar_service, this, search_url);
     if (infobar_delegate)
-      map_entry->SetInfoBar(infobar_delegate);
+      map_entry->SetInfoBarDelegate(infobar_delegate);
     else
       map_entry->Close(false);
   }
@@ -389,12 +389,12 @@
         map_entry.navigation_controller(), false);
   } else {
     DCHECK(!must_be_listening_for_commit);
-    DCHECK(map_entry.has_infobar());
+    DCHECK(map_entry.has_infobar_delegate());
   }
   const bool registered_for_tab_destruction =
       nav_helper_->IsListeningForTabDestruction(
           map_entry.navigation_controller());
-  DCHECK_NE(registered_for_tab_destruction, map_entry.has_infobar());
+  DCHECK_NE(registered_for_tab_destruction, map_entry.has_infobar_delegate());
   if (registered_for_tab_destruction) {
     nav_helper_->SetListeningForTabDestruction(
         map_entry.navigation_controller(), false);
diff --git a/chrome/browser/google/google_url_tracker.h b/chrome/browser/google/google_url_tracker.h
index d71e7e7..5f2c85e 100644
--- a/chrome/browser/google/google_url_tracker.h
+++ b/chrome/browser/google/google_url_tracker.h
@@ -105,8 +105,7 @@
   // |pending_id| is the unique ID of the newly pending NavigationEntry.
   // If there is already a visible GoogleURLTracker infobar for this tab, this
   // function resets its associated pending entry ID to the new ID.  Otherwise
-  // this function creates a (still-invisible) InfoBarDelegate for the
-  // associated tab.
+  // this function creates a map entry for the associated tab.
   virtual void OnNavigationPending(
       content::NavigationController* navigation_controller,
       InfoBarService* infobar_service,
diff --git a/chrome/browser/google/google_url_tracker_factory.cc b/chrome/browser/google/google_url_tracker_factory.cc
index 8f82b05..88ad9d2 100644
--- a/chrome/browser/google/google_url_tracker_factory.cc
+++ b/chrome/browser/google/google_url_tracker_factory.cc
@@ -42,7 +42,7 @@
                               GoogleURLTracker::NORMAL_MODE);
 }
 
-void GoogleURLTrackerFactory::RegisterUserPrefs(
+void GoogleURLTrackerFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* user_prefs) {
   user_prefs->RegisterStringPref(
       prefs::kLastKnownGoogleURL,
diff --git a/chrome/browser/google/google_url_tracker_factory.h b/chrome/browser/google/google_url_tracker_factory.h
index d1eecf0..7175381 100644
--- a/chrome/browser/google/google_url_tracker_factory.h
+++ b/chrome/browser/google/google_url_tracker_factory.h
@@ -30,7 +30,7 @@
   // BrowserContextKeyedServiceFactory:
   virtual BrowserContextKeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const OVERRIDE;
diff --git a/chrome/browser/google/google_url_tracker_infobar_delegate.cc b/chrome/browser/google/google_url_tracker_infobar_delegate.cc
index df1f8b8..e5437ce 100644
--- a/chrome/browser/google/google_url_tracker_infobar_delegate.cc
+++ b/chrome/browser/google/google_url_tracker_infobar_delegate.cc
@@ -44,21 +44,29 @@
 }
 
 void GoogleURLTrackerInfoBarDelegate::Close(bool redo_search) {
+  // It's not obvious whether calling OpenURL() with a search URL would
+  // auto-close us or not.  If it did, we wouldn't want to try to
+  // RemoveInfoBar() afterwards.  So for safety, we always call RemoveInfoBar()
+  // directly, and then navigate if necessary afterwards.
+  GURL new_search_url;
   if (redo_search) {
     // Re-do the user's search on the new domain.
     DCHECK(search_url_.is_valid());
     url_canon::Replacements<char> replacements;
     const std::string& host(google_url_tracker_->fetched_google_url().host());
     replacements.SetHost(host.data(), url_parse::Component(0, host.length()));
-    GURL new_search_url(search_url_.ReplaceComponents(replacements));
-    if (new_search_url.is_valid()) {
-      web_contents()->OpenURL(content::OpenURLParams(
-          new_search_url, content::Referrer(), CURRENT_TAB,
-          content::PAGE_TRANSITION_GENERATED, false));
-    }
+    new_search_url = search_url_.ReplaceComponents(replacements);
   }
 
+  content::WebContents* contents = web_contents();
   owner()->RemoveInfoBar(this);
+  // WARNING: |this| may be deleted at this point!  Do not access any members!
+
+  if (new_search_url.is_valid()) {
+    contents->OpenURL(content::OpenURLParams(
+        new_search_url, content::Referrer(), CURRENT_TAB,
+        content::PAGE_TRANSITION_GENERATED, false));
+  }
 }
 
 GoogleURLTrackerInfoBarDelegate::GoogleURLTrackerInfoBarDelegate(
@@ -99,12 +107,13 @@
 
 bool GoogleURLTrackerInfoBarDelegate::LinkClicked(
     WindowOpenDisposition disposition) {
-  content::OpenURLParams params(google_util::AppendGoogleLocaleParam(GURL(
-      "https://www.google.com/support/chrome/bin/answer.py?answer=1618699")),
+  web_contents()->OpenURL(content::OpenURLParams(
+      google_util::AppendGoogleLocaleParam(GURL(
+          "https://www.google.com/support/chrome/bin/answer.py?"
+          "answer=1618699")),
       content::Referrer(),
       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
-      content::PAGE_TRANSITION_LINK, false);
-  web_contents()->OpenURL(params);
+      content::PAGE_TRANSITION_LINK, false));
   return false;
 }
 
diff --git a/chrome/browser/google/google_url_tracker_map_entry.cc b/chrome/browser/google/google_url_tracker_map_entry.cc
index 5a2d617..3748fdb 100644
--- a/chrome/browser/google/google_url_tracker_map_entry.cc
+++ b/chrome/browser/google/google_url_tracker_map_entry.cc
@@ -4,10 +4,10 @@
 
 #include "chrome/browser/google/google_url_tracker_map_entry.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_url_tracker.h"
 #include "chrome/browser/google/google_url_tracker_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 
@@ -18,7 +18,7 @@
     const content::NavigationController* navigation_controller)
     : google_url_tracker_(google_url_tracker),
       infobar_service_(infobar_service),
-      infobar_(NULL),
+      infobar_delegate_(NULL),
       navigation_controller_(navigation_controller) {
 }
 
@@ -29,25 +29,27 @@
     int type,
     const content::NotificationSource& source,
     const content::NotificationDetails& details) {
+  DCHECK(infobar_delegate_);
   DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
   DCHECK_EQ(infobar_service_, content::Source<InfoBarService>(source).ptr());
-  if (content::Details<InfoBarRemovedDetails>(details)->first == infobar_) {
+  if (content::Details<InfoBarRemovedDetails>(details)->first ==
+      infobar_delegate_) {
     google_url_tracker_->DeleteMapEntryForService(infobar_service_);
     // WARNING: At this point |this| has been deleted!
   }
 }
 
-void GoogleURLTrackerMapEntry::SetInfoBar(
-    GoogleURLTrackerInfoBarDelegate* infobar) {
-  DCHECK(!infobar_);
-  infobar_ = infobar;
+void GoogleURLTrackerMapEntry::SetInfoBarDelegate(
+    GoogleURLTrackerInfoBarDelegate* infobar_delegate) {
+  DCHECK(!infobar_delegate_);
+  infobar_delegate_ = infobar_delegate;
   registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
                  content::Source<InfoBarService>(infobar_service_));
 }
 
 void GoogleURLTrackerMapEntry::Close(bool redo_search) {
-  if (infobar_) {
-    infobar_->Close(redo_search);
+  if (infobar_delegate_) {
+    infobar_delegate_->Close(redo_search);
   } else {
     // WARNING: |infobar_service_| may point to a deleted object.  Do not
     // dereference it!  See GoogleURLTracker::OnTabClosed().
diff --git a/chrome/browser/google/google_url_tracker_map_entry.h b/chrome/browser/google/google_url_tracker_map_entry.h
index 2a190f8..2e035a7 100644
--- a/chrome/browser/google/google_url_tracker_map_entry.h
+++ b/chrome/browser/google/google_url_tracker_map_entry.h
@@ -24,9 +24,11 @@
       const content::NavigationController* navigation_controller);
   virtual ~GoogleURLTrackerMapEntry();
 
-  bool has_infobar() const { return !!infobar_; }
-  GoogleURLTrackerInfoBarDelegate* infobar() { return infobar_; }
-  void SetInfoBar(GoogleURLTrackerInfoBarDelegate* infobar);
+  bool has_infobar_delegate() const { return !!infobar_delegate_; }
+  GoogleURLTrackerInfoBarDelegate* infobar_delegate() {
+    return infobar_delegate_;
+  }
+  void SetInfoBarDelegate(GoogleURLTrackerInfoBarDelegate* infobar_delegate);
 
   const content::NavigationController* navigation_controller() const {
     return navigation_controller_;
@@ -45,7 +47,7 @@
   content::NotificationRegistrar registrar_;
   GoogleURLTracker* const google_url_tracker_;
   const InfoBarService* const infobar_service_;
-  GoogleURLTrackerInfoBarDelegate* infobar_;
+  GoogleURLTrackerInfoBarDelegate* infobar_delegate_;
   const content::NavigationController* const navigation_controller_;
 
   DISALLOW_COPY_AND_ASSIGN(GoogleURLTrackerMapEntry);
diff --git a/chrome/browser/google/google_url_tracker_navigation_helper_impl.cc b/chrome/browser/google/google_url_tracker_navigation_helper_impl.cc
index 867a84f..b6aa6c3 100644
--- a/chrome/browser/google/google_url_tracker_navigation_helper_impl.cc
+++ b/chrome/browser/google/google_url_tracker_navigation_helper_impl.cc
@@ -4,9 +4,9 @@
 
 #include "chrome/browser/google/google_url_tracker_navigation_helper_impl.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_url_tracker.h"
 #include "chrome/browser/infobars/infobar_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/google/google_url_tracker_unittest.cc b/chrome/browser/google/google_url_tracker_unittest.cc
index 8f999a7..0e6632d 100644
--- a/chrome/browser/google/google_url_tracker_unittest.cc
+++ b/chrome/browser/google/google_url_tracker_unittest.cc
@@ -9,12 +9,12 @@
 
 #include "base/message_loop.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_url_tracker_factory.h"
 #include "chrome/browser/google/google_url_tracker_infobar_delegate.h"
 #include "chrome/browser/google/google_url_tracker_navigation_helper.h"
 #include "chrome/browser/infobars/infobar.h"
 #include "chrome/browser/infobars/infobar_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_service.h"
@@ -231,7 +231,7 @@
   void CommitSearch(intptr_t unique_id, const GURL& search_url);
   void CloseTab(intptr_t unique_id);
   GoogleURLTrackerMapEntry* GetMapEntry(intptr_t unique_id);
-  GoogleURLTrackerInfoBarDelegate* GetInfoBar(intptr_t unique_id);
+  GoogleURLTrackerInfoBarDelegate* GetInfoBarDelegate(intptr_t unique_id);
   void ExpectDefaultURLs() const;
   void ExpectListeningForCommit(intptr_t unique_id, bool listening);
   bool observer_notified() const { return observer_.notified(); }
@@ -241,7 +241,7 @@
   // Since |infobar_service| is really a magic number rather than an actual
   // object, we don't add the created infobar to it.  Instead we will simulate
   // any helper<->infobar interaction necessary.  The returned object will be
-  // cleaned up in CloseTab().
+  // cleaned up in OnInfoBarClosed().
   GoogleURLTrackerInfoBarDelegate* CreateTestInfoBar(
       InfoBarService* infobar_service,
       GoogleURLTracker* google_url_tracker,
@@ -273,7 +273,7 @@
       google_url_tracker_->entry_map_.find(infobar_service);
   ASSERT_FALSE(i == google_url_tracker_->entry_map_.end());
   GoogleURLTrackerMapEntry* map_entry = i->second;
-  ASSERT_EQ(infobar, map_entry->infobar());
+  ASSERT_EQ(infobar, map_entry->infobar_delegate());
   map_entry->Observe(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
                      content::Source<InfoBarService>(infobar_service),
                      content::Details<InfoBarRemovedDetails>(&removed_details));
@@ -386,14 +386,14 @@
 
   // The infobar should be showing; otherwise the pending non-search should
   // have closed it.
-  ASSERT_TRUE(map_entry->has_infobar());
+  ASSERT_TRUE(map_entry->has_infobar_delegate());
 
   // The pending_id should have been reset to 0 when the non-search became
   // pending.
-  EXPECT_EQ(0, map_entry->infobar()->pending_id());
+  EXPECT_EQ(0, map_entry->infobar_delegate()->pending_id());
 
   // Committing the navigation would close the infobar.
-  map_entry->infobar()->Close(false);
+  map_entry->infobar_delegate()->Close(false);
 }
 
 void GoogleURLTrackerTest::CommitSearch(intptr_t unique_id,
@@ -402,8 +402,7 @@
   if (nav_helper_->IsListeningForNavigationCommit(
       reinterpret_cast<content::NavigationController*>(unique_id))) {
     google_url_tracker_->OnNavigationCommitted(
-        reinterpret_cast<InfoBarService*>(unique_id),
-        search_url);
+        reinterpret_cast<InfoBarService*>(unique_id), search_url);
   }
 }
 
@@ -415,9 +414,9 @@
     google_url_tracker_->OnTabClosed(nav_controller);
   } else {
     // Closing a tab with an infobar showing would close the infobar.
-    GoogleURLTrackerInfoBarDelegate* infobar = GetInfoBar(unique_id);
-    if (infobar)
-      infobar->Close(false);
+    GoogleURLTrackerInfoBarDelegate* delegate = GetInfoBarDelegate(unique_id);
+    if (delegate)
+      delegate->Close(false);
   }
 }
 
@@ -429,10 +428,10 @@
   return (i == google_url_tracker_->entry_map_.end()) ? NULL : i->second;
 }
 
-GoogleURLTrackerInfoBarDelegate* GoogleURLTrackerTest::GetInfoBar(
+GoogleURLTrackerInfoBarDelegate* GoogleURLTrackerTest::GetInfoBarDelegate(
     intptr_t unique_id) {
   GoogleURLTrackerMapEntry* map_entry = GetMapEntry(unique_id);
-  return map_entry ? map_entry->infobar() : NULL;
+  return map_entry ? map_entry->infobar_delegate() : NULL;
 }
 
 void GoogleURLTrackerTest::ExpectDefaultURLs() const {
@@ -493,6 +492,7 @@
 
 void TestInfoBarDelegate::Close(bool redo_search) {
   test_harness_->OnInfoBarClosed(this, infobar_service_);
+  // WARNING: At this point |this| has been deleted!
 }
 
 }  // namespace
@@ -739,7 +739,7 @@
   SetNavigationPending(1, true);
   GoogleURLTrackerMapEntry* map_entry = GetMapEntry(1);
   ASSERT_FALSE(map_entry == NULL);
-  EXPECT_FALSE(map_entry->has_infobar());
+  EXPECT_FALSE(map_entry->has_infobar_delegate());
   EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage), google_url());
   EXPECT_EQ(GURL("http://www.google.co.uk/"), GetLastPromptedGoogleURL());
   EXPECT_FALSE(observer_notified());
@@ -759,7 +759,7 @@
 
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.co.uk/search?q=test"));
-  EXPECT_FALSE(GetInfoBar(1) == NULL);
+  EXPECT_FALSE(GetInfoBarDelegate(1) == NULL);
 
   CloseTab(1);
   EXPECT_TRUE(GetMapEntry(1) == NULL);
@@ -776,7 +776,7 @@
 
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.co.uk/search?q=test"));
-  GoogleURLTrackerInfoBarDelegate* infobar = GetInfoBar(1);
+  GoogleURLTrackerInfoBarDelegate* infobar = GetInfoBarDelegate(1);
   ASSERT_FALSE(infobar == NULL);
 
   infobar->Close(false);
@@ -794,7 +794,7 @@
 
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.co.uk/search?q=test"));
-  GoogleURLTrackerInfoBarDelegate* infobar = GetInfoBar(1);
+  GoogleURLTrackerInfoBarDelegate* infobar = GetInfoBarDelegate(1);
   ASSERT_FALSE(infobar == NULL);
 
   infobar->Cancel();
@@ -812,7 +812,7 @@
 
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.co.uk/search?q=test"));
-  GoogleURLTrackerInfoBarDelegate* infobar = GetInfoBar(1);
+  GoogleURLTrackerInfoBarDelegate* infobar = GetInfoBarDelegate(1);
   ASSERT_FALSE(infobar == NULL);
 
   infobar->Accept();
@@ -833,7 +833,7 @@
   MockSearchDomainCheckResponse("http://www.google.co.uk/");
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.com/search?q=test"));
-  EXPECT_FALSE(GetInfoBar(1) == NULL);
+  EXPECT_FALSE(GetInfoBarDelegate(1) == NULL);
   NotifyIPAddressChanged();
   MockSearchDomainCheckResponse(google_url().spec());
   EXPECT_EQ(google_url(), GetLastPromptedGoogleURL());
@@ -844,7 +844,7 @@
   MockSearchDomainCheckResponse("http://www.google.co.uk/");
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.com/search?q=test"));
-  EXPECT_FALSE(GetInfoBar(1) == NULL);
+  EXPECT_FALSE(GetInfoBarDelegate(1) == NULL);
   NotifyIPAddressChanged();
   url_canon::Replacements<char> replacements;
   const std::string& scheme("https");
@@ -861,7 +861,7 @@
   MockSearchDomainCheckResponse("http://www.google.co.jp/");
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.com/search?q=test"));
-  EXPECT_FALSE(GetInfoBar(1) == NULL);
+  EXPECT_FALSE(GetInfoBarDelegate(1) == NULL);
   NotifyIPAddressChanged();
   MockSearchDomainCheckResponse("http://www.google.co.uk/");
   EXPECT_EQ(new_google_url, google_url());
@@ -873,7 +873,7 @@
   MockSearchDomainCheckResponse("http://www.google.co.jp/");
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.com/search?q=test"));
-  EXPECT_FALSE(GetInfoBar(1) == NULL);
+  EXPECT_FALSE(GetInfoBarDelegate(1) == NULL);
   NotifyIPAddressChanged();
   MockSearchDomainCheckResponse("https://www.google.co.uk/");
   EXPECT_EQ(new_google_url, google_url());
@@ -885,7 +885,7 @@
   MockSearchDomainCheckResponse("http://www.google.co.jp/");
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.com/search?q=test"));
-  EXPECT_FALSE(GetInfoBar(1) == NULL);
+  EXPECT_FALSE(GetInfoBarDelegate(1) == NULL);
   NotifyIPAddressChanged();
   MockSearchDomainCheckResponse("https://www.google.co.in/");
   EXPECT_EQ(new_google_url, google_url());
@@ -902,15 +902,15 @@
   MockSearchDomainCheckResponse("http://www.google.co.uk/");
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.com/search?q=test"));
-  GoogleURLTrackerInfoBarDelegate* infobar = GetInfoBar(1);
-  ASSERT_FALSE(infobar == NULL);
+  GoogleURLTrackerInfoBarDelegate* delegate = GetInfoBarDelegate(1);
+  ASSERT_FALSE(delegate == NULL);
   EXPECT_EQ(GURL("http://www.google.co.uk/"), fetched_google_url());
 
   // If while an infobar is showing we fetch a new URL that differs from the
   // infobar's only by scheme, the infobar should stay showing.
   NotifyIPAddressChanged();
   MockSearchDomainCheckResponse("https://www.google.co.uk/");
-  EXPECT_EQ(infobar, GetInfoBar(1));
+  EXPECT_EQ(delegate, GetInfoBarDelegate(1));
   EXPECT_EQ(GURL("https://www.google.co.uk/"), fetched_google_url());
 }
 
@@ -924,7 +924,7 @@
   SetNavigationPending(1, true);
   GoogleURLTrackerMapEntry* map_entry = GetMapEntry(1);
   ASSERT_FALSE(map_entry == NULL);
-  EXPECT_FALSE(map_entry->has_infobar());
+  EXPECT_FALSE(map_entry->has_infobar_delegate());
   SetNavigationPending(1, false);
   EXPECT_TRUE(GetMapEntry(1) == NULL);
 
@@ -932,15 +932,15 @@
   SetNavigationPending(1, true);
   map_entry = GetMapEntry(1);
   ASSERT_FALSE(map_entry == NULL);
-  EXPECT_FALSE(map_entry->has_infobar());
+  EXPECT_FALSE(map_entry->has_infobar_delegate());
   SetNavigationPending(1, true);
   ASSERT_EQ(map_entry, GetMapEntry(1));
-  EXPECT_FALSE(map_entry->has_infobar());
+  EXPECT_FALSE(map_entry->has_infobar_delegate());
   ASSERT_NO_FATAL_FAILURE(ExpectListeningForCommit(1, true));
 
   // Committing this search should show an infobar.
   CommitSearch(1, GURL("http://www.google.co.uk/search?q=test2"));
-  EXPECT_TRUE(map_entry->has_infobar());
+  EXPECT_TRUE(map_entry->has_infobar_delegate());
   EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage), google_url());
   EXPECT_EQ(GURL("http://www.google.co.uk/"), GetLastPromptedGoogleURL());
   EXPECT_FALSE(observer_notified());
@@ -954,20 +954,20 @@
   MockSearchDomainCheckResponse("http://www.google.co.jp/");
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.co.uk/search?q=test"));
-  GoogleURLTrackerInfoBarDelegate* infobar = GetInfoBar(1);
-  ASSERT_FALSE(infobar == NULL);
+  GoogleURLTrackerInfoBarDelegate* delegate = GetInfoBarDelegate(1);
+  ASSERT_FALSE(delegate == NULL);
   ASSERT_NO_FATAL_FAILURE(ExpectListeningForCommit(1, false));
 
   // A pending non-search on a visible infobar should basically do nothing.
   SetNavigationPending(1, false);
-  ASSERT_EQ(infobar, GetInfoBar(1));
-  EXPECT_EQ(0, infobar->pending_id());
+  ASSERT_EQ(delegate, GetInfoBarDelegate(1));
+  EXPECT_EQ(0, delegate->pending_id());
   ASSERT_NO_FATAL_FAILURE(ExpectListeningForCommit(1, false));
 
   // As should another pending non-search after the first.
   SetNavigationPending(1, false);
-  ASSERT_EQ(infobar, GetInfoBar(1));
-  EXPECT_EQ(0, infobar->pending_id());
+  ASSERT_EQ(delegate, GetInfoBarDelegate(1));
+  EXPECT_EQ(0, delegate->pending_id());
   ASSERT_NO_FATAL_FAILURE(ExpectListeningForCommit(1, false));
 
   // Committing this non-search should close the infobar.  The control flow in
@@ -980,38 +980,38 @@
   // for the search to commit.
   SetNavigationPending(1, true);
   CommitSearch(1, GURL("http://www.google.co.uk/search?q=test"));
-  infobar = GetInfoBar(1);
-  ASSERT_FALSE(infobar == NULL);
+  delegate = GetInfoBarDelegate(1);
+  ASSERT_FALSE(delegate == NULL);
   SetNavigationPending(1, true);
-  ASSERT_EQ(infobar, GetInfoBar(1));
-  EXPECT_EQ(1, infobar->pending_id());
+  ASSERT_EQ(delegate, GetInfoBarDelegate(1));
+  EXPECT_EQ(1, delegate->pending_id());
   ASSERT_NO_FATAL_FAILURE(ExpectListeningForCommit(1, true));
 
   // But a non-search after this should cancel that state.
   SetNavigationPending(1, false);
-  ASSERT_EQ(infobar, GetInfoBar(1));
-  EXPECT_EQ(0, infobar->pending_id());
+  ASSERT_EQ(delegate, GetInfoBarDelegate(1));
+  EXPECT_EQ(0, delegate->pending_id());
   ASSERT_NO_FATAL_FAILURE(ExpectListeningForCommit(1, false));
 
   // Another pending search after the non-search should put us back into
   // "waiting for commit" mode.
   SetNavigationPending(1, true);
-  ASSERT_EQ(infobar, GetInfoBar(1));
-  EXPECT_EQ(1, infobar->pending_id());
+  ASSERT_EQ(delegate, GetInfoBarDelegate(1));
+  EXPECT_EQ(1, delegate->pending_id());
   ASSERT_NO_FATAL_FAILURE(ExpectListeningForCommit(1, true));
 
   // A second pending search after the first should not really change anything.
   SetNavigationPending(1, true);
-  ASSERT_EQ(infobar, GetInfoBar(1));
-  EXPECT_EQ(1, infobar->pending_id());
+  ASSERT_EQ(delegate, GetInfoBarDelegate(1));
+  EXPECT_EQ(1, delegate->pending_id());
   ASSERT_NO_FATAL_FAILURE(ExpectListeningForCommit(1, true));
 
   // Committing this search should change the visible infobar's search_url.
   CommitSearch(1, GURL("http://www.google.co.uk/search?q=test2"));
-  ASSERT_EQ(infobar, GetInfoBar(1));
+  ASSERT_EQ(delegate, GetInfoBarDelegate(1));
   EXPECT_EQ(GURL("http://www.google.co.uk/search?q=test2"),
-            infobar->search_url());
-  EXPECT_EQ(0, infobar->pending_id());
+            delegate->search_url());
+  EXPECT_EQ(0, delegate->pending_id());
   ASSERT_NO_FATAL_FAILURE(ExpectListeningForCommit(1, false));
   EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage), google_url());
   EXPECT_EQ(GURL("http://www.google.co.uk/"), GetLastPromptedGoogleURL());
@@ -1027,35 +1027,35 @@
   SetNavigationPending(1, true);
   GoogleURLTrackerMapEntry* map_entry = GetMapEntry(1);
   ASSERT_FALSE(map_entry == NULL);
-  EXPECT_FALSE(map_entry->has_infobar());
+  EXPECT_FALSE(map_entry->has_infobar_delegate());
 
   SetNavigationPending(2, true);
   CommitSearch(2, GURL("http://www.google.co.uk/search?q=test2"));
-  GoogleURLTrackerInfoBarDelegate* infobar2 = GetInfoBar(2);
-  ASSERT_FALSE(infobar2 == NULL);
+  GoogleURLTrackerInfoBarDelegate* delegate2 = GetInfoBarDelegate(2);
+  ASSERT_FALSE(delegate2 == NULL);
   EXPECT_EQ(GURL("http://www.google.co.uk/search?q=test2"),
-            infobar2->search_url());
+            delegate2->search_url());
 
   SetNavigationPending(3, true);
   GoogleURLTrackerMapEntry* map_entry3 = GetMapEntry(3);
   ASSERT_FALSE(map_entry3 == NULL);
-  EXPECT_FALSE(map_entry3->has_infobar());
+  EXPECT_FALSE(map_entry3->has_infobar_delegate());
 
   SetNavigationPending(4, true);
   CommitSearch(4, GURL("http://www.google.co.uk/search?q=test4"));
-  GoogleURLTrackerInfoBarDelegate* infobar4 = GetInfoBar(4);
-  ASSERT_FALSE(infobar4 == NULL);
+  GoogleURLTrackerInfoBarDelegate* delegate4 = GetInfoBarDelegate(4);
+  ASSERT_FALSE(delegate4 == NULL);
   EXPECT_EQ(GURL("http://www.google.co.uk/search?q=test4"),
-            infobar4->search_url());
+            delegate4->search_url());
 
   CommitSearch(1, GURL("http://www.google.co.uk/search?q=test"));
-  EXPECT_TRUE(map_entry->has_infobar());
+  EXPECT_TRUE(map_entry->has_infobar_delegate());
 
-  infobar2->Close(false);
+  delegate2->Close(false);
   EXPECT_TRUE(GetMapEntry(2) == NULL);
   EXPECT_FALSE(observer_notified());
 
-  infobar4->Accept();
+  delegate4->Accept();
   EXPECT_TRUE(GetMapEntry(1) == NULL);
   EXPECT_TRUE(GetMapEntry(3) == NULL);
   EXPECT_TRUE(GetMapEntry(4) == NULL);
@@ -1076,12 +1076,12 @@
   CommitSearch(1, GURL("http://www.google.co.uk/search?q=test"));
   SetNavigationPending(2, true);
   CommitSearch(2, GURL("http://www.google.co.uk/search?q=test2"));
-  EXPECT_FALSE(GetInfoBar(1) == NULL);
-  GoogleURLTrackerInfoBarDelegate* infobar2 = GetInfoBar(2);
-  ASSERT_FALSE(infobar2 == NULL);
+  EXPECT_FALSE(GetInfoBarDelegate(1) == NULL);
+  GoogleURLTrackerInfoBarDelegate* delegate2 = GetInfoBarDelegate(2);
+  ASSERT_FALSE(delegate2 == NULL);
   SetNavigationPending(1, true);
   ASSERT_NO_FATAL_FAILURE(ExpectListeningForCommit(1, true));
-  infobar2->Close(false);
+  delegate2->Close(false);
   SetNavigationPending(1, false);
   ASSERT_NO_FATAL_FAILURE(ExpectListeningForCommit(1, false));
 }
diff --git a/chrome/browser/google_apis/DEPS b/chrome/browser/google_apis/DEPS
index 3fc08f4..a1a8e1e 100644
--- a/chrome/browser/google_apis/DEPS
+++ b/chrome/browser/google_apis/DEPS
@@ -2,9 +2,6 @@
   "-chrome",
   "-content",
   "+chrome/browser/google_apis",
-
-  # BrowserThread should be gone: crbug.com/256112
-  "!content/public/browser/browser_thread.h",
 ]
 
 # Exceptions are temporarily needed. crbug.com/146989
@@ -12,15 +9,13 @@
   ".*requests.*unittest\.cc": [
     # This is necessary for AuthService. See below.
     "!chrome/test/base/testing_profile.h",
-    # TestBrowserThreadBundle should be gone: crbug.com/256109
-    "!content/public/test/test_browser_thread_bundle.h",
   ],
   # AuthService should be gone. crbug.com/162157
   "auth_service\.(h|cc)": [
+    "!chrome/browser/chrome_notification_types.h",
     "!chrome/browser/profiles/profile.h",
     "!chrome/browser/signin/token_service_factory.h",
     "!chrome/browser/signin/token_service.h",
-    "!chrome/common/chrome_notification_types.h",
     "!content/public/browser/notification_details.h",
     "!content/public/browser/notification_observer.h",
     "!content/public/browser/notification_registrar.h",
diff --git a/chrome/browser/google_apis/auth_service.cc b/chrome/browser/google_apis/auth_service.cc
index 10377f1..ff492bb 100644
--- a/chrome/browser/google_apis/auth_service.cc
+++ b/chrome/browser/google_apis/auth_service.cc
@@ -10,11 +10,11 @@
 #include "base/bind.h"
 #include "base/message_loop/message_loop_proxy.h"
 #include "base/metrics/histogram.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google_apis/auth_service_observer.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/signin/token_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/notification_types.h"
diff --git a/chrome/browser/google_apis/base_requests.cc b/chrome/browser/google_apis/base_requests.cc
index 49a5f07..8963eb9 100644
--- a/chrome/browser/google_apis/base_requests.cc
+++ b/chrome/browser/google_apis/base_requests.cc
@@ -5,13 +5,12 @@
 #include "chrome/browser/google_apis/base_requests.h"
 
 #include "base/json/json_reader.h"
+#include "base/location.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/task_runner_util.h"
-#include "base/threading/sequenced_worker_pool.h"
 #include "base/values.h"
 #include "chrome/browser/google_apis/request_sender.h"
-#include "content/public/browser/browser_thread.h"
 #include "net/base/load_flags.h"
 #include "net/base/net_errors.h"
 #include "net/http/http_byte_range.h"
@@ -20,7 +19,6 @@
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_request_status.h"
 
-using content::BrowserThread;
 using net::URLFetcher;
 
 namespace {
@@ -80,9 +78,11 @@
 
 namespace google_apis {
 
-void ParseJson(const std::string& json, const ParseJsonCallback& callback) {
+void ParseJson(base::TaskRunner* blocking_task_runner,
+               const std::string& json,
+               const ParseJsonCallback& callback) {
   base::PostTaskAndReplyWithResult(
-      BrowserThread::GetBlockingPool(),
+      blocking_task_runner,
       FROM_HERE,
       base::Bind(&ParseJsonOnBlockingPool, json),
       callback);
@@ -131,7 +131,7 @@
   if (GetOutputFilePath(&output_file_path)) {
     url_fetcher_->SaveResponseToFileAtPath(
         output_file_path,
-        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
+        blocking_task_runner());
   }
 
   // Add request headers.
@@ -165,7 +165,7 @@
           local_file_path,
           range_offset,
           range_length,
-          BrowserThread::GetBlockingPool());
+          blocking_task_runner());
     } else {
       // Even if there is no content data, UrlFetcher requires to set empty
       // upload data string for POST, PUT and PATCH methods, explicitly.
@@ -233,6 +233,10 @@
   return thread_checker_.CalledOnValidThread();
 }
 
+base::TaskRunner* UrlFetchRequestBase::blocking_task_runner() const {
+  return sender_->blocking_task_runner();
+}
+
 void UrlFetchRequestBase::OnProcessURLFetchResultsComplete(bool result) {
   sender_->RequestFinished(this);
 }
@@ -308,7 +312,8 @@
 
   VLOG(1) << "JSON received from " << GetURL().spec() << ": "
           << data.size() << " bytes";
-  ParseJson(data,
+  ParseJson(blocking_task_runner(),
+            data,
             base::Bind(&GetDataRequest::OnDataParsed,
                        weak_ptr_factory_.GetWeakPtr(),
                        fetch_error_code));
@@ -490,7 +495,8 @@
     std::string response_content;
     source->GetResponseAsString(&response_content);
 
-    ParseJson(response_content,
+    ParseJson(blocking_task_runner(),
+              response_content,
               base::Bind(&UploadRangeRequestBase::OnDataParsed,
                          weak_ptr_factory_.GetWeakPtr(),
                          code));
diff --git a/chrome/browser/google_apis/base_requests.h b/chrome/browser/google_apis/base_requests.h
index d57a6c6..45cc358 100644
--- a/chrome/browser/google_apis/base_requests.h
+++ b/chrome/browser/google_apis/base_requests.h
@@ -35,10 +35,12 @@
 // Callback used for DownloadFileRequest and ResumeUploadRequestBase.
 typedef base::Callback<void(int64 progress, int64 total)> ProgressCallback;
 
-// Parses JSON passed in |json| on blocking pool. Runs |callback| on the calling
-// thread when finished with either success or failure.
+// Parses JSON passed in |json| on |blocking_task_runner|. Runs |callback| on
+// the calling thread when finished with either success or failure.
 // The callback must not be null.
-void ParseJson(const std::string& json, const ParseJsonCallback& callback);
+void ParseJson(base::TaskRunner* blocking_task_runner,
+               const std::string& json,
+               const ParseJsonCallback& callback);
 
 //======================= AuthenticatedRequestInterface ======================
 
@@ -146,6 +148,9 @@
   // Returns true if called on the thread where the constructor was called.
   bool CalledOnValidThread();
 
+  // Returns the task runner that should be used for blocking tasks.
+  base::TaskRunner* blocking_task_runner() const;
+
  private:
   // URLFetcherDelegate overrides.
   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
@@ -176,8 +181,8 @@
 // It is meant to be used for requests that return no JSON blobs.
 class EntryActionRequest : public UrlFetchRequestBase {
  public:
-  // |url_request_context_getter| is used to initialize URLFetcher.
-  // |callback| must not be null.
+  // |callback| is called when the request is finished either by success or by
+  // failure. It must not be null.
   EntryActionRequest(RequestSender* sender,
                      const EntryActionCallback& callback);
   virtual ~EntryActionRequest();
@@ -205,7 +210,8 @@
 // content into a base::Value.
 class GetDataRequest : public UrlFetchRequestBase {
  public:
-  // |callback| must not be null.
+  // |callback| is called when the request finishes either by success or by
+  // failure. On success, a JSON Value object is passed. It must not be null.
   GetDataRequest(RequestSender* sender, const GetDataCallback& callback);
   virtual ~GetDataRequest();
 
@@ -258,8 +264,7 @@
 class InitiateUploadRequestBase : public UrlFetchRequestBase {
  protected:
   // |callback| will be called with the upload URL, where upload data is
-  // uploaded to with ResumeUploadRequestBase.
-  // |callback| must not be null.
+  // uploaded to with ResumeUploadRequestBase. It must not be null.
   // |content_type| and |content_length| should be the attributes of the
   // uploading file.
   InitiateUploadRequestBase(RequestSender* sender,
diff --git a/chrome/browser/google_apis/base_requests_server_unittest.cc b/chrome/browser/google_apis/base_requests_server_unittest.cc
index 58f8941..8b0f815 100644
--- a/chrome/browser/google_apis/base_requests_server_unittest.cc
+++ b/chrome/browser/google_apis/base_requests_server_unittest.cc
@@ -7,14 +7,13 @@
 #include "base/bind.h"
 #include "base/file_util.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "chrome/browser/google_apis/auth_service.h"
 #include "chrome/browser/google_apis/request_sender.h"
 #include "chrome/browser/google_apis/task_util.h"
 #include "chrome/browser/google_apis/test_util.h"
 #include "chrome/test/base/testing_profile.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/test/test_browser_thread_bundle.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
@@ -33,20 +32,18 @@
 class BaseRequestsServerTest : public testing::Test {
  protected:
   BaseRequestsServerTest()
-      : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
-        test_server_(content::BrowserThread::GetMessageLoopProxyForThread(
-            content::BrowserThread::IO)) {
+      : test_server_(message_loop_.message_loop_proxy()) {
   }
 
   virtual void SetUp() OVERRIDE {
     profile_.reset(new TestingProfile);
 
     request_context_getter_ = new net::TestURLRequestContextGetter(
-        content::BrowserThread::GetMessageLoopProxyForThread(
-            content::BrowserThread::IO));
+        message_loop_.message_loop_proxy());
 
     request_sender_.reset(new RequestSender(profile_.get(),
                                             request_context_getter_.get(),
+                                            message_loop_.message_loop_proxy(),
                                             std::vector<std::string>(),
                                             kTestUserAgent));
     request_sender_->auth_service()->set_access_token_for_testing(
@@ -64,7 +61,7 @@
     return profile_->GetPath().Append(file_name);
   }
 
-  content::TestBrowserThreadBundle thread_bundle_;
+  base::MessageLoopForIO message_loop_;  // Test server needs IO thread.
   net::test_server::EmbeddedTestServer test_server_;
   scoped_ptr<TestingProfile> profile_;
   scoped_ptr<RequestSender> request_sender_;
@@ -97,7 +94,7 @@
 
   std::string contents;
   file_util::ReadFileToString(temp_file, &contents);
-  base::Delete(temp_file, false);
+  base::DeleteFile(temp_file, false);
 
   EXPECT_EQ(HTTP_SUCCESS, result_code);
   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
diff --git a/chrome/browser/google_apis/base_requests_unittest.cc b/chrome/browser/google_apis/base_requests_unittest.cc
index a4eb9f0..723d0f5 100644
--- a/chrome/browser/google_apis/base_requests_unittest.cc
+++ b/chrome/browser/google_apis/base_requests_unittest.cc
@@ -6,11 +6,12 @@
 
 #include "base/bind.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "base/values.h"
 #include "chrome/browser/google_apis/request_sender.h"
 #include "chrome/browser/google_apis/test_util.h"
 #include "chrome/test/base/testing_profile.h"
-#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace google_apis {
@@ -45,23 +46,23 @@
     profile_.reset(new TestingProfile);
     sender_.reset(new RequestSender(profile_.get(),
                                     NULL /* url_request_context_getter */,
+                                    message_loop_.message_loop_proxy(),
                                     std::vector<std::string>() /* scopes */,
                                     std::string() /* custom user agent */));
     sender_->Initialize();
   }
 
-  content::TestBrowserThreadBundle thread_bundle_;
+  base::MessageLoop message_loop_;
   scoped_ptr<TestingProfile> profile_;
   scoped_ptr<RequestSender> sender_;
 };
 
 TEST_F(BaseRequestsTest, ParseValidJson) {
   scoped_ptr<base::Value> json;
-  ParseJson(kValidJsonString,
+  ParseJson(message_loop_.message_loop_proxy(),
+            kValidJsonString,
             base::Bind(test_util::CreateCopyResultCallback(&json)));
-  // Should wait for a blocking pool task, as the JSON parsing is done in the
-  // blocking pool.
-  test_util::RunBlockingPoolTask();
+  base::RunLoop().RunUntilIdle();
 
   DictionaryValue* root_dict = NULL;
   ASSERT_TRUE(json);
@@ -75,11 +76,10 @@
 TEST_F(BaseRequestsTest, ParseInvalidJson) {
   // Initialize with a valid pointer to verify that null is indeed assigned.
   scoped_ptr<base::Value> json(base::Value::CreateNullValue());
-  ParseJson(kInvalidJsonString,
+  ParseJson(message_loop_.message_loop_proxy(),
+            kInvalidJsonString,
             base::Bind(test_util::CreateCopyResultCallback(&json)));
-  // Should wait for a blocking pool task, as the JSON parsing is done in the
-  // blocking pool.
-  test_util::RunBlockingPoolTask();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_FALSE(json);
 }
@@ -93,9 +93,7 @@
           base::Bind(test_util::CreateCopyResultCallback(&error, &value)));
 
   get_data_request->ParseResponse(HTTP_SUCCESS, kValidJsonString);
-  // Should wait for a blocking pool task, as the JSON parsing is done in the
-  // blocking pool.
-  test_util::RunBlockingPoolTask();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(HTTP_SUCCESS, error);
   EXPECT_TRUE(value);
@@ -110,9 +108,7 @@
           base::Bind(test_util::CreateCopyResultCallback(&error, &value)));
 
   get_data_request->ParseResponse(HTTP_SUCCESS, kInvalidJsonString);
-  // Should wait for a blocking pool task, as the JSON parsing is done in the
-  // blocking pool.
-  test_util::RunBlockingPoolTask();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(GDATA_PARSE_ERROR, error);
   EXPECT_FALSE(value);
diff --git a/chrome/browser/google_apis/drive_api_parser.cc b/chrome/browser/google_apis/drive_api_parser.cc
index fa8872b..1bea266 100644
--- a/chrome/browser/google_apis/drive_api_parser.cc
+++ b/chrome/browser/google_apis/drive_api_parser.cc
@@ -25,6 +25,12 @@
 
 namespace {
 
+bool CreateFileResourceFromValue(const base::Value* value,
+                                 scoped_ptr<FileResource>* file) {
+  *file = FileResource::CreateFrom(*value);
+  return !!*file;
+}
+
 // Converts |url_string| to |result|.  Always returns true to be used
 // for JSONValueConverter::RegisterCustomField method.
 // TODO(mukai): make it return false in case of invalid |url_string|.
@@ -704,7 +710,8 @@
                                         &base::StringToInt64);
   converter->RegisterStringField(kFileId, &ChangeResource::file_id_);
   converter->RegisterBoolField(kDeleted, &ChangeResource::deleted_);
-  converter->RegisterNestedField(kFile, &ChangeResource::file_);
+  converter->RegisterCustomValueField(kFile, &ChangeResource::file_,
+                                      &CreateFileResourceFromValue);
 }
 
 // static
diff --git a/chrome/browser/google_apis/drive_api_parser.h b/chrome/browser/google_apis/drive_api_parser.h
index 7042320..7c23f24 100644
--- a/chrome/browser/google_apis/drive_api_parser.h
+++ b/chrome/browser/google_apis/drive_api_parser.h
@@ -573,6 +573,9 @@
   void set_created_date(const base::Time& created_date) {
     created_date_ = created_date;
   }
+  void set_modified_date(const base::Time& modified_date) {
+    modified_date_ = modified_date;
+  }
   void set_modified_by_me_date(const base::Time& modified_by_me_date) {
     modified_by_me_date_ = modified_by_me_date;
   }
@@ -728,7 +731,7 @@
   bool is_deleted() const { return deleted_; }
 
   // Returns FileResource of the file which the change refers to.
-  const FileResource& file() const { return file_; }
+  const FileResource* file() const { return file_.get(); }
 
   void set_change_id(int64 change_id) {
     change_id_ = change_id;
@@ -739,8 +742,8 @@
   void set_deleted(bool deleted) {
     deleted_ = deleted;
   }
-  void set_file(const FileResource& file) {
-    file_ = file;
+  void set_file(scoped_ptr<FileResource> file) {
+    file_ = file.Pass();
   }
 
  private:
@@ -754,7 +757,7 @@
   int64 change_id_;
   std::string file_id_;
   bool deleted_;
-  FileResource file_;
+  scoped_ptr<FileResource> file_;
 
   DISALLOW_COPY_AND_ASSIGN(ChangeResource);
 };
diff --git a/chrome/browser/google_apis/drive_api_parser_unittest.cc b/chrome/browser/google_apis/drive_api_parser_unittest.cc
index 60d4f35..cf816d0 100644
--- a/chrome/browser/google_apis/drive_api_parser_unittest.cc
+++ b/chrome/browser/google_apis/drive_api_parser_unittest.cc
@@ -13,9 +13,6 @@
 
 namespace google_apis {
 
-// TODO(nhiroki): Make it possible to run these tests on any platforms after
-// moving json files to out of 'chromeos' directory (http://crbug.com/149788).
-#if defined(OS_CHROMEOS)
 // Test about resource parsing.
 TEST(DriveAPIParserTest, AboutResourceParser) {
   std::string error;
@@ -370,7 +367,7 @@
   EXPECT_EQ(8421, change1.change_id());
   EXPECT_FALSE(change1.is_deleted());
   EXPECT_EQ("1Pc8jzfU1ErbN_eucMMqdqzY3eBm0v8sxXm_1CtLxABC", change1.file_id());
-  EXPECT_EQ(change1.file_id(), change1.file().file_id());
+  EXPECT_EQ(change1.file_id(), change1.file()->file_id());
 
   scoped_ptr<ResourceEntry> entry1(
       ResourceEntry::CreateFromChangeResource(change1));
@@ -381,7 +378,7 @@
   EXPECT_EQ(8424, change2.change_id());
   EXPECT_FALSE(change2.is_deleted());
   EXPECT_EQ("0B4v7G8yEYAWHUmRrU2lMS2hLABC", change2.file_id());
-  EXPECT_EQ(change2.file_id(), change2.file().file_id());
+  EXPECT_EQ(change2.file_id(), change2.file()->file_id());
 
   scoped_ptr<ResourceEntry> entry2(
       ResourceEntry::CreateFromChangeResource(change2));
@@ -392,7 +389,7 @@
   EXPECT_EQ(8429, change3.change_id());
   EXPECT_FALSE(change3.is_deleted());
   EXPECT_EQ("0B4v7G8yEYAWHYW1OcExsUVZLABC", change3.file_id());
-  EXPECT_EQ(change3.file_id(), change3.file().file_id());
+  EXPECT_EQ(change3.file_id(), change3.file()->file_id());
 
   scoped_ptr<ResourceEntry> entry3(
       ResourceEntry::CreateFromChangeResource(change3));
@@ -423,6 +420,5 @@
   EXPECT_FALSE(FileList::HasFileListKind(*change_list_json));
   EXPECT_TRUE(FileList::HasFileListKind(*file_list_json));
 }
-#endif  // OS_CHROMEOS
 
 }  // namespace google_apis
diff --git a/chrome/browser/google_apis/drive_api_requests.cc b/chrome/browser/google_apis/drive_api_requests.cc
index 04e163e..58ffbb0 100644
--- a/chrome/browser/google_apis/drive_api_requests.cc
+++ b/chrome/browser/google_apis/drive_api_requests.cc
@@ -194,16 +194,16 @@
     RequestSender* sender,
     const DriveApiUrlGenerator& url_generator,
     const std::string& parent_resource_id,
-    const std::string& directory_name,
+    const std::string& directory_title,
     const FileResourceCallback& callback)
     : GetDataRequest(sender,
                      base::Bind(&ParseJsonAndRun<FileResource>, callback)),
       url_generator_(url_generator),
       parent_resource_id_(parent_resource_id),
-      directory_name_(directory_name) {
+      directory_title_(directory_title) {
   DCHECK(!callback.is_null());
   DCHECK(!parent_resource_id_.empty());
-  DCHECK(!directory_name_.empty());
+  DCHECK(!directory_title_.empty());
 }
 
 CreateDirectoryRequest::~CreateDirectoryRequest() {}
@@ -221,7 +221,7 @@
   *upload_content_type = kContentTypeApplicationJson;
 
   base::DictionaryValue root;
-  root.SetString("title", directory_name_);
+  root.SetString("title", directory_title_);
   {
     base::DictionaryValue* parent_value = new base::DictionaryValue;
     parent_value->SetString("id", parent_resource_id_);
@@ -244,12 +244,12 @@
     RequestSender* sender,
     const DriveApiUrlGenerator& url_generator,
     const std::string& resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const EntryActionCallback& callback)
     : EntryActionRequest(sender, callback),
       url_generator_(url_generator),
       resource_id_(resource_id),
-      new_name_(new_name) {
+      new_title_(new_title) {
   DCHECK(!callback.is_null());
 }
 
@@ -275,7 +275,7 @@
   *upload_content_type = kContentTypeApplicationJson;
 
   base::DictionaryValue root;
-  root.SetString("title", new_name_);
+  root.SetString("title", new_title_);
   base::JSONWriter::Write(&root, upload_content);
 
   DVLOG(1) << "RenameResource data: " << *upload_content_type << ", ["
@@ -342,14 +342,14 @@
     const DriveApiUrlGenerator& url_generator,
     const std::string& resource_id,
     const std::string& parent_resource_id,
-    const std::string& new_name,
+    const std::string& new_title,
     const FileResourceCallback& callback)
     : GetDataRequest(sender,
                      base::Bind(&ParseJsonAndRun<FileResource>, callback)),
       url_generator_(url_generator),
       resource_id_(resource_id),
       parent_resource_id_(parent_resource_id),
-      new_name_(new_name) {
+      new_title_(new_title) {
   DCHECK(!callback.is_null());
 }
 
@@ -369,7 +369,7 @@
   *upload_content_type = kContentTypeApplicationJson;
 
   base::DictionaryValue root;
-  root.SetString("title", new_name_);
+  root.SetString("title", new_title_);
 
   if (!parent_resource_id_.empty()) {
     // Set the parent resource (destination directory) of the new resource.
diff --git a/chrome/browser/google_apis/drive_api_requests.h b/chrome/browser/google_apis/drive_api_requests.h
index 0fa5a79..9367b1f 100644
--- a/chrome/browser/google_apis/drive_api_requests.h
+++ b/chrome/browser/google_apis/drive_api_requests.h
@@ -180,7 +180,7 @@
   CreateDirectoryRequest(RequestSender* sender,
                          const DriveApiUrlGenerator& url_generator,
                          const std::string& parent_resource_id,
-                         const std::string& directory_name,
+                         const std::string& directory_title,
                          const FileResourceCallback& callback);
   virtual ~CreateDirectoryRequest();
 
@@ -194,7 +194,7 @@
  private:
   const DriveApiUrlGenerator url_generator_;
   const std::string parent_resource_id_;
-  const std::string directory_name_;
+  const std::string directory_title_;
 
   DISALLOW_COPY_AND_ASSIGN(CreateDirectoryRequest);
 };
@@ -208,7 +208,7 @@
   RenameResourceRequest(RequestSender* sender,
                         const DriveApiUrlGenerator& url_generator,
                         const std::string& resource_id,
-                        const std::string& new_name,
+                        const std::string& new_title,
                         const EntryActionCallback& callback);
   virtual ~RenameResourceRequest();
 
@@ -224,7 +224,7 @@
   const DriveApiUrlGenerator url_generator_;
 
   const std::string resource_id_;
-  const std::string new_name_;
+  const std::string new_title_;
 
   DISALLOW_COPY_AND_ASSIGN(RenameResourceRequest);
 };
@@ -269,7 +269,7 @@
 // This class performs the request for copying a resource.
 //
 // Copies the resource with |resource_id| into a directory with
-// |parent_resource_id|. The new resource will be named as |new_name|.
+// |parent_resource_id|. The new resource will be named as |new_title|.
 // |parent_resource_id| can be empty. In the case, the copy will be created
 // directly under the default root directory (this is the default behavior
 // of Drive API v2's copy request).
@@ -283,7 +283,7 @@
                       const DriveApiUrlGenerator& url_generator,
                       const std::string& resource_id,
                       const std::string& parent_resource_id,
-                      const std::string& new_name,
+                      const std::string& new_title,
                       const FileResourceCallback& callback);
   virtual ~CopyResourceRequest();
 
@@ -296,7 +296,7 @@
   const DriveApiUrlGenerator url_generator_;
   const std::string resource_id_;
   const std::string parent_resource_id_;
-  const std::string new_name_;
+  const std::string new_title_;
 
   DISALLOW_COPY_AND_ASSIGN(CopyResourceRequest);
 };
diff --git a/chrome/browser/google_apis/drive_api_requests_unittest.cc b/chrome/browser/google_apis/drive_api_requests_unittest.cc
index 903e2df..e73b848 100644
--- a/chrome/browser/google_apis/drive_api_requests_unittest.cc
+++ b/chrome/browser/google_apis/drive_api_requests_unittest.cc
@@ -6,6 +6,7 @@
 #include "base/file_util.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
@@ -16,8 +17,6 @@
 #include "chrome/browser/google_apis/request_sender.h"
 #include "chrome/browser/google_apis/test_util.h"
 #include "chrome/test/base/testing_profile.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/test/test_browser_thread_bundle.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
@@ -49,20 +48,18 @@
 class DriveApiRequestsTest : public testing::Test {
  public:
   DriveApiRequestsTest()
-      : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
-        test_server_(content::BrowserThread::GetMessageLoopProxyForThread(
-            content::BrowserThread::IO)) {
+      : test_server_(message_loop_.message_loop_proxy()) {
   }
 
   virtual void SetUp() OVERRIDE {
     profile_.reset(new TestingProfile);
 
     request_context_getter_ = new net::TestURLRequestContextGetter(
-        content::BrowserThread::GetMessageLoopProxyForThread(
-            content::BrowserThread::IO));
+        message_loop_.message_loop_proxy());
 
     request_sender_.reset(new RequestSender(profile_.get(),
                                             request_context_getter_.get(),
+                                            message_loop_.message_loop_proxy(),
                                             std::vector<std::string>(),
                                             kTestUserAgent));
     request_sender_->auth_service()->set_access_token_for_testing(
@@ -100,7 +97,7 @@
     content_length_ = 0;
   }
 
-  content::TestBrowserThreadBundle thread_bundle_;
+  base::MessageLoopForIO message_loop_;  // Test server needs IO thread.
   net::test_server::EmbeddedTestServer test_server_;
   scoped_ptr<TestingProfile> profile_;
   scoped_ptr<RequestSender> request_sender_;
@@ -564,7 +561,7 @@
             request_sender_.get(),
             *url_generator_,
             "resource_id",
-            "new name",
+            "new title",
             test_util::CreateQuitCallback(
                 &run_loop,
                 test_util::CreateCopyResultCallback(&error)));
@@ -578,7 +575,7 @@
   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
 
   EXPECT_TRUE(http_request_.has_content);
-  EXPECT_EQ("{\"title\":\"new name\"}", http_request_.content);
+  EXPECT_EQ("{\"title\":\"new title\"}", http_request_.content);
 }
 
 TEST_F(DriveApiRequestsTest, TouchResourceRequest) {
@@ -631,7 +628,7 @@
   GDataErrorCode error = GDATA_OTHER_ERROR;
   scoped_ptr<FileResource> file_resource;
 
-  // Copy the file to a new file named "new name".
+  // Copy the file to a new file named "new title".
   {
     base::RunLoop run_loop;
     drive::CopyResourceRequest* request =
@@ -640,7 +637,7 @@
             *url_generator_,
             "resource_id",
             "parent_resource_id",
-            "new name",
+            "new title",
             test_util::CreateQuitCallback(
                 &run_loop,
                 test_util::CreateCopyResultCallback(&error, &file_resource)));
@@ -655,7 +652,7 @@
 
   EXPECT_TRUE(http_request_.has_content);
   EXPECT_EQ(
-      "{\"parents\":[{\"id\":\"parent_resource_id\"}],\"title\":\"new name\"}",
+      "{\"parents\":[{\"id\":\"parent_resource_id\"}],\"title\":\"new title\"}",
       http_request_.content);
   EXPECT_TRUE(file_resource);
 }
@@ -669,7 +666,7 @@
   GDataErrorCode error = GDATA_OTHER_ERROR;
   scoped_ptr<FileResource> file_resource;
 
-  // Copy the file to a new file named "new name".
+  // Copy the file to a new file named "new title".
   {
     base::RunLoop run_loop;
     drive::CopyResourceRequest* request =
@@ -678,7 +675,7 @@
             *url_generator_,
             "resource_id",
             std::string(),  // parent resource id.
-            "new name",
+            "new title",
             test_util::CreateQuitCallback(
                 &run_loop,
                 test_util::CreateCopyResultCallback(&error, &file_resource)));
@@ -692,7 +689,7 @@
   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
 
   EXPECT_TRUE(http_request_.has_content);
-  EXPECT_EQ("{\"title\":\"new name\"}", http_request_.content);
+  EXPECT_EQ("{\"title\":\"new title\"}", http_request_.content);
   EXPECT_TRUE(file_resource);
 }
 
@@ -1387,7 +1384,7 @@
 
   std::string contents;
   file_util::ReadFileToString(temp_file, &contents);
-  base::Delete(temp_file, false);
+  base::DeleteFile(temp_file, false);
 
   EXPECT_EQ(HTTP_SUCCESS, result_code);
   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
diff --git a/chrome/browser/google_apis/gdata_wapi_parser.cc b/chrome/browser/google_apis/gdata_wapi_parser.cc
index 8e27223..7e11303 100644
--- a/chrome/browser/google_apis/gdata_wapi_parser.cc
+++ b/chrome/browser/google_apis/gdata_wapi_parser.cc
@@ -771,7 +771,11 @@
 // static
 scoped_ptr<ResourceEntry> ResourceEntry::CreateFromChangeResource(
     const ChangeResource& change) {
-  scoped_ptr<ResourceEntry> entry = CreateFromFileResource(change.file());
+  scoped_ptr<ResourceEntry> entry;
+  if (change.file())
+    entry = CreateFromFileResource(*change.file()).Pass();
+  else
+    entry.reset(new ResourceEntry);
 
   entry->resource_id_ = change.file_id();
   // If |is_deleted()| returns true, the file is removed from Drive.
diff --git a/chrome/browser/google_apis/gdata_wapi_requests.cc b/chrome/browser/google_apis/gdata_wapi_requests.cc
index 187ee2b..0b22d34 100644
--- a/chrome/browser/google_apis/gdata_wapi_requests.cc
+++ b/chrome/browser/google_apis/gdata_wapi_requests.cc
@@ -4,21 +4,20 @@
 
 #include "chrome/browser/google_apis/gdata_wapi_requests.h"
 
+#include "base/location.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/task_runner_util.h"
-#include "base/threading/sequenced_worker_pool.h"
 #include "base/values.h"
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
 #include "chrome/browser/google_apis/gdata_wapi_url_generator.h"
+#include "chrome/browser/google_apis/request_sender.h"
 #include "chrome/browser/google_apis/request_util.h"
 #include "chrome/browser/google_apis/time_util.h"
-#include "content/public/browser/browser_thread.h"
 #include "net/base/escape.h"
 #include "net/base/url_util.h"
 #include "third_party/libxml/chromium/libxml_utils.h"
 
-using content::BrowserThread;
 using net::URLFetcher;
 
 namespace google_apis {
@@ -57,9 +56,11 @@
 
 // Parses the JSON value to ResourceList on the blocking pool and runs
 // |callback| on the UI thread once parsing is done.
-void ParseResourceListAndRun(const GetResourceListCallback& callback,
-                             GDataErrorCode error,
-                             scoped_ptr<base::Value> value) {
+void ParseResourceListAndRun(
+    scoped_refptr<base::TaskRunner> blocking_task_runner,
+    const GetResourceListCallback& callback,
+    GDataErrorCode error,
+    scoped_ptr<base::Value> value) {
   DCHECK(!callback.is_null());
 
   if (!value) {
@@ -68,7 +69,7 @@
   }
 
   base::PostTaskAndReplyWithResult(
-      BrowserThread::GetBlockingPool(),
+      blocking_task_runner,
       FROM_HERE,
       base::Bind(&ParseResourceListOnBlockingPool, base::Passed(&value)),
       base::Bind(&DidParseResourceListOnBlockingPool, callback, error));
@@ -162,8 +163,11 @@
     const std::string& search_string,
     const std::string& directory_resource_id,
     const GetResourceListCallback& callback)
-    : GetDataRequest(sender,
-                     base::Bind(&ParseResourceListAndRun, callback)),
+    : GetDataRequest(
+          sender,
+          base::Bind(&ParseResourceListAndRun,
+                     make_scoped_refptr(sender->blocking_task_runner()),
+                     callback)),
       url_generator_(url_generator),
       override_url_(override_url),
       start_changestamp_(start_changestamp),
@@ -189,8 +193,11 @@
     const std::string& title,
     const std::string& directory_resource_id,
     const GetResourceListCallback& callback)
-    : GetDataRequest(sender,
-                     base::Bind(&ParseResourceListAndRun, callback)),
+    : GetDataRequest(
+          sender,
+          base::Bind(&ParseResourceListAndRun,
+                     make_scoped_refptr(sender->blocking_task_runner()),
+                     callback)),
       url_generator_(url_generator),
       title_(title),
       directory_resource_id_(directory_resource_id) {
@@ -282,11 +289,11 @@
     const GDataWapiUrlGenerator& url_generator,
     const GetDataCallback& callback,
     const std::string& parent_resource_id,
-    const std::string& directory_name)
+    const std::string& directory_title)
     : GetDataRequest(sender, callback),
       url_generator_(url_generator),
       parent_resource_id_(parent_resource_id),
-      directory_name_(directory_name) {
+      directory_title_(directory_title) {
   DCHECK(!callback.is_null());
 }
 
@@ -316,7 +323,7 @@
                           "http://schemas.google.com/docs/2007#folder");
   xml_writer.EndElement();  // Ends "category" element.
 
-  xml_writer.WriteElement("title", directory_name_);
+  xml_writer.WriteElement("title", directory_title_);
 
   xml_writer.EndElement();  // Ends "entry" element.
   xml_writer.StopWriting();
@@ -333,11 +340,11 @@
     const GDataWapiUrlGenerator& url_generator,
     const GetDataCallback& callback,
     const std::string& resource_id,
-    const std::string& new_name)
+    const std::string& new_title)
     : GetDataRequest(sender, callback),
       url_generator_(url_generator),
       resource_id_(resource_id),
-      new_name_(new_name) {
+      new_title_(new_title) {
   DCHECK(!callback.is_null());
 }
 
@@ -361,7 +368,7 @@
   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
 
   xml_writer.WriteElement("id", resource_id_);
-  xml_writer.WriteElement("title", new_name_);
+  xml_writer.WriteElement("title", new_title_);
 
   xml_writer.EndElement();  // Ends "entry" element.
   xml_writer.StopWriting();
@@ -378,11 +385,11 @@
     const GDataWapiUrlGenerator& url_generator,
     const EntryActionCallback& callback,
     const std::string& resource_id,
-    const std::string& new_name)
+    const std::string& new_title)
     : EntryActionRequest(sender, callback),
       url_generator_(url_generator),
       resource_id_(resource_id),
-      new_name_(new_name) {
+      new_title_(new_title) {
   DCHECK(!callback.is_null());
 }
 
@@ -411,7 +418,7 @@
   xml_writer.StartElement("entry");
   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
 
-  xml_writer.WriteElement("title", new_name_);
+  xml_writer.WriteElement("title", new_title_);
 
   xml_writer.EndElement();  // Ends "entry" element.
   xml_writer.StopWriting();
diff --git a/chrome/browser/google_apis/gdata_wapi_requests.h b/chrome/browser/google_apis/gdata_wapi_requests.h
index ba6f774..fa6c6d9 100644
--- a/chrome/browser/google_apis/gdata_wapi_requests.h
+++ b/chrome/browser/google_apis/gdata_wapi_requests.h
@@ -195,7 +195,7 @@
                          const GDataWapiUrlGenerator& url_generator,
                          const GetDataCallback& callback,
                          const std::string& parent_resource_id,
-                         const std::string& directory_name);
+                         const std::string& directory_title);
   virtual ~CreateDirectoryRequest();
 
  protected:
@@ -208,7 +208,7 @@
  private:
   const GDataWapiUrlGenerator url_generator_;
   const std::string parent_resource_id_;
-  const std::string directory_name_;
+  const std::string directory_title_;
 
   DISALLOW_COPY_AND_ASSIGN(CreateDirectoryRequest);
 };
@@ -225,7 +225,7 @@
                             const GDataWapiUrlGenerator& url_generator,
                             const GetDataCallback& callback,
                             const std::string& resource_id,
-                            const std::string& new_name);
+                            const std::string& new_title);
   virtual ~CopyHostedDocumentRequest();
 
  protected:
@@ -238,7 +238,7 @@
  private:
   const GDataWapiUrlGenerator url_generator_;
   const std::string resource_id_;
-  const std::string new_name_;
+  const std::string new_title_;
 
   DISALLOW_COPY_AND_ASSIGN(CopyHostedDocumentRequest);
 };
@@ -253,7 +253,7 @@
                         const GDataWapiUrlGenerator& url_generator,
                         const EntryActionCallback& callback,
                         const std::string& resource_id,
-                        const std::string& new_name);
+                        const std::string& new_title);
   virtual ~RenameResourceRequest();
 
  protected:
@@ -267,7 +267,7 @@
  private:
   const GDataWapiUrlGenerator url_generator_;
   const std::string resource_id_;
-  const std::string new_name_;
+  const std::string new_title_;
 
   DISALLOW_COPY_AND_ASSIGN(RenameResourceRequest);
 };
diff --git a/chrome/browser/google_apis/gdata_wapi_requests_unittest.cc b/chrome/browser/google_apis/gdata_wapi_requests_unittest.cc
index 39302ac..6373d24 100644
--- a/chrome/browser/google_apis/gdata_wapi_requests_unittest.cc
+++ b/chrome/browser/google_apis/gdata_wapi_requests_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
+#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
@@ -22,8 +23,6 @@
 #include "chrome/browser/google_apis/request_sender.h"
 #include "chrome/browser/google_apis/test_util.h"
 #include "chrome/test/base/testing_profile.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/test/test_browser_thread_bundle.h"
 #include "net/base/escape.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/embedded_test_server/http_request.h"
@@ -43,20 +42,18 @@
 class GDataWapiRequestsTest : public testing::Test {
  public:
   GDataWapiRequestsTest()
-      : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
-        test_server_(content::BrowserThread::GetMessageLoopProxyForThread(
-            content::BrowserThread::IO)) {
+      : test_server_(message_loop_.message_loop_proxy()) {
   }
 
   virtual void SetUp() OVERRIDE {
     profile_.reset(new TestingProfile);
 
     request_context_getter_ = new net::TestURLRequestContextGetter(
-        content::BrowserThread::GetMessageLoopProxyForThread(
-            content::BrowserThread::IO));
+        message_loop_.message_loop_proxy());
 
     request_sender_.reset(new RequestSender(profile_.get(),
                                             request_context_getter_.get(),
+                                            message_loop_.message_loop_proxy(),
                                             std::vector<std::string>(),
                                             kTestUserAgent));
     request_sender_->auth_service()->set_access_token_for_testing(
@@ -334,7 +331,7 @@
     return response.PassAs<net::test_server::HttpResponse>();
   }
 
-  content::TestBrowserThreadBundle thread_bundle_;
+  base::MessageLoopForIO message_loop_;  // Test server needs IO thread.
   net::test_server::EmbeddedTestServer test_server_;
   scoped_ptr<TestingProfile> profile_;
   scoped_ptr<RequestSender> request_sender_;
@@ -1590,7 +1587,7 @@
 
   std::string contents;
   file_util::ReadFileToString(temp_file, &contents);
-  base::Delete(temp_file, false);
+  base::DeleteFile(temp_file, false);
 
   EXPECT_EQ(HTTP_SUCCESS, result_code);
   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
diff --git a/chrome/browser/google_apis/request_sender.cc b/chrome/browser/google_apis/request_sender.cc
index b2709dc..7df6354 100644
--- a/chrome/browser/google_apis/request_sender.cc
+++ b/chrome/browser/google_apis/request_sender.cc
@@ -14,10 +14,12 @@
 RequestSender::RequestSender(
     Profile* profile,
     net::URLRequestContextGetter* url_request_context_getter,
+    base::TaskRunner* blocking_task_runner,
     const std::vector<std::string>& scopes,
     const std::string& custom_user_agent)
     : profile_(profile),
       url_request_context_getter_(url_request_context_getter),
+      blocking_task_runner_(blocking_task_runner),
       auth_service_(new AuthService(url_request_context_getter, scopes)),
       custom_user_agent_(custom_user_agent),
       weak_ptr_factory_(this) {
diff --git a/chrome/browser/google_apis/request_sender.h b/chrome/browser/google_apis/request_sender.h
index f20c394..96b3fd1 100644
--- a/chrome/browser/google_apis/request_sender.h
+++ b/chrome/browser/google_apis/request_sender.h
@@ -11,6 +11,7 @@
 
 #include "base/basictypes.h"
 #include "base/callback_forward.h"
+#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
@@ -18,6 +19,10 @@
 
 class Profile;
 
+namespace base {
+class TaskRunner;
+}
+
 namespace net {
 class URLRequestContextGetter;
 }
@@ -31,8 +36,11 @@
 // AuthenticatedRequestInterface and handles retries and authentication.
 class RequestSender {
  public:
-  // |url_request_context_getter| is used to perform authentication with
-  // AuthService.
+  // |url_request_context_getter| is the context used to perform network
+  // requests from this RequestSender.
+  //
+  // |blocking_task_runner| is used for running blocking operation, e.g.,
+  // parsing JSON response from the server.
   //
   // |scopes| specifies OAuth2 scopes.
   //
@@ -40,6 +48,7 @@
   // requests issued through the request sender if the value is not empty.
   RequestSender(Profile* profile,
                 net::URLRequestContextGetter* url_request_context_getter,
+                base::TaskRunner* blocking_task_runner,
                 const std::vector<std::string>& scopes,
                 const std::string& custom_user_agent);
   virtual ~RequestSender();
@@ -50,6 +59,10 @@
     return url_request_context_getter_;
   }
 
+  base::TaskRunner* blocking_task_runner() const {
+    return blocking_task_runner_.get();
+  }
+
   // Prepares the object for use.
   virtual void Initialize();
 
@@ -85,6 +98,7 @@
 
   Profile* profile_;  // Not owned.
   net::URLRequestContextGetter* url_request_context_getter_;  // Not owned.
+  scoped_refptr<base::TaskRunner> blocking_task_runner_;
 
   scoped_ptr<AuthService> auth_service_;
   std::set<AuthenticatedRequestInterface*> in_flight_requests_;
diff --git a/chrome/browser/google_apis/task_util.h b/chrome/browser/google_apis/task_util.h
index f6e874b..3c72beb 100644
--- a/chrome/browser/google_apis/task_util.h
+++ b/chrome/browser/google_apis/task_util.h
@@ -96,6 +96,33 @@
   }
 };
 
+// GetDefaultValue returns a value constructed by the default constructor.
+template<typename T> struct DefaultValueCreator {
+  static T GetDefaultValue() { return T(); }
+};
+template<typename T> struct DefaultValueCreator<const T&> {
+  static T GetDefaultValue() { return T(); }
+};
+
+// Helper of CreateErrorRunCallback implementation.
+// Provides:
+// - ResultType; the type of the Callback which should be returned by
+//     CreateErrorRunCallback.
+// - Run(): a static function which takes the original |callback| and |error|,
+//     and runs the |callback|.Run() with the error code and default values
+//     for remaining arguments.
+template<typename CallbackType> struct CreateErrorRunCallbackHelper;
+
+// CreateErrorRunCallback with two arguments.
+template<typename ErrorType, typename P1>
+struct CreateErrorRunCallbackHelper<void(ErrorType, P1)> {
+  typedef base::Callback<void(ErrorType)> ResultType;
+  static void Run(
+      const base::Callback<void(ErrorType, P1)>& callback, ErrorType error) {
+    callback.Run(error, DefaultValueCreator<P1>::GetDefaultValue());
+  }
+};
+
 }  // namespace internal
 
 // Returns callback that takes arguments (arg1, arg2, ...), create a closure
@@ -121,6 +148,15 @@
       callback);
 }
 
+// Returns a callback with the tail parameter bound to its default value.
+// In other words, returned_callback.Run(error) runs callback.Run(error, T()).
+template<typename CallbackType>
+typename internal::CreateErrorRunCallbackHelper<CallbackType>::ResultType
+CreateErrorRunCallback(const base::Callback<CallbackType>& callback) {
+  return base::Bind(
+      &internal::CreateErrorRunCallbackHelper<CallbackType>::Run, callback);
+}
+
 }  // namespace google_apis
 
 #endif  // CHROME_BROWSER_GOOGLE_APIS_TASK_UTIL_H_
diff --git a/chrome/browser/google_apis/test_util.cc b/chrome/browser/google_apis/test_util.cc
index 30c2d35..acb6756 100644
--- a/chrome/browser/google_apis/test_util.cc
+++ b/chrome/browser/google_apis/test_util.cc
@@ -9,18 +9,15 @@
 #include "base/json/json_reader.h"
 #include "base/message_loop.h"
 #include "base/path_service.h"
-#include "base/pending_task.h"
 #include "base/rand_util.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
-#include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/google_apis/drive_api_parser.h"
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
 #include "chrome/browser/google_apis/gdata_wapi_requests.h"
-#include "content/public/browser/browser_thread.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
 #include "url/gurl.h"
@@ -28,27 +25,6 @@
 namespace google_apis {
 namespace test_util {
 
-// This class is used to monitor if any task is posted to a message loop.
-class TaskObserver : public base::MessageLoop::TaskObserver {
- public:
-  TaskObserver() : posted_(false) {}
-  virtual ~TaskObserver() {}
-
-  // MessageLoop::TaskObserver overrides.
-  virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE {
-  }
-  virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {
-    posted_ = true;
-  }
-
-  // Returns true if any task was posted.
-  bool posted() const { return posted_; }
-
- private:
-  bool posted_;
-  DISALLOW_COPY_AND_ASSIGN(TaskObserver);
-};
-
 bool RemovePrefix(const std::string& input,
                   const std::string& prefix,
                   std::string* output) {
@@ -74,19 +50,6 @@
   return GURL(base::StringPrintf("http://127.0.0.1:%d/", port));
 }
 
-void RunBlockingPoolTask() {
-  while (true) {
-    content::BrowserThread::GetBlockingPool()->FlushForTesting();
-
-    TaskObserver task_observer;
-    base::MessageLoop::current()->AddTaskObserver(&task_observer);
-    base::RunLoop().RunUntilIdle();
-    base::MessageLoop::current()->RemoveTaskObserver(&task_observer);
-    if (!task_observer.posted())
-      break;
-  }
-}
-
 void RunAndQuit(base::RunLoop* run_loop, const base::Closure& closure) {
   closure.Run();
   run_loop->Quit();
diff --git a/chrome/browser/google_apis/test_util.h b/chrome/browser/google_apis/test_util.h
index 173674d..42facc4 100644
--- a/chrome/browser/google_apis/test_util.h
+++ b/chrome/browser/google_apis/test_util.h
@@ -37,15 +37,6 @@
 namespace google_apis {
 namespace test_util {
 
-// Runs a task posted to the blocking pool, including subsequent tasks posted
-// to the UI message loop and the blocking pool.
-//
-// A task is often posted to the blocking pool with PostTaskAndReply(). In
-// that case, a task is posted back to the UI message loop, which can again
-// post a task to the blocking pool. This function processes these tasks
-// repeatedly.
-void RunBlockingPoolTask();
-
 // Runs the closure, and then quits the |run_loop|.
 void RunAndQuit(base::RunLoop* run_loop, const base::Closure& closure);
 
@@ -129,7 +120,8 @@
 //   PerformAsynchronousTask(
 //       param1, param2, ...,
 //       CreateCopyResultCallback(&result1, &result2, ...));
-//   RunBlockingPoolTask();  // Run message loop to complete the async task.
+//   base::RunLoop().RunUntilIdle();  // Run message loop to complete
+//                                    // the async task.
 //
 //   // Hereafter, we can write expectation with results.
 //   EXPECT_EQ(expected_result1, result1);
diff --git a/chrome/browser/guestview/adview/adview_constants.cc b/chrome/browser/guestview/adview/adview_constants.cc
index 98790ea..8ba709c 100644
--- a/chrome/browser/guestview/adview/adview_constants.cc
+++ b/chrome/browser/guestview/adview/adview_constants.cc
@@ -7,6 +7,7 @@
 namespace adview {
 
 // Events.
+const char kEventLoadAbort[] = "adview.onLoadAbort";
 const char kEventLoadCommit[] = "adview.onLoadCommit";
 
 }  // namespace adview
diff --git a/chrome/browser/guestview/adview/adview_constants.h b/chrome/browser/guestview/adview/adview_constants.h
index 480bc5c..5bb5490 100644
--- a/chrome/browser/guestview/adview/adview_constants.h
+++ b/chrome/browser/guestview/adview/adview_constants.h
@@ -10,6 +10,7 @@
 namespace adview {
 
 // Events.
+extern const char kEventLoadAbort[];
 extern const char kEventLoadCommit[];
 
 }  // namespace adview
diff --git a/chrome/browser/guestview/adview/adview_guest.cc b/chrome/browser/guestview/adview/adview_guest.cc
index 1f20a21..e62bb4e 100644
--- a/chrome/browser/guestview/adview/adview_guest.cc
+++ b/chrome/browser/guestview/adview/adview_guest.cc
@@ -4,9 +4,11 @@
 
 #include "chrome/browser/guestview/adview/adview_guest.h"
 
+#include "base/strings/string_util.h"
 #include "chrome/browser/guestview/adview/adview_constants.h"
 #include "chrome/browser/guestview/guestview_constants.h"
 #include "content/public/browser/web_contents.h"
+#include "net/base/net_errors.h"
 
 using content::WebContents;
 
@@ -51,6 +53,20 @@
   DispatchEvent(new GuestView::Event(adview::kEventLoadCommit, args.Pass()));
 }
 
-void AdViewGuest::WebContentsDestroyed(WebContents* web_contents) {
-  delete this;
+void AdViewGuest::DidFailProvisionalLoad(
+    int64 frame_id,
+    bool is_main_frame,
+    const GURL& validated_url,
+    int error_code,
+    const string16& error_description,
+    content::RenderViewHost* render_view_host) {
+  // Translate the |error_code| into an error string.
+  std::string error_type;
+  RemoveChars(net::ErrorToString(error_code), "net::", &error_type);
+
+  scoped_ptr<DictionaryValue> args(new DictionaryValue());
+  args->SetBoolean(guestview::kIsTopLevel, is_main_frame);
+  args->SetString(guestview::kUrl, validated_url.spec());
+  args->SetString(guestview::kReason, error_type);
+  DispatchEvent(new GuestView::Event(adview::kEventLoadAbort, args.Pass()));
 }
diff --git a/chrome/browser/guestview/adview/adview_guest.h b/chrome/browser/guestview/adview/adview_guest.h
index 35db3c3..9d4385c 100644
--- a/chrome/browser/guestview/adview/adview_guest.h
+++ b/chrome/browser/guestview/adview/adview_guest.h
@@ -37,8 +37,13 @@
       const GURL& url,
       content::PageTransition transition_type,
       content::RenderViewHost* render_view_host) OVERRIDE;
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void DidFailProvisionalLoad(
+      int64 frame_id,
+      bool is_main_frame,
+      const GURL& validated_url,
+      int error_code,
+      const string16& error_description,
+      content::RenderViewHost* render_view_host) OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(AdViewGuest);
 };
diff --git a/chrome/browser/guestview/guestview.h b/chrome/browser/guestview/guestview.h
index 4a0570b..09b01b5 100644
--- a/chrome/browser/guestview/guestview.h
+++ b/chrome/browser/guestview/guestview.h
@@ -8,6 +8,7 @@
 #include <queue>
 
 #include "base/values.h"
+#include "content/public/browser/browser_plugin_guest_delegate.h"
 #include "content/public/browser/web_contents.h"
 
 class AdViewGuest;
@@ -17,7 +18,7 @@
 // tag. GuestView maintains an association between a guest WebContents and an
 // embedder WebContents. It receives events issued from the guest and relays
 // them to the embedder.
-class GuestView {
+class GuestView : public content::BrowserPluginGuestDelegate {
  public:
   enum Type {
     WEBVIEW,
diff --git a/chrome/browser/guestview/guestview_constants.cc b/chrome/browser/guestview/guestview_constants.cc
index 3659bec..870de3c 100644
--- a/chrome/browser/guestview/guestview_constants.cc
+++ b/chrome/browser/guestview/guestview_constants.cc
@@ -8,6 +8,7 @@
 
 // Parameters/properties on events.
 const char kIsTopLevel[] = "isTopLevel";
+const char kReason[] = "reason";
 const char kUrl[] = "url";
 
 // Attributes.
diff --git a/chrome/browser/guestview/guestview_constants.h b/chrome/browser/guestview/guestview_constants.h
index 70a09a5..aaf0002 100644
--- a/chrome/browser/guestview/guestview_constants.h
+++ b/chrome/browser/guestview/guestview_constants.h
@@ -11,6 +11,7 @@
 
 // Parameters/properties on events.
 extern const char kIsTopLevel[];
+extern const char kReason[];
 extern const char kUrl[];
 
 // Attributes.
diff --git a/chrome/browser/guestview/webview/webview_constants.cc b/chrome/browser/guestview/webview/webview_constants.cc
index dd4c8f4..b80b635 100644
--- a/chrome/browser/guestview/webview/webview_constants.cc
+++ b/chrome/browser/guestview/webview/webview_constants.cc
@@ -7,19 +7,29 @@
 namespace webview {
 
 // Events.
+const char kEventClose[] = "webview.onClose";
+const char kEventConsoleMessage[] = "webview.onConsoleMessage";
 const char kEventContentLoad[] = "webview.onContentLoad";
+const char kEventExit[] = "webview.onExit";
+const char kEventLoadAbort[] = "webview.onLoadAbort";
 const char kEventLoadCommit[] = "webview.onLoadCommit";
 const char kEventLoadRedirect[] = "webview.onLoadRedirect";
 const char kEventLoadStart[] = "webview.onLoadStart";
 const char kEventLoadStop[] = "webview.onLoadStop";
 
+// Parameters/properties on events.
+const char kLevel[] = "level";
+const char kLine[] = "line";
+const char kMessage[] = "message";
+const char kNewURL[] = "newUrl";
+const char kOldURL[] = "oldUrl";
+const char kProcessId[] = "processId";
+const char kReason[] = "reason";
+const char kSourceId[] = "sourceId";
+
 // Internal parameters/properties on events.
 const char kInternalCurrentEntryIndex[] = "currentEntryIndex";
 const char kInternalEntryCount[] = "entryCount";
 const char kInternalProcessId[] = "processId";
 
-// Parameters/properties on events.
-extern const char kNewURL[];
-extern const char kOldURL[];
-
 }  // namespace webview
diff --git a/chrome/browser/guestview/webview/webview_constants.h b/chrome/browser/guestview/webview/webview_constants.h
index 01cec96..e8ce5a4 100644
--- a/chrome/browser/guestview/webview/webview_constants.h
+++ b/chrome/browser/guestview/webview/webview_constants.h
@@ -10,20 +10,32 @@
 namespace webview {
 
 // Events.
+extern const char kEventClose[];
+extern const char kEventConsoleMessage[];
 extern const char kEventContentLoad[];
+extern const char kEventExit[];
+extern const char kEventLoadAbort[];
 extern const char kEventLoadCommit[];
 extern const char kEventLoadRedirect[];
 extern const char kEventLoadStart[];
 extern const char kEventLoadStop[];
 
+// Parameters/properties on events.
+extern const char kMessage[];
+extern const char kLevel[];
+extern const char kLine[];
+extern const char kNewURL[];
+extern const char kOldURL[];
+extern const char kProcessId[];
+extern const char kReason[];
+extern const char kSourceId[];
+
 // Internal parameters/properties on events.
 extern const char kInternalCurrentEntryIndex[];
 extern const char kInternalEntryCount[];
 extern const char kInternalProcessId[];
 
 // Parameters/properties on events.
-const char kNewURL[] = "newUrl";
-const char kOldURL[] = "oldUrl";
 
 }  // namespace webview
 
diff --git a/chrome/browser/guestview/webview/webview_guest.cc b/chrome/browser/guestview/webview/webview_guest.cc
index 5c15a6f..71a4e6c 100644
--- a/chrome/browser/guestview/webview/webview_guest.cc
+++ b/chrome/browser/guestview/webview/webview_guest.cc
@@ -10,17 +10,39 @@
 #include "chrome/browser/guestview/guestview_constants.h"
 #include "chrome/browser/guestview/webview/webview_constants.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/resource_request_details.h"
+#include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/result_codes.h"
+#include "net/base/net_errors.h"
 
 using content::WebContents;
 
 namespace {
 
+static std::string TerminationStatusToString(base::TerminationStatus status) {
+  switch (status) {
+    case base::TERMINATION_STATUS_NORMAL_TERMINATION:
+      return "normal";
+    case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
+    case base::TERMINATION_STATUS_STILL_RUNNING:
+      return "abnormal";
+    case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
+      return "killed";
+    case base::TERMINATION_STATUS_PROCESS_CRASHED:
+      return "crashed";
+    case base::TERMINATION_STATUS_MAX_ENUM:
+      break;
+  }
+  NOTREACHED() << "Unknown Termination Status.";
+  return "unknown";
+}
+
 void RemoveWebViewEventListenersOnIOThread(
     void* profile,
     const std::string& extension_id,
@@ -78,6 +100,66 @@
   return NULL;
 }
 
+void WebViewGuest::AddMessageToConsole(int32 level,
+                                       const string16& message,
+                                       int32 line_no,
+                                       const string16& source_id) {
+  scoped_ptr<DictionaryValue> args(new DictionaryValue());
+  // Log levels are from base/logging.h: LogSeverity.
+  args->SetInteger(webview::kLevel, level);
+  args->SetString(webview::kMessage, message);
+  args->SetInteger(webview::kLine, line_no);
+  args->SetString(webview::kSourceId, source_id);
+  DispatchEvent(
+      new GuestView::Event(webview::kEventConsoleMessage, args.Pass()));
+}
+
+void WebViewGuest::Close() {
+  scoped_ptr<DictionaryValue> args(new DictionaryValue());
+  DispatchEvent(new GuestView::Event(webview::kEventClose, args.Pass()));
+}
+
+void WebViewGuest::GuestProcessGone(base::TerminationStatus status) {
+  scoped_ptr<DictionaryValue> args(new DictionaryValue());
+  args->SetInteger(webview::kProcessId,
+                   web_contents()->GetRenderProcessHost()->GetID());
+  args->SetString(webview::kReason, TerminationStatusToString(status));
+  DispatchEvent(
+      new GuestView::Event(webview::kEventExit, args.Pass()));
+}
+
+bool WebViewGuest::HandleKeyboardEvent(
+    const content::NativeWebKeyboardEvent& event) {
+  if (event.type != WebKit::WebInputEvent::RawKeyDown)
+    return false;
+
+#if defined(OS_MACOSX)
+  if (event.modifiers != WebKit::WebInputEvent::MetaKey)
+    return false;
+
+  if (event.windowsKeyCode == ui::VKEY_OEM_4) {
+    Go(-1);
+    return true;
+  }
+
+  if (event.windowsKeyCode == ui::VKEY_OEM_6) {
+    Go(1);
+    return true;
+  }
+#else
+  if (event.windowsKeyCode == ui::VKEY_BROWSER_BACK) {
+    Go(-1);
+    return true;
+  }
+
+  if (event.windowsKeyCode == ui::VKEY_BROWSER_FORWARD) {
+    Go(1);
+    return true;
+  }
+#endif
+  return false;
+}
+
 void WebViewGuest::Observe(int type,
                            const content::NotificationSource& source,
                            const content::NotificationDetails& details) {
@@ -111,6 +193,25 @@
   guest_web_contents()->GetController().GoToOffset(relative_index);
 }
 
+void WebViewGuest::Reload() {
+  // TODO(fsamuel): Don't check for repost because we don't want to show
+  // Chromium's repost warning. We might want to implement a separate API
+  // for registering a callback if a repost is about to happen.
+  guest_web_contents()->GetController().Reload(false);
+}
+
+void WebViewGuest::Stop() {
+  guest_web_contents()->Stop();
+}
+
+void WebViewGuest::Terminate() {
+  content::RecordAction(content::UserMetricsAction("WebView.Guest.Terminate"));
+  base::ProcessHandle process_handle =
+      guest_web_contents()->GetRenderProcessHost()->GetHandle();
+  if (process_handle)
+    base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false);
+}
+
 WebViewGuest::~WebViewGuest() {
 }
 
@@ -132,6 +233,24 @@
   DispatchEvent(new GuestView::Event(webview::kEventLoadCommit, args.Pass()));
 }
 
+void WebViewGuest::DidFailProvisionalLoad(
+    int64 frame_id,
+    bool is_main_frame,
+    const GURL& validated_url,
+    int error_code,
+    const string16& error_description,
+    content::RenderViewHost* render_view_host) {
+  // Translate the |error_code| into an error string.
+  std::string error_type;
+  RemoveChars(net::ErrorToString(error_code), "net::", &error_type);
+
+  scoped_ptr<DictionaryValue> args(new DictionaryValue());
+  args->SetBoolean(guestview::kIsTopLevel, is_main_frame);
+  args->SetString(guestview::kUrl, validated_url.spec());
+  args->SetString(guestview::kReason, error_type);
+  DispatchEvent(new GuestView::Event(webview::kEventLoadAbort, args.Pass()));
+}
+
 void WebViewGuest::DidStartProvisionalLoadForFrame(
     int64 frame_id,
     int64 parent_frame_id,
@@ -161,7 +280,6 @@
           browser_context(), extension_id(),
           embedder_render_process_id(),
           view_instance_id()));
-  delete this;
 }
 
 void WebViewGuest::LoadHandlerCalled() {
diff --git a/chrome/browser/guestview/webview/webview_guest.h b/chrome/browser/guestview/webview/webview_guest.h
index 905d346..5f63ecd 100644
--- a/chrome/browser/guestview/webview/webview_guest.h
+++ b/chrome/browser/guestview/webview/webview_guest.h
@@ -39,6 +39,16 @@
   virtual WebViewGuest* AsWebView() OVERRIDE;
   virtual AdViewGuest* AsAdView() OVERRIDE;
 
+  // GuestDelegate implementation.
+  virtual void AddMessageToConsole(int32 level,
+                                   const string16& message,
+                                   int32 line_no,
+                                   const string16& source_id) OVERRIDE;
+  virtual void Close() OVERRIDE;
+  virtual void GuestProcessGone(base::TerminationStatus status) OVERRIDE;
+  virtual bool HandleKeyboardEvent(
+      const content::NativeWebKeyboardEvent& event) OVERRIDE;
+
   // NotificationObserver implementation.
   virtual void Observe(int type,
                        const content::NotificationSource& source,
@@ -48,6 +58,15 @@
   // current navigation entry.
   void Go(int relative_index);
 
+  // Reload the guest.
+  void Reload();
+
+  // Stop loading the guest.
+  void Stop();
+
+  // Kill the guest process.
+  void Terminate();
+
   extensions::ScriptExecutor* script_executor() {
     return script_executor_.get();
   }
@@ -62,6 +81,13 @@
       const GURL& url,
       content::PageTransition transition_type,
       content::RenderViewHost* render_view_host) OVERRIDE;
+  virtual void DidFailProvisionalLoad(
+      int64 frame_id,
+      bool is_main_frame,
+      const GURL& validated_url,
+      int error_code,
+      const string16& error_description,
+      content::RenderViewHost* render_view_host) OVERRIDE;
   virtual void DidStartProvisionalLoadForFrame(
       int64 frame_id,
       int64 parent_frame_id,
diff --git a/chrome/browser/history/DEPS b/chrome/browser/history/DEPS
index 0c2e7a8..8898d52 100644
--- a/chrome/browser/history/DEPS
+++ b/chrome/browser/history/DEPS
@@ -3,6 +3,7 @@
   # basic rules followed by temporary exceptions.  Please don't
   # add to the list of exceptions!
   "-chrome/browser",
+  "+chrome/browser/chrome_notification_types.h",
   "+chrome/browser/common",
   "+chrome/browser/favicon",
   "+chrome/browser/history",
diff --git a/chrome/browser/history/android/android_provider_backend.cc b/chrome/browser/history/android/android_provider_backend.cc
index 6205c31..ff69a0e 100644
--- a/chrome/browser/history/android/android_provider_backend.cc
+++ b/chrome/browser/history/android/android_provider_backend.cc
@@ -6,6 +6,7 @@
 
 #include "base/i18n/case_conversion.h"
 #include "chrome/browser/bookmarks/bookmark_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_changed_details.h"
 #include "chrome/browser/history/android/android_time.h"
 #include "chrome/browser/history/android/android_urls_sql_handler.h"
@@ -16,7 +17,6 @@
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_database.h"
 #include "chrome/browser/history/thumbnail_database.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/common/page_transition_types.h"
 #include "sql/connection.h"
 
diff --git a/chrome/browser/history/android/android_provider_backend_unittest.cc b/chrome/browser/history/android/android_provider_backend_unittest.cc
index 74f2200..830f74c 100644
--- a/chrome/browser/history/android/android_provider_backend_unittest.cc
+++ b/chrome/browser/history/android/android_provider_backend_unittest.cc
@@ -15,12 +15,12 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/bookmark_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_changed_details.h"
 #include "chrome/browser/history/android/android_time.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -262,8 +262,8 @@
 
   // The history_db_name and thumbnail_db_name files should be created by
   // HistoryBackend. We need to open the same database files.
-  ASSERT_TRUE(file_util::PathExists(history_db_name_));
-  ASSERT_TRUE(file_util::PathExists(thumbnail_db_name_));
+  ASSERT_TRUE(base::PathExists(history_db_name_));
+  ASSERT_TRUE(base::PathExists(thumbnail_db_name_));
 
   ASSERT_EQ(sql::INIT_OK, history_db_.Init(history_db_name_));
   ASSERT_EQ(sql::INIT_OK, thumbnail_db_.Init(thumbnail_db_name_, NULL,
@@ -412,8 +412,8 @@
 
   // The history_db_name and thumbnail_db_name files should be created by
   // HistoryBackend. We need to open the same database files.
-  ASSERT_TRUE(file_util::PathExists(history_db_name_));
-  ASSERT_TRUE(file_util::PathExists(thumbnail_db_name_));
+  ASSERT_TRUE(base::PathExists(history_db_name_));
+  ASSERT_TRUE(base::PathExists(thumbnail_db_name_));
 
   ASSERT_EQ(sql::INIT_OK, history_db_.Init(history_db_name_));
   ASSERT_EQ(sql::INIT_OK, thumbnail_db_.Init(thumbnail_db_name_, NULL,
@@ -1826,8 +1826,8 @@
 
   // The history_db_name and thumbnail_db_name files should be created by
   // HistoryBackend. We need to open the same database files.
-  ASSERT_TRUE(file_util::PathExists(history_db_name_));
-  ASSERT_TRUE(file_util::PathExists(thumbnail_db_name_));
+  ASSERT_TRUE(base::PathExists(history_db_name_));
+  ASSERT_TRUE(base::PathExists(thumbnail_db_name_));
 
   // Only creates the history database
   ASSERT_EQ(sql::INIT_OK, history_db_.Init(history_db_name_));
diff --git a/chrome/browser/history/download_database.cc b/chrome/browser/history/download_database.cc
index 4d1d70e..5a0dc26 100644
--- a/chrome/browser/history/download_database.cc
+++ b/chrome/browser/history/download_database.cc
@@ -33,6 +33,8 @@
 enum DroppedReason {
   DROPPED_REASON_BAD_STATE = 0,
   DROPPED_REASON_BAD_DANGER_TYPE = 1,
+  DROPPED_REASON_BAD_ID = 2,
+  DROPPED_REASON_DUPLICATE_ID = 3,
   DROPPED_REASON_MAX
 };
 
@@ -84,15 +86,8 @@
 
 #endif
 
-// Key in the meta_table containing the next id to use for a new download in
-// this profile.
-static const char kNextDownloadId[] = "next_download_id";
-
 }  // namespace
 
-// static
-const int64 DownloadDatabase::kUninitializedHandle = -1;
-
 // These constants and the transformation functions below are used to allow
 // DownloadItem::DownloadState and DownloadDangerType to change without
 // breaking the database schema.
@@ -195,8 +190,6 @@
 DownloadDatabase::DownloadDatabase()
     : owning_thread_set_(false),
       owning_thread_(0),
-      next_id_(0),
-      next_db_handle_(0),
       in_progress_entry_cleanup_completed_(false) {
 }
 
@@ -212,7 +205,7 @@
 
 bool DownloadDatabase::MigrateDownloadsState() {
   sql::Statement statement(GetDB().GetUniqueStatement(
-        "UPDATE downloads SET state=? WHERE state=?"));
+      "UPDATE downloads SET state=? WHERE state=?"));
   statement.BindInt(0, kStateInterrupted);
   statement.BindInt(1, kStateBug140687);
   return statement.Run();
@@ -271,7 +264,6 @@
 }
 
 bool DownloadDatabase::InitDownloadTable() {
-  GetMetaTable().GetValue(kNextDownloadId, &next_id_);
   if (GetDB().DoesTableExist("downloads")) {
     return EnsureColumnExists("end_time", "INTEGER NOT NULL DEFAULT 0") &&
            EnsureColumnExists("opened", "INTEGER NOT NULL DEFAULT 0");
@@ -283,6 +275,26 @@
   }
 }
 
+void DownloadDatabase::GetNextDownloadId(uint32* id) {
+  sql::Statement select_max_id(GetDB().GetUniqueStatement(
+      "SELECT max(id) FROM downloads"));
+  if (!select_max_id.Step()) {
+    DCHECK(false);
+    *id = content::DownloadItem::kInvalidId + 1;
+    return;
+  }
+  // If there are zero records in the downloads table, then max(id) will return
+  // 0 = kInvalidId, so GetNextDownloadId() will set *id = kInvalidId + 1.
+  // If there is at least one record but all of the |id|s are <= kInvalidId,
+  // then max(id) will return <= kInvalidId, so GetNextDownloadId should return
+  // kInvalidId + 1. Note that any records with |id <= kInvalidId| will be
+  // dropped in QueryDownloads()
+  // SQLITE doesn't have unsigned integers.
+  *id = 1 + static_cast<uint32>(std::max(
+      static_cast<int64>(content::DownloadItem::kInvalidId),
+      select_max_id.ColumnInt64(0)));
+}
+
 bool DownloadDatabase::DropDownloadTable() {
   return GetDB().Execute("DROP TABLE downloads");
 }
@@ -292,11 +304,9 @@
   EnsureInProgressEntriesCleanedUp();
 
   results->clear();
-  if (next_db_handle_ < 1)
-    next_db_handle_ = 1;
-  std::set<int64> db_handles;
+  std::set<uint32> ids;
 
-  std::map<DownloadID, DownloadRow*> info_map;
+  std::map<uint32, DownloadRow*> info_map;
 
   sql::Statement statement_main(GetDB().GetCachedStatement(SQL_FROM_HERE,
       "SELECT id, current_path, target_path, start_time, received_bytes, "
@@ -308,8 +318,11 @@
     scoped_ptr<DownloadRow> info(new DownloadRow());
     int column = 0;
 
-    int db_handle = statement_main.ColumnInt64(column++);
-    info->db_handle = db_handle;
+    // SQLITE does not have unsigned integers, so explicitly handle negative
+    // |id|s instead of casting them to very large uint32s, which would break
+    // the max(id) logic in GetNextDownloadId().
+    int64 signed_id = statement_main.ColumnInt64(column++);
+    info->id = static_cast<uint32>(signed_id);
     info->current_path = ColumnFilePath(statement_main, column++);
     info->target_path = ColumnFilePath(statement_main, column++);
     info->start_time = base::Time::FromInternalValue(
@@ -327,33 +340,30 @@
         statement_main.ColumnInt64(column++));
     info->opened = statement_main.ColumnInt(column++) != 0;
     info->referrer_url = GURL(statement_main.ColumnString(column++));
-    if (info->db_handle >= next_db_handle_)
-      next_db_handle_ = info->db_handle + 1;
-    if (!db_handles.insert(info->db_handle).second) {
-      // info->db_handle was already in db_handles. The database is corrupt.
-      base::debug::Alias(&info->db_handle);
-      DCHECK(false);
-    }
 
     // If the record is corrupted, note that and drop it.
-    if (info->state == DownloadItem::MAX_DOWNLOAD_STATE ||
-        info->danger_type == content::DOWNLOAD_DANGER_TYPE_MAX) {
-      DroppedReason reason = DROPPED_REASON_MAX;
-      if (info->state == DownloadItem::MAX_DOWNLOAD_STATE)
-        reason = DROPPED_REASON_BAD_STATE;
-      else if (info->danger_type == content::DOWNLOAD_DANGER_TYPE_MAX)
-        reason = DROPPED_REASON_BAD_DANGER_TYPE;
-      else
-        NOTREACHED();
-
-      UMA_HISTOGRAM_ENUMERATION(
-          "Download.DatabaseRecordDropped", reason, DROPPED_REASON_MAX + 1);
-
-      continue;
+    // http://crbug.com/251269
+    DroppedReason dropped_reason = DROPPED_REASON_MAX;
+    if (signed_id <= static_cast<int64>(content::DownloadItem::kInvalidId)) {
+      // SQLITE doesn't have unsigned integers.
+      dropped_reason = DROPPED_REASON_BAD_ID;
+    } else if (!ids.insert(info->id).second) {
+      dropped_reason = DROPPED_REASON_DUPLICATE_ID;
+      NOTREACHED() << info->id;
+    } else if (info->state == DownloadItem::MAX_DOWNLOAD_STATE) {
+      dropped_reason = DROPPED_REASON_BAD_STATE;
+    } else if (info->danger_type == content::DOWNLOAD_DANGER_TYPE_MAX) {
+      dropped_reason = DROPPED_REASON_BAD_DANGER_TYPE;
     }
-
-    DCHECK(!ContainsKey(info_map, info->db_handle));
-    info_map[db_handle] = info.release();
+    if (dropped_reason != DROPPED_REASON_MAX) {
+      UMA_HISTOGRAM_ENUMERATION("Download.DatabaseRecordDropped",
+                                dropped_reason,
+                                DROPPED_REASON_MAX + 1);
+    } else {
+      DCHECK(!ContainsKey(info_map, info->id));
+      uint32 id = info->id;
+      info_map[id] = info.release();
+    }
   }
 
   sql::Statement statement_chain(GetDB().GetCachedStatement(
@@ -363,24 +373,29 @@
 
   while (statement_chain.Step()) {
     int column = 0;
-    int64 db_handle = statement_chain.ColumnInt64(column++);
+    // See the comment above about SQLITE lacking unsigned integers.
+    int64 signed_id = statement_chain.ColumnInt64(column++);
     int chain_index = statement_chain.ColumnInt(column++);
 
+    if (signed_id <= static_cast<int64>(content::DownloadItem::kInvalidId))
+      continue;
+    uint32 id = static_cast<uint32>(signed_id);
+
     // Note that these DCHECKs may trip as a result of corrupted databases.
     // We have them because in debug builds the chances are higher there's
     // an actual bug than that the database is corrupt, but we handle the
     // DB corruption case in production code.
 
-    // Confirm the handle has already been seen--if it hasn't, discard the
+    // Confirm the id has already been seen--if it hasn't, discard the
     // record.
-    DCHECK(ContainsKey(info_map, db_handle));
-    if (!ContainsKey(info_map, db_handle))
+    DCHECK(ContainsKey(info_map, id));
+    if (!ContainsKey(info_map, id))
       continue;
 
     // Confirm all previous URLs in the chain have already been seen;
     // if not, fill in with null or discard record.
-    int current_chain_size = info_map[db_handle]->url_chain.size();
-    std::vector<GURL>* url_chain(&info_map[db_handle]->url_chain);
+    int current_chain_size = info_map[id]->url_chain.size();
+    std::vector<GURL>* url_chain(&info_map[id]->url_chain);
     DCHECK_EQ(chain_index, current_chain_size);
     while (current_chain_size < chain_index) {
       url_chain->push_back(GURL());
@@ -393,13 +408,13 @@
     url_chain->push_back(GURL(statement_chain.ColumnString(2)));
   }
 
-  for (std::map<DownloadID, DownloadRow*>::iterator
+  for (std::map<uint32, DownloadRow*>::iterator
            it = info_map.begin(); it != info_map.end(); ++it) {
     DownloadRow* row = it->second;
     bool empty_url_chain = row->url_chain.empty();
     UMA_HISTOGRAM_BOOLEAN("Download.DatabaseEmptyUrlChain", empty_url_chain);
     if (empty_url_chain) {
-      RemoveDownload(row->db_handle);
+      RemoveDownload(row->id);
     } else {
       // Copy the contents of the stored info.
       results->push_back(*row);
@@ -412,7 +427,7 @@
 bool DownloadDatabase::UpdateDownload(const DownloadRow& data) {
   EnsureInProgressEntriesCleanedUp();
 
-  DCHECK(data.db_handle > 0);
+  DCHECK_NE(content::DownloadItem::kInvalidId, data.id);
   int state = StateToInt(data.state);
   if (state == kStateInvalid) {
     NOTREACHED();
@@ -439,7 +454,7 @@
   statement.BindInt64(column++, data.end_time.ToInternalValue());
   statement.BindInt64(column++, data.total_bytes);
   statement.BindInt(column++, (data.opened ? 1 : 0));
-  statement.BindInt64(column++, data.db_handle);
+  statement.BindInt(column++, data.id);
 
   return statement.Run();
 }
@@ -458,29 +473,20 @@
   in_progress_entry_cleanup_completed_ = true;
 }
 
-int64 DownloadDatabase::CreateDownload(const DownloadRow& info) {
+bool DownloadDatabase::CreateDownload(const DownloadRow& info) {
+  DCHECK_NE(content::DownloadItem::kInvalidId, info.id);
   EnsureInProgressEntriesCleanedUp();
 
-  if (next_db_handle_ == 0) {
-    // This is unlikely. All current known tests and users already call
-    // QueryDownloads() before CreateDownload().
-    std::vector<DownloadRow> results;
-    QueryDownloads(&results);
-    CHECK_NE(0, next_db_handle_);
-  }
-
   if (info.url_chain.empty())
-    return kUninitializedHandle;
+    return false;
 
   int state = StateToInt(info.state);
   if (state == kStateInvalid)
-    return kUninitializedHandle;
+    return false;
 
   int danger_type = DangerTypeToInt(info.danger_type);
   if (danger_type == kDangerTypeInvalid)
-    return kUninitializedHandle;
-
-  int db_handle = next_db_handle_++;
+    return false;
 
   {
     sql::Statement statement_insert(GetDB().GetCachedStatement(
@@ -492,7 +498,7 @@
         "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
 
     int column = 0;
-    statement_insert.BindInt64(column++, db_handle);
+    statement_insert.BindInt(column++, info.id);
     BindFilePath(statement_insert, info.current_path, column++);
     BindFilePath(statement_insert, info.target_path, column++);
     statement_insert.BindInt64(column++, info.start_time.ToInternalValue());
@@ -512,22 +518,22 @@
       // http://www.sqlite.org/c3ref/c_abort_rollback.html
       UMA_HISTOGRAM_ENUMERATION("Download.DatabaseMainInsertError",
                                 GetDB().GetErrorCode() & 0xff, 50);
-      return kUninitializedHandle;
+      return false;
     }
   }
 
   {
     sql::Statement count_urls(GetDB().GetCachedStatement(SQL_FROM_HERE,
         "SELECT count(*) FROM downloads_url_chains WHERE id=?"));
-    count_urls.BindInt64(0, db_handle);
+    count_urls.BindInt(0, info.id);
     if (count_urls.Step()) {
       bool corrupt_urls = count_urls.ColumnInt(0) > 0;
       UMA_HISTOGRAM_BOOLEAN("Download.DatabaseCorruptUrls", corrupt_urls);
       if (corrupt_urls) {
         // There should not be any URLs in downloads_url_chains for this
-        // db_handle.  If there are, we don't want them to interfere with
+        // info.id.  If there are, we don't want them to interfere with
         // inserting the correct URLs, so just remove them.
-        RemoveDownloadURLs(db_handle);
+        RemoveDownloadURLs(info.id);
       }
     }
   }
@@ -538,48 +544,45 @@
                                  "(id, chain_index, url) "
                                  "VALUES (?, ?, ?)"));
   for (size_t i = 0; i < info.url_chain.size(); ++i) {
-    statement_insert_chain.BindInt64(0, db_handle);
+    statement_insert_chain.BindInt(0, info.id);
     statement_insert_chain.BindInt(1, i);
     statement_insert_chain.BindString(2, info.url_chain[i].spec());
     if (!statement_insert_chain.Run()) {
       UMA_HISTOGRAM_ENUMERATION("Download.DatabaseURLChainInsertError",
                                 GetDB().GetErrorCode() & 0xff, 50);
-      RemoveDownload(db_handle);
-      return kUninitializedHandle;
+      RemoveDownload(info.id);
+      return false;
     }
     statement_insert_chain.Reset(true);
   }
-
-  // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;}
-  GetMetaTable().SetValue(kNextDownloadId, ++next_id_);
-  return db_handle;
+  return true;
 }
 
-void DownloadDatabase::RemoveDownload(int64 handle) {
+void DownloadDatabase::RemoveDownload(uint32 id) {
   EnsureInProgressEntriesCleanedUp();
 
   sql::Statement downloads_statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
       "DELETE FROM downloads WHERE id=?"));
-  downloads_statement.BindInt64(0, handle);
+  downloads_statement.BindInt(0, id);
   if (!downloads_statement.Run()) {
     UMA_HISTOGRAM_ENUMERATION("Download.DatabaseMainDeleteError",
                               GetDB().GetErrorCode() & 0xff, 50);
     return;
   }
-  RemoveDownloadURLs(handle);
+  RemoveDownloadURLs(id);
 }
 
-void DownloadDatabase::RemoveDownloadURLs(int64 handle) {
+void DownloadDatabase::RemoveDownloadURLs(uint32 id) {
   sql::Statement urlchain_statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
       "DELETE FROM downloads_url_chains WHERE id=?"));
-  urlchain_statement.BindInt64(0, handle);
+  urlchain_statement.BindInt(0, id);
   if (!urlchain_statement.Run()) {
     UMA_HISTOGRAM_ENUMERATION("Download.DatabaseURLChainDeleteError",
                               GetDB().GetErrorCode() & 0xff, 50);
   }
 }
 
-int DownloadDatabase::CountDownloads() {
+size_t DownloadDatabase::CountDownloads() {
   EnsureInProgressEntriesCleanedUp();
 
   sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
diff --git a/chrome/browser/history/download_database.h b/chrome/browser/history/download_database.h
index ef85279..1550a0a 100644
--- a/chrome/browser/history/download_database.h
+++ b/chrome/browser/history/download_database.h
@@ -24,40 +24,34 @@
 // Maintains a table of downloads.
 class DownloadDatabase {
  public:
-  // The value of |db_handle| indicating that the associated DownloadItem is not
-  // yet persisted.
-  static const int64 kUninitializedHandle;
-
   // Must call InitDownloadTable before using any other functions.
   DownloadDatabase();
   virtual ~DownloadDatabase();
 
-  int next_download_id() const { return next_id_; }
+  void GetNextDownloadId(uint32* id);
 
   // Get all the downloads from the database.
   void QueryDownloads(
       std::vector<DownloadRow>* results);
 
   // Update the state of one download. Returns true if successful.
-  // Does not update |url|, |start_time|; uses |db_handle| only
+  // Does not update |url|, |start_time|; uses |id| only
   // to select the row in the database table to update.
   bool UpdateDownload(const DownloadRow& data);
 
-  // Create a new database entry for one download and return its primary db id.
-  int64 CreateDownload(const DownloadRow& info);
+  // Create a new database entry for one download and return true if the
+  // creation succeeded, false otherwise.
+  bool CreateDownload(const DownloadRow& info);
 
-  // Remove |handle| from the database.
-  void RemoveDownload(int64 handle);
+  // Remove |id| from the database.
+  void RemoveDownload(uint32 id);
 
-  int CountDownloads();
+  size_t CountDownloads();
 
  protected:
   // Returns the database for the functions in this interface.
   virtual sql::Connection& GetDB() = 0;
 
-  // Returns the meta-table object for the functions in this interface.
-  virtual sql::MetaTable& GetMetaTable() = 0;
-
   // Returns true if able to successfully rewrite the invalid values for the
   // |state| field from 3 to 4. Returns false if there was an error fixing the
   // database. See http://crbug.com/140687
@@ -110,7 +104,7 @@
 
   bool EnsureColumnExists(const std::string& name, const std::string& type);
 
-  void RemoveDownloadURLs(int64 handle);
+  void RemoveDownloadURLs(uint32 id);
 
   // Utility functions for conversion between DownloadItem types
   // and DownloadDatabase constants.
@@ -122,9 +116,6 @@
   bool owning_thread_set_;
   base::PlatformThreadId owning_thread_;
 
-  int next_id_;
-  int next_db_handle_;
-
   // Initialized to false on construction, and checked in all functional
   // routines post-migration in the database for a possible call to
   // CleanUpInProgressEntries().  This allows us to avoid
diff --git a/chrome/browser/history/download_row.cc b/chrome/browser/history/download_row.cc
index 7858608..4f47d1f 100644
--- a/chrome/browser/history/download_row.cc
+++ b/chrome/browser/history/download_row.cc
@@ -12,7 +12,7 @@
       state(content::DownloadItem::IN_PROGRESS),
       danger_type(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS),
       interrupt_reason(content::DOWNLOAD_INTERRUPT_REASON_NONE),
-      db_handle(0),
+      id(content::DownloadItem::kInvalidId),
       opened(false) {
 }
 
@@ -28,7 +28,7 @@
     content::DownloadItem::DownloadState download_state,
     content::DownloadDangerType danger_type,
     content::DownloadInterruptReason interrupt_reason,
-    int64 handle,
+    uint32 id,
     bool download_opened)
     : current_path(current_path),
       target_path(target_path),
@@ -41,7 +41,7 @@
       state(download_state),
       danger_type(danger_type),
       interrupt_reason(interrupt_reason),
-      db_handle(handle),
+      id(id),
       opened(download_opened) {
 }
 
diff --git a/chrome/browser/history/download_row.h b/chrome/browser/history/download_row.h
index 7e91655..fe6b937 100644
--- a/chrome/browser/history/download_row.h
+++ b/chrome/browser/history/download_row.h
@@ -33,7 +33,7 @@
       content::DownloadItem::DownloadState download_state,
       content::DownloadDangerType danger_type,
       content::DownloadInterruptReason interrupt_reason,
-      int64 handle,
+      uint32 id,
       bool download_opened);
   ~DownloadRow();
 
@@ -76,9 +76,8 @@
   // state == DownloadItem::INTERRUPTED
   content::DownloadInterruptReason interrupt_reason;
 
-  // The handle of the download in the database. Is not changed by
-  // UpdateDownload().
-  int64 db_handle;
+  // The id of the download in the database. Is not changed by UpdateDownload().
+  uint32 id;
 
   // Whether this download has ever been opened from the browser.
   bool opened;
diff --git a/chrome/browser/history/expire_history_backend.cc b/chrome/browser/history/expire_history_backend.cc
index 4e46a2e..6895c8b 100644
--- a/chrome/browser/history/expire_history_backend.cc
+++ b/chrome/browser/history/expire_history_backend.cc
@@ -15,13 +15,13 @@
 #include "base/logging.h"
 #include "base/message_loop.h"
 #include "chrome/browser/bookmarks/bookmark_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/archived_database.h"
 #include "chrome/browser/history/history_database.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/text_database.h"
 #include "chrome/browser/history/text_database_manager.h"
 #include "chrome/browser/history/thumbnail_database.h"
-#include "chrome/common/chrome_notification_types.h"
 
 using base::Time;
 using base::TimeDelta;
diff --git a/chrome/browser/history/expire_history_backend_unittest.cc b/chrome/browser/history/expire_history_backend_unittest.cc
index 415d6b2..d36a6a1 100644
--- a/chrome/browser/history/expire_history_backend_unittest.cc
+++ b/chrome/browser/history/expire_history_backend_unittest.cc
@@ -18,6 +18,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/archived_database.h"
 #include "chrome/browser/history/expire_history_backend.h"
 #include "chrome/browser/history/history_database.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/history/text_database_manager.h"
 #include "chrome/browser/history/thumbnail_database.h"
 #include "chrome/browser/history/top_sites.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/thumbnail_score.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/tools/profiles/thumbnail-inl.h"
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index ed1419c..2660fb5 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -24,6 +24,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/autocomplete/history_url_provider.h"
 #include "chrome/browser/bookmarks/bookmark_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_changed_details.h"
 #include "chrome/browser/history/download_row.h"
 #include "chrome/browser/history/history_db_task.h"
@@ -36,7 +37,6 @@
 #include "chrome/browser/history/typed_url_syncable_service.h"
 #include "chrome/browser/history/visit_filter.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/importer/imported_favicon_usage.h"
 #include "chrome/common/url_constants.h"
 #include "grit/chromium_strings.h"
@@ -1294,9 +1294,9 @@
 
 // Downloads -------------------------------------------------------------------
 
-void HistoryBackend::GetNextDownloadId(int* id) {
+void HistoryBackend::GetNextDownloadId(uint32* next_id) {
   if (db_)
-    *id = db_->next_download_id();
+    db_->GetNextDownloadId(next_id);
 }
 
 // Get all the download entries from the database.
@@ -1314,43 +1314,45 @@
 }
 
 void HistoryBackend::CreateDownload(const history::DownloadRow& history_info,
-                                    int64* db_handle) {
+                                    bool* success) {
   if (!db_)
     return;
-  *db_handle = db_->CreateDownload(history_info);
+  *success = db_->CreateDownload(history_info);
   ScheduleCommit();
 }
 
-void HistoryBackend::RemoveDownloads(const std::set<int64>& handles) {
+void HistoryBackend::RemoveDownloads(const std::set<uint32>& ids) {
   if (!db_)
     return;
-  int downloads_count_before = db_->CountDownloads();
+  size_t downloads_count_before = db_->CountDownloads();
   base::TimeTicks started_removing = base::TimeTicks::Now();
   // HistoryBackend uses a long-running Transaction that is committed
   // periodically, so this loop doesn't actually hit the disk too hard.
-  for (std::set<int64>::const_iterator it = handles.begin();
-       it != handles.end(); ++it) {
+  for (std::set<uint32>::const_iterator it = ids.begin();
+       it != ids.end(); ++it) {
     db_->RemoveDownload(*it);
   }
-  base::TimeTicks finished_removing = base::TimeTicks::Now();
-  int downloads_count_after = db_->CountDownloads();
-  int num_downloads_deleted = downloads_count_before - downloads_count_after;
-  if (num_downloads_deleted >= 0) {
-    UMA_HISTOGRAM_COUNTS("Download.DatabaseRemoveDownloadsCount",
-                         num_downloads_deleted);
-    base::TimeDelta micros = (1000 * (finished_removing - started_removing));
-    UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTime", micros);
-    if (num_downloads_deleted > 0) {
-      UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTimePerRecord",
-                          (1000 * micros) / num_downloads_deleted);
-    }
-  }
-  int num_downloads_not_deleted = handles.size() - num_downloads_deleted;
-  if (num_downloads_not_deleted >= 0) {
-    UMA_HISTOGRAM_COUNTS("Download.DatabaseRemoveDownloadsCountNotRemoved",
-                         num_downloads_not_deleted);
-  }
   ScheduleCommit();
+  base::TimeTicks finished_removing = base::TimeTicks::Now();
+  size_t downloads_count_after = db_->CountDownloads();
+
+  DCHECK_LE(downloads_count_after, downloads_count_before);
+  if (downloads_count_after > downloads_count_before)
+    return;
+  size_t num_downloads_deleted = downloads_count_before - downloads_count_after;
+  UMA_HISTOGRAM_COUNTS("Download.DatabaseRemoveDownloadsCount",
+                        num_downloads_deleted);
+  base::TimeDelta micros = (1000 * (finished_removing - started_removing));
+  UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTime", micros);
+  if (num_downloads_deleted > 0) {
+    UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTimePerRecord",
+                        (1000 * micros) / num_downloads_deleted);
+  }
+  DCHECK_GE(ids.size(), num_downloads_deleted);
+  if (ids.size() < num_downloads_deleted)
+    return;
+  UMA_HISTOGRAM_COUNTS("Download.DatabaseRemoveDownloadsCountNotRemoved",
+                        ids.size() - num_downloads_deleted);
 }
 
 void HistoryBackend::QueryHistory(scoped_refptr<QueryHistoryRequest> request,
diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h
index 188847b..fbc17a9 100644
--- a/chrome/browser/history/history_backend.h
+++ b/chrome/browser/history/history_backend.h
@@ -307,12 +307,12 @@
 
   // Downloads -----------------------------------------------------------------
 
-  void GetNextDownloadId(int* id);
+  void GetNextDownloadId(uint32* next_id);
   void QueryDownloads(std::vector<DownloadRow>* rows);
   void UpdateDownload(const DownloadRow& data);
   void CreateDownload(const history::DownloadRow& history_info,
-                      int64* db_handle);
-  void RemoveDownloads(const std::set<int64>& db_handles);
+                      bool* success);
+  void RemoveDownloads(const std::set<uint32>& ids);
 
   // Segment usage -------------------------------------------------------------
 
diff --git a/chrome/browser/history/history_backend_unittest.cc b/chrome/browser/history/history_backend_unittest.cc
index 75b426b..7bd2328 100644
--- a/chrome/browser/history/history_backend_unittest.cc
+++ b/chrome/browser/history/history_backend_unittest.cc
@@ -391,7 +391,7 @@
       backend_->Closing();
     backend_ = NULL;
     mem_backend_.reset();
-    base::Delete(test_dir_, true);
+    base::DeleteFile(test_dir_, true);
     base::RunLoop().RunUntilIdle();
   }
 
@@ -1275,11 +1275,11 @@
   // Copy history database file to current directory so that it will be deleted
   // in Teardown.
   base::FilePath new_history_path(getTestDir());
-  base::Delete(new_history_path, true);
+  base::DeleteFile(new_history_path, true);
   file_util::CreateDirectory(new_history_path);
   base::FilePath new_history_file =
       new_history_path.Append(chrome::kHistoryFilename);
-  ASSERT_TRUE(file_util::CopyFile(old_history_path, new_history_file));
+  ASSERT_TRUE(base::CopyFile(old_history_path, new_history_file));
 
   backend_ = new HistoryBackend(new_history_path,
                                 0,
@@ -2514,14 +2514,14 @@
   // Copy history database file to current directory so that it will be deleted
   // in Teardown.
   base::FilePath new_history_path(getTestDir());
-  base::Delete(new_history_path, true);
+  base::DeleteFile(new_history_path, true);
   file_util::CreateDirectory(new_history_path);
   base::FilePath new_history_file =
       new_history_path.Append(chrome::kHistoryFilename);
   base::FilePath new_archived_file =
       new_history_path.Append(chrome::kArchivedHistoryFilename);
-  ASSERT_TRUE(file_util::CopyFile(old_history, new_history_file));
-  ASSERT_TRUE(file_util::CopyFile(old_archived, new_archived_file));
+  ASSERT_TRUE(base::CopyFile(old_history, new_history_file));
+  ASSERT_TRUE(base::CopyFile(old_archived, new_archived_file));
 
   backend_ = new HistoryBackend(new_history_path,
                                 0,
diff --git a/chrome/browser/history/history_database.cc b/chrome/browser/history/history_database.cc
index 4c49ee8..43ce119 100644
--- a/chrome/browser/history/history_database.cc
+++ b/chrome/browser/history/history_database.cc
@@ -95,6 +95,9 @@
   CreateMainURLIndex();
   CreateKeywordSearchTermsIndices();
 
+  // TODO(benjhayden) Remove at some point.
+  meta_table_.DeleteKey("next_download_id");
+
   // Version check.
   sql::InitStatus version_status = EnsureCurrentVersion();
   if (version_status != sql::INIT_OK)
@@ -297,10 +300,6 @@
   return db_;
 }
 
-sql::MetaTable& HistoryDatabase::GetMetaTable() {
-  return meta_table_;
-}
-
 // Migration -------------------------------------------------------------------
 
 sql::InitStatus HistoryDatabase::EnsureCurrentVersion() {
diff --git a/chrome/browser/history/history_database.h b/chrome/browser/history/history_database.h
index eecdc87..01df342 100644
--- a/chrome/browser/history/history_database.h
+++ b/chrome/browser/history/history_database.h
@@ -179,9 +179,6 @@
   // Overridden from URLDatabase:
   virtual sql::Connection& GetDB() OVERRIDE;
 
-  // Overridden from DownloadDatabase:
-  virtual sql::MetaTable& GetMetaTable() OVERRIDE;
-
   // Migration -----------------------------------------------------------------
 
   // Makes sure the version is up-to-date, updating if necessary. If the
diff --git a/chrome/browser/history/history_database_unittest.cc b/chrome/browser/history/history_database_unittest.cc
index 45832d4..720a37e 100644
--- a/chrome/browser/history/history_database_unittest.cc
+++ b/chrome/browser/history/history_database_unittest.cc
@@ -28,7 +28,7 @@
   old_history_path = old_history_path.AppendASCII("bookmarks");
   old_history_path = old_history_path.Append(
       FILE_PATH_LITERAL("History_with_starred"));
-  file_util::CopyFile(old_history_path, db_file);
+  base::CopyFile(old_history_path, db_file);
 
   // Load the DB twice. The first time it should migrate. Make sure that the
   // migration leaves it in a state fit to load again later.
diff --git a/chrome/browser/history/history_service.cc b/chrome/browser/history/history_service.cc
index 49e4b07..343e9d0 100644
--- a/chrome/browser/history/history_service.cc
+++ b/chrome/browser/history/history_service.cc
@@ -40,6 +40,7 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/download_row.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_notifications.h"
@@ -55,7 +56,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/profile_error_dialog.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/importer/imported_favicon_usage.h"
 #include "chrome/common/pref_names.h"
@@ -63,6 +63,7 @@
 #include "chrome/common/url_constants.h"
 #include "components/visitedlink/browser/visitedlink_master.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/download_item.h"
 #include "content/public/browser/notification_service.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
@@ -76,16 +77,9 @@
 
 static const char* kHistoryThreadName = "Chrome_HistoryThread";
 
-void DerefDownloadDbHandle(
-    const HistoryService::DownloadCreateCallback& callback,
-    int64* db_handle) {
-  callback.Run(*db_handle);
-}
-
-void DerefDownloadId(
-    const HistoryService::DownloadNextIdCallback& callback,
-    int* id) {
-  callback.Run(*id);
+template<typename PODType> void DerefPODType(
+    const base::Callback<void(PODType)>& callback, PODType* pod_value) {
+  callback.Run(*pod_value);
 }
 
 void RunWithFaviconResults(
@@ -462,6 +456,11 @@
                   from_time, max_result_count);
 }
 
+void HistoryService::FlushForTest(const base::Closure& flushed) {
+  thread_->message_loop_proxy()->PostTaskAndReply(
+      FROM_HERE, base::Bind(&base::DoNothing), flushed);
+}
+
 void HistoryService::SetOnBackendDestroyTask(const base::Closure& task) {
   DCHECK(thread_checker_.CalledOnValidThread());
   ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::SetOnBackendDestroyTask,
@@ -783,28 +782,28 @@
   DCHECK(thread_) << "History service being called after cleanup";
   DCHECK(thread_checker_.CalledOnValidThread());
   LoadBackendIfNecessary();
-  int64* db_handle = new int64(
-      history::DownloadDatabase::kUninitializedHandle);
+  bool* success = new bool(false);
   thread_->message_loop_proxy()->PostTaskAndReply(
       FROM_HERE,
       base::Bind(&HistoryBackend::CreateDownload,
                  history_backend_.get(),
                  create_info,
-                 db_handle),
-      base::Bind(&DerefDownloadDbHandle, callback, base::Owned(db_handle)));
+                 success),
+      base::Bind(&DerefPODType<bool>, callback, base::Owned(success)));
 }
 
-void HistoryService::GetNextDownloadId(const DownloadNextIdCallback& callback) {
+void HistoryService::GetNextDownloadId(
+    const content::DownloadIdCallback& callback) {
   DCHECK(thread_) << "History service being called after cleanup";
   DCHECK(thread_checker_.CalledOnValidThread());
   LoadBackendIfNecessary();
-  int* id = new int(history::DownloadDatabase::kUninitializedHandle);
+  uint32* next_id = new uint32(content::DownloadItem::kInvalidId);
   thread_->message_loop_proxy()->PostTaskAndReply(
       FROM_HERE,
       base::Bind(&HistoryBackend::GetNextDownloadId,
                  history_backend_.get(),
-                 id),
-      base::Bind(&DerefDownloadId, callback, base::Owned(id)));
+                 next_id),
+      base::Bind(&DerefPODType<uint32>, callback, base::Owned(next_id)));
 }
 
 // Handle queries for a list of all downloads in the history database's
@@ -834,10 +833,10 @@
   ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::UpdateDownload, data);
 }
 
-void HistoryService::RemoveDownloads(const std::set<int64>& db_handles) {
+void HistoryService::RemoveDownloads(const std::set<uint32>& ids) {
   DCHECK(thread_checker_.CalledOnValidThread());
   ScheduleAndForget(PRIORITY_NORMAL,
-                    &HistoryBackend::RemoveDownloads, db_handles);
+                    &HistoryBackend::RemoveDownloads, ids);
 }
 
 HistoryService::Handle HistoryService::QueryHistory(
diff --git a/chrome/browser/history/history_service.h b/chrome/browser/history/history_service.h
index 885c75c..060614d 100644
--- a/chrome/browser/history/history_service.h
+++ b/chrome/browser/history/history_service.h
@@ -30,6 +30,7 @@
 #include "chrome/common/ref_counted_util.h"
 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
 #include "components/visitedlink/browser/visitedlink_delegate.h"
+#include "content/public/browser/download_manager_delegate.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/common/page_transition_types.h"
@@ -440,7 +441,7 @@
 
   // Implemented by the caller of 'CreateDownload' below, and is called when the
   // history service has created a new entry for a download in the history db.
-  typedef base::Callback<void(int64)> DownloadCreateCallback;
+  typedef base::Callback<void(bool)> DownloadCreateCallback;
 
   // Begins a history request to create a new row for a download. 'info'
   // contains all the download's creation state, and 'callback' runs when the
@@ -450,12 +451,9 @@
       const history::DownloadRow& info,
       const DownloadCreateCallback& callback);
 
-  // Implemented by the caller of 'GetNextDownloadId' below.
-  typedef base::Callback<void(int)> DownloadNextIdCallback;
-
-  // Runs the callback with the next available download id. The callback is
-  // called on the thread that calls GetNextDownloadId().
-  void GetNextDownloadId(const DownloadNextIdCallback& callback);
+  // Responds on the calling thread with the maximum id of all downloads records
+  // in the database plus 1.
+  void GetNextDownloadId(const content::DownloadIdCallback& callback);
 
   // Implemented by the caller of 'QueryDownloads' below, and is called when the
   // history service has retrieved a list of all download state. The call
@@ -476,7 +474,7 @@
 
   // Permanently remove some downloads from the history system. This is a 'fire
   // and forget' operation.
-  void RemoveDownloads(const std::set<int64>& db_handles);
+  void RemoveDownloads(const std::set<uint32>& ids);
 
   // Visit Segments ------------------------------------------------------------
 
@@ -562,6 +560,9 @@
 
   // Testing -------------------------------------------------------------------
 
+  // Runs |flushed| after bouncing off the history thread.
+  void FlushForTest(const base::Closure& flushed);
+
   // Designed for unit tests, this passes the given task on to the history
   // backend to be called once the history backend has terminated. This allows
   // callers to know when the history thread is complete and the database files
diff --git a/chrome/browser/history/history_types.h b/chrome/browser/history/history_types.h
index d78d40f..87836eb 100644
--- a/chrome/browser/history/history_types.h
+++ b/chrome/browser/history/history_types.h
@@ -42,7 +42,6 @@
 // Container for a list of URLs.
 typedef std::vector<GURL> RedirectList;
 
-typedef int64 DownloadID;   // Identifier for a download.
 typedef int64 FaviconBitmapID; // Identifier for a bitmap in a favicon.
 typedef int64 SegmentID;  // URL segments for the most visited view.
 typedef int64 SegmentDurationID;  // Unique identifier for segment_duration.
diff --git a/chrome/browser/history/history_unittest.cc b/chrome/browser/history/history_unittest.cc
index ebdf67d..fe9cadf 100644
--- a/chrome/browser/history/history_unittest.cc
+++ b/chrome/browser/history/history_unittest.cc
@@ -161,7 +161,9 @@
     base::MessageLoop::current()->Run();
   }
 
-  int64 AddDownload(DownloadItem::DownloadState state, const Time& time) {
+  bool AddDownload(uint32 id,
+                   DownloadItem::DownloadState state,
+                   const Time& time) {
     std::vector<GURL> url_chain;
     url_chain.push_back(GURL("foo-url"));
 
@@ -176,7 +178,7 @@
                          state,
                          content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
                          content::DOWNLOAD_INTERRUPT_REASON_NONE,
-                         0,
+                         id,
                          false);
     return db_->CreateDownload(download);
   }
@@ -223,9 +225,9 @@
 
   // Add a download, test that it was added correctly, remove it, test that it
   // was removed.
-  DownloadID handle;
   Time now = Time();
-  EXPECT_NE(0, handle = AddDownload(DownloadItem::COMPLETE, now));
+  uint32 id = 1;
+  EXPECT_TRUE(AddDownload(id, DownloadItem::COMPLETE, Time()));
   db_->QueryDownloads(&downloads);
   EXPECT_EQ(1U, downloads.size());
 
@@ -248,7 +250,9 @@
             downloads[0].interrupt_reason);
   EXPECT_FALSE(downloads[0].opened);
 
-  db_->RemoveDownload(handle);
+  db_->QueryDownloads(&downloads);
+  EXPECT_EQ(1U, downloads.size());
+  db_->RemoveDownload(id);
   db_->QueryDownloads(&downloads);
   EXPECT_EQ(0U, downloads.size());
 }
@@ -335,9 +339,9 @@
         "received_bytes, total_bytes, state, end_time, opened) VALUES "
         "(?, ?, ?, ?, ?, ?, ?, ?, ?)"));
 
-    int64 db_handle = 0;
+    int64 id = 0;
     // Null path.
-    s.BindInt64(0, ++db_handle);
+    s.BindInt64(0, ++id);
     s.BindString(1, std::string());
     s.BindString(2, "http://whatever.com/index.html");
     s.BindInt64(3, now.ToTimeT());
@@ -350,7 +354,7 @@
     s.Reset(true);
 
     // Non-null path.
-    s.BindInt64(0, ++db_handle);
+    s.BindInt64(0, ++id);
     s.BindString(1, "/path/to/some/file");
     s.BindString(2, "http://whatever.com/index1.html");
     s.BindInt64(3, now.ToTimeT());
@@ -487,11 +491,10 @@
   base::Time now(base::Time::Now());
 
   // Add some downloads.
-  AddDownload(DownloadItem::COMPLETE, now);
-  int64 did2 = AddDownload(DownloadItem::COMPLETE, now +
-                           base::TimeDelta::FromDays(2));
-  int64 did3 = AddDownload(DownloadItem::COMPLETE, now -
-                           base::TimeDelta::FromDays(2));
+  uint32 id1 = 1, id2 = 2, id3 = 3;
+  AddDownload(id1, DownloadItem::COMPLETE, now);
+  AddDownload(id2, DownloadItem::COMPLETE, now + base::TimeDelta::FromDays(2));
+  AddDownload(id3, DownloadItem::COMPLETE, now - base::TimeDelta::FromDays(2));
 
   // Confirm that resulted in the correct number of rows in the DB.
   DeleteBackend();
@@ -511,8 +514,8 @@
 
   // Delete some rows and make sure the results are still correct.
   CreateBackendAndDatabase();
-  db_->RemoveDownload(did2);
-  db_->RemoveDownload(did3);
+  db_->RemoveDownload(id2);
+  db_->RemoveDownload(id3);
   DeleteBackend();
   {
     sql::Connection db;
@@ -544,15 +547,14 @@
                        DownloadItem::COMPLETE,
                        content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
                        content::DOWNLOAD_INTERRUPT_REASON_NONE,
-                       0,
+                       1,
                        0);
 
   // Creating records without any urls should fail.
-  EXPECT_EQ(DownloadDatabase::kUninitializedHandle,
-            db_->CreateDownload(download));
+  EXPECT_FALSE(db_->CreateDownload(download));
 
   download.url_chain.push_back(GURL("foo-url"));
-  EXPECT_EQ(1, db_->CreateDownload(download));
+  EXPECT_TRUE(db_->CreateDownload(download));
 
   // Pretend that the URLs were dropped.
   DeleteBackend();
@@ -589,7 +591,7 @@
   base::Time now(base::Time::Now());
 
   // Put an IN_PROGRESS download in the DB.
-  AddDownload(DownloadItem::IN_PROGRESS, now);
+  AddDownload(1, DownloadItem::IN_PROGRESS, now);
 
   // Confirm that they made it into the DB unchanged.
   DeleteBackend();
@@ -1545,7 +1547,7 @@
   global_id_directive->set_start_time_usec(3);
   global_id_directive->set_end_time_usec(10);
   directives.push_back(
-      syncer::SyncData::CreateRemoteData(1, entity_specs));
+      syncer::SyncData::CreateRemoteData(1, entity_specs, base::Time()));
 
   // 2nd directive.
   global_id_directive->Clear();
@@ -1555,7 +1557,7 @@
   global_id_directive->set_start_time_usec(13);
   global_id_directive->set_end_time_usec(19);
   directives.push_back(
-      syncer::SyncData::CreateRemoteData(2, entity_specs));
+      syncer::SyncData::CreateRemoteData(2, entity_specs, base::Time()));
 
   TestChangeProcessor change_processor;
   EXPECT_FALSE(
@@ -1621,13 +1623,17 @@
           ->mutable_time_range_directive();
   time_range_directive->set_start_time_usec(2);
   time_range_directive->set_end_time_usec(5);
-  directives.push_back(syncer::SyncData::CreateRemoteData(1, entity_specs));
+  directives.push_back(syncer::SyncData::CreateRemoteData(1,
+                                                          entity_specs,
+                                                          base::Time()));
 
   // 2nd directive.
   time_range_directive->Clear();
   time_range_directive->set_start_time_usec(8);
   time_range_directive->set_end_time_usec(10);
-  directives.push_back(syncer::SyncData::CreateRemoteData(2, entity_specs));
+  directives.push_back(syncer::SyncData::CreateRemoteData(2,
+                                                          entity_specs,
+                                                          base::Time()));
 
   TestChangeProcessor change_processor;
   EXPECT_FALSE(
diff --git a/chrome/browser/history/in_memory_history_backend.cc b/chrome/browser/history/in_memory_history_backend.cc
index ce9f965..a099737 100644
--- a/chrome/browser/history/in_memory_history_backend.cc
+++ b/chrome/browser/history/in_memory_history_backend.cc
@@ -11,11 +11,11 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/in_memory_database.h"
 #include "chrome/browser/history/url_database.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 
diff --git a/chrome/browser/history/in_memory_url_index.cc b/chrome/browser/history/in_memory_url_index.cc
index e0f4462..0f6ee80 100644
--- a/chrome/browser/history/in_memory_url_index.cc
+++ b/chrome/browser/history/in_memory_url_index.cc
@@ -10,13 +10,13 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/bookmark_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/history/url_database.h"
 #include "chrome/browser/history/url_index_private_data.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
@@ -31,7 +31,7 @@
 // there is no private data to save. Runs on the FILE thread.
 void DeleteCacheFile(const base::FilePath& path) {
   DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-  base::Delete(path, false);
+  base::DeleteFile(path, false);
 }
 
 // Initializes a whitelist of URL schemes.
diff --git a/chrome/browser/history/in_memory_url_index_unittest.cc b/chrome/browser/history/in_memory_url_index_unittest.cc
index 8a2d1de..4a9848f 100644
--- a/chrome/browser/history/in_memory_url_index_unittest.cc
+++ b/chrome/browser/history/in_memory_url_index_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/autocomplete/autocomplete_provider.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_database.h"
 #include "chrome/browser/history/history_notifications.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/history/in_memory_url_index.h"
 #include "chrome/browser/history/in_memory_url_index_types.h"
 #include "chrome/browser/history/url_index_private_data.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/history_index_restore_observer.h"
 #include "chrome/test/base/testing_profile.h"
@@ -203,7 +203,7 @@
   history_proto_path = history_proto_path.Append(
       FILE_PATH_LITERAL("History"));
   history_proto_path = history_proto_path.Append(TestDBName());
-  EXPECT_TRUE(file_util::PathExists(history_proto_path));
+  EXPECT_TRUE(base::PathExists(history_proto_path));
 
   std::ifstream proto_file(history_proto_path.value().c_str());
   static const size_t kCommandBufferMaxSize = 2048;
diff --git a/chrome/browser/history/shortcuts_backend.cc b/chrome/browser/history/shortcuts_backend.cc
index 7aded72..dfa7257 100644
--- a/chrome/browser/history/shortcuts_backend.cc
+++ b/chrome/browser/history/shortcuts_backend.cc
@@ -15,12 +15,12 @@
 #include "base/strings/string_util.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
 #include "chrome/browser/autocomplete/autocomplete_result.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/shortcuts_database.h"
 #include "chrome/browser/omnibox/omnibox_log.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/history/text_database.cc b/chrome/browser/history/text_database.cc
index b37073a..0f5db89 100644
--- a/chrome/browser/history/text_database.cc
+++ b/chrome/browser/history/text_database.cc
@@ -14,7 +14,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/diagnostics/sqlite_diagnostics.h"
 #include "sql/statement.h"
 #include "sql/transaction.h"
 
@@ -128,7 +127,7 @@
 bool TextDatabase::Init() {
   // Make sure, if we're not allowed to create the file, that it exists.
   if (!allow_create_) {
-    if (!file_util::PathExists(file_name_))
+    if (!base::PathExists(file_name_))
       return false;
   }
 
diff --git a/chrome/browser/history/text_database_manager_unittest.cc b/chrome/browser/history/text_database_manager_unittest.cc
index fa5a1f3..51a632e 100644
--- a/chrome/browser/history/text_database_manager_unittest.cc
+++ b/chrome/browser/history/text_database_manager_unittest.cc
@@ -161,7 +161,7 @@
   }
 
   virtual void TearDown() {
-    base::Delete(dir_, true);
+    base::DeleteFile(dir_, true);
   }
 
   base::MessageLoop message_loop_;
diff --git a/chrome/browser/history/thumbnail_database.cc b/chrome/browser/history/thumbnail_database.cc
index ef5c439..da34646 100644
--- a/chrome/browser/history/thumbnail_database.cc
+++ b/chrome/browser/history/thumbnail_database.cc
@@ -20,7 +20,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
-#include "chrome/browser/diagnostics/sqlite_diagnostics.h"
 #include "chrome/browser/history/history_publisher.h"
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/history/url_database.h"
diff --git a/chrome/browser/history/top_sites_database.cc b/chrome/browser/history/top_sites_database.cc
index ec0e1de..6192a87 100644
--- a/chrome/browser/history/top_sites_database.cc
+++ b/chrome/browser/history/top_sites_database.cc
@@ -6,7 +6,6 @@
 #include "base/memory/ref_counted.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
-#include "chrome/browser/diagnostics/sqlite_diagnostics.h"
 #include "chrome/browser/history/history_types.h"
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/history/top_sites_database.h"
@@ -26,7 +25,7 @@
 }
 
 bool TopSitesDatabase::Init(const base::FilePath& db_name) {
-  bool file_existed = file_util::PathExists(db_name);
+  bool file_existed = base::PathExists(db_name);
 
   if (!file_existed)
     may_need_history_migration_ = true;
diff --git a/chrome/browser/history/top_sites_impl.cc b/chrome/browser/history/top_sites_impl.cc
index 097c401..c8f0466 100644
--- a/chrome/browser/history/top_sites_impl.cc
+++ b/chrome/browser/history/top_sites_impl.cc
@@ -18,6 +18,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/task_runner.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_db_task.h"
 #include "chrome/browser/history/history_notifications.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/ntp/most_visited_handler.h"
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/thumbnail_score.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/history/top_sites_impl_unittest.cc b/chrome/browser/history/top_sites_impl_unittest.cc
index 566e8e9..251accb 100644
--- a/chrome/browser/history/top_sites_impl_unittest.cc
+++ b/chrome/browser/history/top_sites_impl_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_database.h"
 #include "chrome/browser/history/history_db_task.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/ui/webui/ntp/most_visited_handler.h"
 #include "chrome/common/cancelable_task_tracker.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_profile.h"
@@ -910,7 +910,7 @@
   WaitForHistory();
 
   // Make sure there is no longer a Thumbnails file on disk.
-  ASSERT_FALSE(file_util::PathExists(
+  ASSERT_FALSE(base::PathExists(
                    profile()->GetPath().Append(chrome::kThumbnailsFilename)));
 
   // Recreate top sites and make sure everything is still there.
diff --git a/chrome/browser/history/top_sites_likely_impl.cc b/chrome/browser/history/top_sites_likely_impl.cc
index 0cabb18..1b7e277 100644
--- a/chrome/browser/history/top_sites_likely_impl.cc
+++ b/chrome/browser/history/top_sites_likely_impl.cc
@@ -18,6 +18,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/task_runner.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_db_task.h"
 #include "chrome/browser/history/history_notifications.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/ntp/most_visited_handler.h"
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/thumbnail_score.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/history/top_sites_likely_impl_unittest.cc b/chrome/browser/history/top_sites_likely_impl_unittest.cc
index 14529ca..8ef73a2 100644
--- a/chrome/browser/history/top_sites_likely_impl_unittest.cc
+++ b/chrome/browser/history/top_sites_likely_impl_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_database.h"
 #include "chrome/browser/history/history_db_task.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/ui/webui/ntp/most_visited_handler.h"
 #include "chrome/common/cancelable_task_tracker.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_profile.h"
@@ -911,7 +911,7 @@
   WaitForHistory();
 
   // Make sure there is no longer a Thumbnails file on disk.
-  ASSERT_FALSE(file_util::PathExists(
+  ASSERT_FALSE(base::PathExists(
                    profile()->GetPath().Append(chrome::kThumbnailsFilename)));
 
   // Recreate top sites and make sure everything is still there.
diff --git a/chrome/browser/history/url_index_private_data.cc b/chrome/browser/history/url_index_private_data.cc
index 3315adb..d4548cb 100644
--- a/chrome/browser/history/url_index_private_data.cc
+++ b/chrome/browser/history/url_index_private_data.cc
@@ -396,7 +396,7 @@
     const base::FilePath& file_path,
     const std::string& languages) {
   base::TimeTicks beginning_time = base::TimeTicks::Now();
-  if (!file_util::PathExists(file_path))
+  if (!base::PathExists(file_path))
     return NULL;
   std::string data;
   // If there is no cache file then simply give up. This will cause us to
diff --git a/chrome/browser/icon_loader_linux.cc b/chrome/browser/icon_loader_linux.cc
index acecd0a..b75da17 100644
--- a/chrome/browser/icon_loader_linux.cc
+++ b/chrome/browser/icon_loader_linux.cc
@@ -11,8 +11,8 @@
 #include "base/logging.h"
 #include "base/message_loop.h"
 #include "base/nix/mime_util_xdg.h"
-#include "content/public/child/image_decoder_utils.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/codec/png_codec.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/size.h"
 
@@ -45,18 +45,19 @@
   }
 
   base::FilePath filename = base::nix::GetMimeIcon(group_, size_pixels);
-  // We don't support SVG icons; this just spams the terminal so fail quickly
-  // and don't try to read the file from disk first.
-  if (filename.Extension() != ".svg") {
+  // We don't support SVG or XPM icons; this just spams the terminal so fail
+  // quickly and don't try to read the file from disk first.
+  if (filename.Extension() != ".svg" &&
+      filename.Extension() != ".xpm") {
     string icon_data;
     file_util::ReadFileToString(filename, &icon_data);
 
     SkBitmap bitmap;
-    bitmap = content::DecodeImage(
+    bool success = gfx::PNGCodec::Decode(
         reinterpret_cast<const unsigned char*>(icon_data.data()),
-        gfx::Size(),
-        icon_data.length());
-    if (!bitmap.empty()) {
+        icon_data.length(),
+        &bitmap);
+    if (success && !bitmap.empty()) {
       DCHECK_EQ(size_pixels, bitmap.width());
       DCHECK_EQ(size_pixels, bitmap.height());
       gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
diff --git a/chrome/browser/importer/bookmark_html_reader.cc b/chrome/browser/importer/bookmark_html_reader.cc
deleted file mode 100644
index e618bad..0000000
--- a/chrome/browser/importer/bookmark_html_reader.cc
+++ /dev/null
@@ -1,432 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/bookmark_html_reader.h"
-
-#include "base/callback.h"
-#include "base/file_util.h"
-#include "base/i18n/icu_string_conversions.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/time/time.h"
-#include "chrome/browser/favicon/favicon_util.h"
-#include "chrome/common/importer/imported_bookmark_entry.h"
-#include "chrome/common/importer/imported_favicon_usage.h"
-#include "content/public/common/url_constants.h"
-#include "net/base/data_url.h"
-#include "net/base/escape.h"
-#include "url/gurl.h"
-
-namespace {
-
-// Fetches the given |attribute| value from the |attribute_list|. Returns true
-// if successful, and |value| will contain the value.
-bool GetAttribute(const std::string& attribute_list,
-                  const std::string& attribute,
-                  std::string* value) {
-  const char kQuote[] = "\"";
-
-  size_t begin = attribute_list.find(attribute + "=" + kQuote);
-  if (begin == std::string::npos)
-    return false;  // Can't find the attribute.
-
-  begin += attribute.size() + 2;
-  size_t end = begin + 1;
-
-  while (end < attribute_list.size()) {
-    if (attribute_list[end] == '"' &&
-        attribute_list[end - 1] != '\\') {
-      break;
-    }
-    end++;
-  }
-
-  if (end == attribute_list.size())
-    return false;  // The value is not quoted.
-
-  *value = attribute_list.substr(begin, end - begin);
-  return true;
-}
-
-// Given the URL of a page and a favicon data URL, adds an appropriate record
-// to the given favicon usage vector.
-void DataURLToFaviconUsage(
-    const GURL& link_url,
-    const GURL& favicon_data,
-    std::vector<ImportedFaviconUsage>* favicons) {
-  if (!link_url.is_valid() || !favicon_data.is_valid() ||
-      !favicon_data.SchemeIs(chrome::kDataScheme))
-    return;
-
-  // Parse the data URL.
-  std::string mime_type, char_set, data;
-  if (!net::DataURL::Parse(favicon_data, &mime_type, &char_set, &data) ||
-      data.empty())
-    return;
-
-  ImportedFaviconUsage usage;
-  if (!FaviconUtil::ReencodeFavicon(
-          reinterpret_cast<const unsigned char*>(&data[0]),
-          data.size(), &usage.png_data))
-    return;  // Unable to decode.
-
-  // We need to make up a URL for the favicon. We use a version of the page's
-  // URL so that we can be sure it will not collide.
-  usage.favicon_url = GURL(std::string("made-up-favicon:") + link_url.spec());
-
-  // We only have one URL per favicon for Firefox 2 bookmarks.
-  usage.urls.insert(link_url);
-
-  favicons->push_back(usage);
-}
-
-}  // namespace
-
-namespace bookmark_html_reader {
-
-void ImportBookmarksFile(
-      const base::Callback<bool(void)>& cancellation_callback,
-      const base::Callback<bool(const GURL&)>& valid_url_callback,
-      const base::FilePath& file_path,
-      std::vector<ImportedBookmarkEntry>* bookmarks,
-      std::vector<ImportedFaviconUsage>* favicons) {
-  std::string content;
-  file_util::ReadFileToString(file_path, &content);
-  std::vector<std::string> lines;
-  base::SplitString(content, '\n', &lines);
-
-  base::string16 last_folder;
-  bool last_folder_on_toolbar = false;
-  bool last_folder_is_empty = true;
-  bool has_subfolder = false;
-  base::Time last_folder_add_date;
-  std::vector<base::string16> path;
-  size_t toolbar_folder_index = 0;
-  std::string charset;
-  for (size_t i = 0;
-       i < lines.size() &&
-           (cancellation_callback.is_null() || !cancellation_callback.Run());
-       ++i) {
-    std::string line;
-    TrimString(lines[i], " ", &line);
-
-    // Get the encoding of the bookmark file.
-    if (internal::ParseCharsetFromLine(line, &charset))
-      continue;
-
-    // Get the folder name.
-    if (internal::ParseFolderNameFromLine(line,
-                                          charset,
-                                          &last_folder,
-                                          &last_folder_on_toolbar,
-                                          &last_folder_add_date)) {
-      continue;
-    }
-
-    // Get the bookmark entry.
-    base::string16 title;
-    base::string16 shortcut;
-    GURL url, favicon;
-    base::Time add_date;
-    base::string16 post_data;
-    bool is_bookmark;
-    // TODO(jcampan): http://b/issue?id=1196285 we do not support POST based
-    //                keywords yet.
-    is_bookmark =
-        internal::ParseBookmarkFromLine(line, charset, &title,
-                                        &url, &favicon, &shortcut,
-                                        &add_date, &post_data) ||
-        internal::ParseMinimumBookmarkFromLine(line, charset, &title, &url);
-
-    if (is_bookmark)
-      last_folder_is_empty = false;
-
-    if (is_bookmark &&
-        post_data.empty() &&
-        (valid_url_callback.is_null() || valid_url_callback.Run(url))) {
-      if (toolbar_folder_index > path.size() && !path.empty()) {
-        NOTREACHED();  // error in parsing.
-        break;
-      }
-
-      ImportedBookmarkEntry entry;
-      entry.creation_time = add_date;
-      entry.url = url;
-      entry.title = title;
-
-      if (toolbar_folder_index) {
-        // The toolbar folder should be at the top level.
-        entry.in_toolbar = true;
-        entry.path.assign(path.begin() + toolbar_folder_index - 1, path.end());
-      } else {
-        // Add this bookmark to the list of |bookmarks|.
-        if (!has_subfolder && !last_folder.empty()) {
-          path.push_back(last_folder);
-          last_folder.clear();
-        }
-        entry.path.assign(path.begin(), path.end());
-      }
-      bookmarks->push_back(entry);
-
-      // Save the favicon. DataURLToFaviconUsage will handle the case where
-      // there is no favicon.
-      if (favicons)
-        DataURLToFaviconUsage(url, favicon, favicons);
-
-      continue;
-    }
-
-    // Bookmarks in sub-folder are encapsulated with <DL> tag.
-    if (StartsWithASCII(line, "<DL>", false)) {
-      has_subfolder = true;
-      if (!last_folder.empty()) {
-        path.push_back(last_folder);
-        last_folder.clear();
-      }
-      if (last_folder_on_toolbar && !toolbar_folder_index)
-        toolbar_folder_index = path.size();
-
-      // Mark next folder empty as initial state.
-      last_folder_is_empty = true;
-    } else if (StartsWithASCII(line, "</DL>", false)) {
-      if (path.empty())
-        break;  // Mismatch <DL>.
-
-      base::string16 folder_title = path.back();
-      path.pop_back();
-
-      if (last_folder_is_empty) {
-        // Empty folder should be added explicitly.
-        ImportedBookmarkEntry entry;
-        entry.is_folder = true;
-        entry.creation_time = last_folder_add_date;
-        entry.title = folder_title;
-        if (toolbar_folder_index) {
-          // The toolbar folder should be at the top level.
-          // Make sure we don't add the toolbar folder itself if it is empty.
-          if (toolbar_folder_index <= path.size()) {
-            entry.in_toolbar = true;
-            entry.path.assign(path.begin() + toolbar_folder_index - 1,
-                              path.end());
-            bookmarks->push_back(entry);
-          }
-        } else {
-          // Add this folder to the list of |bookmarks|.
-          entry.path.assign(path.begin(), path.end());
-          bookmarks->push_back(entry);
-        }
-
-        // Parent folder include current one, so it's not empty.
-        last_folder_is_empty = false;
-      }
-
-      if (toolbar_folder_index > path.size())
-        toolbar_folder_index = 0;
-    }
-  }
-}
-
-namespace internal {
-
-bool ParseCharsetFromLine(const std::string& line, std::string* charset) {
-  const char kCharset[] = "charset=";
-  if (StartsWithASCII(line, "<META", false) &&
-      (line.find("CONTENT=\"") != std::string::npos ||
-          line.find("content=\"") != std::string::npos)) {
-    size_t begin = line.find(kCharset);
-    if (begin == std::string::npos)
-      return false;
-    begin += std::string(kCharset).size();
-    size_t end = line.find_first_of('\"', begin);
-    *charset = line.substr(begin, end - begin);
-    return true;
-  }
-  return false;
-}
-
-bool ParseFolderNameFromLine(const std::string& line,
-                             const std::string& charset,
-                             base::string16* folder_name,
-                             bool* is_toolbar_folder,
-                             base::Time* add_date) {
-  const char kFolderOpen[] = "<DT><H3";
-  const char kFolderClose[] = "</H3>";
-  const char kToolbarFolderAttribute[] = "PERSONAL_TOOLBAR_FOLDER";
-  const char kAddDateAttribute[] = "ADD_DATE";
-
-  if (!StartsWithASCII(line, kFolderOpen, true))
-    return false;
-
-  size_t end = line.find(kFolderClose);
-  size_t tag_end = line.rfind('>', end) + 1;
-  // If no end tag or start tag is broken, we skip to find the folder name.
-  if (end == std::string::npos || tag_end < arraysize(kFolderOpen))
-    return false;
-
-  base::CodepageToUTF16(line.substr(tag_end, end - tag_end), charset.c_str(),
-                        base::OnStringConversionError::SKIP, folder_name);
-  *folder_name = net::UnescapeForHTML(*folder_name);
-
-  std::string attribute_list = line.substr(arraysize(kFolderOpen),
-      tag_end - arraysize(kFolderOpen) - 1);
-  std::string value;
-
-  // Add date
-  if (GetAttribute(attribute_list, kAddDateAttribute, &value)) {
-    int64 time;
-    base::StringToInt64(value, &time);
-    // Upper bound it at 32 bits.
-    if (0 < time && time < (1LL << 32))
-      *add_date = base::Time::FromTimeT(time);
-  }
-
-  if (GetAttribute(attribute_list, kToolbarFolderAttribute, &value) &&
-      LowerCaseEqualsASCII(value, "true"))
-    *is_toolbar_folder = true;
-  else
-    *is_toolbar_folder = false;
-
-  return true;
-}
-
-bool ParseBookmarkFromLine(const std::string& line,
-                           const std::string& charset,
-                           base::string16* title,
-                           GURL* url,
-                           GURL* favicon,
-                           base::string16* shortcut,
-                           base::Time* add_date,
-                           base::string16* post_data) {
-  const char kItemOpen[] = "<DT><A";
-  const char kItemClose[] = "</A>";
-  const char kFeedURLAttribute[] = "FEEDURL";
-  const char kHrefAttribute[] = "HREF";
-  const char kIconAttribute[] = "ICON";
-  const char kShortcutURLAttribute[] = "SHORTCUTURL";
-  const char kAddDateAttribute[] = "ADD_DATE";
-  const char kPostDataAttribute[] = "POST_DATA";
-
-  title->clear();
-  *url = GURL();
-  *favicon = GURL();
-  shortcut->clear();
-  post_data->clear();
-  *add_date = base::Time();
-
-  if (!StartsWithASCII(line, kItemOpen, true))
-    return false;
-
-  size_t end = line.find(kItemClose);
-  size_t tag_end = line.rfind('>', end) + 1;
-  if (end == std::string::npos || tag_end < arraysize(kItemOpen))
-    return false;  // No end tag or start tag is broken.
-
-  std::string attribute_list = line.substr(arraysize(kItemOpen),
-      tag_end - arraysize(kItemOpen) - 1);
-
-  // We don't import Live Bookmark folders, which is Firefox's RSS reading
-  // feature, since the user never necessarily bookmarked them and we don't
-  // have this feature to update their contents.
-  std::string value;
-  if (GetAttribute(attribute_list, kFeedURLAttribute, &value))
-    return false;
-
-  // Title
-  base::CodepageToUTF16(line.substr(tag_end, end - tag_end), charset.c_str(),
-                        base::OnStringConversionError::SKIP, title);
-  *title = net::UnescapeForHTML(*title);
-
-  // URL
-  if (GetAttribute(attribute_list, kHrefAttribute, &value)) {
-    base::string16 url16;
-    base::CodepageToUTF16(value, charset.c_str(),
-                          base::OnStringConversionError::SKIP, &url16);
-    url16 = net::UnescapeForHTML(url16);
-
-    *url = GURL(url16);
-  }
-
-  // Favicon
-  if (GetAttribute(attribute_list, kIconAttribute, &value))
-    *favicon = GURL(value);
-
-  // Keyword
-  if (GetAttribute(attribute_list, kShortcutURLAttribute, &value)) {
-    base::CodepageToUTF16(value, charset.c_str(),
-                          base::OnStringConversionError::SKIP, shortcut);
-    *shortcut = net::UnescapeForHTML(*shortcut);
-  }
-
-  // Add date
-  if (GetAttribute(attribute_list, kAddDateAttribute, &value)) {
-    int64 time;
-    base::StringToInt64(value, &time);
-    // Upper bound it at 32 bits.
-    if (0 < time && time < (1LL << 32))
-      *add_date = base::Time::FromTimeT(time);
-  }
-
-  // Post data.
-  if (GetAttribute(attribute_list, kPostDataAttribute, &value)) {
-    base::CodepageToUTF16(value, charset.c_str(),
-                          base::OnStringConversionError::SKIP, post_data);
-    *post_data = net::UnescapeForHTML(*post_data);
-  }
-
-  return true;
-}
-
-bool ParseMinimumBookmarkFromLine(const std::string& line,
-                                  const std::string& charset,
-                                  base::string16* title,
-                                  GURL* url) {
-  const char kItemOpen[] = "<DT><A";
-  const char kItemClose[] = "</";
-  const char kHrefAttributeUpper[] = "HREF";
-  const char kHrefAttributeLower[] = "href";
-
-  title->clear();
-  *url = GURL();
-
-  // Case-insensitive check of open tag.
-  if (!StartsWithASCII(line, kItemOpen, false))
-    return false;
-
-  // Find any close tag.
-  size_t end = line.find(kItemClose);
-  size_t tag_end = line.rfind('>', end) + 1;
-  if (end == std::string::npos || tag_end < arraysize(kItemOpen))
-    return false;  // No end tag or start tag is broken.
-
-  std::string attribute_list = line.substr(arraysize(kItemOpen),
-      tag_end - arraysize(kItemOpen) - 1);
-
-  // Title
-  base::CodepageToUTF16(line.substr(tag_end, end - tag_end), charset.c_str(),
-                        base::OnStringConversionError::SKIP, title);
-  *title = net::UnescapeForHTML(*title);
-
-  // URL
-  std::string value;
-  if (GetAttribute(attribute_list, kHrefAttributeUpper, &value) ||
-      GetAttribute(attribute_list, kHrefAttributeLower, &value)) {
-    if (charset.length() != 0) {
-      base::string16 url16;
-      base::CodepageToUTF16(value, charset.c_str(),
-                            base::OnStringConversionError::SKIP, &url16);
-      url16 = net::UnescapeForHTML(url16);
-
-      *url = GURL(url16);
-    } else {
-      *url = GURL(value);
-    }
-  }
-
-  return true;
-}
-
-}  // namespace internal
-
-}  // namespace bookmark_html_reader
diff --git a/chrome/browser/importer/bookmark_html_reader.h b/chrome/browser/importer/bookmark_html_reader.h
deleted file mode 100644
index 5d34ab2..0000000
--- a/chrome/browser/importer/bookmark_html_reader.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_BOOKMARK_HTML_READER_H_
-#define CHROME_BROWSER_IMPORTER_BOOKMARK_HTML_READER_H_
-
-#include <string>
-#include <vector>
-
-#include "base/callback_forward.h"
-#include "base/strings/string16.h"
-
-class GURL;
-struct ImportedBookmarkEntry;
-struct ImportedFaviconUsage;
-
-namespace base {
-class FilePath;
-class Time;
-}
-
-namespace bookmark_html_reader {
-
-// Imports the bookmarks from the specified file.
-//
-// |cancellation_callback| is polled to query if the import should be cancelled;
-// if it returns |true| at any time the import will be cancelled. If
-// |cancellation_callback| is a null callback the import will run to completion.
-//
-// |valid_url_callback| is called to determine if a specified URL is valid for
-// import; it returns |true| if it is. If |valid_url_callback| is a null
-// callback, all URLs are considered to be valid.
-//
-// |file_path| is the path of the file on disk to import.
-//
-// |bookmarks| is a pointer to a vector, which is filled with the imported
-// bookmarks. It may not be NULL.
-//
-// |favicons| is a pointer to a vector, which is filled with the favicons of
-// imported bookmarks. It may be NULL, in which case favicons are not imported.
-void ImportBookmarksFile(
-    const base::Callback<bool(void)>& cancellation_callback,
-    const base::Callback<bool(const GURL&)>& valid_url_callback,
-    const base::FilePath& file_path,
-    std::vector<ImportedBookmarkEntry>* bookmarks,
-    std::vector<ImportedFaviconUsage>* favicons);
-
-namespace internal {
-
-// The file format that BookmarkHTMLReader parses starts with a heading
-// tag, which contains its title. All bookmarks and sub-folders follow,
-// bracketed by a <DL> tag:
-//   <DT><H3 PERSONAL_TOOLBAR_FOLDER="true" ...>title</H3>
-//   <DL><p>
-//      ... container ...
-//   </DL><p>
-// And a bookmark is presented by a <A> tag:
-//   <DT><A HREF="url" SHORTCUTURL="shortcut" ADD_DATE="11213014"...>name</A>
-// Reference: http://kb.mozillazine.org/Bookmarks.html
-
-bool ParseCharsetFromLine(const std::string& line,
-                          std::string* charset);
-bool ParseFolderNameFromLine(const std::string& line,
-                             const std::string& charset,
-                             base::string16* folder_name,
-                             bool* is_toolbar_folder,
-                             base::Time* add_date);
-// See above, this will also put the data: URL of the favicon into |*favicon|
-// if there is a favicon given. |post_data| is set for POST base keywords to
-// the contents of the actual POST (with %s for the search term).
-bool ParseBookmarkFromLine(const std::string& line,
-                           const std::string& charset,
-                           base::string16* title,
-                           GURL* url,
-                           GURL* favicon,
-                           base::string16* shortcut,
-                           base::Time* add_date,
-                           base::string16* post_data);
-// Save bookmarks imported from browsers with Firefox 2 compatible bookmark
-// systems such as Epiphany. This bookmark format is the same as that of the
-// basic Firefox 2 bookmark, but it misses additional properties and uses
-// lower-case tag:
-//   ...<h1>Bookmarks</h1><dl>
-//   <dt><a href="url">name</a></dt>
-//   <dt><a href="url">name</a></dt>
-//   </dl>
-bool ParseMinimumBookmarkFromLine(const std::string& line,
-                                  const std::string& charset,
-                                  base::string16* title,
-                                  GURL* url);
-
-}  // namespace internal
-
-}  // namespace bookmark_html_reader
-
-#endif  // CHROME_BROWSER_IMPORTER_BOOKMARK_HTML_READER_H_
diff --git a/chrome/browser/importer/bookmark_html_reader_unittest.cc b/chrome/browser/importer/bookmark_html_reader_unittest.cc
deleted file mode 100644
index 8374a12..0000000
--- a/chrome/browser/importer/bookmark_html_reader_unittest.cc
+++ /dev/null
@@ -1,275 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/bookmark_html_reader.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/files/file_path.h"
-#include "base/path_service.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/importer/imported_bookmark_entry.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace bookmark_html_reader {
-
-TEST(BookmarkHTMLReaderTest, ParseTests) {
-  bool result;
-
-  // Tests charset.
-  std::string charset;
-  result = internal::ParseCharsetFromLine(
-      "<META HTTP-EQUIV=\"Content-Type\" "
-      "CONTENT=\"text/html; charset=UTF-8\">",
-      &charset);
-  EXPECT_TRUE(result);
-  EXPECT_EQ("UTF-8", charset);
-
-  // Escaped characters in name.
-  base::string16 folder_name;
-  bool is_toolbar_folder;
-  base::Time folder_add_date;
-  result = internal::ParseFolderNameFromLine(
-      "<DT><H3 ADD_DATE=\"1207558707\" >&lt; &gt;"
-      " &amp; &quot; &#39; \\ /</H3>",
-      charset, &folder_name, &is_toolbar_folder, &folder_add_date);
-  EXPECT_TRUE(result);
-  EXPECT_EQ(ASCIIToUTF16("< > & \" ' \\ /"), folder_name);
-  EXPECT_FALSE(is_toolbar_folder);
-  EXPECT_TRUE(base::Time::FromTimeT(1207558707) == folder_add_date);
-
-  // Empty name and toolbar folder attribute.
-  result = internal::ParseFolderNameFromLine(
-      "<DT><H3 PERSONAL_TOOLBAR_FOLDER=\"true\"></H3>",
-      charset, &folder_name, &is_toolbar_folder, &folder_add_date);
-  EXPECT_TRUE(result);
-  EXPECT_EQ(base::string16(), folder_name);
-  EXPECT_TRUE(is_toolbar_folder);
-
-  // Unicode characters in title and shortcut.
-  base::string16 title;
-  GURL url, favicon;
-  base::string16 shortcut;
-  base::string16 post_data;
-  base::Time add_date;
-  result = internal::ParseBookmarkFromLine(
-      "<DT><A HREF=\"http://chinese.site.cn/path?query=1#ref\" "
-      "SHORTCUTURL=\"\xE4\xB8\xAD\">\xE4\xB8\xAD\xE6\x96\x87</A>",
-      charset, &title, &url, &favicon, &shortcut, &add_date, &post_data);
-  EXPECT_TRUE(result);
-  EXPECT_EQ(L"\x4E2D\x6587", UTF16ToWide(title));
-  EXPECT_EQ("http://chinese.site.cn/path?query=1#ref", url.spec());
-  EXPECT_EQ(L"\x4E2D", UTF16ToWide(shortcut));
-  EXPECT_EQ(base::string16(), post_data);
-  EXPECT_TRUE(base::Time() == add_date);
-
-  // No shortcut, and url contains %22 ('"' character).
-  result = internal::ParseBookmarkFromLine(
-      "<DT><A HREF=\"http://domain.com/?q=%22<>%22\">name</A>",
-      charset, &title, &url, &favicon, &shortcut, &add_date, &post_data);
-  EXPECT_TRUE(result);
-  EXPECT_EQ(ASCIIToUTF16("name"), title);
-  EXPECT_EQ("http://domain.com/?q=%22%3C%3E%22", url.spec());
-  EXPECT_EQ(base::string16(), shortcut);
-  EXPECT_EQ(base::string16(), post_data);
-  EXPECT_TRUE(base::Time() == add_date);
-
-  result = internal::ParseBookmarkFromLine(
-      "<DT><A HREF=\"http://domain.com/?g=&quot;\"\">name</A>",
-      charset, &title, &url, &favicon, &shortcut, &add_date, &post_data);
-  EXPECT_TRUE(result);
-  EXPECT_EQ(ASCIIToUTF16("name"), title);
-  EXPECT_EQ("http://domain.com/?g=%22", url.spec());
-  EXPECT_EQ(base::string16(), shortcut);
-  EXPECT_EQ(base::string16(), post_data);
-  EXPECT_TRUE(base::Time() == add_date);
-
-  // Creation date.
-  result = internal::ParseBookmarkFromLine(
-      "<DT><A HREF=\"http://site/\" ADD_DATE=\"1121301154\">name</A>",
-      charset, &title, &url, &favicon, &shortcut, &add_date, &post_data);
-  EXPECT_TRUE(result);
-  EXPECT_EQ(ASCIIToUTF16("name"), title);
-  EXPECT_EQ(GURL("http://site/"), url);
-  EXPECT_EQ(base::string16(), shortcut);
-  EXPECT_EQ(base::string16(), post_data);
-  EXPECT_TRUE(base::Time::FromTimeT(1121301154) == add_date);
-
-  // Post-data
-  result = internal::ParseBookmarkFromLine(
-      "<DT><A HREF=\"http://localhost:8080/test/hello.html\" ADD_DATE=\""
-      "1212447159\" LAST_VISIT=\"1212447251\" LAST_MODIFIED=\"1212447248\""
-      "SHORTCUTURL=\"post\" ICON=\"data:\" POST_DATA=\"lname%3D%25s\""
-      "LAST_CHARSET=\"UTF-8\" ID=\"rdf:#$weKaR3\">Test Post keyword</A>",
-      charset, &title, &url, &favicon, &shortcut, &add_date, &post_data);
-  EXPECT_TRUE(result);
-  EXPECT_EQ(ASCIIToUTF16("Test Post keyword"), title);
-  EXPECT_EQ("http://localhost:8080/test/hello.html", url.spec());
-  EXPECT_EQ(ASCIIToUTF16("post"), shortcut);
-  EXPECT_EQ(ASCIIToUTF16("lname%3D%25s"), post_data);
-  EXPECT_TRUE(base::Time::FromTimeT(1212447159) == add_date);
-
-  // Invalid case.
-  result = internal::ParseBookmarkFromLine(
-      "<DT><A HREF=\"http://domain.com/?q=%22",
-      charset, &title, &url, &favicon, &shortcut, &add_date, &post_data);
-  EXPECT_FALSE(result);
-  EXPECT_EQ(base::string16(), title);
-  EXPECT_EQ("", url.spec());
-  EXPECT_EQ(base::string16(), shortcut);
-  EXPECT_EQ(base::string16(), post_data);
-  EXPECT_TRUE(base::Time() == add_date);
-
-  // Epiphany format.
-  result = internal::ParseMinimumBookmarkFromLine(
-      "<dt><a href=\"http://www.google.com/\">Google</a></dt>",
-      charset, &title, &url);
-  EXPECT_TRUE(result);
-  EXPECT_EQ(ASCIIToUTF16("Google"), title);
-  EXPECT_EQ("http://www.google.com/", url.spec());
-}
-
-namespace {
-
-void ExpectFirstFirefox2Bookmark(const ImportedBookmarkEntry& entry) {
-  EXPECT_EQ(ASCIIToUTF16("Empty"), entry.title);
-  EXPECT_TRUE(entry.is_folder);
-  EXPECT_EQ(base::Time::FromTimeT(1295938143), entry.creation_time);
-  EXPECT_EQ(1U, entry.path.size());
-  if (entry.path.size() == 1)
-    EXPECT_EQ(ASCIIToUTF16("Empty's Parent"), entry.path.front());
-}
-
-void ExpectSecondFirefox2Bookmark(const ImportedBookmarkEntry& entry) {
-  EXPECT_EQ(ASCIIToUTF16("[Tamura Yukari.com]"), entry.title);
-  EXPECT_FALSE(entry.is_folder);
-  EXPECT_EQ(base::Time::FromTimeT(1234567890), entry.creation_time);
-  EXPECT_EQ(1U, entry.path.size());
-  if (entry.path.size() == 1)
-    EXPECT_EQ(ASCIIToUTF16("Not Empty"), entry.path.front());
-  EXPECT_EQ("http://www.tamurayukari.com/", entry.url.spec());
-}
-
-void ExpectThirdFirefox2Bookmark(const ImportedBookmarkEntry& entry) {
-  EXPECT_EQ(ASCIIToUTF16("Google"), entry.title);
-  EXPECT_FALSE(entry.is_folder);
-  EXPECT_EQ(base::Time::FromTimeT(0000000000), entry.creation_time);
-  EXPECT_EQ(1U, entry.path.size());
-  if (entry.path.size() == 1)
-    EXPECT_EQ(ASCIIToUTF16("Not Empty But Default"), entry.path.front());
-  EXPECT_EQ("http://www.google.com/", entry.url.spec());
-}
-
-void ExpectFirstEpiphanyBookmark(const ImportedBookmarkEntry& entry) {
-  EXPECT_EQ(ASCIIToUTF16("[Tamura Yukari.com]"), entry.title);
-  EXPECT_EQ("http://www.tamurayukari.com/", entry.url.spec());
-  EXPECT_EQ(0U, entry.path.size());
-}
-
-void ExpectSecondEpiphanyBookmark(const ImportedBookmarkEntry& entry) {
-  EXPECT_EQ(ASCIIToUTF16("Google"), entry.title);
-  EXPECT_EQ("http://www.google.com/", entry.url.spec());
-  EXPECT_EQ(0U, entry.path.size());
-}
-
-}  // namespace
-
-TEST(BookmarkHTMLReaderTest, Firefox2BookmarkFileImport) {
-  base::FilePath path;
-  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
-  path = path.AppendASCII("bookmark_html_reader");
-  path = path.AppendASCII("firefox2.html");
-
-  std::vector<ImportedBookmarkEntry> bookmarks;
-  ImportBookmarksFile(base::Callback<bool(void)>(),
-                      base::Callback<bool(const GURL&)>(),
-                      path, &bookmarks, NULL);
-
-  ASSERT_EQ(3U, bookmarks.size());
-  ExpectFirstFirefox2Bookmark(bookmarks[0]);
-  ExpectSecondFirefox2Bookmark(bookmarks[1]);
-  ExpectThirdFirefox2Bookmark(bookmarks[2]);
-}
-
-TEST(BookmarkHTMLReaderTest, EpiphanyBookmarkFileImport) {
-  base::FilePath path;
-  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
-  path = path.AppendASCII("bookmark_html_reader");
-  path = path.AppendASCII("epiphany.html");
-
-  std::vector<ImportedBookmarkEntry> bookmarks;
-  ImportBookmarksFile(base::Callback<bool(void)>(),
-                      base::Callback<bool(const GURL&)>(),
-                      path, &bookmarks, NULL);
-
-  ASSERT_EQ(2U, bookmarks.size());
-  ExpectFirstEpiphanyBookmark(bookmarks[0]);
-  ExpectSecondEpiphanyBookmark(bookmarks[1]);
-}
-
-namespace {
-
-class CancelAfterFifteenCalls {
-  int count;
- public:
-  CancelAfterFifteenCalls() : count(0) { }
-  bool ShouldCancel() {
-    return ++count > 16;
-  }
-};
-
-}  // namespace
-
-TEST(BookmarkHTMLReaderTest, CancellationCallback) {
-  base::FilePath path;
-  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
-  path = path.AppendASCII("bookmark_html_reader");
-  // Use a file for testing that has multiple bookmarks.
-  path = path.AppendASCII("firefox2.html");
-
-  std::vector<ImportedBookmarkEntry> bookmarks;
-  CancelAfterFifteenCalls cancel_fifteen;
-  ImportBookmarksFile(base::Bind(&CancelAfterFifteenCalls::ShouldCancel,
-                                 base::Unretained(&cancel_fifteen)),
-                      base::Callback<bool(const GURL&)>(),
-                      path, &bookmarks, NULL);
-
-  // The cancellation callback is checked before each line is read, so fifteen
-  // lines are imported. The first fifteen lines of firefox2.html include only
-  // one bookmark.
-  ASSERT_EQ(1U, bookmarks.size());
-  ExpectFirstFirefox2Bookmark(bookmarks[0]);
-}
-
-namespace {
-
-bool IsURLValid(const GURL& url) {
-  // No offense to whomever owns this domain...
-  return !url.DomainIs("tamurayukari.com");
-}
-
-}  // namespace
-
-TEST(BookmarkHTMLReaderTest, ValidURLCallback) {
-  base::FilePath path;
-  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
-  path = path.AppendASCII("bookmark_html_reader");
-  // Use a file for testing that has multiple bookmarks.
-  path = path.AppendASCII("firefox2.html");
-
-  std::vector<ImportedBookmarkEntry> bookmarks;
-  ImportBookmarksFile(base::Callback<bool(void)>(),
-                      base::Bind(&IsURLValid),
-                      path, &bookmarks, NULL);
-
-  ASSERT_EQ(2U, bookmarks.size());
-  ExpectFirstFirefox2Bookmark(bookmarks[0]);
-  ExpectThirdFirefox2Bookmark(bookmarks[1]);
-}
-
-}  // namespace bookmark_html_reader
diff --git a/chrome/browser/importer/bookmarks_file_importer.cc b/chrome/browser/importer/bookmarks_file_importer.cc
deleted file mode 100644
index 3a1c871..0000000
--- a/chrome/browser/importer/bookmarks_file_importer.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/bookmarks_file_importer.h"
-
-#include "base/bind.h"
-#include "chrome/browser/importer/bookmark_html_reader.h"
-#include "chrome/browser/importer/firefox_importer_utils.h"
-#include "chrome/browser/importer/importer_bridge.h"
-#include "chrome/common/importer/imported_bookmark_entry.h"
-#include "chrome/common/importer/imported_favicon_usage.h"
-#include "chrome/common/importer/importer_data_types.h"
-#include "grit/generated_resources.h"
-
-namespace {
-
-bool IsImporterCancelled(BookmarksFileImporter* importer) {
-  return importer->cancelled();
-}
-
-}  // namespace
-
-BookmarksFileImporter::BookmarksFileImporter() {}
-
-BookmarksFileImporter::~BookmarksFileImporter() {}
-
-void BookmarksFileImporter::StartImport(
-    const importer::SourceProfile& source_profile,
-    uint16 items,
-    ImporterBridge* bridge) {
-  // The only thing this importer can import is a bookmarks file, aka
-  // "favorites".
-  DCHECK_EQ(importer::FAVORITES, items);
-
-  bridge->NotifyStarted();
-  bridge->NotifyItemStarted(importer::FAVORITES);
-
-  std::vector<ImportedBookmarkEntry> bookmarks;
-  std::vector<ImportedFaviconUsage> favicons;
-
-  bookmark_html_reader::ImportBookmarksFile(
-      base::Bind(IsImporterCancelled, base::Unretained(this)),
-      base::Bind(CanImportURL),
-      source_profile.source_path,
-      &bookmarks,
-      &favicons);
-
-  if (!bookmarks.empty() && !cancelled()) {
-    base::string16 first_folder_name =
-        bridge->GetLocalizedString(IDS_BOOKMARK_GROUP);
-    bridge->AddBookmarks(bookmarks, first_folder_name);
-  }
-  if (!favicons.empty())
-    bridge->SetFavicons(favicons);
-
-  bridge->NotifyItemEnded(importer::FAVORITES);
-  bridge->NotifyEnded();
-}
diff --git a/chrome/browser/importer/bookmarks_file_importer.h b/chrome/browser/importer/bookmarks_file_importer.h
deleted file mode 100644
index 46156d3..0000000
--- a/chrome/browser/importer/bookmarks_file_importer.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_BOOKMARKS_FILE_IMPORTER_H_
-#define CHROME_BROWSER_IMPORTER_BOOKMARKS_FILE_IMPORTER_H_
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "chrome/browser/importer/importer.h"
-
-// Importer for bookmarks files.
-class BookmarksFileImporter : public Importer {
- public:
-  BookmarksFileImporter();
-
-  virtual void StartImport(const importer::SourceProfile& source_profile,
-                           uint16 items,
-                           ImporterBridge* bridge) OVERRIDE;
-
- private:
-  virtual ~BookmarksFileImporter();
-
-  DISALLOW_COPY_AND_ASSIGN(BookmarksFileImporter);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_BOOKMARKS_FILE_IMPORTER_H_
diff --git a/chrome/browser/importer/external_process_importer_bridge.cc b/chrome/browser/importer/external_process_importer_bridge.cc
deleted file mode 100644
index 23cc3bc..0000000
--- a/chrome/browser/importer/external_process_importer_bridge.cc
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/external_process_importer_bridge.h"
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/task_runner.h"
-#include "base/values.h"
-#include "chrome/common/importer/imported_bookmark_entry.h"
-#include "chrome/common/importer/imported_favicon_usage.h"
-#include "chrome/common/importer/importer_data_types.h"
-#include "chrome/common/importer/profile_import_process_messages.h"
-#include "content/public/common/password_form.h"
-#include "ipc/ipc_sender.h"
-
-#if defined(OS_WIN)
-#include "components/webdata/encryptor/ie7_password.h"
-#endif
-
-namespace {
-
-// Rather than sending all import items over IPC at once we chunk them into
-// separate requests.  This avoids the case of a large import causing
-// oversized IPC messages.
-const int kNumBookmarksToSend = 100;
-const int kNumHistoryRowsToSend = 100;
-const int kNumFaviconsToSend = 100;
-
-}
-
-ExternalProcessImporterBridge::ExternalProcessImporterBridge(
-    const DictionaryValue& localized_strings,
-    IPC::Sender* sender,
-    base::TaskRunner* task_runner)
-    : sender_(sender),
-      task_runner_(task_runner) {
-  // Bridge needs to make its own copy because OS 10.6 autoreleases the
-  // localized_strings value that is passed in (see http://crbug.com/46003 ).
-  localized_strings_.reset(localized_strings.DeepCopy());
-}
-
-void ExternalProcessImporterBridge::AddBookmarks(
-    const std::vector<ImportedBookmarkEntry>& bookmarks,
-    const string16& first_folder_name) {
-  Send(new ProfileImportProcessHostMsg_NotifyBookmarksImportStart(
-      first_folder_name, bookmarks.size()));
-
-  // |bookmarks_left| is required for the checks below as Windows has a
-  // Debug bounds-check which prevents pushing an iterator beyond its end()
-  // (i.e., |it + 2 < s.end()| crashes in debug mode if |i + 1 == s.end()|).
-  int bookmarks_left = bookmarks.end() - bookmarks.begin();
-  for (std::vector<ImportedBookmarkEntry>::const_iterator it =
-           bookmarks.begin(); it < bookmarks.end();) {
-    std::vector<ImportedBookmarkEntry> bookmark_group;
-    std::vector<ImportedBookmarkEntry>::const_iterator end_group =
-        it + std::min(bookmarks_left, kNumBookmarksToSend);
-    bookmark_group.assign(it, end_group);
-
-    Send(new ProfileImportProcessHostMsg_NotifyBookmarksImportGroup(
-        bookmark_group));
-    bookmarks_left -= end_group - it;
-    it = end_group;
-  }
-  DCHECK_EQ(0, bookmarks_left);
-}
-
-void ExternalProcessImporterBridge::AddHomePage(const GURL& home_page) {
-  NOTIMPLEMENTED();
-}
-
-#if defined(OS_WIN)
-void ExternalProcessImporterBridge::AddIE7PasswordInfo(
-    const IE7PasswordInfo& password_info) {
-  NOTIMPLEMENTED();
-}
-#endif
-
-void ExternalProcessImporterBridge::SetFavicons(
-    const std::vector<ImportedFaviconUsage>& favicons) {
-  Send(new ProfileImportProcessHostMsg_NotifyFaviconsImportStart(
-    favicons.size()));
-
-  // |favicons_left| is required for the checks below as Windows has a
-  // Debug bounds-check which prevents pushing an iterator beyond its end()
-  // (i.e., |it + 2 < s.end()| crashes in debug mode if |i + 1 == s.end()|).
-  int favicons_left = favicons.end() - favicons.begin();
-  for (std::vector<ImportedFaviconUsage>::const_iterator it =
-           favicons.begin(); it < favicons.end();) {
-    std::vector<ImportedFaviconUsage> favicons_group;
-    std::vector<ImportedFaviconUsage>::const_iterator end_group =
-        it + std::min(favicons_left, kNumFaviconsToSend);
-    favicons_group.assign(it, end_group);
-
-    Send(new ProfileImportProcessHostMsg_NotifyFaviconsImportGroup(
-        favicons_group));
-    favicons_left -= end_group - it;
-    it = end_group;
-  }
-  DCHECK_EQ(0, favicons_left);
-}
-
-void ExternalProcessImporterBridge::SetHistoryItems(
-    const std::vector<ImporterURLRow>& rows,
-    history::VisitSource visit_source) {
-  Send(new ProfileImportProcessHostMsg_NotifyHistoryImportStart(rows.size()));
-
-  // |rows_left| is required for the checks below as Windows has a
-  // Debug bounds-check which prevents pushing an iterator beyond its end()
-  // (i.e., |it + 2 < s.end()| crashes in debug mode if |i + 1 == s.end()|).
-  int rows_left = rows.end() - rows.begin();
-  for (std::vector<ImporterURLRow>::const_iterator it = rows.begin();
-       it < rows.end();) {
-    std::vector<ImporterURLRow> row_group;
-    std::vector<ImporterURLRow>::const_iterator end_group =
-        it + std::min(rows_left, kNumHistoryRowsToSend);
-    row_group.assign(it, end_group);
-
-    Send(new ProfileImportProcessHostMsg_NotifyHistoryImportGroup(
-        row_group, visit_source));
-    rows_left -= end_group - it;
-    it = end_group;
-  }
-  DCHECK_EQ(0, rows_left);
-}
-
-void ExternalProcessImporterBridge::SetKeywords(
-    const std::vector<importer::URLKeywordInfo>& url_keywords,
-    bool unique_on_host_and_path) {
-  Send(new ProfileImportProcessHostMsg_NotifyKeywordsReady(
-      url_keywords, unique_on_host_and_path));
-}
-
-void ExternalProcessImporterBridge::SetFirefoxSearchEnginesXMLData(
-    const std::vector<std::string>& search_engine_data) {
-  Send(new ProfileImportProcessHostMsg_NotifyFirefoxSearchEngData(
-      search_engine_data));
-}
-
-void ExternalProcessImporterBridge::SetPasswordForm(
-    const content::PasswordForm& form) {
-  Send(new ProfileImportProcessHostMsg_NotifyPasswordFormReady(form));
-}
-
-void ExternalProcessImporterBridge::NotifyStarted() {
-  Send(new ProfileImportProcessHostMsg_Import_Started());
-}
-
-void ExternalProcessImporterBridge::NotifyItemStarted(
-    importer::ImportItem item) {
-  Send(new ProfileImportProcessHostMsg_ImportItem_Started(item));
-}
-
-void ExternalProcessImporterBridge::NotifyItemEnded(importer::ImportItem item) {
-  Send(new ProfileImportProcessHostMsg_ImportItem_Finished(item));
-}
-
-void ExternalProcessImporterBridge::NotifyEnded() {
-  // The internal process detects import end when all items have been received.
-}
-
-string16 ExternalProcessImporterBridge::GetLocalizedString(int message_id) {
-  string16 message;
-  localized_strings_->GetString(base::IntToString(message_id), &message);
-  return message;
-}
-
-ExternalProcessImporterBridge::~ExternalProcessImporterBridge() {}
-
-void ExternalProcessImporterBridge::Send(IPC::Message* message) {
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&ExternalProcessImporterBridge::SendInternal,
-                 this, message));
-}
-
-void ExternalProcessImporterBridge::SendInternal(IPC::Message* message) {
-  DCHECK(task_runner_->RunsTasksOnCurrentThread());
-  sender_->Send(message);
-}
diff --git a/chrome/browser/importer/external_process_importer_bridge.h b/chrome/browser/importer/external_process_importer_bridge.h
deleted file mode 100644
index b1cb519..0000000
--- a/chrome/browser/importer/external_process_importer_bridge.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_EXTERNAL_PROCESS_IMPORTER_BRIDGE_H_
-#define CHROME_BROWSER_IMPORTER_EXTERNAL_PROCESS_IMPORTER_BRIDGE_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/importer/importer_bridge.h"
-
-class GURL;
-struct ImportedBookmarkEntry;
-
-namespace base {
-class DictionaryValue;
-class TaskRunner;
-}
-
-namespace importer {
-struct URLKeywordInfo;
-}
-
-namespace IPC {
-class Message;
-class Sender;
-}
-
-// When the importer is run in an external process, the bridge is effectively
-// split in half by the IPC infrastructure.  The external bridge receives data
-// and notifications from the importer, and sends it across IPC.  The
-// internal bridge gathers the data from the IPC host and writes it to the
-// profile.
-class ExternalProcessImporterBridge : public ImporterBridge {
- public:
-  ExternalProcessImporterBridge(
-      const base::DictionaryValue& localized_strings,
-      IPC::Sender* sender,
-      base::TaskRunner* task_runner);
-
-  // Begin ImporterBridge implementation:
-  virtual void AddBookmarks(
-      const std::vector<ImportedBookmarkEntry>& bookmarks,
-      const string16& first_folder_name) OVERRIDE;
-
-  virtual void AddHomePage(const GURL& home_page) OVERRIDE;
-
-#if defined(OS_WIN)
-  virtual void AddIE7PasswordInfo(
-      const IE7PasswordInfo& password_info) OVERRIDE;
-#endif
-
-  virtual void SetFavicons(
-      const std::vector<ImportedFaviconUsage>& favicons) OVERRIDE;
-
-  virtual void SetHistoryItems(const std::vector<ImporterURLRow>& rows,
-                               history::VisitSource visit_source) OVERRIDE;
-
-  virtual void SetKeywords(
-      const std::vector<importer::URLKeywordInfo>& url_keywords,
-      bool unique_on_host_and_path) OVERRIDE;
-
-  virtual void SetFirefoxSearchEnginesXMLData(
-      const std::vector<std::string>& seach_engine_data) OVERRIDE;
-
-  virtual void SetPasswordForm(
-      const content::PasswordForm& form) OVERRIDE;
-
-  virtual void NotifyStarted() OVERRIDE;
-  virtual void NotifyItemStarted(importer::ImportItem item) OVERRIDE;
-  virtual void NotifyItemEnded(importer::ImportItem item) OVERRIDE;
-  virtual void NotifyEnded() OVERRIDE;
-
-  virtual string16 GetLocalizedString(int message_id) OVERRIDE;
-  // End ImporterBridge implementation.
-
- private:
-  virtual ~ExternalProcessImporterBridge();
-
-  void Send(IPC::Message* message);
-  void SendInternal(IPC::Message* message);
-
-  // Holds strings needed by the external importer because the resource
-  // bundle isn't available to the external process.
-  scoped_ptr<base::DictionaryValue> localized_strings_;
-
-  IPC::Sender* sender_;
-  scoped_refptr<base::TaskRunner> task_runner_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExternalProcessImporterBridge);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_EXTERNAL_PROCESS_IMPORTER_BRIDGE_H_
diff --git a/chrome/browser/importer/external_process_importer_client.cc b/chrome/browser/importer/external_process_importer_client.cc
index d90d9a0..7861c9c 100644
--- a/chrome/browser/importer/external_process_importer_client.cc
+++ b/chrome/browser/importer/external_process_importer_client.cc
@@ -8,8 +8,8 @@
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/importer/external_process_importer_host.h"
-#include "chrome/browser/importer/firefox_importer_utils.h"
 #include "chrome/browser/importer/in_process_importer_bridge.h"
+#include "chrome/common/importer/firefox_importer_utils.h"
 #include "chrome/common/importer/imported_bookmark_entry.h"
 #include "chrome/common/importer/profile_import_process_messages.h"
 #include "content/public/browser/browser_thread.h"
@@ -102,6 +102,10 @@
                         OnKeywordsImportReady)
     IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFirefoxSearchEngData,
                         OnFirefoxSearchEngineDataReceived)
+#if defined(OS_WIN)
+    IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyIE7PasswordInfo,
+                        OnIE7PasswordReceived)
+#endif
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
@@ -164,7 +168,7 @@
                        history_rows_group.end());
   if (history_rows_.size() == total_history_rows_count_)
     bridge_->SetHistoryItems(history_rows_,
-                             static_cast<history::VisitSource>(visit_source));
+                             static_cast<importer::VisitSource>(visit_source));
 }
 
 void ExternalProcessImporterClient::OnHomePageImportReady(
@@ -242,6 +246,15 @@
   bridge_->SetFirefoxSearchEnginesXMLData(search_engine_data);
 }
 
+#if defined(OS_WIN)
+void ExternalProcessImporterClient::OnIE7PasswordReceived(
+    const importer::ImporterIE7PasswordInfo& importer_password_info) {
+  if (cancelled_)
+    return;
+  bridge_->AddIE7PasswordInfo(importer_password_info);
+}
+#endif
+
 ExternalProcessImporterClient::~ExternalProcessImporterClient() {}
 
 void ExternalProcessImporterClient::Cleanup() {
diff --git a/chrome/browser/importer/external_process_importer_client.h b/chrome/browser/importer/external_process_importer_client.h
index 5af485e..7461fd0 100644
--- a/chrome/browser/importer/external_process_importer_client.h
+++ b/chrome/browser/importer/external_process_importer_client.h
@@ -29,6 +29,9 @@
 }
 
 namespace importer {
+#if defined(OS_WIN)
+struct ImporterIE7PasswordInfo;
+#endif
 struct URLKeywordInfo;
 }
 
@@ -75,6 +78,10 @@
       bool unique_on_host_and_path);
   void OnFirefoxSearchEngineDataReceived(
       const std::vector<std::string> search_engine_data);
+#if defined(OS_WIN)
+  void OnIE7PasswordReceived(
+        const importer::ImporterIE7PasswordInfo& importer_password_info);
+#endif
 
  protected:
   virtual ~ExternalProcessImporterClient();
diff --git a/chrome/browser/importer/external_process_importer_host.cc b/chrome/browser/importer/external_process_importer_host.cc
index a461aac..2615d00 100644
--- a/chrome/browser/importer/external_process_importer_host.cc
+++ b/chrome/browser/importer/external_process_importer_host.cc
@@ -5,18 +5,16 @@
 #include "chrome/browser/importer/external_process_importer_host.h"
 
 #include "base/bind.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/importer/external_process_importer_client.h"
 #include "chrome/browser/importer/firefox_profile_lock.h"
-#include "chrome/browser/importer/importer.h"
-#include "chrome/browser/importer/importer_creator.h"
 #include "chrome/browser/importer/importer_lock_dialog.h"
 #include "chrome/browser/importer/importer_progress_observer.h"
 #include "chrome/browser/importer/in_process_importer_bridge.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_source.h"
 
diff --git a/chrome/browser/importer/firefox3_importer.cc b/chrome/browser/importer/firefox3_importer.cc
deleted file mode 100644
index c3ec58d..0000000
--- a/chrome/browser/importer/firefox3_importer.cc
+++ /dev/null
@@ -1,588 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/firefox3_importer.h"
-
-#include <set>
-
-#include "base/file_util.h"
-#include "base/files/file_enumerator.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
-#include "base/stl_util.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/favicon/favicon_util.h"
-#include "chrome/browser/importer/bookmark_html_reader.h"
-#include "chrome/browser/importer/firefox_importer_utils.h"
-#include "chrome/browser/importer/importer_bridge.h"
-#include "chrome/browser/importer/nss_decryptor.h"
-#include "chrome/common/importer/imported_bookmark_entry.h"
-#include "chrome/common/importer/imported_favicon_usage.h"
-#include "chrome/common/importer/importer_url_row.h"
-#include "chrome/common/time_format.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/common/password_form.h"
-#include "grit/generated_resources.h"
-#include "sql/connection.h"
-#include "sql/statement.h"
-#include "url/gurl.h"
-
-using content::BrowserThread;
-
-namespace {
-
-// Original definition is in http://mxr.mozilla.org/firefox/source/toolkit/
-//  components/places/public/nsINavBookmarksService.idl
-enum BookmarkItemType {
-  TYPE_BOOKMARK = 1,
-  TYPE_FOLDER = 2,
-  TYPE_SEPARATOR = 3,
-  TYPE_DYNAMIC_CONTAINER = 4
-};
-
-// Loads the default bookmarks in the Firefox installed at |app_path|,
-// and stores their locations in |urls|.
-void LoadDefaultBookmarks(const base::FilePath& app_path,
-                          std::set<GURL>* urls) {
-  base::FilePath file = app_path.AppendASCII("defaults")
-      .AppendASCII("profile")
-      .AppendASCII("bookmarks.html");
-  urls->clear();
-
-  std::vector<ImportedBookmarkEntry> bookmarks;
-  bookmark_html_reader::ImportBookmarksFile(base::Callback<bool(void)>(),
-                                            base::Callback<bool(const GURL&)>(),
-                                            file,
-                                            &bookmarks,
-                                            NULL);
-  for (size_t i = 0; i < bookmarks.size(); ++i)
-    urls->insert(bookmarks[i].url);
-}
-
-}  // namespace
-
-struct Firefox3Importer::BookmarkItem {
-  int parent;
-  int id;
-  GURL url;
-  string16 title;
-  BookmarkItemType type;
-  std::string keyword;
-  base::Time date_added;
-  int64 favicon;
-  bool empty_folder;
-};
-
-Firefox3Importer::Firefox3Importer() {
-}
-
-Firefox3Importer::~Firefox3Importer() {
-}
-
-void Firefox3Importer::StartImport(
-    const importer::SourceProfile& source_profile,
-    uint16 items,
-    ImporterBridge* bridge) {
-  bridge_ = bridge;
-  source_path_ = source_profile.source_path;
-  app_path_ = source_profile.app_path;
-
-#if defined(OS_POSIX)
-  locale_ = source_profile.locale;
-#endif
-
-  // The order here is important!
-  bridge_->NotifyStarted();
-  if ((items & importer::HOME_PAGE) && !cancelled())
-    ImportHomepage();  // Doesn't have a UI item.
-
-  // Note history should be imported before bookmarks because bookmark import
-  // will also import favicons and we store favicon for a URL only if the URL
-  // exist in history or bookmarks.
-  if ((items & importer::HISTORY) && !cancelled()) {
-    bridge_->NotifyItemStarted(importer::HISTORY);
-    ImportHistory();
-    bridge_->NotifyItemEnded(importer::HISTORY);
-  }
-
-  if ((items & importer::FAVORITES) && !cancelled()) {
-    bridge_->NotifyItemStarted(importer::FAVORITES);
-    ImportBookmarks();
-    bridge_->NotifyItemEnded(importer::FAVORITES);
-  }
-  if ((items & importer::SEARCH_ENGINES) && !cancelled()) {
-    bridge_->NotifyItemStarted(importer::SEARCH_ENGINES);
-    ImportSearchEngines();
-    bridge_->NotifyItemEnded(importer::SEARCH_ENGINES);
-  }
-  if ((items & importer::PASSWORDS) && !cancelled()) {
-    bridge_->NotifyItemStarted(importer::PASSWORDS);
-    ImportPasswords();
-    bridge_->NotifyItemEnded(importer::PASSWORDS);
-  }
-  bridge_->NotifyEnded();
-}
-
-void Firefox3Importer::ImportHistory() {
-  base::FilePath file = source_path_.AppendASCII("places.sqlite");
-  if (!file_util::PathExists(file))
-    return;
-
-  sql::Connection db;
-  if (!db.Open(file))
-    return;
-
-  // |visit_type| represent the transition type of URLs (typed, click,
-  // redirect, bookmark, etc.) We eliminate some URLs like sub-frames and
-  // redirects, since we don't want them to appear in history.
-  // Firefox transition types are defined in:
-  //   toolkit/components/places/public/nsINavHistoryService.idl
-  const char* query = "SELECT h.url, h.title, h.visit_count, "
-                      "h.hidden, h.typed, v.visit_date "
-                      "FROM moz_places h JOIN moz_historyvisits v "
-                      "ON h.id = v.place_id "
-                      "WHERE v.visit_type <= 3";
-
-  sql::Statement s(db.GetUniqueStatement(query));
-
-  std::vector<ImporterURLRow> rows;
-  while (s.Step() && !cancelled()) {
-    GURL url(s.ColumnString(0));
-
-    // Filter out unwanted URLs.
-    if (!CanImportURL(url))
-      continue;
-
-    ImporterURLRow row(url);
-    row.title = s.ColumnString16(1);
-    row.visit_count = s.ColumnInt(2);
-    row.hidden = s.ColumnInt(3) == 1;
-    row.typed_count = s.ColumnInt(4);
-    row.last_visit = base::Time::FromTimeT(s.ColumnInt64(5)/1000000);
-
-    rows.push_back(row);
-  }
-
-  if (!rows.empty() && !cancelled())
-    bridge_->SetHistoryItems(rows, history::SOURCE_FIREFOX_IMPORTED);
-}
-
-void Firefox3Importer::ImportBookmarks() {
-  base::FilePath file = source_path_.AppendASCII("places.sqlite");
-  if (!file_util::PathExists(file))
-    return;
-
-  sql::Connection db;
-  if (!db.Open(file))
-    return;
-
-  // Get the bookmark folders that we are interested in.
-  int toolbar_folder_id = -1;
-  int menu_folder_id = -1;
-  int unsorted_folder_id = -1;
-  LoadRootNodeID(&db, &toolbar_folder_id, &menu_folder_id, &unsorted_folder_id);
-
-  // Load livemark IDs.
-  std::set<int> livemark_id;
-  LoadLivemarkIDs(&db, &livemark_id);
-
-  // Load the default bookmarks.
-  std::set<GURL> default_urls;
-  LoadDefaultBookmarks(app_path_, &default_urls);
-
-  BookmarkList list;
-  GetTopBookmarkFolder(&db, toolbar_folder_id, &list);
-  GetTopBookmarkFolder(&db, menu_folder_id, &list);
-  GetTopBookmarkFolder(&db, unsorted_folder_id, &list);
-  size_t count = list.size();
-  for (size_t i = 0; i < count; ++i)
-    GetWholeBookmarkFolder(&db, &list, i, NULL);
-
-  std::vector<ImportedBookmarkEntry> bookmarks;
-  std::vector<importer::URLKeywordInfo> url_keywords;
-  FaviconMap favicon_map;
-
-  // TODO(jcampan): http://b/issue?id=1196285 we do not support POST based
-  //                keywords yet.  We won't include them in the list.
-  std::set<int> post_keyword_ids;
-  const char* query = "SELECT b.id FROM moz_bookmarks b "
-      "INNER JOIN moz_items_annos ia ON ia.item_id = b.id "
-      "INNER JOIN moz_anno_attributes aa ON ia.anno_attribute_id = aa.id "
-      "WHERE aa.name = 'bookmarkProperties/POSTData'";
-  sql::Statement s(db.GetUniqueStatement(query));
-
-  if (!s.is_valid())
-    return;
-
-  while (s.Step() && !cancelled())
-    post_keyword_ids.insert(s.ColumnInt(0));
-
-  for (size_t i = 0; i < list.size(); ++i) {
-    BookmarkItem* item = list[i];
-
-    if (item->type == TYPE_FOLDER) {
-      // Folders are added implicitly on adding children, so we only explicitly
-      // add empty folders.
-      if (!item->empty_folder)
-        continue;
-    } else if (item->type == TYPE_BOOKMARK) {
-      // Import only valid bookmarks
-      if (!CanImportURL(item->url))
-        continue;
-    } else {
-      continue;
-    }
-
-    // Skip the default bookmarks and unwanted URLs.
-    if (default_urls.find(item->url) != default_urls.end() ||
-        post_keyword_ids.find(item->id) != post_keyword_ids.end())
-      continue;
-
-    // Find the bookmark path by tracing their links to parent folders.
-    std::vector<string16> path;
-    BookmarkItem* child = item;
-    bool found_path = false;
-    bool is_in_toolbar = false;
-    while (child->parent >= 0) {
-      BookmarkItem* parent = list[child->parent];
-      if (livemark_id.find(parent->id) != livemark_id.end()) {
-        // Don't import live bookmarks.
-        break;
-      }
-
-      if (parent->id != menu_folder_id) {
-        // To avoid excessive nesting, omit the name for the bookmarks menu
-        // folder.
-        path.insert(path.begin(), parent->title);
-      }
-
-      if (parent->id == toolbar_folder_id)
-        is_in_toolbar = true;
-
-      if (parent->id == toolbar_folder_id ||
-          parent->id == menu_folder_id ||
-          parent->id == unsorted_folder_id) {
-        // We've reached a root node, hooray!
-        found_path = true;
-        break;
-      }
-
-      child = parent;
-    }
-
-    if (!found_path)
-      continue;
-
-    ImportedBookmarkEntry entry;
-    entry.creation_time = item->date_added;
-    entry.title = item->title;
-    entry.url = item->url;
-    entry.path = path;
-    entry.in_toolbar = is_in_toolbar;
-    entry.is_folder = item->type == TYPE_FOLDER;
-
-    bookmarks.push_back(entry);
-
-    if (item->type == TYPE_BOOKMARK) {
-      if (item->favicon)
-        favicon_map[item->favicon].insert(item->url);
-
-      // This bookmark has a keyword, we should import it.
-      if (!item->keyword.empty() && item->url.is_valid()) {
-        importer::URLKeywordInfo url_keyword_info;
-        url_keyword_info.url = item->url;
-        url_keyword_info.keyword.assign(UTF8ToUTF16(item->keyword));
-        url_keyword_info.display_name = item->title;
-        url_keywords.push_back(url_keyword_info);
-      }
-    }
-  }
-
-  STLDeleteElements(&list);
-
-  // Write into profile.
-  if (!bookmarks.empty() && !cancelled()) {
-    const string16& first_folder_name =
-        bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_FIREFOX);
-    bridge_->AddBookmarks(bookmarks, first_folder_name);
-  }
-  if (!url_keywords.empty() && !cancelled()) {
-    bridge_->SetKeywords(url_keywords, false);
-  }
-  if (!favicon_map.empty() && !cancelled()) {
-    std::vector<ImportedFaviconUsage> favicons;
-    LoadFavicons(&db, favicon_map, &favicons);
-    bridge_->SetFavicons(favicons);
-  }
-}
-
-void Firefox3Importer::ImportPasswords() {
-  // Initializes NSS3.
-  NSSDecryptor decryptor;
-  if (!decryptor.Init(source_path_, source_path_) &&
-      !decryptor.Init(app_path_, source_path_)) {
-    return;
-  }
-
-  std::vector<content::PasswordForm> forms;
-  base::FilePath source_path = source_path_;
-  base::FilePath file = source_path.AppendASCII("signons.sqlite");
-  if (file_util::PathExists(file)) {
-    // Since Firefox 3.1, passwords are in signons.sqlite db.
-    decryptor.ReadAndParseSignons(file, &forms);
-  } else {
-    // Firefox 3.0 uses signons3.txt to store the passwords.
-    file = source_path.AppendASCII("signons3.txt");
-    if (!file_util::PathExists(file))
-      file = source_path.AppendASCII("signons2.txt");
-
-    std::string content;
-    file_util::ReadFileToString(file, &content);
-    decryptor.ParseSignons(content, &forms);
-  }
-
-  if (!cancelled()) {
-    for (size_t i = 0; i < forms.size(); ++i) {
-      bridge_->SetPasswordForm(forms[i]);
-    }
-  }
-}
-
-void Firefox3Importer::ImportSearchEngines() {
-  std::vector<std::string> search_engine_data;
-  GetSearchEnginesXMLData(&search_engine_data);
-
-  bridge_->SetFirefoxSearchEnginesXMLData(search_engine_data);
-}
-
-void Firefox3Importer::ImportHomepage() {
-  GURL home_page = GetHomepage(source_path_);
-  if (home_page.is_valid() && !IsDefaultHomepage(home_page, app_path_)) {
-    bridge_->AddHomePage(home_page);
-  }
-}
-
-void Firefox3Importer::GetSearchEnginesXMLData(
-    std::vector<std::string>* search_engine_data) {
-  base::FilePath file = source_path_.AppendASCII("search.sqlite");
-  if (!file_util::PathExists(file))
-    return;
-
-  sql::Connection db;
-  if (!db.Open(file))
-    return;
-
-  const char* query = "SELECT engineid FROM engine_data "
-                      "WHERE engineid NOT IN "
-                      "(SELECT engineid FROM engine_data "
-                      "WHERE name='hidden') "
-                      "ORDER BY value ASC";
-
-  sql::Statement s(db.GetUniqueStatement(query));
-  if (!s.is_valid())
-    return;
-
-  base::FilePath app_path = app_path_.AppendASCII("searchplugins");
-  base::FilePath profile_path = source_path_.AppendASCII("searchplugins");
-
-  // Firefox doesn't store a search engine in its sqlite database unless the
-  // user has added a engine. So we get search engines from sqlite db as well
-  // as from the file system.
-  if (s.Step()) {
-    const std::string kAppPrefix("[app]/");
-    const std::string kProfilePrefix("[profile]/");
-    do {
-      base::FilePath file;
-      std::string engine(s.ColumnString(0));
-
-      // The string contains [app]/<name>.xml or [profile]/<name>.xml where
-      // the [app] and [profile] need to be replaced with the actual app or
-      // profile path.
-      size_t index = engine.find(kAppPrefix);
-      if (index != std::string::npos) {
-        // Remove '[app]/'.
-        file = app_path.AppendASCII(engine.substr(index + kAppPrefix.length()));
-      } else if ((index = engine.find(kProfilePrefix)) != std::string::npos) {
-        // Remove '[profile]/'.
-          file = profile_path.AppendASCII(
-              engine.substr(index + kProfilePrefix.length()));
-      } else {
-        // Looks like absolute path to the file.
-        file = base::FilePath::FromUTF8Unsafe(engine);
-      }
-      std::string file_data;
-      file_util::ReadFileToString(file, &file_data);
-      search_engine_data->push_back(file_data);
-    } while (s.Step() && !cancelled());
-  }
-
-#if defined(OS_POSIX)
-  // Ubuntu-flavored Firefox3 supports locale-specific search engines via
-  // locale-named subdirectories. They fall back to en-US.
-  // See http://crbug.com/53899
-  // TODO(jshin): we need to make sure our locale code matches that of
-  // Firefox.
-  DCHECK(!locale_.empty());
-  base::FilePath locale_app_path = app_path.AppendASCII(locale_);
-  base::FilePath default_locale_app_path = app_path.AppendASCII("en-US");
-  if (file_util::DirectoryExists(locale_app_path))
-    app_path = locale_app_path;
-  else if (file_util::DirectoryExists(default_locale_app_path))
-    app_path = default_locale_app_path;
-#endif
-
-  // Get search engine definition from file system.
-  base::FileEnumerator engines(app_path, false, base::FileEnumerator::FILES);
-  for (base::FilePath engine_path = engines.Next();
-       !engine_path.value().empty(); engine_path = engines.Next()) {
-    std::string file_data;
-    file_util::ReadFileToString(file, &file_data);
-    search_engine_data->push_back(file_data);
-  }
-}
-
-void Firefox3Importer::LoadRootNodeID(sql::Connection* db,
-                                      int* toolbar_folder_id,
-                                      int* menu_folder_id,
-                                      int* unsorted_folder_id) {
-  static const char* kToolbarFolderName = "toolbar";
-  static const char* kMenuFolderName = "menu";
-  static const char* kUnsortedFolderName = "unfiled";
-
-  const char* query = "SELECT root_name, folder_id FROM moz_bookmarks_roots";
-  sql::Statement s(db->GetUniqueStatement(query));
-
-  while (s.Step()) {
-    std::string folder = s.ColumnString(0);
-    int id = s.ColumnInt(1);
-    if (folder == kToolbarFolderName)
-      *toolbar_folder_id = id;
-    else if (folder == kMenuFolderName)
-      *menu_folder_id = id;
-    else if (folder == kUnsortedFolderName)
-      *unsorted_folder_id = id;
-  }
-}
-
-void Firefox3Importer::LoadLivemarkIDs(sql::Connection* db,
-                                       std::set<int>* livemark) {
-  static const char* kFeedAnnotation = "livemark/feedURI";
-  livemark->clear();
-
-  const char* query = "SELECT b.item_id "
-                      "FROM moz_anno_attributes a "
-                      "JOIN moz_items_annos b ON a.id = b.anno_attribute_id "
-                      "WHERE a.name = ? ";
-  sql::Statement s(db->GetUniqueStatement(query));
-  s.BindString(0, kFeedAnnotation);
-
-  while (s.Step() && !cancelled())
-    livemark->insert(s.ColumnInt(0));
-}
-
-void Firefox3Importer::GetTopBookmarkFolder(sql::Connection* db,
-                                            int folder_id,
-                                            BookmarkList* list) {
-  const char* query = "SELECT b.title "
-                     "FROM moz_bookmarks b "
-                     "WHERE b.type = 2 AND b.id = ? "
-                     "ORDER BY b.position";
-  sql::Statement s(db->GetUniqueStatement(query));
-  s.BindInt(0, folder_id);
-
-  if (s.Step()) {
-    BookmarkItem* item = new BookmarkItem;
-    item->parent = -1;  // The top level folder has no parent.
-    item->id = folder_id;
-    item->title = s.ColumnString16(0);
-    item->type = TYPE_FOLDER;
-    item->favicon = 0;
-    item->empty_folder = true;
-    list->push_back(item);
-  }
-}
-
-void Firefox3Importer::GetWholeBookmarkFolder(sql::Connection* db,
-                                              BookmarkList* list,
-                                              size_t position,
-                                              bool* empty_folder) {
-  if (position >= list->size()) {
-    NOTREACHED();
-    return;
-  }
-
-  const char* query = "SELECT b.id, h.url, COALESCE(b.title, h.title), "
-         "b.type, k.keyword, b.dateAdded, h.favicon_id "
-         "FROM moz_bookmarks b "
-         "LEFT JOIN moz_places h ON b.fk = h.id "
-         "LEFT JOIN moz_keywords k ON k.id = b.keyword_id "
-         "WHERE b.type IN (1,2) AND b.parent = ? "
-         "ORDER BY b.position";
-  sql::Statement s(db->GetUniqueStatement(query));
-  s.BindInt(0, (*list)[position]->id);
-
-  BookmarkList temp_list;
-  while (s.Step()) {
-    BookmarkItem* item = new BookmarkItem;
-    item->parent = static_cast<int>(position);
-    item->id = s.ColumnInt(0);
-    item->url = GURL(s.ColumnString(1));
-    item->title = s.ColumnString16(2);
-    item->type = static_cast<BookmarkItemType>(s.ColumnInt(3));
-    item->keyword = s.ColumnString(4);
-    item->date_added = base::Time::FromTimeT(s.ColumnInt64(5)/1000000);
-    item->favicon = s.ColumnInt64(6);
-    item->empty_folder = true;
-
-    temp_list.push_back(item);
-    if (empty_folder != NULL)
-      *empty_folder = false;
-  }
-
-  // Appends all items to the list.
-  for (BookmarkList::iterator i = temp_list.begin();
-       i != temp_list.end(); ++i) {
-    list->push_back(*i);
-    // Recursive add bookmarks in sub-folders.
-    if ((*i)->type == TYPE_FOLDER)
-      GetWholeBookmarkFolder(db, list, list->size() - 1, &(*i)->empty_folder);
-  }
-}
-
-void Firefox3Importer::LoadFavicons(
-    sql::Connection* db,
-    const FaviconMap& favicon_map,
-    std::vector<ImportedFaviconUsage>* favicons) {
-  const char* query = "SELECT url, data FROM moz_favicons WHERE id=?";
-  sql::Statement s(db->GetUniqueStatement(query));
-
-  if (!s.is_valid())
-    return;
-
-  for (FaviconMap::const_iterator i = favicon_map.begin();
-       i != favicon_map.end(); ++i) {
-    s.BindInt64(0, i->first);
-    if (s.Step()) {
-      ImportedFaviconUsage usage;
-
-      usage.favicon_url = GURL(s.ColumnString(0));
-      if (!usage.favicon_url.is_valid())
-        continue;  // Don't bother importing favicons with invalid URLs.
-
-      std::vector<unsigned char> data;
-      s.ColumnBlobAsVector(1, &data);
-      if (data.empty())
-        continue;  // Data definitely invalid.
-
-      if (!FaviconUtil::ReencodeFavicon(&data[0], data.size(), &usage.png_data))
-        continue;  // Unable to decode.
-
-      usage.urls = i->second;
-      favicons->push_back(usage);
-    }
-    s.Reset(true);
-  }
-}
diff --git a/chrome/browser/importer/firefox3_importer.h b/chrome/browser/importer/firefox3_importer.h
deleted file mode 100644
index a609f80..0000000
--- a/chrome/browser/importer/firefox3_importer.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_FIREFOX3_IMPORTER_H_
-#define CHROME_BROWSER_IMPORTER_FIREFOX3_IMPORTER_H_
-
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/files/file_path.h"
-#include "chrome/browser/importer/importer.h"
-
-class GURL;
-struct ImportedFaviconUsage;
-
-namespace sql {
-class Connection;
-}
-
-// Importer for Mozilla Firefox 3 and later.
-// Firefox 3 stores its persistent information in a new system called places.
-// http://wiki.mozilla.org/Places
-class Firefox3Importer : public Importer {
- public:
-  Firefox3Importer();
-
-  // Importer:
-  virtual void StartImport(const importer::SourceProfile& source_profile,
-                           uint16 items,
-                           ImporterBridge* bridge) OVERRIDE;
-
- private:
-  typedef std::map<int64, std::set<GURL> > FaviconMap;
-
-  virtual ~Firefox3Importer();
-
-  void ImportBookmarks();
-  void ImportPasswords();
-  void ImportHistory();
-  void ImportSearchEngines();
-  // Import the user's home page, unless it is set to default home page as
-  // defined in browserconfig.properties.
-  void ImportHomepage();
-  void GetSearchEnginesXMLData(std::vector<std::string>* search_engine_data);
-
-  // The struct stores the information about a bookmark item.
-  struct BookmarkItem;
-  typedef std::vector<BookmarkItem*> BookmarkList;
-
-  // Gets the specific IDs of bookmark root node from |db|.
-  void LoadRootNodeID(sql::Connection* db, int* toolbar_folder_id,
-                      int* menu_folder_id, int* unsorted_folder_id);
-
-  // Loads all livemark IDs from database |db|.
-  void LoadLivemarkIDs(sql::Connection* db, std::set<int>* livemark);
-
-  // Gets the bookmark folder with given ID, and adds the entry in |list|
-  // if successful.
-  void GetTopBookmarkFolder(sql::Connection* db,
-                            int folder_id,
-                            BookmarkList* list);
-
-  // Loads all children of the given folder, and appends them to the |list|.
-  void GetWholeBookmarkFolder(sql::Connection* db, BookmarkList* list,
-                              size_t position, bool* empty_folder);
-
-  // Loads the favicons given in the map from the database, loads the data,
-  // and converts it into FaviconUsage structures.
-  void LoadFavicons(sql::Connection* db,
-                    const FaviconMap& favicon_map,
-                    std::vector<ImportedFaviconUsage>* favicons);
-
-  base::FilePath source_path_;
-  base::FilePath app_path_;
-
-#if defined(OS_POSIX)
-  // Stored because we can only access it from the UI thread.
-  std::string locale_;
-#endif
-
-  DISALLOW_COPY_AND_ASSIGN(Firefox3Importer);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_FIREFOX3_IMPORTER_H_
diff --git a/chrome/browser/importer/firefox_importer_browsertest.cc b/chrome/browser/importer/firefox_importer_browsertest.cc
index 8cde615..0290ba2 100644
--- a/chrome/browser/importer/firefox_importer_browsertest.cc
+++ b/chrome/browser/importer/firefox_importer_browsertest.cc
@@ -12,7 +12,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/importer/external_process_importer_host.h"
-#include "chrome/browser/importer/firefox_importer_unittest_utils.h"
 #include "chrome/browser/importer/importer_progress_observer.h"
 #include "chrome/browser/importer/importer_unittest_utils.h"
 #include "chrome/browser/search_engines/template_url.h"
@@ -219,7 +218,7 @@
     // Creates a new profile in a new subdirectory in the temp directory.
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     base::FilePath test_path = temp_dir_.path().AppendASCII("ImporterTest");
-    base::Delete(test_path, true);
+    base::DeleteFile(test_path, true);
     file_util::CreateDirectory(test_path);
     profile_path_ = test_path.AppendASCII("profile");
     app_path_ = test_path.AppendASCII("app");
@@ -237,10 +236,10 @@
     base::FilePath data_path;
     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
     data_path = data_path.AppendASCII(profile_dir);
-    ASSERT_TRUE(file_util::CopyDirectory(data_path, profile_path_, true));
+    ASSERT_TRUE(base::CopyDirectory(data_path, profile_path_, true));
     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
     data_path = data_path.AppendASCII("firefox3_nss");
-    ASSERT_TRUE(file_util::CopyDirectory(data_path, profile_path_, false));
+    ASSERT_TRUE(base::CopyDirectory(data_path, profile_path_, false));
 
     base::FilePath search_engine_path = app_path_;
     search_engine_path = search_engine_path.AppendASCII("searchplugins");
@@ -248,13 +247,12 @@
     if (import_search_plugins) {
       ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path));
       data_path = data_path.AppendASCII("firefox3_searchplugins");
-      if (!file_util::PathExists(data_path)) {
+      if (!base::PathExists(data_path)) {
         // TODO(maruel):  Create search test data that we can open source!
         LOG(ERROR) << L"Missing internal test data";
         return;
       }
-      ASSERT_TRUE(file_util::CopyDirectory(data_path,
-                                           search_engine_path, false));
+      ASSERT_TRUE(base::CopyDirectory(data_path, search_engine_path, false));
     }
 
     importer::SourceProfile source_profile;
diff --git a/chrome/browser/importer/firefox_importer_unittest.cc b/chrome/browser/importer/firefox_importer_unittest.cc
deleted file mode 100644
index bdfa18f..0000000
--- a/chrome/browser/importer/firefox_importer_unittest.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012 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 "testing/gtest/include/gtest/gtest.h"
-
-#include "base/files/file_path.h"
-#include "base/path_service.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/importer/firefox_importer_unittest_utils.h"
-#include "chrome/browser/importer/nss_decryptor.h"
-#include "chrome/common/chrome_paths.h"
-
-// TODO(jschuh): Disabled on Win64 build. http://crbug.com/179688
-#if defined(OS_WIN) && defined(ARCH_CPU_X86_64)
-#define MAYBE_NSS(x) DISABLED_##x
-#else
-#define MAYBE_NSS(x) x
-#endif
-
-// The following test requires the use of the NSSDecryptor, on OSX this needs
-// to run in a separate process, so we use a proxy object so we can share the
-// same test between platforms.
-TEST(FirefoxImporterTest, MAYBE_NSS(Firefox3NSS3Decryptor)) {
-  base::FilePath nss_path;
-  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &nss_path));
-#if defined(OS_MACOSX)
-  nss_path = nss_path.AppendASCII("firefox3_nss_mac");
-#else
-  nss_path = nss_path.AppendASCII("firefox3_nss");
-#endif  // !OS_MACOSX
-  base::FilePath db_path;
-  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &db_path));
-  db_path = db_path.AppendASCII("firefox3_profile");
-
-  FFUnitTestDecryptorProxy decryptor_proxy;
-  ASSERT_TRUE(decryptor_proxy.Setup(nss_path));
-
-  ASSERT_TRUE(decryptor_proxy.DecryptorInit(nss_path, db_path));
-  EXPECT_EQ(ASCIIToUTF16("hello"),
-      decryptor_proxy.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECKa"
-                              "jtRg4qFSHBAhv9luFkXgDJA=="));
-  // Test UTF-16 encoding.
-  EXPECT_EQ(WideToUTF16(L"\x4E2D"),
-      decryptor_proxy.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECLW"
-                              "qqiccfQHWBAie74hxnULxlw=="));
-}
diff --git a/chrome/browser/importer/firefox_importer_unittest_messages_internal.h b/chrome/browser/importer/firefox_importer_unittest_messages_internal.h
deleted file mode 100644
index ce29947..0000000
--- a/chrome/browser/importer/firefox_importer_unittest_messages_internal.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2009 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 "ipc/ipc_message_macros.h"
-
-#define IPC_MESSAGE_START FirefoxImporterUnittestMsgStart
-
-// Messages definitions for messages sent between the unit test binary and
-// a child process by FFUnitTestDecryptorProxy.
-
-// Server->Child: Initialize the decrytor with the following paramters.
-IPC_MESSAGE_CONTROL2(Msg_Decryptor_Init,
-                     base::FilePath /* dll_path */,
-                     base::FilePath /* db_path */)
-// Child->Server: Return paramter from init call.
-IPC_MESSAGE_CONTROL1(Msg_Decryptor_InitReturnCode,
-                     bool /* ret */)
-
-// Server->Child: Decrypt a given string.
-IPC_MESSAGE_CONTROL1(Msg_Decrypt,
-                     std::string /* crypt */)
-// Child->Server: Decrypted String.
-IPC_MESSAGE_CONTROL1(Msg_Decryptor_Response,
-                     string16 /* unencrypted_str */)
-
-// Server->Child: Die.
-IPC_MESSAGE_CONTROL0(Msg_Decryptor_Quit)
diff --git a/chrome/browser/importer/firefox_importer_unittest_utils.h b/chrome/browser/importer/firefox_importer_unittest_utils.h
deleted file mode 100644
index 480b09e..0000000
--- a/chrome/browser/importer/firefox_importer_unittest_utils.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UNITTEST_UTILS_H_
-#define CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UNITTEST_UTILS_H_
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/process_util.h"
-#include "chrome/browser/importer/nss_decryptor.h"
-
-class FFDecryptorServerChannelListener;
-
-namespace base {
-class MessageLoopForIO;
-}
-
-namespace IPC {
-class Channel;
-}  // namespace IPC
-
-// On OS X NSSDecryptor needs to run in a separate process. To allow us to use
-// the same unit test on all platforms we use a proxy class which spawns a
-// child process to do decryption on OS X, and calls through directly
-// to NSSDecryptor on other platforms.
-// On OS X:
-// 2 IPC messages are sent for every method of NSSDecryptor, one containing the
-// input arguments sent from Server->Child and one coming back containing
-// the return argument e.g.
-//
-// -> Msg_Decryptor_Init(dll_path, db_path)
-// <- Msg_Decryptor_InitReturnCode(bool)
-class FFUnitTestDecryptorProxy {
- public:
-  FFUnitTestDecryptorProxy();
-  virtual ~FFUnitTestDecryptorProxy();
-
-  // Initialize a decryptor, returns true if the object was
-  // constructed successfully.
-  bool Setup(const base::FilePath& nss_path);
-
-  // This match the parallel functions in NSSDecryptor.
-  bool DecryptorInit(const base::FilePath& dll_path,
-                     const base::FilePath& db_path);
-  string16 Decrypt(const std::string& crypt);
-
- private:
-#if defined(OS_MACOSX)
-  // Blocks until either a timeout is reached, or until the client process
-  // responds to an IPC message.
-  // Returns true if a reply was received successfully and false if the
-  // the operation timed out.
-  bool WaitForClientResponse();
-
-  base::ProcessHandle child_process_;
-  scoped_ptr<IPC::Channel> channel_;
-  scoped_ptr<FFDecryptorServerChannelListener> listener_;
-  scoped_ptr<base::MessageLoopForIO> message_loop_;
-#else
-  NSSDecryptor decryptor_;
-#endif  // !OS_MACOSX
-  DISALLOW_COPY_AND_ASSIGN(FFUnitTestDecryptorProxy);
-};
-
-// On Non-OSX platforms FFUnitTestDecryptorProxy simply calls through to
-// NSSDecryptor.
-#if !defined(OS_MACOSX)
-FFUnitTestDecryptorProxy::FFUnitTestDecryptorProxy() {
-}
-
-FFUnitTestDecryptorProxy::~FFUnitTestDecryptorProxy() {
-}
-
-bool FFUnitTestDecryptorProxy::Setup(const base::FilePath& nss_path) {
-  return true;
-}
-
-bool FFUnitTestDecryptorProxy::DecryptorInit(const base::FilePath& dll_path,
-                                             const base::FilePath& db_path) {
-  return decryptor_.Init(dll_path, db_path);
-}
-
-string16 FFUnitTestDecryptorProxy::Decrypt(const std::string& crypt) {
-  return decryptor_.Decrypt(crypt);
-}
-#endif  // !OS_MACOSX
-
-#endif  // CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UNITTEST_UTILS_H_
diff --git a/chrome/browser/importer/firefox_importer_unittest_utils_mac.cc b/chrome/browser/importer/firefox_importer_unittest_utils_mac.cc
deleted file mode 100644
index 33c877a..0000000
--- a/chrome/browser/importer/firefox_importer_unittest_utils_mac.cc
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/firefox_importer_unittest_utils.h"
-
-#include "base/base_switches.h"
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/file_util.h"
-#include "base/files/file_path.h"
-#include "base/message_loop.h"
-#include "base/test/test_timeouts.h"
-#include "chrome/browser/importer/firefox_importer_utils.h"
-#include "ipc/ipc_channel.h"
-#include "ipc/ipc_descriptors.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_message.h"
-#include "ipc/ipc_multiprocess_test.h"
-#include "ipc/ipc_switches.h"
-#include "testing/multiprocess_func_list.h"
-
-#define IPC_MESSAGE_IMPL
-#include "chrome/browser/importer/firefox_importer_unittest_messages_internal.h"
-
-namespace {
-
-// Name of IPC Channel to use for Server<-> Child Communications.
-const char kTestChannelID[] = "T1";
-
-// Launch the child process:
-// |nss_path| - path to the NSS directory holding the decryption libraries.
-// |channel| - IPC Channel to use for communication.
-// |handle| - On return, the process handle to use to communicate with the
-// child.
-bool LaunchNSSDecrypterChildProcess(const base::FilePath& nss_path,
-    IPC::Channel* channel, base::ProcessHandle* handle) {
-  CommandLine cl(*CommandLine::ForCurrentProcess());
-  cl.AppendSwitchASCII(switches::kTestChildProcess, "NSSDecrypterChildProcess");
-
-  // Set env variable needed for FF encryption libs to load.
-  // See "chrome/browser/importer/nss_decryptor_mac.mm" for an explanation of
-  // why we need this.
-  base::EnvironmentVector env;
-  std::pair<std::string, std::string> dyld_override;
-  dyld_override.first = "DYLD_FALLBACK_LIBRARY_PATH";
-  dyld_override.second = nss_path.value();
-  env.push_back(dyld_override);
-
-  int ipcfd = channel->TakeClientFileDescriptor();
-  if (ipcfd == -1)
-    return false;
-
-  file_util::ScopedFD client_file_descriptor_closer(&ipcfd);
-  base::FileHandleMappingVector fds_to_map;
-  fds_to_map.push_back(std::pair<int,int>(ipcfd, kPrimaryIPCChannel + 3));
-
-  bool debug_on_start = CommandLine::ForCurrentProcess()->HasSwitch(
-                            switches::kDebugChildren);
-  base::LaunchOptions options;
-  options.environ = &env;
-  options.fds_to_remap = &fds_to_map;
-  options.wait = debug_on_start;
-  return base::LaunchProcess(cl.argv(), options, handle);
-}
-
-}  // namespace
-
-//----------------------- Server --------------------
-
-// Class to communicate on the server side of the IPC Channel.
-// Method calls are sent over IPC and replies are read back into class
-// variables.
-// This class needs to be called on a single thread.
-class FFDecryptorServerChannelListener : public IPC::Listener {
- public:
-  FFDecryptorServerChannelListener()
-      : got_result(false), sender_(NULL) {}
-
-  void SetSender(IPC::Sender* sender) {
-    sender_ = sender;
-  }
-
-  void OnInitDecryptorResponse(bool result) {
-    DCHECK(!got_result);
-    result_bool = result;
-    got_result = true;
-    base::MessageLoop::current()->Quit();
-  }
-
-  void OnDecryptedTextResonse(const string16& decrypted_text) {
-    DCHECK(!got_result);
-    result_string = decrypted_text;
-    got_result = true;
-    base::MessageLoop::current()->Quit();
-  }
-
-  void QuitClient() {
-    if (sender_)
-      sender_->Send(new Msg_Decryptor_Quit());
-  }
-
-  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
-    bool handled = true;
-    IPC_BEGIN_MESSAGE_MAP(FFDecryptorServerChannelListener, msg)
-      IPC_MESSAGE_HANDLER(Msg_Decryptor_InitReturnCode, OnInitDecryptorResponse)
-      IPC_MESSAGE_HANDLER(Msg_Decryptor_Response, OnDecryptedTextResonse)
-      IPC_MESSAGE_UNHANDLED(handled = false)
-    IPC_END_MESSAGE_MAP()
-    return handled;
-  }
-
-  // If an error occured, just kill the message Loop.
-  virtual void OnChannelError() OVERRIDE {
-    got_result = false;
-    base::MessageLoop::current()->Quit();
-  }
-
-  // Results of IPC calls.
-  string16 result_string;
-  bool result_bool;
-  // True if IPC call succeeded and data in above variables is valid.
-  bool got_result;
-
- private:
-  IPC::Sender* sender_;  // weak
-};
-
-FFUnitTestDecryptorProxy::FFUnitTestDecryptorProxy()
-    : child_process_(0) {
-}
-
-bool FFUnitTestDecryptorProxy::Setup(const base::FilePath& nss_path) {
-  // Create a new message loop and spawn the child process.
-  message_loop_.reset(new base::MessageLoopForIO());
-
-  listener_.reset(new FFDecryptorServerChannelListener());
-  channel_.reset(new IPC::Channel(kTestChannelID,
-                                  IPC::Channel::MODE_SERVER,
-                                  listener_.get()));
-  CHECK(channel_->Connect());
-  listener_->SetSender(channel_.get());
-
-  // Spawn child and set up sync IPC connection.
-  bool ret = LaunchNSSDecrypterChildProcess(nss_path,
-                                            channel_.get(),
-                                            &child_process_);
-  return ret && (child_process_ != 0);
-}
-
-FFUnitTestDecryptorProxy::~FFUnitTestDecryptorProxy() {
-  listener_->QuitClient();
-  channel_->Close();
-
-  if (child_process_) {
-    base::WaitForSingleProcess(child_process_, base::TimeDelta::FromSeconds(5));
-    base::CloseProcessHandle(child_process_);
-  }
-}
-
-// A message_loop task that quits the message loop when invoked, setting cancel
-// causes the task to do nothing when invoked.
-class CancellableQuitMsgLoop : public base::RefCounted<CancellableQuitMsgLoop> {
- public:
-  CancellableQuitMsgLoop() : cancelled_(false) {}
-  void QuitNow() {
-    if (!cancelled_)
-      base::MessageLoop::current()->Quit();
-  }
-  bool cancelled_;
-
- private:
-  friend class base::RefCounted<CancellableQuitMsgLoop>;
-  ~CancellableQuitMsgLoop() {}
-};
-
-// Spin until either a client response arrives or a timeout occurs.
-bool FFUnitTestDecryptorProxy::WaitForClientResponse() {
-  // What we're trying to do here is to wait for an RPC message to go over the
-  // wire and the client to reply.  If the client does not reply by a given
-  // timeout we kill the message loop.
-  // The way we do this is to post a CancellableQuitMsgLoop for 3 seconds in
-  // the future and cancel it if an RPC message comes back earlier.
-  // This relies on the IPC listener class to quit the message loop itself when
-  // a message comes in.
-  scoped_refptr<CancellableQuitMsgLoop> quit_task(
-      new CancellableQuitMsgLoop());
-  base::MessageLoop::current()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&CancellableQuitMsgLoop::QuitNow, quit_task.get()),
-      TestTimeouts::action_max_timeout());
-
-  message_loop_->Run();
-  bool ret = !quit_task->cancelled_;
-  quit_task->cancelled_ = false;
-  return ret;
-}
-
-bool FFUnitTestDecryptorProxy::DecryptorInit(const base::FilePath& dll_path,
-                                             const base::FilePath& db_path) {
-  channel_->Send(new Msg_Decryptor_Init(dll_path, db_path));
-  bool ok = WaitForClientResponse();
-  if (ok && listener_->got_result) {
-    listener_->got_result = false;
-    return listener_->result_bool;
-  }
-  return false;
-}
-
-string16 FFUnitTestDecryptorProxy::Decrypt(const std::string& crypt) {
-  channel_->Send(new Msg_Decrypt(crypt));
-  bool ok = WaitForClientResponse();
-  if (ok && listener_->got_result) {
-    listener_->got_result = false;
-    return listener_->result_string;
-  }
-  return string16();
-}
-
-//---------------------------- Child Process -----------------------
-
-// Class to listen on the client side of the ipc channel, it calls through
-// to the NSSDecryptor and sends back a reply.
-class FFDecryptorClientChannelListener : public IPC::Listener {
- public:
-  FFDecryptorClientChannelListener()
-      : sender_(NULL) {}
-
-  void SetSender(IPC::Sender* sender) {
-    sender_ = sender;
-  }
-
-  void OnDecryptor_Init(base::FilePath dll_path, base::FilePath db_path) {
-    bool ret = decryptor_.Init(dll_path, db_path);
-    sender_->Send(new Msg_Decryptor_InitReturnCode(ret));
-  }
-
-  void OnDecrypt(std::string crypt) {
-    string16 unencrypted_str = decryptor_.Decrypt(crypt);
-    sender_->Send(new Msg_Decryptor_Response(unencrypted_str));
-  }
-
-  void OnQuitRequest() {
-    base::MessageLoop::current()->Quit();
-  }
-
-  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
-    bool handled = true;
-    IPC_BEGIN_MESSAGE_MAP(FFDecryptorClientChannelListener, msg)
-      IPC_MESSAGE_HANDLER(Msg_Decryptor_Init, OnDecryptor_Init)
-      IPC_MESSAGE_HANDLER(Msg_Decrypt, OnDecrypt)
-      IPC_MESSAGE_HANDLER(Msg_Decryptor_Quit, OnQuitRequest)
-      IPC_MESSAGE_UNHANDLED(handled = false)
-    IPC_END_MESSAGE_MAP()
-    return handled;
-  }
-
-  virtual void OnChannelError() OVERRIDE {
-    base::MessageLoop::current()->Quit();
-  }
-
- private:
-  NSSDecryptor decryptor_;
-  IPC::Sender* sender_;
-};
-
-// Entry function in child process.
-MULTIPROCESS_IPC_TEST_MAIN(NSSDecrypterChildProcess) {
-  base::MessageLoopForIO main_message_loop;
-  FFDecryptorClientChannelListener listener;
-
-  IPC::Channel channel(kTestChannelID, IPC::Channel::MODE_CLIENT, &listener);
-  CHECK(channel.Connect());
-  listener.SetSender(&channel);
-
-  // run message loop
-  base::MessageLoop::current()->Run();
-
-  return 0;
-}
diff --git a/chrome/browser/importer/firefox_importer_utils.cc b/chrome/browser/importer/firefox_importer_utils.cc
deleted file mode 100644
index 5610f5b..0000000
--- a/chrome/browser/importer/firefox_importer_utils.cc
+++ /dev/null
@@ -1,351 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/firefox_importer_utils.h"
-
-#include <algorithm>
-#include <map>
-#include <string>
-
-#include "base/file_util.h"
-#include "base/ini_parser.h"
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "grit/generated_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "url/gurl.h"
-
-base::FilePath GetFirefoxProfilePath() {
-  base::FilePath ini_file = GetProfilesINI();
-  std::string content;
-  file_util::ReadFileToString(ini_file, &content);
-  base::DictionaryValueINIParser ini_parser;
-  ini_parser.Parse(content);
-  const DictionaryValue& root = ini_parser.root();
-
-  base::FilePath source_path;
-  for (int i = 0; ; ++i) {
-    std::string current_profile = base::StringPrintf("Profile%d", i);
-    if (!root.HasKey(current_profile)) {
-      // Profiles are continuously numbered. So we exit when we can't
-      // find the i-th one.
-      break;
-    }
-    std::string is_relative;
-    string16 path16;
-    if (root.GetStringASCII(current_profile + ".IsRelative", &is_relative) &&
-        root.GetString(current_profile + ".Path", &path16)) {
-#if defined(OS_WIN)
-      ReplaceSubstringsAfterOffset(
-          &path16, 0, ASCIIToUTF16("/"), ASCIIToUTF16("\\"));
-#endif
-      base::FilePath path =
-          base::FilePath::FromWStringHack(UTF16ToWide(path16));
-
-      // IsRelative=1 means the folder path would be relative to the
-      // path of profiles.ini. IsRelative=0 refers to a custom profile
-      // location.
-      if (is_relative == "1") {
-        path = ini_file.DirName().Append(path);
-      }
-
-      // We only import the default profile when multiple profiles exist,
-      // since the other profiles are used mostly by developers for testing.
-      // Otherwise, Profile0 will be imported.
-      std::string is_default;
-      if ((root.GetStringASCII(current_profile + ".Default", &is_default) &&
-           is_default == "1") || i == 0) {
-        // We have found the default profile.
-        return path;
-      }
-    }
-  }
-  return base::FilePath();
-}
-
-
-bool GetFirefoxVersionAndPathFromProfile(const base::FilePath& profile_path,
-                                         int* version,
-                                         base::FilePath* app_path) {
-  bool ret = false;
-  base::FilePath compatibility_file =
-      profile_path.AppendASCII("compatibility.ini");
-  std::string content;
-  file_util::ReadFileToString(compatibility_file, &content);
-  ReplaceSubstringsAfterOffset(&content, 0, "\r\n", "\n");
-  std::vector<std::string> lines;
-  base::SplitString(content, '\n', &lines);
-
-  for (size_t i = 0; i < lines.size(); ++i) {
-    const std::string& line = lines[i];
-    if (line.empty() || line[0] == '#' || line[0] == ';')
-      continue;
-    size_t equal = line.find('=');
-    if (equal != std::string::npos) {
-      std::string key = line.substr(0, equal);
-      if (key == "LastVersion") {
-        base::StringToInt(line.substr(equal + 1), version);
-        ret = true;
-      } else if (key == "LastAppDir") {
-        // TODO(evanm): If the path in question isn't convertible to
-        // UTF-8, what does Firefox do?  If it puts raw bytes in the
-        // file, we could go straight from bytes -> filepath;
-        // otherwise, we're out of luck here.
-        *app_path = base::FilePath::FromWStringHack(
-            UTF8ToWide(line.substr(equal + 1)));
-      }
-    }
-  }
-  return ret;
-}
-
-bool CanImportURL(const GURL& url) {
-  const char* kInvalidSchemes[] = {"wyciwyg", "place", "about", "chrome"};
-
-  // The URL is not valid.
-  if (!url.is_valid())
-    return false;
-
-  // Filter out the URLs with unsupported schemes.
-  for (size_t i = 0; i < arraysize(kInvalidSchemes); ++i) {
-    if (url.SchemeIs(kInvalidSchemes[i]))
-      return false;
-  }
-
-  return true;
-}
-
-bool ReadPrefFile(const base::FilePath& path, std::string* content) {
-  if (content == NULL)
-    return false;
-
-  file_util::ReadFileToString(path, content);
-
-  if (content->empty()) {
-    LOG(WARNING) << "Firefox preference file " << path.value() << " is empty.";
-    return false;
-  }
-
-  return true;
-}
-
-std::string ReadBrowserConfigProp(const base::FilePath& app_path,
-                                  const std::string& pref_key) {
-  std::string content;
-  if (!ReadPrefFile(app_path.AppendASCII("browserconfig.properties"), &content))
-    return std::string();
-
-  // This file has the syntax: key=value.
-  size_t prop_index = content.find(pref_key + "=");
-  if (prop_index == std::string::npos)
-    return std::string();
-
-  size_t start = prop_index + pref_key.length();
-  size_t stop = std::string::npos;
-  if (start != std::string::npos)
-    stop = content.find("\n", start + 1);
-
-  if (start == std::string::npos ||
-      stop == std::string::npos || (start == stop)) {
-    LOG(WARNING) << "Firefox property " << pref_key << " could not be parsed.";
-    return std::string();
-  }
-
-  return content.substr(start + 1, stop - start - 1);
-}
-
-std::string ReadPrefsJsValue(const base::FilePath& profile_path,
-                             const std::string& pref_key) {
-  std::string content;
-  if (!ReadPrefFile(profile_path.AppendASCII("prefs.js"), &content))
-    return std::string();
-
-  return GetPrefsJsValue(content, pref_key);
-}
-
-GURL GetHomepage(const base::FilePath& profile_path) {
-  std::string home_page_list =
-      ReadPrefsJsValue(profile_path, "browser.startup.homepage");
-
-  size_t seperator = home_page_list.find_first_of('|');
-  if (seperator == std::string::npos)
-    return GURL(home_page_list);
-
-  return GURL(home_page_list.substr(0, seperator));
-}
-
-bool IsDefaultHomepage(const GURL& homepage, const base::FilePath& app_path) {
-  if (!homepage.is_valid())
-    return false;
-
-  std::string default_homepages =
-      ReadBrowserConfigProp(app_path, "browser.startup.homepage");
-
-  size_t seperator = default_homepages.find_first_of('|');
-  if (seperator == std::string::npos)
-    return homepage.spec() == GURL(default_homepages).spec();
-
-  // Crack the string into separate homepage urls.
-  std::vector<std::string> urls;
-  base::SplitString(default_homepages, '|', &urls);
-
-  for (size_t i = 0; i < urls.size(); ++i) {
-    if (homepage.spec() == GURL(urls[i]).spec())
-      return true;
-  }
-
-  return false;
-}
-
-bool ParsePrefFile(const base::FilePath& pref_file, DictionaryValue* prefs) {
-  // The string that is before a pref key.
-  const std::string kUserPrefString = "user_pref(\"";
-  std::string contents;
-  if (!file_util::ReadFileToString(pref_file, &contents))
-    return false;
-
-  std::vector<std::string> lines;
-  Tokenize(contents, "\n", &lines);
-
-  for (std::vector<std::string>::const_iterator iter = lines.begin();
-       iter != lines.end(); ++iter) {
-    const std::string& line = *iter;
-    size_t start_key = line.find(kUserPrefString);
-    if (start_key == std::string::npos)
-      continue;  // Could be a comment or a blank line.
-    start_key += kUserPrefString.length();
-    size_t stop_key = line.find('"', start_key);
-    if (stop_key == std::string::npos) {
-      LOG(ERROR) << "Invalid key found in Firefox pref file '" <<
-          pref_file.value() << "' line is '" << line << "'.";
-      continue;
-    }
-    std::string key = line.substr(start_key, stop_key - start_key);
-    size_t start_value = line.find(',', stop_key + 1);
-    if (start_value == std::string::npos) {
-      LOG(ERROR) << "Invalid value found in Firefox pref file '" <<
-          pref_file.value() << "' line is '" << line << "'.";
-      continue;
-    }
-    size_t stop_value = line.find(");", start_value + 1);
-    if (stop_value == std::string::npos) {
-      LOG(ERROR) << "Invalid value found in Firefox pref file '" <<
-          pref_file.value() << "' line is '" << line << "'.";
-      continue;
-    }
-    std::string value = line.substr(start_value + 1,
-                                    stop_value - start_value - 1);
-    TrimWhitespace(value, TRIM_ALL, &value);
-    // Value could be a boolean.
-    bool is_value_true = LowerCaseEqualsASCII(value, "true");
-    if (is_value_true || LowerCaseEqualsASCII(value, "false")) {
-      prefs->SetBoolean(key, is_value_true);
-      continue;
-    }
-
-    // Value could be a string.
-    if (value.size() >= 2U &&
-        value[0] == '"' && value[value.size() - 1] == '"') {
-      value = value.substr(1, value.size() - 2);
-      // ValueString only accept valid UTF-8.  Simply ignore that entry if it is
-      // not UTF-8.
-      if (IsStringUTF8(value))
-        prefs->SetString(key, value);
-      else
-        VLOG(1) << "Non UTF8 value for key " << key << ", ignored.";
-      continue;
-    }
-
-    // Or value could be an integer.
-    int int_value = 0;
-    if (base::StringToInt(value, &int_value)) {
-      prefs->SetInteger(key, int_value);
-      continue;
-    }
-
-    LOG(ERROR) << "Invalid value found in Firefox pref file '"
-               << pref_file.value() << "' value is '" << value << "'.";
-  }
-  return true;
-}
-
-std::string GetPrefsJsValue(const std::string& content,
-                            const std::string& pref_key) {
-  // This file has the syntax: user_pref("key", value);
-  std::string search_for = std::string("user_pref(\"") + pref_key +
-                           std::string("\", ");
-  size_t prop_index = content.find(search_for);
-  if (prop_index == std::string::npos)
-    return std::string();
-
-  size_t start = prop_index + search_for.length();
-  size_t stop = std::string::npos;
-  if (start != std::string::npos) {
-    // Stop at the last ')' on this line.
-    stop = content.find("\n", start + 1);
-    stop = content.rfind(")", stop);
-  }
-
-  if (start == std::string::npos || stop == std::string::npos ||
-      stop < start) {
-    LOG(WARNING) << "Firefox property " << pref_key << " could not be parsed.";
-    return std::string();
-  }
-
-  // String values have double quotes we don't need to return to the caller.
-  if (content[start] == '\"' && content[stop - 1] == '\"') {
-    ++start;
-    --stop;
-  }
-
-  return content.substr(start, stop - start);
-}
-
-// The branding name is obtained from the application.ini file from the Firefox
-// application directory. A sample application.ini file is the following:
-//   [App]
-//   Vendor=Mozilla
-//   Name=Iceweasel
-//   Profile=mozilla/firefox
-//   Version=3.5.16
-//   BuildID=20120421070307
-//   Copyright=Copyright (c) 1998 - 2010 mozilla.org
-//   ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
-//   .........................................
-// In this example the function returns "Iceweasel" (or a localized equivalent).
-string16 GetFirefoxImporterName(const base::FilePath& app_path) {
-  const base::FilePath app_ini_file = app_path.AppendASCII("application.ini");
-  std::string branding_name;
-  if (file_util::PathExists(app_ini_file)) {
-    std::string content;
-    file_util::ReadFileToString(app_ini_file, &content);
-    std::vector<std::string> lines;
-    base::SplitString(content, '\n', &lines);
-    const std::string name_attr("Name=");
-    bool in_app_section = false;
-    for (size_t i = 0; i < lines.size(); ++i) {
-      TrimWhitespace(lines[i], TRIM_ALL, &lines[i]);
-      if (lines[i] == "[App]") {
-        in_app_section = true;
-      } else if (in_app_section) {
-        if (lines[i].find(name_attr) == 0) {
-          branding_name = lines[i].substr(name_attr.size());
-          break;
-        } else if (lines[i].length() > 0 && lines[i][0] == '[') {
-          // No longer in the [App] section.
-          break;
-        }
-      }
-    }
-  }
-
-  StringToLowerASCII(&branding_name);
-  if (branding_name.find("iceweasel") != std::string::npos)
-    return l10n_util::GetStringUTF16(IDS_IMPORT_FROM_ICEWEASEL);
-  return l10n_util::GetStringUTF16(IDS_IMPORT_FROM_FIREFOX);
-}
diff --git a/chrome/browser/importer/firefox_importer_utils.h b/chrome/browser/importer/firefox_importer_utils.h
deleted file mode 100644
index 5446ddf..0000000
--- a/chrome/browser/importer/firefox_importer_utils.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UTILS_H_
-#define CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UTILS_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/strings/string16.h"
-#include "build/build_config.h"
-
-class GURL;
-class TemplateURL;
-
-namespace base {
-class DictionaryValue;
-class FilePath;
-}
-
-#if defined(OS_WIN)
-// Detects which version of Firefox is installed from registry. Returns its
-// major version, and drops the minor version. Returns 0 if failed. If there are
-// indicators of both Firefox 2 and Firefox 3 it is biased to return the biggest
-// version.
-int GetCurrentFirefoxMajorVersionFromRegistry();
-
-// Detects where Firefox lives. Returns an empty path if Firefox is not
-// installed.
-base::FilePath GetFirefoxInstallPathFromRegistry();
-#endif  // OS_WIN
-
-#if defined(OS_MACOSX)
-// Get the directory in which the Firefox .dylibs live, we need to load these
-// in order to decoded FF profile passwords.
-// The Path is usuall FF App Bundle/Contents/Mac OS/
-// Returns empty path on failure.
-base::FilePath GetFirefoxDylibPath();
-#endif  // OS_MACOSX
-
-// Returns the path to the Firefox profile.
-base::FilePath GetFirefoxProfilePath();
-
-// Detects version of Firefox and installation path for the given Firefox
-// profile.
-bool GetFirefoxVersionAndPathFromProfile(const base::FilePath& profile_path,
-                                         int* version,
-                                         base::FilePath* app_path);
-
-// Gets the full path of the profiles.ini file. This file records the profiles
-// that can be used by Firefox. Returns an empty path if failed.
-base::FilePath GetProfilesINI();
-
-// Parses the profile.ini file, and stores its information in |root|.
-// This file is a plain-text file. Key/value pairs are stored one per line, and
-// they are separated in different sections. For example:
-//   [General]
-//   StartWithLastProfile=1
-//
-//   [Profile0]
-//   Name=default
-//   IsRelative=1
-//   Path=Profiles/abcdefeg.default
-// We set "[value]" in path "<Section>.<Key>". For example, the path
-// "Genenral.StartWithLastProfile" has the value "1".
-void ParseProfileINI(const base::FilePath& file, base::DictionaryValue* root);
-
-// Returns true if we want to add the URL to the history. We filter out the URL
-// with a unsupported scheme.
-bool CanImportURL(const GURL& url);
-
-// Returns the home page set in Firefox in a particular profile.
-GURL GetHomepage(const base::FilePath& profile_path);
-
-// Checks to see if this home page is a default home page, as specified by
-// the resource file browserconfig.properties in the Firefox application
-// directory.
-bool IsDefaultHomepage(const GURL& homepage, const base::FilePath& app_path);
-
-// Parses the prefs found in the file |pref_file| and puts the key/value pairs
-// in |prefs|. Keys are strings, and values can be strings, booleans or
-// integers.  Returns true if it succeeded, false otherwise (in which case
-// |prefs| is not filled).
-// Note: for strings, only valid UTF-8 string values are supported. If a
-// key/pair is not valid UTF-8, it is ignored and will not appear in |prefs|.
-bool ParsePrefFile(const base::FilePath& pref_file, base::DictionaryValue* prefs);
-
-// Parses the value of a particular firefox preference from a string that is the
-// contents of the prefs file.
-std::string GetPrefsJsValue(const std::string& prefs,
-                            const std::string& pref_key);
-
-// Returns the localized Firefox branding name.
-// This is useful to differentiate between Firefox and Iceweasel.
-// If anything goes wrong while trying to obtain the branding name,
-// the function assumes it's Firefox.
-string16 GetFirefoxImporterName(const base::FilePath& app_path);
-
-#endif  // CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UTILS_H_
diff --git a/chrome/browser/importer/firefox_importer_utils_linux.cc b/chrome/browser/importer/firefox_importer_utils_linux.cc
deleted file mode 100644
index 98f9c2a..0000000
--- a/chrome/browser/importer/firefox_importer_utils_linux.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/firefox_importer_utils.h"
-
-#include "base/file_util.h"
-
-base::FilePath GetProfilesINI() {
-  base::FilePath ini_file;
-  // The default location of the profile folder containing user data is
-  // under user HOME directory in .mozilla/firefox folder on Linux.
-  base::FilePath home = file_util::GetHomeDir();
-  if (!home.empty()) {
-    ini_file = home.Append(".mozilla/firefox/profiles.ini");
-  }
-  if (file_util::PathExists(ini_file))
-    return ini_file;
-
-  return base::FilePath();
-}
diff --git a/chrome/browser/importer/firefox_importer_utils_mac.mm b/chrome/browser/importer/firefox_importer_utils_mac.mm
deleted file mode 100644
index 6aa9040..0000000
--- a/chrome/browser/importer/firefox_importer_utils_mac.mm
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2011 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 <Cocoa/Cocoa.h>
-#include <sys/param.h>
-
-#include "chrome/browser/importer/firefox_importer_utils.h"
-
-#include "base/file_util.h"
-#include "base/mac/foundation_util.h"
-#include "base/path_service.h"
-
-base::FilePath GetProfilesINI() {
-  base::FilePath app_data_path;
-  if (!PathService::Get(base::DIR_APP_DATA, &app_data_path)) {
-    return base::FilePath();
-  }
-  base::FilePath ini_file =
-      app_data_path.Append("Firefox").Append("profiles.ini");
-  if (!file_util::PathExists(ini_file)) {
-    return base::FilePath();
-  }
-  return ini_file;
-}
-
-base::FilePath GetFirefoxDylibPath() {
-  CFURLRef appURL = nil;
-  if (LSFindApplicationForInfo(kLSUnknownCreator,
-                              CFSTR("org.mozilla.firefox"),
-                              NULL,
-                              NULL,
-                              &appURL) != noErr) {
-    return base::FilePath();
-  }
-  NSBundle *ff_bundle =
-      [NSBundle bundleWithPath:[base::mac::CFToNSCast(appURL) path]];
-  CFRelease(appURL);
-  NSString *ff_library_path =
-      [[ff_bundle executablePath] stringByDeletingLastPathComponent];
-  char buf[MAXPATHLEN];
-  if (![ff_library_path getFileSystemRepresentation:buf maxLength:sizeof(buf)])
-    return base::FilePath();
-  return base::FilePath(buf);
-}
diff --git a/chrome/browser/importer/firefox_importer_utils_unittest.cc b/chrome/browser/importer/firefox_importer_utils_unittest.cc
deleted file mode 100644
index b393d71..0000000
--- a/chrome/browser/importer/firefox_importer_utils_unittest.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "chrome/browser/importer/firefox_importer_utils.h"
-#include "grit/generated_resources.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/l10n/l10n_util.h"
-
-namespace {
-
-struct GetPrefsJsValueCase {
-  std::string prefs_content;
-  std::string pref_name;
-  std::string pref_value;
-} GetPrefsJsValueCases[] = {
-  // Basic case. Single pref, unquoted value.
-  { "user_pref(\"foo.bar\", 1);", "foo.bar", "1" },
-  // Value is quoted. Quotes should be stripped.
-  { "user_pref(\"foo.bar\", \"1\");", "foo.bar", "1" },
-  // Value has parens.
-  { "user_pref(\"foo.bar\", \"Value (detail)\");",
-    "foo.bar", "Value (detail)" },
-  // Multi-line case.
-  { "user_pref(\"foo.bar\", 1);\n"
-    "user_pref(\"foo.baz\", 2);\n"
-    "user_pref(\"foo.bag\", 3);",
-    "foo.baz", "2" },
-  // Malformed content.
-  { "user_pref(\"foo.bar\", 1);\n"
-    "user_pref(\"foo.baz\", 2;\n"
-    "user_pref(\"foo.bag\", 3);",
-    "foo.baz", "" },
-  // Malformed content.
-  { "uesr_pref(\"foo.bar\", 1);", "foo.bar", "" },
-};
-
-struct GetFirefoxImporterNameCase {
-  std::string app_ini_content;
-  int resource_id;
-} GetFirefoxImporterNameCases[] = {
-  // Basic case
-  { "[App]\n"
-    "Vendor=Mozilla\n"
-    "Name=iceweasel\n"
-    "Version=10.0.6\n"
-    "BuildID=20120717115048\n"
-    "ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}",
-    IDS_IMPORT_FROM_ICEWEASEL },
-  // Whitespace
-  { " \t[App] \n"
-    "Vendor=Mozilla\n"
-    "   Name=Firefox\t \r\n"
-    "Version=10.0.6\n",
-    IDS_IMPORT_FROM_FIREFOX },
-  // No Name setting
-  { "[App]\n"
-    "Vendor=Mozilla\n"
-    "Version=10.0.6\n"
-    "BuildID=20120717115048\n"
-    "ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}",
-    IDS_IMPORT_FROM_FIREFOX },
-  // No [App] section
-  { "[Foo]\n"
-    "Vendor=Mozilla\n"
-    "Name=Foo\n",
-    IDS_IMPORT_FROM_FIREFOX },
-  // Multiple Name settings in different sections
-  { "[Foo]\n"
-    "Vendor=Mozilla\n"
-    "Name=Firefox\n"
-    "[App]\n"
-    "Profile=mozilla/firefox\n"
-    "Name=iceweasel\n"
-    "[Bar]\n"
-    "Name=Bar\n"
-    "ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}",
-    IDS_IMPORT_FROM_ICEWEASEL },
-  // Case-insensitivity
-  { "[App]\n"
-    "Vendor=Mozilla\n"
-    "Name=IceWeasel\n"
-    "Version=10.0.6\n",
-    IDS_IMPORT_FROM_ICEWEASEL },
-  // Empty file
-  { "", IDS_IMPORT_FROM_FIREFOX }
-};
-
-}  // anonymous namespace
-
-TEST(FirefoxImporterUtilsTest, GetPrefsJsValue) {
-  for (size_t i = 0; i < arraysize(GetPrefsJsValueCases); ++i) {
-    EXPECT_EQ(
-      GetPrefsJsValueCases[i].pref_value,
-      GetPrefsJsValue(GetPrefsJsValueCases[i].prefs_content,
-                      GetPrefsJsValueCases[i].pref_name));
-  }
-}
-
-TEST(FirefoxImporterUtilsTest, GetFirefoxImporterName) {
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-  const base::FilePath app_ini_file(
-      temp_dir.path().AppendASCII("application.ini"));
-  for (size_t i = 0; i < arraysize(GetFirefoxImporterNameCases); ++i) {
-    file_util::WriteFile(app_ini_file,
-                         GetFirefoxImporterNameCases[i].app_ini_content.c_str(),
-                         GetFirefoxImporterNameCases[i].app_ini_content.size());
-    EXPECT_EQ(GetFirefoxImporterName(temp_dir.path()),
-        l10n_util::GetStringUTF16(GetFirefoxImporterNameCases[i].resource_id));
-  }
-  EXPECT_EQ(l10n_util::GetStringUTF16(
-          IDS_IMPORT_FROM_FIREFOX),
-      GetFirefoxImporterName(base::FilePath(
-                                        FILE_PATH_LITERAL("/invalid/path"))));
-}
diff --git a/chrome/browser/importer/firefox_importer_utils_win.cc b/chrome/browser/importer/firefox_importer_utils_win.cc
deleted file mode 100644
index 68a4453..0000000
--- a/chrome/browser/importer/firefox_importer_utils_win.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/firefox_importer_utils.h"
-
-#include <shlobj.h>
-
-#include "base/file_util.h"
-#include "base/path_service.h"
-#include "base/strings/string16.h"
-#include "base/win/registry.h"
-
-// NOTE: Keep these in order since we need test all those paths according
-// to priority. For example. One machine has multiple users. One non-admin
-// user installs Firefox 2, which causes there is a Firefox2 entry under HKCU.
-// One admin user installs Firefox 3, which causes there is a Firefox 3 entry
-// under HKLM. So when the non-admin user log in, we should deal with Firefox 2
-// related data instead of Firefox 3.
-static const HKEY kFireFoxRegistryPaths[] = {
-  HKEY_CURRENT_USER,
-  HKEY_LOCAL_MACHINE
-};
-
-static const wchar_t* kFirefoxPath = L"Software\\Mozilla\\Mozilla Firefox";
-static const wchar_t* kCurrentVersion = L"CurrentVersion";
-
-int GetCurrentFirefoxMajorVersionFromRegistry() {
-  TCHAR ver_buffer[128];
-  DWORD ver_buffer_length = sizeof(ver_buffer);
-  int highest_version = 0;
-  // When installing Firefox with admin account, the product keys will be
-  // written under HKLM\Mozilla. Otherwise it the keys will be written under
-  // HKCU\Mozilla.
-  for (int i = 0; i < arraysize(kFireFoxRegistryPaths); ++i) {
-    base::win::RegKey reg_key(kFireFoxRegistryPaths[i], kFirefoxPath,
-                              KEY_READ);
-
-    LONG result = reg_key.ReadValue(kCurrentVersion, ver_buffer,
-                                    &ver_buffer_length, NULL);
-    if (result != ERROR_SUCCESS)
-      continue;
-    highest_version = std::max(highest_version, _wtoi(ver_buffer));
-  }
-  return highest_version;
-}
-
-base::FilePath GetFirefoxInstallPathFromRegistry() {
-  // Detects the path that Firefox is installed in.
-  string16 registry_path = kFirefoxPath;
-  wchar_t buffer[MAX_PATH];
-  DWORD buffer_length = sizeof(buffer);
-  base::win::RegKey reg_key(HKEY_LOCAL_MACHINE, registry_path.c_str(),
-                            KEY_READ);
-  LONG result = reg_key.ReadValue(kCurrentVersion, buffer,
-                                  &buffer_length, NULL);
-  if (result != ERROR_SUCCESS)
-    return base::FilePath();
-
-  registry_path += L"\\" + string16(buffer) + L"\\Main";
-  buffer_length = sizeof(buffer);
-  base::win::RegKey reg_key_directory(HKEY_LOCAL_MACHINE,
-                                      registry_path.c_str(), KEY_READ);
-  result = reg_key_directory.ReadValue(L"Install Directory", buffer,
-                                       &buffer_length, NULL);
-
-  return (result != ERROR_SUCCESS) ? base::FilePath() : base::FilePath(buffer);
-}
-
-base::FilePath GetProfilesINI() {
-  base::FilePath ini_file;
-  // The default location of the profile folder containing user data is
-  // under the "Application Data" folder in Windows XP, Vista, and 7.
-  if (!PathService::Get(base::DIR_APP_DATA, &ini_file))
-    return base::FilePath();
-
-  ini_file = ini_file.AppendASCII("Mozilla");
-  ini_file = ini_file.AppendASCII("Firefox");
-  ini_file = ini_file.AppendASCII("profiles.ini");
-
-  return file_util::PathExists(ini_file) ? ini_file : base::FilePath();
-}
diff --git a/chrome/browser/importer/firefox_profile_lock_posix.cc b/chrome/browser/importer/firefox_profile_lock_posix.cc
index dd00b70..5beb3d4 100644
--- a/chrome/browser/importer/firefox_profile_lock_posix.cc
+++ b/chrome/browser/importer/firefox_profile_lock_posix.cc
@@ -78,7 +78,7 @@
     return;
   close(lock_fd_);
   lock_fd_ = -1;
-  base::Delete(old_lock_file_, false);
+  base::DeleteFile(old_lock_file_, false);
 }
 
 bool FirefoxProfileLock::HasAcquired() {
diff --git a/chrome/browser/importer/firefox_profile_lock_unittest.cc b/chrome/browser/importer/firefox_profile_lock_unittest.cc
index 7506a71..95a4b4b 100644
--- a/chrome/browser/importer/firefox_profile_lock_unittest.cc
+++ b/chrome/browser/importer/firefox_profile_lock_unittest.cc
@@ -39,27 +39,27 @@
 
   scoped_ptr<FirefoxProfileLock> lock;
   EXPECT_EQ(static_cast<FirefoxProfileLock*>(NULL), lock.get());
-  EXPECT_FALSE(file_util::PathExists(lock_file_path));
+  EXPECT_FALSE(base::PathExists(lock_file_path));
   lock.reset(new FirefoxProfileLock(test_path));
   EXPECT_TRUE(lock->HasAcquired());
-  EXPECT_TRUE(file_util::PathExists(lock_file_path));
+  EXPECT_TRUE(base::PathExists(lock_file_path));
   lock->Unlock();
   EXPECT_FALSE(lock->HasAcquired());
 
   // In the posix code, we don't delete the file when releasing the lock.
 #if !defined(OS_POSIX)
-  EXPECT_FALSE(file_util::PathExists(lock_file_path));
+  EXPECT_FALSE(base::PathExists(lock_file_path));
 #endif  // !defined(OS_POSIX)
   lock->Lock();
   EXPECT_TRUE(lock->HasAcquired());
-  EXPECT_TRUE(file_util::PathExists(lock_file_path));
+  EXPECT_TRUE(base::PathExists(lock_file_path));
   lock->Lock();
   EXPECT_TRUE(lock->HasAcquired());
   lock->Unlock();
   EXPECT_FALSE(lock->HasAcquired());
   // In the posix code, we don't delete the file when releasing the lock.
 #if !defined(OS_POSIX)
-  EXPECT_FALSE(file_util::PathExists(lock_file_path));
+  EXPECT_FALSE(base::PathExists(lock_file_path));
 #endif  // !defined(OS_POSIX)
 }
 
@@ -74,7 +74,7 @@
   FILE* lock_file = file_util::OpenFile(lock_file_path, "w");
   ASSERT_TRUE(lock_file);
   file_util::CloseFile(lock_file);
-  EXPECT_TRUE(file_util::PathExists(lock_file_path));
+  EXPECT_TRUE(base::PathExists(lock_file_path));
 
   scoped_ptr<FirefoxProfileLock> lock;
   EXPECT_EQ(static_cast<FirefoxProfileLock*>(NULL), lock.get());
diff --git a/chrome/browser/importer/firefox_proxy_settings.cc b/chrome/browser/importer/firefox_proxy_settings.cc
index 75d5735..58aa4f3 100644
--- a/chrome/browser/importer/firefox_proxy_settings.cc
+++ b/chrome/browser/importer/firefox_proxy_settings.cc
@@ -8,7 +8,7 @@
 #include "base/strings/string_tokenizer.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
-#include "chrome/browser/importer/firefox_importer_utils.h"
+#include "chrome/common/importer/firefox_importer_utils.h"
 #include "net/proxy/proxy_config.h"
 
 namespace {
diff --git a/chrome/browser/importer/ie_importer.cc b/chrome/browser/importer/ie_importer.cc
deleted file mode 100644
index b5ad754..0000000
--- a/chrome/browser/importer/ie_importer.cc
+++ /dev/null
@@ -1,889 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/ie_importer.h"
-
-#include <ole2.h>
-#include <intshcut.h>
-#include <shlobj.h>
-#include <urlhist.h>
-#include <wininet.h>
-
-#include <algorithm>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/file_util.h"
-#include "base/files/file_enumerator.h"
-#include "base/files/file_path.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
-#include "base/win/registry.h"
-#include "base/win/scoped_co_mem.h"
-#include "base/win/scoped_comptr.h"
-#include "base/win/scoped_handle.h"
-#include "base/win/scoped_propvariant.h"
-#include "base/win/windows_version.h"
-#include "chrome/browser/favicon/favicon_util.h"
-#include "chrome/browser/importer/ie_importer_utils_win.h"
-#include "chrome/browser/importer/importer_bridge.h"
-#include "chrome/browser/importer/pstore_declarations.h"
-#include "chrome/common/importer/imported_bookmark_entry.h"
-#include "chrome/common/importer/imported_favicon_usage.h"
-#include "chrome/common/importer/importer_data_types.h"
-#include "chrome/common/importer/importer_url_row.h"
-#include "chrome/common/time_format.h"
-#include "chrome/common/url_constants.h"
-#include "components/webdata/encryptor/ie7_password.h"
-#include "content/public/common/password_form.h"
-#include "grit/generated_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "url/gurl.h"
-
-namespace {
-
-// Registry key paths from which we import IE settings.
-const char16 kStorage2Path[] =
-  L"Software\\Microsoft\\Internet Explorer\\IntelliForms\\Storage2";
-const char16 kSearchScopePath[] =
-  L"Software\\Microsoft\\Internet Explorer\\SearchScopes";
-const char16 kIESettingsMain[] =
-  L"Software\\Microsoft\\Internet Explorer\\Main";
-const char16 kIEVersionKey[] =
-  L"Software\\Microsoft\\Internet Explorer";
-const char16 kIEToolbarKey[] =
-  L"Software\\Microsoft\\Internet Explorer\\Toolbar";
-
-// NTFS stream name of favicon image data.
-const char16 kFaviconStreamName[] = L":favicon:$DATA";
-
-// A struct that hosts the information of AutoComplete data in PStore.
-struct AutoCompleteInfo {
-  string16 key;
-  std::vector<string16> data;
-  bool is_url;
-};
-
-// Gets the creation time of the given file or directory.
-base::Time GetFileCreationTime(const string16& file) {
-  base::Time creation_time;
-  base::win::ScopedHandle file_handle(
-      CreateFile(file.c_str(), GENERIC_READ,
-                 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-                 NULL, OPEN_EXISTING,
-                 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL));
-  FILETIME creation_filetime;
-  if (GetFileTime(file_handle, &creation_filetime, NULL, NULL))
-    creation_time = base::Time::FromFileTime(creation_filetime);
-  return creation_time;
-}
-
-// Safely read an object of type T from a raw sequence of bytes.
-template<typename T>
-bool BinaryRead(T* data, size_t offset, const std::vector<uint8>& blob) {
-  if (offset + sizeof(T) > blob.size())
-    return false;
-  memcpy(data, &blob[offset], sizeof(T));
-  return true;
-}
-
-// Safely read an ITEMIDLIST from a raw sequence of bytes.
-//
-// An ITEMIDLIST is a list of SHITEMIDs, terminated by a SHITEMID with
-// .cb = 0. Here, before simply casting &blob[offset] to LPITEMIDLIST,
-// we verify that the list structure is not overrunning the boundary of
-// the binary blob.
-LPCITEMIDLIST BinaryReadItemIDList(size_t offset, size_t idlist_size,
-                                   const std::vector<uint8>& blob) {
-  size_t head = 0;
-  while (true) {
-    // Use a USHORT instead of SHITEMID to avoid buffer over read.
-    USHORT id_cb;
-    if (head >= idlist_size || !BinaryRead(&id_cb, offset + head, blob))
-      return NULL;
-    if (id_cb == 0)
-      break;
-    head += id_cb;
-  }
-  return reinterpret_cast<LPCITEMIDLIST>(&blob[offset]);
-}
-
-// Compares the two bookmarks in the order of IE's Favorites menu.
-// Returns true if rhs should come later than lhs (lhs < rhs).
-struct IEOrderBookmarkComparator {
-  bool operator()(const ImportedBookmarkEntry& lhs,
-                  const ImportedBookmarkEntry& rhs) const {
-    static const uint32 kNotSorted = 0xfffffffb; // IE uses this magic value.
-    base::FilePath lhs_prefix;
-    base::FilePath rhs_prefix;
-    for (size_t i = 0; i <= lhs.path.size() && i <= rhs.path.size(); ++i) {
-      const base::FilePath::StringType lhs_i =
-        (i < lhs.path.size() ? lhs.path[i] : lhs.title + L".url");
-      const base::FilePath::StringType rhs_i =
-        (i < rhs.path.size() ? rhs.path[i] : rhs.title + L".url");
-      lhs_prefix = lhs_prefix.Append(lhs_i);
-      rhs_prefix = rhs_prefix.Append(rhs_i);
-      if (lhs_i == rhs_i)
-        continue;
-      // The first path element that differs between the two.
-      std::map<base::FilePath, uint32>::const_iterator lhs_iter =
-        sort_index_->find(lhs_prefix);
-      std::map<base::FilePath, uint32>::const_iterator rhs_iter =
-        sort_index_->find(rhs_prefix);
-      uint32 lhs_sort_index = (lhs_iter == sort_index_->end() ? kNotSorted
-        : lhs_iter->second);
-      uint32 rhs_sort_index = (rhs_iter == sort_index_->end() ? kNotSorted
-        : rhs_iter->second);
-      if (lhs_sort_index != rhs_sort_index)
-        return lhs_sort_index < rhs_sort_index;
-      // If they have the same sort order, sort alphabetically.
-      return lhs_i < rhs_i;
-    }
-    return lhs.path.size() < rhs.path.size();
-  }
-  const std::map<base::FilePath, uint32>* sort_index_;
-};
-
-// IE stores the order of the Favorites menu in registry under:
-// HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Favorites.
-// The folder hierarchy of Favorites menu is directly mapped to the key
-// hierarchy in the registry.
-//
-// If the order of the items in a folder is customized by user, the order is
-// recorded in the REG_BINARY value named "Order" of the corresponding key.
-// The content of the "Order" value is a raw binary dump of an array of the
-// following data structure
-//   struct {
-//     uint32 size;  // Note that ITEMIDLIST is variably-sized.
-//     uint32 sort_index;  // 0 means this is the first item, 1 the second, ...
-//     ITEMIDLIST item_id;
-//   };
-// where each item_id should correspond to a favorites link file (*.url) in
-// the current folder.
-bool ParseFavoritesOrderBlob(
-    const Importer* importer,
-    const std::vector<uint8>& blob,
-    const base::FilePath& path,
-    std::map<base::FilePath, uint32>* sort_index) WARN_UNUSED_RESULT {
-  static const int kItemCountOffset = 16;
-  static const int kItemListStartOffset = 20;
-
-  // Read the number of items.
-  uint32 item_count = 0;
-  if (!BinaryRead(&item_count, kItemCountOffset, blob))
-    return false;
-
-  // Traverse over the items.
-  size_t base_offset = kItemListStartOffset;
-  for (uint32 i = 0; i < item_count && !importer->cancelled(); ++i) {
-    static const int kSizeOffset = 0;
-    static const int kSortIndexOffset = 4;
-    static const int kItemIDListOffset = 8;
-
-    // Read the size (number of bytes) of the current item.
-    uint32 item_size = 0;
-    if (!BinaryRead(&item_size, base_offset + kSizeOffset, blob) ||
-        base_offset + item_size <= base_offset || // checking overflow
-        base_offset + item_size > blob.size())
-      return false;
-
-    // Read the sort index of the current item.
-    uint32 item_sort_index = 0;
-    if (!BinaryRead(&item_sort_index, base_offset + kSortIndexOffset, blob))
-      return false;
-
-    // Read the file name from the ITEMIDLIST structure.
-    LPCITEMIDLIST idlist = BinaryReadItemIDList(
-      base_offset + kItemIDListOffset, item_size - kItemIDListOffset, blob);
-    TCHAR item_filename[MAX_PATH];
-    if (!idlist || FAILED(SHGetPathFromIDList(idlist, item_filename)))
-      return false;
-    base::FilePath item_relative_path =
-      path.Append(base::FilePath(item_filename).BaseName());
-
-    // Record the retrieved information and go to the next item.
-    sort_index->insert(std::make_pair(item_relative_path, item_sort_index));
-    base_offset += item_size;
-  }
-  return true;
-}
-
-bool ParseFavoritesOrderRegistryTree(
-    const Importer* importer,
-    const base::win::RegKey& key,
-    const base::FilePath& path,
-    std::map<base::FilePath, uint32>* sort_index) WARN_UNUSED_RESULT {
-  // Parse the order information of the current folder.
-  DWORD blob_length = 0;
-  if (key.ReadValue(L"Order", NULL, &blob_length, NULL) == ERROR_SUCCESS) {
-    std::vector<uint8> blob(blob_length);
-    if (blob_length > 0 &&
-        key.ReadValue(L"Order", reinterpret_cast<DWORD*>(&blob[0]),
-                      &blob_length, NULL) == ERROR_SUCCESS) {
-      if (!ParseFavoritesOrderBlob(importer, blob, path, sort_index))
-        return false;
-    }
-  }
-
-  // Recursively parse subfolders.
-  for (base::win::RegistryKeyIterator child(key.Handle(), L"");
-       child.Valid() && !importer->cancelled();
-       ++child) {
-    base::win::RegKey subkey(key.Handle(), child.Name(), KEY_READ);
-    if (subkey.Valid()) {
-      base::FilePath subpath(path.Append(child.Name()));
-      if (!ParseFavoritesOrderRegistryTree(importer, subkey, subpath,
-                                           sort_index)) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-bool ParseFavoritesOrderInfo(
-    const Importer* importer,
-    std::map<base::FilePath, uint32>* sort_index) WARN_UNUSED_RESULT {
-  base::string16 key_path(importer::GetIEFavoritesOrderKey());
-  base::win::RegKey key(HKEY_CURRENT_USER, key_path.c_str(), KEY_READ);
-  if (!key.Valid())
-    return false;
-  return ParseFavoritesOrderRegistryTree(importer, key, base::FilePath(),
-                                         sort_index);
-}
-
-// Reads the sort order from registry. If failed, we don't touch the list
-// and use the default (alphabetical) order.
-void SortBookmarksInIEOrder(
-    const Importer* importer,
-    std::vector<ImportedBookmarkEntry>* bookmarks) {
-  std::map<base::FilePath, uint32> sort_index;
-  if (!ParseFavoritesOrderInfo(importer, &sort_index))
-    return;
-  IEOrderBookmarkComparator compare = {&sort_index};
-  std::sort(bookmarks->begin(), bookmarks->end(), compare);
-}
-
-// Reads an internet shortcut (*.url) |file| and returns a COM object
-// representing it.
-bool LoadInternetShortcut(
-    const string16& file,
-    base::win::ScopedComPtr<IUniformResourceLocator>* shortcut) {
-  base::win::ScopedComPtr<IUniformResourceLocator> url_locator;
-  if (FAILED(url_locator.CreateInstance(CLSID_InternetShortcut, NULL,
-                                        CLSCTX_INPROC_SERVER)))
-    return false;
-
-  base::win::ScopedComPtr<IPersistFile> persist_file;
-  if (FAILED(persist_file.QueryFrom(url_locator)))
-    return false;
-
-  // Loads the Internet Shortcut from persistent storage.
-  if (FAILED(persist_file->Load(file.c_str(), STGM_READ)))
-    return false;
-
-  std::swap(url_locator, *shortcut);
-  return true;
-}
-
-// Reads the URL stored in the internet shortcut.
-GURL ReadURLFromInternetShortcut(IUniformResourceLocator* url_locator) {
-  base::win::ScopedCoMem<wchar_t> url;
-  // GetURL can return S_FALSE (FAILED(S_FALSE) is false) when url == NULL.
-  return (FAILED(url_locator->GetURL(&url)) || !url) ?
-      GURL() : GURL(WideToUTF16(std::wstring(url)));
-}
-
-// Reads the URL of the favicon of the internet shortcut.
-GURL ReadFaviconURLFromInternetShortcut(IUniformResourceLocator* url_locator) {
-  base::win::ScopedComPtr<IPropertySetStorage> property_set_storage;
-  if (FAILED(property_set_storage.QueryFrom(url_locator)))
-    return GURL();
-
-  base::win::ScopedComPtr<IPropertyStorage> property_storage;
-  if (FAILED(property_set_storage->Open(FMTID_Intshcut, STGM_READ,
-                                        property_storage.Receive()))) {
-    return GURL();
-  }
-
-  PROPSPEC properties[] = {{PRSPEC_PROPID, PID_IS_ICONFILE}};
-  // ReadMultiple takes a non-const array of PROPVARIANTs, but since this code
-  // only needs an array of size 1: a non-const pointer to |output| is
-  // equivalent.
-  base::win::ScopedPropVariant output;
-  // ReadMultiple can return S_FALSE (FAILED(S_FALSE) is false) when the
-  // property is not found, in which case output[0].vt is set to VT_EMPTY.
-  if (FAILED(property_storage->ReadMultiple(1, properties, output.Receive())) ||
-      output.get().vt != VT_LPWSTR)
-    return GURL();
-  return GURL(WideToUTF16(output.get().pwszVal));
-}
-
-// Reads the favicon imaga data in an NTFS alternate data stream. This is where
-// IE7 and above store the data.
-bool ReadFaviconDataFromInternetShortcut(const string16& file,
-                                         std::string* data) {
-  return file_util::ReadFileToString(
-      base::FilePath(file + kFaviconStreamName), data);
-}
-
-// Reads the favicon imaga data in the Internet cache. IE6 doesn't hold the data
-// explicitly, but it might be found in the cache.
-bool ReadFaviconDataFromCache(const GURL& favicon_url, std::string* data) {
-  std::wstring url_wstring(UTF8ToWide(favicon_url.spec()));
-  DWORD info_size = 0;
-  GetUrlCacheEntryInfoEx(url_wstring.c_str(), NULL, &info_size, NULL, NULL,
-                         NULL, 0);
-  if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-    return false;
-
-  std::vector<char> buf(info_size);
-  INTERNET_CACHE_ENTRY_INFO* cache =
-      reinterpret_cast<INTERNET_CACHE_ENTRY_INFO*>(&buf[0]);
-  if (!GetUrlCacheEntryInfoEx(url_wstring.c_str(), cache, &info_size, NULL,
-                              NULL, NULL, 0)) {
-    return false;
-  }
-  return file_util::ReadFileToString(base::FilePath(cache->lpszLocalFileName),
-                                     data);
-}
-
-// Reads the binary image data of favicon of an internet shortcut file |file|.
-// |favicon_url| read by ReadFaviconURLFromInternetShortcut is also needed to
-// examine the IE cache.
-bool ReadReencodedFaviconData(const string16& file,
-                              const GURL& favicon_url,
-                              std::vector<unsigned char>* data) {
-  std::string image_data;
-  if (!ReadFaviconDataFromInternetShortcut(file, &image_data) &&
-      !ReadFaviconDataFromCache(favicon_url, &image_data)) {
-    return false;
-  }
-
-  const unsigned char* ptr =
-      reinterpret_cast<const unsigned char*>(image_data.c_str());
-  return FaviconUtil::ReencodeFavicon(ptr, image_data.size(), data);
-}
-
-// Loads favicon image data and registers to |favicon_map|.
-void UpdateFaviconMap(
-    const string16& url_file,
-    const GURL& url,
-    IUniformResourceLocator* url_locator,
-    std::map<GURL, ImportedFaviconUsage>* favicon_map) {
-  GURL favicon_url = ReadFaviconURLFromInternetShortcut(url_locator);
-  if (!favicon_url.is_valid())
-    return;
-
-  std::map<GURL, ImportedFaviconUsage>::iterator it =
-    favicon_map->find(favicon_url);
-  if (it != favicon_map->end()) {
-    // Known favicon URL.
-    it->second.urls.insert(url);
-  } else {
-    // New favicon URL. Read the image data and store.
-    ImportedFaviconUsage usage;
-    if (ReadReencodedFaviconData(url_file, favicon_url, &usage.png_data)) {
-      usage.favicon_url = favicon_url;
-      usage.urls.insert(url);
-      favicon_map->insert(std::make_pair(favicon_url, usage));
-    }
-  }
-}
-
-}  // namespace
-
-// static
-// {E161255A-37C3-11D2-BCAA-00C04fD929DB}
-const GUID IEImporter::kPStoreAutocompleteGUID = {
-    0xe161255a, 0x37c3, 0x11d2,
-    { 0xbc, 0xaa, 0x00, 0xc0, 0x4f, 0xd9, 0x29, 0xdb }
-};
-// {A79029D6-753E-4e27-B807-3D46AB1545DF}
-const GUID IEImporter::kUnittestGUID = {
-    0xa79029d6, 0x753e, 0x4e27,
-    { 0xb8, 0x7, 0x3d, 0x46, 0xab, 0x15, 0x45, 0xdf }
-};
-
-IEImporter::IEImporter() {
-}
-
-void IEImporter::StartImport(const importer::SourceProfile& source_profile,
-                             uint16 items,
-                             ImporterBridge* bridge) {
-  bridge_ = bridge;
-  source_path_ = source_profile.source_path;
-
-  bridge_->NotifyStarted();
-
-  if ((items & importer::HOME_PAGE) && !cancelled())
-    ImportHomepage();  // Doesn't have a UI item.
-  // The order here is important!
-  if ((items & importer::HISTORY) && !cancelled()) {
-    bridge_->NotifyItemStarted(importer::HISTORY);
-    ImportHistory();
-    bridge_->NotifyItemEnded(importer::HISTORY);
-  }
-  if ((items & importer::FAVORITES) && !cancelled()) {
-    bridge_->NotifyItemStarted(importer::FAVORITES);
-    ImportFavorites();
-    bridge_->NotifyItemEnded(importer::FAVORITES);
-  }
-  if ((items & importer::SEARCH_ENGINES) && !cancelled()) {
-    bridge_->NotifyItemStarted(importer::SEARCH_ENGINES);
-    ImportSearchEngines();
-    bridge_->NotifyItemEnded(importer::SEARCH_ENGINES);
-  }
-  if ((items & importer::PASSWORDS) && !cancelled()) {
-    bridge_->NotifyItemStarted(importer::PASSWORDS);
-    // Always import IE6 passwords.
-    ImportPasswordsIE6();
-
-    if (CurrentIEVersion() >= 7)
-      ImportPasswordsIE7();
-    bridge_->NotifyItemEnded(importer::PASSWORDS);
-  }
-  bridge_->NotifyEnded();
-}
-
-IEImporter::~IEImporter() {
-}
-
-void IEImporter::ImportFavorites() {
-  FavoritesInfo info;
-  if (!GetFavoritesInfo(&info))
-    return;
-
-  BookmarkVector bookmarks;
-  std::vector<ImportedFaviconUsage> favicons;
-  ParseFavoritesFolder(info, &bookmarks, &favicons);
-
-  if (!bookmarks.empty() && !cancelled()) {
-    const string16& first_folder_name =
-        l10n_util::GetStringUTF16(IDS_BOOKMARK_GROUP_FROM_IE);
-    bridge_->AddBookmarks(bookmarks, first_folder_name);
-  }
-  if (!favicons.empty() && !cancelled())
-    bridge_->SetFavicons(favicons);
-}
-
-void IEImporter::ImportHistory() {
-  const std::string kSchemes[] = {chrome::kHttpScheme,
-                                  chrome::kHttpsScheme,
-                                  chrome::kFtpScheme,
-                                  chrome::kFileScheme};
-  int total_schemes = arraysize(kSchemes);
-
-  base::win::ScopedComPtr<IUrlHistoryStg2> url_history_stg2;
-  HRESULT result;
-  result = url_history_stg2.CreateInstance(CLSID_CUrlHistory, NULL,
-                                           CLSCTX_INPROC_SERVER);
-  if (FAILED(result))
-    return;
-  base::win::ScopedComPtr<IEnumSTATURL> enum_url;
-  if (SUCCEEDED(result = url_history_stg2->EnumUrls(enum_url.Receive()))) {
-    std::vector<ImporterURLRow> rows;
-    STATURL stat_url;
-    ULONG fetched;
-    while (!cancelled() &&
-           (result = enum_url->Next(1, &stat_url, &fetched)) == S_OK) {
-      string16 url_string;
-      if (stat_url.pwcsUrl) {
-        url_string = stat_url.pwcsUrl;
-        CoTaskMemFree(stat_url.pwcsUrl);
-      }
-      string16 title_string;
-      if (stat_url.pwcsTitle) {
-        title_string = stat_url.pwcsTitle;
-        CoTaskMemFree(stat_url.pwcsTitle);
-      }
-
-      GURL url(url_string);
-      // Skips the URLs that are invalid or have other schemes.
-      if (!url.is_valid() ||
-          (std::find(kSchemes, kSchemes + total_schemes, url.scheme()) ==
-           kSchemes + total_schemes))
-        continue;
-
-      ImporterURLRow row(url);
-      row.title = title_string;
-      row.last_visit = base::Time::FromFileTime(stat_url.ftLastVisited);
-      if (stat_url.dwFlags == STATURL_QUERYFLAG_TOPLEVEL) {
-        row.visit_count = 1;
-        row.hidden = false;
-      } else {
-        row.hidden = true;
-      }
-
-      rows.push_back(row);
-    }
-
-    if (!rows.empty() && !cancelled()) {
-      bridge_->SetHistoryItems(rows, history::SOURCE_IE_IMPORTED);
-    }
-  }
-}
-
-void IEImporter::ImportPasswordsIE6() {
-  GUID AutocompleteGUID = kPStoreAutocompleteGUID;
-  if (!source_path_.empty()) {
-    // We supply a fake GUID for testting.
-    AutocompleteGUID = kUnittestGUID;
-  }
-
-  // The PStoreCreateInstance function retrieves an interface pointer
-  // to a storage provider. But this function has no associated import
-  // library or header file, we must call it using the LoadLibrary()
-  // and GetProcAddress() functions.
-  typedef HRESULT (WINAPI *PStoreCreateFunc)(IPStore**, DWORD, DWORD, DWORD);
-  HMODULE pstorec_dll = LoadLibrary(L"pstorec.dll");
-  if (!pstorec_dll)
-    return;
-  PStoreCreateFunc PStoreCreateInstance =
-      (PStoreCreateFunc)GetProcAddress(pstorec_dll, "PStoreCreateInstance");
-  if (!PStoreCreateInstance) {
-    FreeLibrary(pstorec_dll);
-    return;
-  }
-
-  base::win::ScopedComPtr<IPStore, &IID_IPStore> pstore;
-  HRESULT result = PStoreCreateInstance(pstore.Receive(), 0, 0, 0);
-  if (result != S_OK) {
-    FreeLibrary(pstorec_dll);
-    return;
-  }
-
-  std::vector<AutoCompleteInfo> ac_list;
-
-  // Enumerates AutoComplete items in the protected database.
-  base::win::ScopedComPtr<IEnumPStoreItems, &IID_IEnumPStoreItems> item;
-  result = pstore->EnumItems(0, &AutocompleteGUID,
-                             &AutocompleteGUID, 0, item.Receive());
-  if (result != PST_E_OK) {
-    pstore.Release();
-    FreeLibrary(pstorec_dll);
-    return;
-  }
-
-  wchar_t* item_name;
-  while (!cancelled() && SUCCEEDED(item->Next(1, &item_name, 0))) {
-    DWORD length = 0;
-    unsigned char* buffer = NULL;
-    result = pstore->ReadItem(0, &AutocompleteGUID, &AutocompleteGUID,
-                              item_name, &length, &buffer, NULL, 0);
-    if (SUCCEEDED(result)) {
-      AutoCompleteInfo ac;
-      ac.key = item_name;
-      string16 data;
-      data.insert(0, reinterpret_cast<wchar_t*>(buffer),
-                  length / sizeof(wchar_t));
-
-      // The key name is always ended with ":StringData".
-      const wchar_t kDataSuffix[] = L":StringData";
-      size_t i = ac.key.rfind(kDataSuffix);
-      if (i != string16::npos && ac.key.substr(i) == kDataSuffix) {
-        ac.key.erase(i);
-        ac.is_url = (ac.key.find(L"://") != string16::npos);
-        ac_list.push_back(ac);
-        base::SplitString(data, L'\0', &ac_list[ac_list.size() - 1].data);
-      }
-      CoTaskMemFree(buffer);
-    }
-    CoTaskMemFree(item_name);
-  }
-  // Releases them before unload the dll.
-  item.Release();
-  pstore.Release();
-  FreeLibrary(pstorec_dll);
-
-  size_t i;
-  for (i = 0; i < ac_list.size(); i++) {
-    if (!ac_list[i].is_url || ac_list[i].data.size() < 2)
-      continue;
-
-    GURL url(ac_list[i].key.c_str());
-    if (!(LowerCaseEqualsASCII(url.scheme(), chrome::kHttpScheme) ||
-        LowerCaseEqualsASCII(url.scheme(), chrome::kHttpsScheme))) {
-      continue;
-    }
-
-    content::PasswordForm form;
-    GURL::Replacements rp;
-    rp.ClearUsername();
-    rp.ClearPassword();
-    rp.ClearQuery();
-    rp.ClearRef();
-    form.origin = url.ReplaceComponents(rp);
-    form.username_value = ac_list[i].data[0];
-    form.password_value = ac_list[i].data[1];
-    form.signon_realm = url.GetOrigin().spec();
-
-    // This is not precise, because a scheme of https does not imply a valid
-    // certificate was presented; however we assign it this way so that if we
-    // import a password from IE whose scheme is https, we give it the benefit
-    // of the doubt and DONT auto-fill it unless the form appears under
-    // valid SSL conditions.
-    form.ssl_valid = url.SchemeIsSecure();
-
-    // Goes through the list to find out the username field
-    // of the web page.
-    size_t list_it, item_it;
-    for (list_it = 0; list_it < ac_list.size(); ++list_it) {
-      if (ac_list[list_it].is_url)
-        continue;
-
-      for (item_it = 0; item_it < ac_list[list_it].data.size(); ++item_it)
-        if (ac_list[list_it].data[item_it] == form.username_value) {
-          form.username_element = ac_list[list_it].key;
-          break;
-        }
-    }
-
-    bridge_->SetPasswordForm(form);
-  }
-}
-
-void IEImporter::ImportPasswordsIE7() {
-  if (!source_path_.empty()) {
-    // We have been called from the unit tests. Don't import real passwords.
-    return;
-  }
-
-  base::win::RegKey key(HKEY_CURRENT_USER, kStorage2Path, KEY_READ);
-  base::win::RegistryValueIterator reg_iterator(HKEY_CURRENT_USER,
-                                                kStorage2Path);
-  IE7PasswordInfo password_info;
-  while (reg_iterator.Valid() && !cancelled()) {
-    // Get the size of the encrypted data.
-    DWORD value_len = 0;
-    key.ReadValue(reg_iterator.Name(), NULL, &value_len, NULL);
-    if (value_len) {
-      // Query the encrypted data.
-      password_info.encrypted_data.resize(value_len);
-      if (key.ReadValue(reg_iterator.Name(),
-                        &password_info.encrypted_data.front(),
-                        &value_len, NULL) == ERROR_SUCCESS) {
-        password_info.url_hash = reg_iterator.Name();
-        password_info.date_created = base::Time::Now();
-
-        bridge_->AddIE7PasswordInfo(password_info);
-      }
-    }
-
-    ++reg_iterator;
-  }
-}
-
-void IEImporter::ImportSearchEngines() {
-  // On IE, search engines are stored in the registry, under:
-  // Software\Microsoft\Internet Explorer\SearchScopes
-  // Each key represents a search engine. The URL value contains the URL and
-  // the DisplayName the name.
-  typedef std::map<std::string, string16> SearchEnginesMap;
-  SearchEnginesMap search_engines_map;
-  for (base::win::RegistryKeyIterator key_iter(HKEY_CURRENT_USER,
-       kSearchScopePath); key_iter.Valid(); ++key_iter) {
-    string16 sub_key_name = kSearchScopePath;
-    sub_key_name.append(L"\\").append(key_iter.Name());
-    base::win::RegKey sub_key(HKEY_CURRENT_USER, sub_key_name.c_str(),
-                              KEY_READ);
-    string16 wide_url;
-    if ((sub_key.ReadValue(L"URL", &wide_url) != ERROR_SUCCESS) ||
-        wide_url.empty()) {
-      VLOG(1) << "No URL for IE search engine at " << key_iter.Name();
-      continue;
-    }
-    // For the name, we try the default value first (as Live Search uses a
-    // non displayable name in DisplayName, and the readable name under the
-    // default value).
-    string16 name;
-    if ((sub_key.ReadValue(NULL, &name) != ERROR_SUCCESS) || name.empty()) {
-      // Try the displayable name.
-      if ((sub_key.ReadValue(L"DisplayName", &name) != ERROR_SUCCESS) ||
-          name.empty()) {
-        VLOG(1) << "No name for IE search engine at " << key_iter.Name();
-        continue;
-      }
-    }
-
-    std::string url(WideToUTF8(wide_url));
-    SearchEnginesMap::iterator t_iter = search_engines_map.find(url);
-    if (t_iter == search_engines_map.end()) {
-      // First time we see that URL.
-      GURL gurl(url);
-      if (gurl.is_valid()) {
-        t_iter = search_engines_map.insert(std::make_pair(url, name)).first;
-      }
-    }
-  }
-  // ProfileWriter::AddKeywords() requires a vector and we have a map.
-  std::vector<importer::URLKeywordInfo> url_keywords;
-  for (SearchEnginesMap::iterator i = search_engines_map.begin();
-       i != search_engines_map.end(); ++i) {
-    importer::URLKeywordInfo url_keyword_info;
-    url_keyword_info.url = GURL(i->first);
-    url_keyword_info.display_name = i->second;
-    url_keywords.push_back(url_keyword_info);
-  }
-  bridge_->SetKeywords(url_keywords, true);
-}
-
-void IEImporter::ImportHomepage() {
-  const wchar_t* kIEHomepage = L"Start Page";
-  const wchar_t* kIEDefaultHomepage = L"Default_Page_URL";
-
-  base::win::RegKey key(HKEY_CURRENT_USER, kIESettingsMain, KEY_READ);
-  string16 homepage_url;
-  if (key.ReadValue(kIEHomepage, &homepage_url) != ERROR_SUCCESS ||
-      homepage_url.empty())
-    return;
-
-  GURL homepage = GURL(homepage_url);
-  if (!homepage.is_valid())
-    return;
-
-  // Check to see if this is the default website and skip import.
-  base::win::RegKey keyDefault(HKEY_LOCAL_MACHINE, kIESettingsMain, KEY_READ);
-  string16 default_homepage_url;
-  LONG result = keyDefault.ReadValue(kIEDefaultHomepage, &default_homepage_url);
-  if (result == ERROR_SUCCESS && !default_homepage_url.empty()) {
-    if (homepage.spec() == GURL(default_homepage_url).spec())
-      return;
-  }
-
-  bridge_->AddHomePage(homepage);
-}
-
-bool IEImporter::GetFavoritesInfo(IEImporter::FavoritesInfo* info) {
-  if (!source_path_.empty()) {
-    // Source path exists during testing.
-    info->path = source_path_;
-    info->path = info->path.AppendASCII("Favorites");
-    info->links_folder = L"Links";
-    return true;
-  }
-
-  // IE stores the favorites in the Favorites under user profile's folder.
-  wchar_t buffer[MAX_PATH];
-  if (FAILED(SHGetFolderPath(NULL, CSIDL_FAVORITES, NULL,
-                             SHGFP_TYPE_CURRENT, buffer)))
-    return false;
-  info->path = base::FilePath(buffer);
-
-  // There is a Links folder under Favorites folder in Windows Vista, but it
-  // is not recording in Vista's registry. So in Vista, we assume the Links
-  // folder is under Favorites folder since it looks like there is not name
-  // different in every language version of Windows Vista.
-  if (base::win::GetVersion() < base::win::VERSION_VISTA) {
-    // The Link folder name is stored in the registry.
-    DWORD buffer_length = sizeof(buffer);
-    base::win::RegKey reg_key(HKEY_CURRENT_USER, kIEToolbarKey, KEY_READ);
-    if (reg_key.ReadValue(L"LinksFolderName", buffer,
-                          &buffer_length, NULL) != ERROR_SUCCESS)
-      return false;
-    info->links_folder = buffer;
-  } else {
-    info->links_folder = L"Links";
-  }
-
-  return true;
-}
-
-void IEImporter::ParseFavoritesFolder(
-    const FavoritesInfo& info,
-    BookmarkVector* bookmarks,
-    std::vector<ImportedFaviconUsage>* favicons) {
-  base::FilePath file;
-  std::vector<base::FilePath::StringType> file_list;
-  base::FilePath favorites_path(info.path);
-  // Favorites path length.  Make sure it doesn't include the trailing \.
-  size_t favorites_path_len =
-      favorites_path.StripTrailingSeparators().value().size();
-  base::FileEnumerator file_enumerator(
-      favorites_path, true, base::FileEnumerator::FILES);
-  while (!(file = file_enumerator.Next()).value().empty() && !cancelled())
-    file_list.push_back(file.value());
-
-  // Keep the bookmarks in alphabetical order.
-  std::sort(file_list.begin(), file_list.end());
-
-  // Map from favicon URLs to the favicon data (the binary image data and the
-  // set of bookmark URLs referring to the favicon).
-  typedef std::map<GURL, ImportedFaviconUsage> FaviconMap;
-  FaviconMap favicon_map;
-
-  for (std::vector<base::FilePath::StringType>::iterator it = file_list.begin();
-       it != file_list.end(); ++it) {
-    base::FilePath shortcut(*it);
-    if (!LowerCaseEqualsASCII(shortcut.Extension(), ".url"))
-      continue;
-
-    // Skip the bookmark with invalid URL.
-    base::win::ScopedComPtr<IUniformResourceLocator> url_locator;
-    if (!LoadInternetShortcut(*it, &url_locator))
-      continue;
-    GURL url = ReadURLFromInternetShortcut(url_locator);
-    if (!url.is_valid())
-      continue;
-    // Skip default bookmarks. go.microsoft.com redirects to
-    // search.microsoft.com, and http://go.microsoft.com/fwlink/?LinkId=XXX,
-    // which URLs IE has as default, to some another sites.
-    // We expect that users will never themselves create bookmarks having this
-    // hostname.
-    if (url.host() == "go.microsoft.com")
-      continue;
-    // Read favicon.
-    UpdateFaviconMap(*it, url, url_locator, &favicon_map);
-
-    // Make the relative path from the Favorites folder, without the basename.
-    // ex. Suppose that the Favorites folder is C:\Users\Foo\Favorites.
-    //   C:\Users\Foo\Favorites\Foo.url -> ""
-    //   C:\Users\Foo\Favorites\Links\Bar\Baz.url -> "Links\Bar"
-    base::FilePath::StringType relative_string =
-        shortcut.DirName().value().substr(favorites_path_len);
-    if (!relative_string.empty() &&
-        base::FilePath::IsSeparator(relative_string[0]))
-      relative_string = relative_string.substr(1);
-    base::FilePath relative_path(relative_string);
-
-    ImportedBookmarkEntry entry;
-    // Remove the dot, the file extension, and the directory path.
-    entry.title = shortcut.RemoveExtension().BaseName().value();
-    entry.url = url;
-    entry.creation_time = GetFileCreationTime(*it);
-    if (!relative_path.empty())
-      relative_path.GetComponents(&entry.path);
-
-    // Add the bookmark.
-    if (!entry.path.empty() && entry.path[0] == info.links_folder) {
-      // Bookmarks in the Link folder should be imported to the toolbar.
-      entry.in_toolbar = true;
-    }
-    bookmarks->push_back(entry);
-  }
-
-  // Reflect the menu order in IE.
-  SortBookmarksInIEOrder(this, bookmarks);
-
-  // Record favicon data.
-  for (FaviconMap::iterator iter = favicon_map.begin();
-       iter != favicon_map.end(); ++iter)
-    favicons->push_back(iter->second);
-}
-
-int IEImporter::CurrentIEVersion() const {
-  static int version = -1;
-  if (version < 0) {
-    wchar_t buffer[128];
-    DWORD buffer_length = sizeof(buffer);
-    base::win::RegKey reg_key(HKEY_LOCAL_MACHINE, kIEVersionKey, KEY_READ);
-    LONG result = reg_key.ReadValue(L"Version", buffer, &buffer_length, NULL);
-    version = ((result == ERROR_SUCCESS)? _wtoi(buffer) : 0);
-  }
-  return version;
-}
diff --git a/chrome/browser/importer/ie_importer.h b/chrome/browser/importer/ie_importer.h
deleted file mode 100644
index c96200c..0000000
--- a/chrome/browser/importer/ie_importer.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_IE_IMPORTER_H_
-#define CHROME_BROWSER_IMPORTER_IE_IMPORTER_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/files/file_path.h"
-#include "base/gtest_prod_util.h"
-#include "base/strings/string16.h"
-#include "chrome/browser/importer/importer.h"
-
-struct ImportedBookmarkEntry;
-struct ImportedFaviconUsage;
-
-class IEImporter : public Importer {
- public:
-  IEImporter();
-
-  // Importer:
-  virtual void StartImport(const importer::SourceProfile& source_profile,
-                           uint16 items,
-                           ImporterBridge* bridge) OVERRIDE;
-
- private:
-  typedef std::vector<ImportedBookmarkEntry> BookmarkVector;
-
-  // A struct that hosts the information of IE Favorite folder.
-  struct FavoritesInfo {
-    base::FilePath path;
-    string16 links_folder;
-  };
-
-  // IE PStore subkey GUID: AutoComplete password & form data.
-  static const GUID kPStoreAutocompleteGUID;
-
-  // A fake GUID for unit test.
-  static const GUID kUnittestGUID;
-
-  FRIEND_TEST_ALL_PREFIXES(ImporterTest, IEImporter);
-
-  virtual ~IEImporter();
-
-  void ImportFavorites();
-
-  // Reads history information from COM interface.
-  void ImportHistory();
-
-  // Import password for IE6 stored in protected storage.
-  void ImportPasswordsIE6();
-
-  // Import password for IE7 and IE8 stored in Storage2.
-  void ImportPasswordsIE7();
-
-  void ImportSearchEngines();
-
-  // Import the homepage setting of IE. Note: IE supports multiple home pages,
-  // whereas Chrome doesn't, so we import only the one defined under the
-  // 'Start Page' registry key. We don't import if the homepage is set to the
-  // machine default.
-  void ImportHomepage();
-
-  // Gets the information of Favorites folder. Returns true if successful.
-  bool GetFavoritesInfo(FavoritesInfo* info);
-
-  // This function will read the files in the Favorites folder, and store
-  // the bookmark items in |bookmarks| and favicon information in |favicons|.
-  void ParseFavoritesFolder(
-      const FavoritesInfo& info,
-      BookmarkVector* bookmarks,
-      std::vector<ImportedFaviconUsage>* favicons);
-
-  // Determines which version of IE is in use.
-  int CurrentIEVersion() const;
-
-  // IE does not have source path. It's used in unit tests only for providing a
-  // fake source.
-  base::FilePath source_path_;
-
-  DISALLOW_COPY_AND_ASSIGN(IEImporter);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_IE_IMPORTER_H_
diff --git a/chrome/browser/importer/ie_importer_browsertest_win.cc b/chrome/browser/importer/ie_importer_browsertest_win.cc
index d4747d4..79d849f 100644
--- a/chrome/browser/importer/ie_importer_browsertest_win.cc
+++ b/chrome/browser/importer/ie_importer_browsertest_win.cc
@@ -29,21 +29,21 @@
 #include "base/win/scoped_propvariant.h"
 #include "base/win/windows_version.h"
 #include "chrome/browser/importer/external_process_importer_host.h"
-#include "chrome/browser/importer/ie_importer.h"
-#include "chrome/browser/importer/ie_importer_test_registry_overrider_win.h"
-#include "chrome/browser/importer/ie_importer_utils_win.h"
-#include "chrome/browser/importer/importer_bridge.h"
 #include "chrome/browser/importer/importer_progress_observer.h"
 #include "chrome/browser/importer/importer_unittest_utils.h"
-#include "chrome/browser/importer/pstore_declarations.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/chrome_paths.h"
+#include "chrome/common/importer/ie_importer_test_registry_overrider_win.h"
+#include "chrome/common/importer/ie_importer_utils_win.h"
 #include "chrome/common/importer/imported_bookmark_entry.h"
 #include "chrome/common/importer/imported_favicon_usage.h"
+#include "chrome/common/importer/importer_bridge.h"
 #include "chrome/common/importer/importer_data_types.h"
+#include "chrome/common/importer/pstore_declarations.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/testing_profile.h"
+#include "components/webdata/encryptor/ie7_password.h"
 #include "content/public/common/password_form.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -255,11 +255,21 @@
 class TestObserver : public ProfileWriter,
                      public importer::ImporterProgressObserver {
  public:
-  TestObserver() : ProfileWriter(NULL) {
-    bookmark_count_ = 0;
-    history_count_ = 0;
-    password_count_ = 0;
-    favicon_count_ = 0;
+  enum TestIEVersion {
+    IE6,
+    IE7,
+  };
+
+  explicit TestObserver(uint16 importer_items, TestIEVersion ie_version)
+      : ProfileWriter(NULL),
+        bookmark_count_(0),
+        history_count_(0),
+        password_count_(0),
+        favicon_count_(0),
+        homepage_count_(0),
+        ie7_password_count_(0),
+        importer_items_(importer_items),
+        ie_version_(ie_version) {
   }
 
   // importer::ImporterProgressObserver:
@@ -268,9 +278,19 @@
   virtual void ImportItemEnded(importer::ImportItem item) OVERRIDE {}
   virtual void ImportEnded() OVERRIDE {
     base::MessageLoop::current()->Quit();
-    EXPECT_EQ(arraysize(kIEBookmarks), bookmark_count_);
-    EXPECT_EQ(1, history_count_);
-    EXPECT_EQ(arraysize(kIEFaviconGroup), favicon_count_);
+    if (importer_items_ & importer::FAVORITES) {
+      EXPECT_EQ(arraysize(kIEBookmarks), bookmark_count_);
+      EXPECT_EQ(arraysize(kIEFaviconGroup), favicon_count_);
+    }
+    if (importer_items_ & importer::HISTORY)
+      EXPECT_EQ(1, history_count_);
+    if (importer_items_ & importer::HOME_PAGE)
+      EXPECT_EQ(1, homepage_count_);
+    if ((importer_items_ & importer::PASSWORDS) && (ie_version_ == IE7))
+      EXPECT_EQ(1, ie7_password_count_);
+    // We need to test the IE6 password importer code.
+    // https://crbug.com/257100
+    // EXPECT_EQ(1, password_count_);
   }
 
   virtual bool BookmarkModelIsLoaded() const {
@@ -351,6 +371,21 @@
     favicon_count_ += usage.size();
   }
 
+  virtual void AddIE7PasswordInfo(const IE7PasswordInfo& info) {
+    // This function also gets called for the IEImporter test. Ignore.
+    if (ie_version_ == IE7) {
+      EXPECT_EQ(L"Test1", info.url_hash);
+      EXPECT_EQ(1, info.encrypted_data[0]);
+      EXPECT_EQ(4, info.encrypted_data.size());
+      ++ie7_password_count_;
+    }
+  }
+
+  virtual void AddHomepage(const GURL& homepage) {
+    EXPECT_EQ(homepage.spec(), "http://www.test.com/");
+    ++homepage_count_;
+  }
+
  private:
   ~TestObserver() {}
 
@@ -358,6 +393,10 @@
   size_t history_count_;
   size_t password_count_;
   size_t favicon_count_;
+  size_t homepage_count_;
+  size_t ie7_password_count_;
+  uint16 importer_items_;
+  TestIEVersion ie_version_;
 };
 
 class MalformedFavoritesRegistryTestObserver
@@ -418,7 +457,8 @@
 
   base::ScopedTempDir temp_dir_;
 
-  // Overrides the default registry key for IE's favorites order blob.
+  // Overrides the default registry key for IE registry keys like favorites,
+  // settings, password store, etc.
   IEImporterTestRegistryOverrider test_registry_overrider_;
 };
 
@@ -485,7 +525,9 @@
   // Starts to import the above settings.
   // Deletes itself.
   ExternalProcessImporterHost* host = new ExternalProcessImporterHost;
-  TestObserver* observer = new TestObserver();
+  TestObserver* observer = new TestObserver(
+      importer::HISTORY | importer::PASSWORDS | importer::FAVORITES,
+      TestObserver::IE6);
   host->set_observer(observer);
 
   importer::SourceProfile source_profile;
@@ -577,3 +619,56 @@
     base::MessageLoop::current()->Run();
   }
 }
+
+IN_PROC_BROWSER_TEST_F(IEImporterBrowserTest, IE7ImporterPasswordsTest) {
+  // Starts to import the IE7 passwords.
+  // Deletes itself.
+  ExternalProcessImporterHost* host = new ExternalProcessImporterHost;
+  TestObserver* observer = new TestObserver(importer::PASSWORDS,
+                                            TestObserver::IE7);
+  host->set_observer(observer);
+
+  base::string16 key_path(importer::GetIE7PasswordsKey());
+  base::win::RegKey key;
+  ASSERT_EQ(ERROR_SUCCESS,
+            key.Create(HKEY_CURRENT_USER, key_path.c_str(), KEY_WRITE));
+  key.WriteValue(L"Test1", 1);
+
+  importer::SourceProfile source_profile;
+  source_profile.importer_type = importer::TYPE_IE;
+  source_profile.source_path = temp_dir_.path();
+
+  host->StartImportSettings(
+      source_profile,
+      browser()->profile(),
+      importer::PASSWORDS,
+      observer);
+  base::MessageLoop::current()->Run();
+}
+
+IN_PROC_BROWSER_TEST_F(IEImporterBrowserTest, IEImporterHomePageTest) {
+  // Starts to import the IE home page.
+  // Deletes itself.
+  ExternalProcessImporterHost* host = new ExternalProcessImporterHost;
+  TestObserver* observer = new TestObserver(importer::HOME_PAGE,
+                                            TestObserver::IE6);
+  host->set_observer(observer);
+
+  base::string16 key_path(importer::GetIESettingsKey());
+  base::win::RegKey key;
+  ASSERT_EQ(ERROR_SUCCESS,
+            key.Create(HKEY_CURRENT_USER, key_path.c_str(), KEY_WRITE));
+  key.WriteValue(L"Start Page", L"http://www.test.com/");
+
+  importer::SourceProfile source_profile;
+  source_profile.importer_type = importer::TYPE_IE;
+  source_profile.source_path = temp_dir_.path();
+
+  host->StartImportSettings(
+      source_profile,
+      browser()->profile(),
+      importer::HOME_PAGE,
+      observer);
+  base::MessageLoop::current()->Run();
+}
+
diff --git a/chrome/browser/importer/ie_importer_test_registry_overrider_win.cc b/chrome/browser/importer/ie_importer_test_registry_overrider_win.cc
deleted file mode 100644
index 7d1dcf4..0000000
--- a/chrome/browser/importer/ie_importer_test_registry_overrider_win.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/ie_importer_test_registry_overrider_win.h"
-
-#include <windows.h>
-
-#include <string>
-
-#include "base/environment.h"
-#include "base/guid.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/win/registry.h"
-
-namespace {
-
-// The key to which a random subkey will be appended. This key itself will never
-// be deleted.
-const wchar_t kTestHKCUOverrideKeyPrefix[] = L"SOFTWARE\\Chromium Unit Tests\\";
-const char kTestHKCUOverrideEnvironmentVariable[] =
-    "IE_IMPORTER_TEST_OVERRIDE_HKCU";
-
-// Reads the environment variable set by a previous call to
-// SetTestRegistryOverride() into |key| if it exists and |key| is not NULL.
-// Returns true if the variable was successfully read.
-bool GetTestKeyFromEnvironment(base::string16* key) {
-  scoped_ptr<base::Environment> env(base::Environment::Create());
-  std::string value;
-  bool result = env->GetVar(kTestHKCUOverrideEnvironmentVariable, &value);
-  if (result)
-    *key = UTF8ToUTF16(value);
-  return result;
-}
-
-}  // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-// IEImporterTestRegistryOverrider, public:
-
-IEImporterTestRegistryOverrider::IEImporterTestRegistryOverrider()
-    : temporary_key_(kTestHKCUOverrideKeyPrefix +
-                     UTF8ToUTF16(base::GenerateGUID())) {
-  DCHECK(!GetTestKeyFromEnvironment(NULL));
-
-  scoped_ptr<base::Environment> env(base::Environment::Create());
-  bool success = env->SetVar(kTestHKCUOverrideEnvironmentVariable,
-                             UTF16ToUTF8(temporary_key_));
-  DCHECK(success);
-}
-
-IEImporterTestRegistryOverrider::~IEImporterTestRegistryOverrider() {
-  base::win::RegKey reg_key(HKEY_CURRENT_USER, temporary_key_.c_str(),
-                            KEY_ALL_ACCESS);
-  DCHECK(reg_key.Valid());
-  reg_key.DeleteKey(L"");
-
-  scoped_ptr<base::Environment> env(base::Environment::Create());
-  bool success = env->UnSetVar(kTestHKCUOverrideEnvironmentVariable);
-  DCHECK(success);
-}
-
-// static
-base::string16 IEImporterTestRegistryOverrider::GetTestRegistryOverride() {
-  base::string16 key;
-  if (!GetTestKeyFromEnvironment(&key))
-    return string16();
-  return key;
-}
diff --git a/chrome/browser/importer/ie_importer_test_registry_overrider_win.h b/chrome/browser/importer/ie_importer_test_registry_overrider_win.h
deleted file mode 100644
index 11b4674..0000000
--- a/chrome/browser/importer/ie_importer_test_registry_overrider_win.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_IE_IMPORTER_TEST_REGISTRY_OVERRIDER_WIN_H_
-#define CHROME_BROWSER_IMPORTER_IE_IMPORTER_TEST_REGISTRY_OVERRIDER_WIN_H_
-
-#include "base/basictypes.h"
-#include "base/strings/string16.h"
-
-// A helper class to let tests generate a random registry key to be used in
-// HKEY_CURRENT_USER in tests. After the key has been generated by constructing
-// an IEImporterTestRegistryOverrider, consumers in this process (or in any
-// child processes created after the key has been generated) can obtain the key
-// via GetTestRegistryOverride(). IEImporterTestRegistryOverrider will delete
-// the temporary key upon being deleted itself. Only one
-// IEImporterTestRegistryOverrider should live at once in a given process
-// hiearchy.
-class IEImporterTestRegistryOverrider {
- public:
-  IEImporterTestRegistryOverrider();
-  ~IEImporterTestRegistryOverrider();
-
-  // Returns a test key if one was chosen and set by a call to
-  // SetTestRegistryOverride(); returns the empty string if none.
-  static base::string16 GetTestRegistryOverride();
-
- private:
-  base::string16 temporary_key_;
-
-  DISALLOW_COPY_AND_ASSIGN(IEImporterTestRegistryOverrider);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_IE_IMPORTER_TEST_REGISTRY_OVERRIDER_WIN_H_
diff --git a/chrome/browser/importer/ie_importer_unittest_win.cc b/chrome/browser/importer/ie_importer_unittest_win.cc
deleted file mode 100644
index df16ade..0000000
--- a/chrome/browser/importer/ie_importer_unittest_win.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2012 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 "testing/gtest/include/gtest/gtest.h"
-
-#include <windows.h>
-
-#include <vector>
-
-#include "base/strings/string16.h"
-#include "components/webdata/encryptor/ie7_password.h"
-
-TEST(IEImporterTest, IE7Importer) {
-  // This is the unencrypted values of my keys under Storage2.
-  // The passwords have been manually changed to abcdef... but the size remains
-  // the same.
-  unsigned char data1[] = "\x0c\x00\x00\x00\x38\x00\x00\x00\x2c\x00\x00\x00"
-                          "\x57\x49\x43\x4b\x18\x00\x00\x00\x02\x00\x00\x00"
-                          "\x67\x00\x72\x00\x01\x00\x00\x00\x00\x00\x00\x00"
-                          "\x00\x00\x00\x00\x4e\xfa\x67\x76\x22\x94\xc8\x01"
-                          "\x08\x00\x00\x00\x12\x00\x00\x00\x4e\xfa\x67\x76"
-                          "\x22\x94\xc8\x01\x0c\x00\x00\x00\x61\x00\x62\x00"
-                          "\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00"
-                          "\x00\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00"
-                          "\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00"
-                          "\x6c\x00\x00\x00";
-
-  unsigned char data2[] = "\x0c\x00\x00\x00\x38\x00\x00\x00\x24\x00\x00\x00"
-                          "\x57\x49\x43\x4b\x18\x00\x00\x00\x02\x00\x00\x00"
-                          "\x67\x00\x72\x00\x01\x00\x00\x00\x00\x00\x00\x00"
-                          "\x00\x00\x00\x00\xa8\xea\xf4\xe5\x9f\x9a\xc8\x01"
-                          "\x09\x00\x00\x00\x14\x00\x00\x00\xa8\xea\xf4\xe5"
-                          "\x9f\x9a\xc8\x01\x07\x00\x00\x00\x61\x00\x62\x00"
-                          "\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00"
-                          "\x69\x00\x00\x00\x61\x00\x62\x00\x63\x00\x64\x00"
-                          "\x65\x00\x66\x00\x67\x00\x00\x00";
-
-
-
-  std::vector<unsigned char> decrypted_data1;
-  decrypted_data1.resize(arraysize(data1));
-  memcpy(&decrypted_data1.front(), data1, sizeof(data1));
-
-  std::vector<unsigned char> decrypted_data2;
-  decrypted_data2.resize(arraysize(data2));
-  memcpy(&decrypted_data2.front(), data2, sizeof(data2));
-
-  string16 password;
-  string16 username;
-  ASSERT_TRUE(ie7_password::GetUserPassFromData(decrypted_data1, &username,
-                                                &password));
-  EXPECT_EQ(L"abcdefgh", username);
-  EXPECT_EQ(L"abcdefghijkl", password);
-
-  ASSERT_TRUE(ie7_password::GetUserPassFromData(decrypted_data2, &username,
-                                                &password));
-  EXPECT_EQ(L"abcdefghi", username);
-  EXPECT_EQ(L"abcdefg", password);
-}
diff --git a/chrome/browser/importer/ie_importer_utils_win.cc b/chrome/browser/importer/ie_importer_utils_win.cc
deleted file mode 100644
index a773f3f..0000000
--- a/chrome/browser/importer/ie_importer_utils_win.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/ie_importer_utils_win.h"
-
-#include "chrome/browser/importer/ie_importer_test_registry_overrider_win.h"
-
-namespace {
-
-const char16 kIEFavoritesOrderKey[] =
-    L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\"
-    L"MenuOrder\\Favorites";
-
-}
-
-namespace importer {
-
-base::string16 GetIEFavoritesOrderKey() {
-  // Return kIEFavoritesOrderKey unless an override has been set for tests.
-  base::string16 test_reg_override(
-      IEImporterTestRegistryOverrider::GetTestRegistryOverride());
-  return test_reg_override.empty() ? kIEFavoritesOrderKey : test_reg_override;
-}
-
-}
diff --git a/chrome/browser/importer/ie_importer_utils_win.h b/chrome/browser/importer/ie_importer_utils_win.h
deleted file mode 100644
index ff61453..0000000
--- a/chrome/browser/importer/ie_importer_utils_win.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_IE_IMPORTER_UTILS_WIN_H_
-#define CHROME_BROWSER_IMPORTER_IE_IMPORTER_UTILS_WIN_H_
-
-#include "base/strings/string16.h"
-
-namespace importer {
-
-// Returns the key to be used in HKCU to look for IE's favorites order blob.
-// Overridable by tests via IEImporterTestRegistryOverrider.
-base::string16 GetIEFavoritesOrderKey();
-
-}
-
-#endif  // CHROME_BROWSER_IMPORTER_IE_IMPORTER_UTILS_WIN_H_
diff --git a/chrome/browser/importer/importer.cc b/chrome/browser/importer/importer.cc
deleted file mode 100644
index a1133a5..0000000
--- a/chrome/browser/importer/importer.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/importer.h"
-
-#include "chrome/browser/importer/importer_bridge.h"
-
-void Importer::Cancel() {
-  cancelled_ = true;
-}
-
-Importer::Importer() : cancelled_(false) {}
-
-Importer::~Importer() {}
diff --git a/chrome/browser/importer/importer.h b/chrome/browser/importer/importer.h
deleted file mode 100644
index a2f2340..0000000
--- a/chrome/browser/importer/importer.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_IMPORTER_H_
-#define CHROME_BROWSER_IMPORTER_IMPORTER_H_
-
-#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
-
-class ImporterBridge;
-
-namespace importer {
-struct SourceProfile;
-}
-
-// The base class of all importers.
-class Importer : public base::RefCountedThreadSafe<Importer> {
- public:
-  // All importers should implement this method by adding their import logic.
-  // And it will be run in file thread by ImporterHost. Since we do async
-  // import, the importer should invoke ImporterHost::NotifyImportEnded() to
-  // notify its host that import stuff have been finished.
-  virtual void StartImport(const importer::SourceProfile& source_profile,
-                           uint16 items,
-                           ImporterBridge* bridge) = 0;
-
-  // Cancels the import process.
-  virtual void Cancel();
-
-  bool cancelled() const { return cancelled_; }
-
- protected:
-  friend class base::RefCountedThreadSafe<Importer>;
-
-  Importer();
-  virtual ~Importer();
-
-  scoped_refptr<ImporterBridge> bridge_;
-
- private:
-  // True if the caller cancels the import process.
-  bool cancelled_;
-
-  DISALLOW_COPY_AND_ASSIGN(Importer);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_IMPORTER_H_
diff --git a/chrome/browser/importer/importer_bridge.cc b/chrome/browser/importer/importer_bridge.cc
deleted file mode 100644
index 7910c6a..0000000
--- a/chrome/browser/importer/importer_bridge.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/importer_bridge.h"
-
-ImporterBridge::ImporterBridge() {}
-
-ImporterBridge::~ImporterBridge() {}
diff --git a/chrome/browser/importer/importer_bridge.h b/chrome/browser/importer/importer_bridge.h
deleted file mode 100644
index ac9cfd5..0000000
--- a/chrome/browser/importer/importer_bridge.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_IMPORTER_BRIDGE_H_
-#define CHROME_BROWSER_IMPORTER_IMPORTER_BRIDGE_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
-#include "base/strings/string16.h"
-#include "build/build_config.h"
-#include "chrome/browser/history/history_types.h"
-#include "chrome/common/importer/importer_data_types.h"
-#include "chrome/common/importer/importer_url_row.h"
-
-class GURL;
-struct IE7PasswordInfo;
-struct ImportedBookmarkEntry;
-struct ImportedFaviconUsage;
-
-namespace importer {
-struct URLKeywordInfo;
-}
-
-namespace content {
-struct PasswordForm;
-}
-
-class ImporterBridge : public base::RefCountedThreadSafe<ImporterBridge> {
- public:
-  ImporterBridge();
-
-  virtual void AddBookmarks(
-      const std::vector<ImportedBookmarkEntry>& bookmarks,
-      const string16& first_folder_name) = 0;
-
-  virtual void AddHomePage(const GURL& home_page) = 0;
-
-#if defined(OS_WIN)
-  virtual void AddIE7PasswordInfo(const IE7PasswordInfo& password_info) = 0;
-#endif
-
-  virtual void SetFavicons(
-      const std::vector<ImportedFaviconUsage>& favicons) = 0;
-
-  virtual void SetHistoryItems(const std::vector<ImporterURLRow>& rows,
-                               history::VisitSource visit_source) = 0;
-
-  virtual void SetKeywords(
-      const std::vector<importer::URLKeywordInfo>& url_keywords,
-      bool unique_on_host_and_path) = 0;
-
-  // The search_engine_data vector contains XML data retrieved from the Firefox
-  // profile and its sqlite db.
-  virtual void SetFirefoxSearchEnginesXMLData(
-      const std::vector<std::string>& search_engine_data) = 0;
-
-  virtual void SetPasswordForm(const content::PasswordForm& form) = 0;
-
-  // Notifies the coordinator that the import operation has begun.
-  virtual void NotifyStarted() = 0;
-
-  // Notifies the coordinator that the collection of data for the specified
-  // item has begun.
-  virtual void NotifyItemStarted(importer::ImportItem item) = 0;
-
-  // Notifies the coordinator that the collection of data for the specified
-  // item has completed.
-  virtual void NotifyItemEnded(importer::ImportItem item) = 0;
-
-  // Notifies the coordinator that the entire import operation has completed.
-  virtual void NotifyEnded() = 0;
-
-  // For InProcessImporters this calls l10n_util. For ExternalProcessImporters
-  // this calls the set of strings we've ported over to the external process.
-  // It's good to avoid having to create a separate ResourceBundle for the
-  // external import process, since the importer only needs a few strings.
-  virtual string16 GetLocalizedString(int message_id) = 0;
-
- protected:
-  friend class base::RefCountedThreadSafe<ImporterBridge>;
-
-  virtual ~ImporterBridge();
-
-  DISALLOW_COPY_AND_ASSIGN(ImporterBridge);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_IMPORTER_BRIDGE_H_
diff --git a/chrome/browser/importer/importer_list.cc b/chrome/browser/importer/importer_list.cc
index 7c9df71..0e9ff34 100644
--- a/chrome/browser/importer/importer_list.cc
+++ b/chrome/browser/importer/importer_list.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/importer/importer_list.h"
 
 #include "base/bind.h"
-#include "chrome/browser/importer/firefox_importer_utils.h"
-#include "chrome/browser/importer/importer_bridge.h"
 #include "chrome/browser/importer/importer_list_observer.h"
 #include "chrome/browser/shell_integration.h"
+#include "chrome/common/importer/firefox_importer_utils.h"
+#include "chrome/common/importer/importer_bridge.h"
 #include "chrome/common/importer/importer_data_types.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -17,7 +17,7 @@
 #include <CoreFoundation/CoreFoundation.h>
 
 #include "base/mac/foundation_util.h"
-#include "chrome/browser/importer/safari_importer.h"
+#include "chrome/common/importer/safari_importer_utils.h"
 #endif
 
 using content::BrowserThread;
@@ -41,7 +41,7 @@
 #if defined(OS_MACOSX)
 void DetectSafariProfiles(std::vector<importer::SourceProfile*>* profiles) {
   uint16 items = importer::NONE;
-  if (!SafariImporter::CanImport(base::mac::GetUserLibraryPath(), &items))
+  if (!SafariImporterCanImport(base::mac::GetUserLibraryPath(), &items))
     return;
 
   importer::SourceProfile* safari = new importer::SourceProfile;
diff --git a/chrome/browser/importer/importer_creator.cc b/chrome/browser/importer/importer_uma.cc
similarity index 66%
rename from chrome/browser/importer/importer_creator.cc
rename to chrome/browser/importer/importer_uma.cc
index 7127ed2..4e62217 100644
--- a/chrome/browser/importer/importer_creator.cc
+++ b/chrome/browser/importer/importer_uma.cc
@@ -2,22 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/importer/importer_creator.h"
-
-#include "base/logging.h"
-#include "base/metrics/histogram.h"
-#include "chrome/browser/importer/bookmarks_file_importer.h"
-#include "chrome/browser/importer/firefox3_importer.h"
-
-#if defined(OS_WIN)
-#include "chrome/browser/importer/ie_importer.h"
-#endif
-
-#if defined(OS_MACOSX)
-#include <CoreFoundation/CoreFoundation.h>
-#include "base/mac/foundation_util.h"
-#include "chrome/browser/importer/safari_importer.h"
-#endif
+#include "build/build_config.h"
+#include "chrome/browser/importer/importer_uma.h"
 
 namespace importer {
 
@@ -42,31 +28,8 @@
   IMPORTER_METRICS_SIZE
 };
 
-
 }  // namespace
 
-Importer* CreateImporterByType(ImporterType type) {
-  switch (type) {
-#if defined(OS_WIN)
-    case TYPE_IE:
-      return new IEImporter();
-#endif
-    case TYPE_BOOKMARKS_FILE:
-      return new BookmarksFileImporter();
-    case TYPE_FIREFOX3:
-      return new Firefox3Importer();
-#if defined(OS_MACOSX)
-    case TYPE_SAFARI:
-      return new SafariImporter(base::mac::GetUserLibraryPath());
-#endif
-    default:
-      NOTREACHED();
-      return NULL;
-  }
-  NOTREACHED();
-  return NULL;
-}
-
 void LogImporterUseToMetrics(const std::string& metric_postfix,
                              ImporterType type) {
   ImporterTypeMetrics metrics_type = IMPORTER_METRICS_UNKNOWN;
diff --git a/chrome/browser/importer/importer_creator.h b/chrome/browser/importer/importer_uma.h
similarity index 70%
rename from chrome/browser/importer/importer_creator.h
rename to chrome/browser/importer/importer_uma.h
index b3b7465..c71e6c9 100644
--- a/chrome/browser/importer/importer_creator.h
+++ b/chrome/browser/importer/importer_uma.h
@@ -2,20 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_IMPORTER_IMPORTER_CREATOR_H_
-#define CHROME_BROWSER_IMPORTER_IMPORTER_CREATOR_H_
+#ifndef CHROME_BROWSER_IMPORTER_IMPORTER_UMA_H_
+#define CHROME_BROWSER_IMPORTER_IMPORTER_UMA_H_
 
 #include <string>
-
+#include "base/metrics/histogram.h"
 #include "chrome/common/importer/importer_type.h"
 
-class Importer;
-
 namespace importer {
 
-// Creates an Importer of the specified |type|.
-Importer* CreateImporterByType(ImporterType type);
-
 // Logs to UMA that an Importer of the specified |type| was used. Uses
 // |metric_postfix| to split by entry point. Note: Values passed via
 // |metric_postfix| require a matching "Import.ImporterType.|metric_postfix|"
@@ -25,4 +20,4 @@
 
 }  // namespace importer
 
-#endif  // CHROME_BROWSER_IMPORTER_IMPORTER_CREATOR_H_
+#endif  // CHROME_BROWSER_IMPORTER_IMPORTER_UMA_H_
diff --git a/chrome/browser/importer/in_process_importer_bridge.cc b/chrome/browser/importer/in_process_importer_bridge.cc
index 14c1593..61d09d2 100644
--- a/chrome/browser/importer/in_process_importer_bridge.cc
+++ b/chrome/browser/importer/in_process_importer_bridge.cc
@@ -43,6 +43,22 @@
   return converted;
 }
 
+history::VisitSource ConvertImporterVisitSourceToHistoryVisitSource(
+    importer::VisitSource visit_source) {
+  switch (visit_source) {
+    case importer::VISIT_SOURCE_BROWSED:
+      return history::SOURCE_BROWSED;
+    case importer::VISIT_SOURCE_FIREFOX_IMPORTED:
+      return history::SOURCE_FIREFOX_IMPORTED;
+    case importer::VISIT_SOURCE_IE_IMPORTED:
+      return history::SOURCE_IE_IMPORTED;
+    case importer::VISIT_SOURCE_SAFARI_IMPORTED:
+      return history::SOURCE_SAFARI_IMPORTED;
+  }
+  NOTREACHED();
+  return history::SOURCE_SYNCED;
+}
+
 }  // namespace
 
 using content::BrowserThread;
@@ -165,10 +181,16 @@
 
 #if defined(OS_WIN)
 void InProcessImporterBridge::AddIE7PasswordInfo(
-    const IE7PasswordInfo& password_info) {
+    const importer::ImporterIE7PasswordInfo& password_info) {
+  IE7PasswordInfo ie7_password_info;
+  ie7_password_info.url_hash = password_info.url_hash;
+  ie7_password_info.encrypted_data = password_info.encrypted_data;
+  ie7_password_info.date_created = password_info.date_created;
+
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::Bind(&ProfileWriter::AddIE7PasswordInfo, writer_, password_info));
+      base::Bind(&ProfileWriter::AddIE7PasswordInfo, writer_,
+                 ie7_password_info));
 }
 #endif  // OS_WIN
 
@@ -181,13 +203,17 @@
 
 void InProcessImporterBridge::SetHistoryItems(
     const std::vector<ImporterURLRow>& rows,
-    history::VisitSource visit_source) {
-  history::URLRows converted = ConvertImporterURLRowsToHistoryURLRows(rows);
-  BrowserThread::PostTask(
-      BrowserThread::UI,
-      FROM_HERE,
-      base::Bind(
-          &ProfileWriter::AddHistoryPage, writer_, converted, visit_source));
+    importer::VisitSource visit_source) {
+  history::URLRows converted_rows =
+      ConvertImporterURLRowsToHistoryURLRows(rows);
+  history::VisitSource converted_visit_source =
+      ConvertImporterVisitSourceToHistoryVisitSource(visit_source);
+  BrowserThread::PostTask(BrowserThread::UI,
+                          FROM_HERE,
+                          base::Bind(&ProfileWriter::AddHistoryPage,
+                                     writer_,
+                                     converted_rows,
+                                     converted_visit_source));
 }
 
 void InProcessImporterBridge::SetKeywords(
diff --git a/chrome/browser/importer/in_process_importer_bridge.h b/chrome/browser/importer/in_process_importer_bridge.h
index 89786d4..664592b 100644
--- a/chrome/browser/importer/in_process_importer_bridge.h
+++ b/chrome/browser/importer/in_process_importer_bridge.h
@@ -12,8 +12,8 @@
 #include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
-#include "chrome/browser/importer/importer_bridge.h"
 #include "chrome/browser/importer/profile_writer.h"
+#include "chrome/common/importer/importer_bridge.h"
 
 class GURL;
 struct ImportedBookmarkEntry;
@@ -21,6 +21,10 @@
 class ExternalProcessImporterHost;
 
 namespace importer {
+#if defined(OS_WIN)
+struct ImporterIE7PasswordInfo;
+#endif
+struct ImporterURlRow;
 struct URLKeywordInfo;
 }
 
@@ -38,14 +42,14 @@
 
 #if defined(OS_WIN)
   virtual void AddIE7PasswordInfo(
-      const IE7PasswordInfo& password_info) OVERRIDE;
+      const importer::ImporterIE7PasswordInfo& password_info) OVERRIDE;
 #endif
 
   virtual void SetFavicons(
       const std::vector<ImportedFaviconUsage>& favicons) OVERRIDE;
 
   virtual void SetHistoryItems(const std::vector<ImporterURLRow>& rows,
-                               history::VisitSource visit_source) OVERRIDE;
+                               importer::VisitSource visit_source) OVERRIDE;
 
   virtual void SetKeywords(
       const std::vector<importer::URLKeywordInfo>& url_keywords,
diff --git a/chrome/browser/importer/nss_decryptor.cc b/chrome/browser/importer/nss_decryptor.cc
deleted file mode 100644
index 6388786..0000000
--- a/chrome/browser/importer/nss_decryptor.cc
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/nss_decryptor.h"
-
-#include <string>
-#include <vector>
-
-#include "base/base64.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "content/public/common/password_form.h"
-#include "sql/connection.h"
-#include "sql/statement.h"
-
-#if defined(USE_NSS)
-#include <pk11pub.h>
-#include <pk11sdr.h>
-#endif  // defined(USE_NSS)
-
-// This method is based on some Firefox code in
-//   security/manager/ssl/src/nsSDR.cpp
-// The license block is:
-
-/* ***** BEGIN LICENSE BLOCK *****
-* Version: MPL 1.1/GPL 2.0/LGPL 2.1
-*
-* The contents of this file are subject to the Mozilla Public License Version
-* 1.1 (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-* http://www.mozilla.org/MPL/
-*
-* Software distributed under the License is distributed on an "AS IS" basis,
-* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-* for the specific language governing rights and limitations under the
-* License.
-*
-* The Original Code is the Netscape security libraries.
-*
-* The Initial Developer of the Original Code is
-* Netscape Communications Corporation.
-* Portions created by the Initial Developer are Copyright (C) 1994-2000
-* the Initial Developer. All Rights Reserved.
-*
-* Contributor(s):
-*
-* Alternatively, the contents of this file may be used under the terms of
-* either the GNU General Public License Version 2 or later (the "GPL"), or
-* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-* in which case the provisions of the GPL or the LGPL are applicable instead
-* of those above. If you wish to allow use of your version of this file only
-* under the terms of either the GPL or the LGPL, and not to allow others to
-* use your version of this file under the terms of the MPL, indicate your
-* decision by deleting the provisions above and replace them with the notice
-* and other provisions required by the GPL or the LGPL. If you do not delete
-* the provisions above, a recipient may use your version of this file under
-* the terms of any one of the MPL, the GPL or the LGPL.
-*
-* ***** END LICENSE BLOCK ***** */
-
-string16 NSSDecryptor::Decrypt(const std::string& crypt) const {
-  // Do nothing if NSS is not loaded.
-  if (!is_nss_initialized_)
-    return string16();
-
-  // The old style password is encoded in base64. They are identified
-  // by a leading '~'. Otherwise, we should decrypt the text.
-  std::string plain;
-  if (crypt[0] != '~') {
-    std::string decoded_data;
-    base::Base64Decode(crypt, &decoded_data);
-    PK11SlotInfo* slot = GetKeySlotForDB();
-    SECStatus result = PK11_Authenticate(slot, PR_TRUE, NULL);
-    if (result != SECSuccess) {
-      FreeSlot(slot);
-      return string16();
-    }
-
-    SECItem request;
-    request.data = reinterpret_cast<unsigned char*>(
-        const_cast<char*>(decoded_data.data()));
-    request.len = static_cast<unsigned int>(decoded_data.size());
-    SECItem reply;
-    reply.data = NULL;
-    reply.len = 0;
-#if defined(USE_NSS)
-    result = PK11SDR_DecryptWithSlot(slot, &request, &reply, NULL);
-#else
-    result = PK11SDR_Decrypt(&request, &reply, NULL);
-#endif  // defined(USE_NSS)
-    if (result == SECSuccess)
-      plain.assign(reinterpret_cast<char*>(reply.data), reply.len);
-
-    SECITEM_FreeItem(&reply, PR_FALSE);
-    FreeSlot(slot);
-  } else {
-    // Deletes the leading '~' before decoding.
-    base::Base64Decode(crypt.substr(1), &plain);
-  }
-
-  return UTF8ToUTF16(plain);
-}
-
-// There are three versions of password files. They store saved user
-// names and passwords.
-// References:
-// http://kb.mozillazine.org/Signons.txt
-// http://kb.mozillazine.org/Signons2.txt
-// http://kb.mozillazine.org/Signons3.txt
-void NSSDecryptor::ParseSignons(
-    const std::string& content,
-    std::vector<content::PasswordForm>* forms) {
-  forms->clear();
-
-  // Splits the file content into lines.
-  std::vector<std::string> lines;
-  base::SplitString(content, '\n', &lines);
-
-  // The first line is the file version. We skip the unknown versions.
-  if (lines.empty())
-    return;
-  int version;
-  if (lines[0] == "#2c")
-    version = 1;
-  else if (lines[0] == "#2d")
-    version = 2;
-  else if (lines[0] == "#2e")
-    version = 3;
-  else
-    return;
-
-  GURL::Replacements rep;
-  rep.ClearQuery();
-  rep.ClearRef();
-  rep.ClearUsername();
-  rep.ClearPassword();
-
-  // Reads never-saved list. Domains are stored one per line.
-  size_t i;
-  for (i = 1; i < lines.size() && lines[i].compare(".") != 0; ++i) {
-    content::PasswordForm form;
-    form.origin = GURL(lines[i]).ReplaceComponents(rep);
-    form.signon_realm = form.origin.GetOrigin().spec();
-    form.blacklisted_by_user = true;
-    forms->push_back(form);
-  }
-  ++i;
-
-  // Reads saved passwords. The information is stored in blocks
-  // seperated by lines that only contain a dot. We find a block
-  // by the seperator and parse them one by one.
-  while (i < lines.size()) {
-    size_t begin = i;
-    size_t end = i + 1;
-    while (end < lines.size() && lines[end].compare(".") != 0)
-      ++end;
-    i = end + 1;
-
-    // A block has at least five lines.
-    if (end - begin < 5)
-      continue;
-
-    content::PasswordForm form;
-
-    // The first line is the site URL.
-    // For HTTP authentication logins, the URL may contain http realm,
-    // which will be in bracket:
-    //   sitename:8080 (realm)
-    GURL url;
-    std::string realm;
-    const char kRealmBracketBegin[] = " (";
-    const char kRealmBracketEnd[] = ")";
-    if (lines[begin].find(kRealmBracketBegin) != std::string::npos) {
-      // In this case, the scheme may not exsit. We assume that the
-      // scheme is HTTP.
-      if (lines[begin].find("://") == std::string::npos)
-        lines[begin] = "http://" + lines[begin];
-
-      size_t start = lines[begin].find(kRealmBracketBegin);
-      url = GURL(lines[begin].substr(0, start));
-
-      start += std::string(kRealmBracketBegin).size();
-      size_t end = lines[begin].rfind(kRealmBracketEnd);
-      realm = lines[begin].substr(start, end - start);
-    } else {
-      // Don't have http realm. It is the URL that the following passwords
-      // belong to.
-      url = GURL(lines[begin]);
-    }
-    // Skips this block if the URL is not valid.
-    if (!url.is_valid())
-      continue;
-    form.origin = url.ReplaceComponents(rep);
-    form.signon_realm = form.origin.GetOrigin().spec();
-    if (!realm.empty())
-      form.signon_realm += realm;
-    form.ssl_valid = form.origin.SchemeIsSecure();
-    ++begin;
-
-    // There may be multiple username/password pairs for this site.
-    // In this case, they are saved in one block without a seperated
-    // line (contains a dot).
-    while (begin + 4 < end) {
-      // The user name.
-      form.username_element = UTF8ToUTF16(lines[begin++]);
-      form.username_value = Decrypt(lines[begin++]);
-      // The element name has a leading '*'.
-      if (lines[begin].at(0) == '*') {
-        form.password_element = UTF8ToUTF16(lines[begin++].substr(1));
-        form.password_value = Decrypt(lines[begin++]);
-      } else {
-        // Maybe the file is bad, we skip to next block.
-        break;
-      }
-      // The action attribute from the form element. This line exists
-      // in versin 2 or above.
-      if (version >= 2) {
-        if (begin < end)
-          form.action = GURL(lines[begin]).ReplaceComponents(rep);
-        ++begin;
-      }
-      // Version 3 has an extra line for further use.
-      if (version == 3) {
-        ++begin;
-      }
-
-      forms->push_back(form);
-    }
-  }
-}
-
-bool NSSDecryptor::ReadAndParseSignons(const base::FilePath& sqlite_file,
-    std::vector<content::PasswordForm>* forms) {
-  sql::Connection db;
-  if (!db.Open(sqlite_file))
-    return false;
-
-  const char* query = "SELECT hostname FROM moz_disabledHosts";
-  sql::Statement s(db.GetUniqueStatement(query));
-  if (!s.is_valid())
-    return false;
-
-  GURL::Replacements rep;
-  rep.ClearQuery();
-  rep.ClearRef();
-  rep.ClearUsername();
-  rep.ClearPassword();
-  // Read domains for which passwords are never saved.
-  while (s.Step()) {
-    content::PasswordForm form;
-    form.origin = GURL(s.ColumnString(0)).ReplaceComponents(rep);
-    form.signon_realm = form.origin.GetOrigin().spec();
-    form.blacklisted_by_user = true;
-    forms->push_back(form);
-  }
-
-  const char* query2 = "SELECT hostname, httpRealm, formSubmitURL, "
-                       "usernameField, passwordField, encryptedUsername, "
-                       "encryptedPassword FROM moz_logins";
-
-  sql::Statement s2(db.GetUniqueStatement(query2));
-  if (!s2.is_valid())
-    return false;
-
-  while (s2.Step()) {
-    GURL url;
-    std::string realm(s2.ColumnString(1));
-    if (!realm.empty()) {
-      // In this case, the scheme may not exsit. Assume HTTP.
-      std::string host(s2.ColumnString(0));
-      if (host.find("://") == std::string::npos)
-        host = "http://" + host;
-      url = GURL(host);
-    } else {
-      url = GURL(s2.ColumnString(0));
-    }
-    // Skip this row if the URL is not valid.
-    if (!url.is_valid())
-      continue;
-
-    content::PasswordForm form;
-    form.origin = url.ReplaceComponents(rep);
-    form.signon_realm = form.origin.GetOrigin().spec();
-    if (!realm.empty())
-      form.signon_realm += realm;
-    form.ssl_valid = form.origin.SchemeIsSecure();
-    // The user name, password and action.
-    form.username_element = s2.ColumnString16(3);
-    form.username_value = Decrypt(s2.ColumnString(5));
-    form.password_element = s2.ColumnString16(4);
-    form.password_value = Decrypt(s2.ColumnString(6));
-    form.action = GURL(s2.ColumnString(2)).ReplaceComponents(rep);
-    forms->push_back(form);
-  }
-  return true;
-}
diff --git a/chrome/browser/importer/nss_decryptor.h b/chrome/browser/importer/nss_decryptor.h
deleted file mode 100644
index a7284d6..0000000
--- a/chrome/browser/importer/nss_decryptor.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_H_
-#define CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_H_
-
-#include "build/build_config.h"
-
-#if defined(OS_MACOSX)
-#include "chrome/browser/importer/nss_decryptor_mac.h"
-#elif defined(OS_WIN)
-#include "chrome/browser/importer/nss_decryptor_win.h"
-#elif defined(USE_OPENSSL)
-// TODO(joth): It should be an error to include this file with USE_OPENSSL
-// defined. (Unless there is a way to do nss decrypt with OpenSSL). Ideally
-// we remove the importers that depend on NSS when doing USE_OPENSSL builds, but
-// that is going to take some non-trivial refactoring so in the meantime we're
-// just falling back to a no-op implementation.
-#include "chrome/browser/importer/nss_decryptor_null.h"
-#elif defined(USE_NSS)
-#include "chrome/browser/importer/nss_decryptor_system_nss.h"
-#endif
-
-#endif  // CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_H_
diff --git a/chrome/browser/importer/nss_decryptor_mac.h b/chrome/browser/importer/nss_decryptor_mac.h
deleted file mode 100644
index 918a227..0000000
--- a/chrome/browser/importer/nss_decryptor_mac.h
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_MAC_H_
-#define CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_MAC_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/strings/string16.h"
-
-namespace base {
-class FilePath;
-}
-
-// The following declarations of functions and types are from Firefox
-// NSS library.
-// source code:
-//   security/nss/lib/util/seccomon.h
-//   security/nss/lib/nss/nss.h
-// The license block is:
-
-/* ***** BEGIN LICENSE BLOCK *****
-* Version: MPL 1.1/GPL 2.0/LGPL 2.1
-*
-* The contents of this file are subject to the Mozilla Public License Version
-* 1.1 (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-* http://www.mozilla.org/MPL/
-*
-* Software distributed under the License is distributed on an "AS IS" basis,
-* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-* for the specific language governing rights and limitations under the
-* License.
-*
-* The Original Code is the Netscape security libraries.
-*
-* The Initial Developer of the Original Code is
-* Netscape Communications Corporation.
-* Portions created by the Initial Developer are Copyright (C) 1994-2000
-* the Initial Developer. All Rights Reserved.
-*
-* Contributor(s):
-*
-* Alternatively, the contents of this file may be used under the terms of
-* either the GNU General Public License Version 2 or later (the "GPL"), or
-* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-* in which case the provisions of the GPL or the LGPL are applicable instead
-* of those above. If you wish to allow use of your version of this file only
-* under the terms of either the GPL or the LGPL, and not to allow others to
-* use your version of this file under the terms of the MPL, indicate your
-* decision by deleting the provisions above and replace them with the notice
-* and other provisions required by the GPL or the LGPL. If you do not delete
-* the provisions above, a recipient may use your version of this file under
-* the terms of any one of the MPL, the GPL or the LGPL.
-*
-* ***** END LICENSE BLOCK ***** */
-
-enum SECItemType {
-  siBuffer = 0,
-  siClearDataBuffer = 1,
-  siCipherDataBuffer = 2,
-  siDERCertBuffer = 3,
-  siEncodedCertBuffer = 4,
-  siDERNameBuffer = 5,
-  siEncodedNameBuffer = 6,
-  siAsciiNameString = 7,
-  siAsciiString = 8,
-  siDEROID = 9,
-  siUnsignedInteger = 10,
-  siUTCTime = 11,
-  siGeneralizedTime = 12
-};
-
-struct SECItem {
-  SECItemType type;
-  unsigned char *data;
-  unsigned int len;
-};
-
-enum SECStatus {
-  SECWouldBlock = -2,
-  SECFailure = -1,
-  SECSuccess = 0
-};
-
-typedef int PRBool;
-#define PR_TRUE 1
-#define PR_FALSE 0
-
-typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus;
-
-typedef struct PK11SlotInfoStr PK11SlotInfo;
-
-typedef SECStatus (*NSSInitFunc)(const char *configdir);
-typedef SECStatus (*NSSShutdownFunc)(void);
-typedef PK11SlotInfo* (*PK11GetInternalKeySlotFunc)(void);
-typedef void (*PK11FreeSlotFunc)(PK11SlotInfo *slot);
-typedef SECStatus (*PK11CheckUserPasswordFunc)(PK11SlotInfo *slot, char *pw);
-typedef SECStatus
-    (*PK11AuthenticateFunc)(PK11SlotInfo *slot, PRBool loadCerts, void *wincx);
-typedef SECStatus
-    (*PK11SDRDecryptFunc)(SECItem *data, SECItem *result, void *cx);
-typedef void (*SECITEMFreeItemFunc)(SECItem *item, PRBool free_it);
-typedef void (*PLArenaFinishFunc)(void);
-typedef PRStatus (*PRCleanupFunc)(void);
-
-namespace content {
-struct PasswordForm;
-}
-
-// A wrapper for Firefox NSS decrypt component.
-class NSSDecryptor {
- public:
-  NSSDecryptor()
-      : NSS_Init(NULL), NSS_Shutdown(NULL), PK11_GetInternalKeySlot(NULL),
-        PK11_CheckUserPassword(NULL), PK11_FreeSlot(NULL),
-        PK11_Authenticate(NULL), PK11SDR_Decrypt(NULL), SECITEM_FreeItem(NULL),
-        is_nss_initialized_(false) {}
-  ~NSSDecryptor();
-
-  // Initializes NSS if it hasn't already been initialized.
-  bool Init(const base::FilePath& dll_path, const base::FilePath& db_path);
-
-  // Decrypts Firefox stored passwords. Before using this method,
-  // make sure Init() returns true.
-  string16 Decrypt(const std::string& crypt) const;
-
-  // Parses the Firefox password file content, decrypts the
-  // username/password and reads other related information.
-  // The result will be stored in |forms|.
-  void ParseSignons(const std::string& content,
-                    std::vector<content::PasswordForm>* forms);
-
-  // Reads and parses the Firefox password sqlite db, decrypts the
-  // username/password and reads other related information.
-  // The result will be stored in |forms|.
-  bool ReadAndParseSignons(const base::FilePath& sqlite_file,
-                           std::vector<content::PasswordForm>* forms);
- private:
-  PK11SlotInfo* GetKeySlotForDB() const { return PK11_GetInternalKeySlot(); }
-  void FreeSlot(PK11SlotInfo* slot) const { PK11_FreeSlot(slot); }
-
-  // Methods in Firefox security components.
-  NSSInitFunc NSS_Init;
-  NSSShutdownFunc NSS_Shutdown;
-  PK11GetInternalKeySlotFunc PK11_GetInternalKeySlot;
-  PK11CheckUserPasswordFunc PK11_CheckUserPassword;
-  PK11FreeSlotFunc PK11_FreeSlot;
-  PK11AuthenticateFunc PK11_Authenticate;
-  PK11SDRDecryptFunc PK11SDR_Decrypt;
-  SECITEMFreeItemFunc SECITEM_FreeItem;
-
-  // True if NSS_Init() has been called
-  bool is_nss_initialized_;
-
-  DISALLOW_COPY_AND_ASSIGN(NSSDecryptor);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_MAC_H_
diff --git a/chrome/browser/importer/nss_decryptor_mac.mm b/chrome/browser/importer/nss_decryptor_mac.mm
deleted file mode 100644
index 7b45a12..0000000
--- a/chrome/browser/importer/nss_decryptor_mac.mm
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2009 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 <Cocoa/Cocoa.h>
-
-#include <dlfcn.h>
-
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/strings/sys_string_conversions.h"
-
-#include "chrome/browser/importer/firefox_importer_utils.h"
-#include "chrome/browser/importer/nss_decryptor_mac.h"
-
-// Important!! : On OS X the nss3 libraries are compiled with depedencies
-// on one another, referenced using dyld's @executable_path directive.
-// To make a long story short in order to get the libraries to load, dyld's
-// fallback path needs to be set to the directory containing the libraries.
-// To do so, the process this function runs in must have the
-// DYLD_FALLBACK_LIBRARY_PATH set on startup to said directory.
-bool NSSDecryptor::Init(const base::FilePath& dll_path,
-                        const base::FilePath& db_path) {
-  if (getenv("DYLD_FALLBACK_LIBRARY_PATH") == NULL) {
-    LOG(ERROR) << "DYLD_FALLBACK_LIBRARY_PATH variable not set";
-    return false;
-  }
-  base::FilePath nss3_path = dll_path.Append("libnss3.dylib");
-
-  void* nss_3_lib = dlopen(nss3_path.value().c_str(), RTLD_LAZY);
-  if (!nss_3_lib) {
-    LOG(ERROR) << "Failed to load nss3 lib" << dlerror();
-    return false;
-  }
-
-  NSS_Init = (NSSInitFunc)dlsym(nss_3_lib, "NSS_Init");
-  NSS_Shutdown = (NSSShutdownFunc)dlsym(nss_3_lib, "NSS_Shutdown");
-  PK11_GetInternalKeySlot =
-      (PK11GetInternalKeySlotFunc)dlsym(nss_3_lib, "PK11_GetInternalKeySlot");
-  PK11_CheckUserPassword =
-      (PK11CheckUserPasswordFunc)dlsym(nss_3_lib, "PK11_CheckUserPassword");
-  PK11_FreeSlot = (PK11FreeSlotFunc)dlsym(nss_3_lib, "PK11_FreeSlot");
-  PK11_Authenticate =
-      (PK11AuthenticateFunc)dlsym(nss_3_lib, "PK11_Authenticate");
-  PK11SDR_Decrypt = (PK11SDRDecryptFunc)dlsym(nss_3_lib, "PK11SDR_Decrypt");
-  SECITEM_FreeItem = (SECITEMFreeItemFunc)dlsym(nss_3_lib, "SECITEM_FreeItem");
-
-  if (!NSS_Init || !NSS_Shutdown || !PK11_GetInternalKeySlot ||
-      !PK11_CheckUserPassword || !PK11_FreeSlot || !PK11_Authenticate ||
-      !PK11SDR_Decrypt || !SECITEM_FreeItem) {
-    LOG(ERROR) << "NSS3 importer couldn't find entry points";
-    return false;
-  }
-
-  SECStatus result = NSS_Init(db_path.value().c_str());
-
-  if (result != SECSuccess) {
-    LOG(ERROR) << "NSS_Init Failed returned: " << result;
-    return false;
-  }
-
-  is_nss_initialized_ = true;
-  return true;
-}
-
-NSSDecryptor::~NSSDecryptor() {
-  if (NSS_Shutdown && is_nss_initialized_) {
-    NSS_Shutdown();
-    is_nss_initialized_ = false;
-  }
-}
diff --git a/chrome/browser/importer/nss_decryptor_null.h b/chrome/browser/importer/nss_decryptor_null.h
deleted file mode 100644
index a9e6d3b..0000000
--- a/chrome/browser/importer/nss_decryptor_null.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_NULL_H_
-#define CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_NULL_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/strings/string16.h"
-
-namespace base {
-class FilePath;
-}
-
-namespace content {
-struct PasswordForm;
-}
-
-// A NULL wrapper for Firefox NSS decrypt component, for use in builds where
-// we do not have the NSS library.
-class NSSDecryptor {
- public:
-  NSSDecryptor() {}
-  bool Init(const base::FilePath& dll_path, const base::FilePath& db_path) { return false; }
-  string16 Decrypt(const std::string& crypt) const { return string16(); }
-  void ParseSignons(const std::string& content,
-                    std::vector<content::PasswordForm>* forms) {}
-  bool ReadAndParseSignons(const base::FilePath& sqlite_file,
-                           std::vector<content::PasswordForm>* forms) {
-    return false;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NSSDecryptor);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_NULL_H_
diff --git a/chrome/browser/importer/nss_decryptor_system_nss.cc b/chrome/browser/importer/nss_decryptor_system_nss.cc
deleted file mode 100644
index 9c12fed..0000000
--- a/chrome/browser/importer/nss_decryptor_system_nss.cc
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/nss_decryptor_system_nss.h"
-
-#include <pk11pub.h>
-#include <pk11sdr.h>
-
-#include "base/basictypes.h"
-#include "base/files/file_path.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/sys_string_conversions.h"
-#include "crypto/nss_util.h"
-
-NSSDecryptor::NSSDecryptor() : is_nss_initialized_(false), db_slot_(NULL) {}
-NSSDecryptor::~NSSDecryptor() {
-  if (db_slot_) {
-    // Deliberately leave the user db open, just in case we need to open more
-    // than one, because there's an NSS bug with reopening user dbs.
-    // https://bugzilla.mozilla.org/show_bug.cgi?id=506140
-    // SECMOD_CloseUserDB(db_slot_);
-    PK11_FreeSlot(db_slot_);
-  }
-}
-
-bool NSSDecryptor::Init(const base::FilePath& dll_path,
-                        const base::FilePath& db_path) {
-  crypto::EnsureNSSInit();
-  is_nss_initialized_ = true;
-  const std::string modspec =
-      base::StringPrintf(
-          "configDir='%s' tokenDescription='Firefox NSS database' "
-          "flags=readOnly",
-          db_path.value().c_str());
-  db_slot_ = SECMOD_OpenUserDB(modspec.c_str());
-  return db_slot_ != NULL;
-}
-
-// This method is based on some NSS code in
-//   security/nss/lib/pk11wrap/pk11sdr.c, CVS revision 1.22
-// This code is copied because the implementation assumes the use of the
-// internal key slot for decryption, but we need to use another slot.
-// The license block is:
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1994-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   thayes@netscape.com
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * Data structure and template for encoding the result of an SDR operation
- *  This is temporary.  It should include the algorithm ID of the encryption
- *  mechanism
- */
-struct SDRResult
-{
-  SECItem keyid;
-  SECAlgorithmID alg;
-  SECItem data;
-};
-typedef struct SDRResult SDRResult;
-
-static SEC_ASN1Template g_template[] = {
-  { SEC_ASN1_SEQUENCE, 0, NULL, sizeof (SDRResult) },
-  { SEC_ASN1_OCTET_STRING, offsetof(SDRResult, keyid) },
-  { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(SDRResult, alg),
-    SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
-  { SEC_ASN1_OCTET_STRING, offsetof(SDRResult, data) },
-  { 0 }
-};
-
-static SECStatus
-unpadBlock(SECItem *data, int blockSize, SECItem *result)
-{
-  SECStatus rv = SECSuccess;
-  int padLength;
-  int i;
-
-  result->data = 0;
-  result->len = 0;
-
-  /* Remove the padding from the end if the input data */
-  if (data->len == 0 || data->len % blockSize  != 0) {
-    rv = SECFailure;
-    goto loser;
-  }
-
-  padLength = data->data[data->len-1];
-  if (padLength > blockSize) { rv = SECFailure; goto loser; }
-
-  /* verify padding */
-  for (i=data->len - padLength; static_cast<uint32>(i) < data->len; i++) {
-    if (data->data[i] != padLength) {
-        rv = SECFailure;
-        goto loser;
-    }
-  }
-
-  result->len = data->len - padLength;
-  result->data = (unsigned char *)PORT_Alloc(result->len);
-  if (!result->data) { rv = SECFailure; goto loser; }
-
-  PORT_Memcpy(result->data, data->data, result->len);
-
-  if (padLength < 2) {
-    return SECWouldBlock;
-  }
-
-loser:
-  return rv;
-}
-
-/* decrypt a block */
-static SECStatus
-pk11Decrypt(PK11SlotInfo *slot, PLArenaPool *arena,
-            CK_MECHANISM_TYPE type, PK11SymKey *key,
-            SECItem *params, SECItem *in, SECItem *result)
-{
-  PK11Context *ctx = 0;
-  SECItem paddedResult;
-  SECStatus rv;
-
-  paddedResult.len = 0;
-  paddedResult.data = 0;
-
-  ctx = PK11_CreateContextBySymKey(type, CKA_DECRYPT, key, params);
-  if (!ctx) { rv = SECFailure; goto loser; }
-
-  paddedResult.len = in->len;
-  paddedResult.data = static_cast<unsigned char*>(
-      PORT_ArenaAlloc(arena, paddedResult.len));
-
-  rv = PK11_CipherOp(ctx, paddedResult.data,
-                        (int*)&paddedResult.len, paddedResult.len,
-                        in->data, in->len);
-  if (rv != SECSuccess) goto loser;
-
-  PK11_Finalize(ctx);
-
-  /* Remove the padding */
-  rv = unpadBlock(&paddedResult, PK11_GetBlockSize(type, 0), result);
-  if (rv) goto loser;
-
-loser:
-  if (ctx) PK11_DestroyContext(ctx, PR_TRUE);
-  return rv;
-}
-
-SECStatus NSSDecryptor::PK11SDR_DecryptWithSlot(
-    PK11SlotInfo* slot, SECItem* data, SECItem* result, void* cx) const {
-  SECStatus rv = SECSuccess;
-  PK11SymKey *key = 0;
-  CK_MECHANISM_TYPE type;
-  SDRResult sdrResult;
-  SECItem *params = 0;
-  SECItem possibleResult = { siBuffer, NULL, 0 };
-  PLArenaPool *arena = 0;
-
-  arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
-  if (!arena) { rv = SECFailure; goto loser; }
-
-  /* Decode the incoming data */
-  memset(&sdrResult, 0, sizeof sdrResult);
-  rv = SEC_QuickDERDecodeItem(arena, &sdrResult, g_template, data);
-  if (rv != SECSuccess) goto loser;  /* Invalid format */
-
-  /* Get the parameter values from the data */
-  params = PK11_ParamFromAlgid(&sdrResult.alg);
-  if (!params) { rv = SECFailure; goto loser; }
-
-  /* Use triple-DES (Should look up the algorithm) */
-  type = CKM_DES3_CBC;
-  key = PK11_FindFixedKey(slot, type, &sdrResult.keyid, cx);
-  if (!key) {
-    rv = SECFailure;
-  } else {
-    rv = pk11Decrypt(slot, arena, type, key, params,
-                     &sdrResult.data, result);
-  }
-
-  /*
-   * if the pad value was too small (1 or 2), then it's statistically
-   * 'likely' that (1 in 256) that we may not have the correct key.
-   * Check the other keys for a better match. If we find none, use
-   * this result.
-   */
-  if (rv == SECWouldBlock)
-    possibleResult = *result;
-
-  /*
-   * handle the case where your key indicies may have been broken
-   */
-  if (rv != SECSuccess) {
-    PK11SymKey *keyList = PK11_ListFixedKeysInSlot(slot, NULL, cx);
-    PK11SymKey *testKey = NULL;
-    PK11SymKey *nextKey = NULL;
-
-    for (testKey = keyList; testKey;
-         testKey = PK11_GetNextSymKey(testKey)) {
-      rv = pk11Decrypt(slot, arena, type, testKey, params,
-                       &sdrResult.data, result);
-      if (rv == SECSuccess)
-        break;
-
-      /* found a close match. If it's our first remember it */
-      if (rv == SECWouldBlock) {
-        if (possibleResult.data) {
-          /* this is unlikely but possible. If we hit this condition,
-           * we have no way of knowing which possibility to prefer.
-           * in this case we just match the key the application
-           * thought was the right one */
-          SECITEM_ZfreeItem(result, PR_FALSE);
-        } else {
-          possibleResult = *result;
-        }
-      }
-    }
-
-    /* free the list */
-    for (testKey = keyList; testKey; testKey = nextKey) {
-         nextKey = PK11_GetNextSymKey(testKey);
-      PK11_FreeSymKey(testKey);
-    }
-  }
-
-  /* we didn't find a better key, use the one with a small pad value */
-  if ((rv != SECSuccess) && (possibleResult.data)) {
-    *result = possibleResult;
-    possibleResult.data = NULL;
-    rv = SECSuccess;
-  }
-
- loser:
-  if (arena) PORT_FreeArena(arena, PR_TRUE);
-  if (key) PK11_FreeSymKey(key);
-  if (params) SECITEM_ZfreeItem(params, PR_TRUE);
-  if (possibleResult.data) SECITEM_ZfreeItem(&possibleResult, PR_FALSE);
-
-  return rv;
-}
diff --git a/chrome/browser/importer/nss_decryptor_system_nss.h b/chrome/browser/importer/nss_decryptor_system_nss.h
deleted file mode 100644
index b71b500..0000000
--- a/chrome/browser/importer/nss_decryptor_system_nss.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_SYSTEM_NSS_H_
-#define CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_SYSTEM_NSS_H_
-
-#include <secmodt.h>
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/strings/string16.h"
-
-namespace base {
-class FilePath;
-}
-
-namespace content {
-struct PasswordForm;
-}
-
-// A wrapper for Firefox NSS decrypt component.
-class NSSDecryptor {
- public:
-  NSSDecryptor();
-  ~NSSDecryptor();
-
-  // Initializes NSS if it hasn't already been initialized.
-  bool Init(const base::FilePath& dll_path, const base::FilePath& db_path);
-
-  // Decrypts Firefox stored passwords. Before using this method,
-  // make sure Init() returns true.
-  string16 Decrypt(const std::string& crypt) const;
-
-  // Parses the Firefox password file content, decrypts the
-  // username/password and reads other related information.
-  // The result will be stored in |forms|.
-  void ParseSignons(const std::string& content,
-                    std::vector<content::PasswordForm>* forms);
-
-  // Reads and parses the Firefox password sqlite db, decrypts the
-  // username/password and reads other related information.
-  // The result will be stored in |forms|.
-  bool ReadAndParseSignons(const base::FilePath& sqlite_file,
-                           std::vector<content::PasswordForm>* forms);
- private:
-  // Does not actually free the slot, since we'll free it when NSSDecryptor is
-  // destroyed.
-  void FreeSlot(PK11SlotInfo* slot) const {}
-  PK11SlotInfo* GetKeySlotForDB() const { return db_slot_; }
-
-  SECStatus PK11SDR_DecryptWithSlot(
-      PK11SlotInfo* slot, SECItem* data, SECItem* result, void* cx) const;
-
-  bool is_nss_initialized_;
-  PK11SlotInfo* db_slot_;
-
-  DISALLOW_COPY_AND_ASSIGN(NSSDecryptor);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_SYSTEM_NSS_H_
diff --git a/chrome/browser/importer/nss_decryptor_win.cc b/chrome/browser/importer/nss_decryptor_win.cc
deleted file mode 100644
index a426ce0..0000000
--- a/chrome/browser/importer/nss_decryptor_win.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/nss_decryptor_win.h"
-
-#include "base/files/file_path.h"
-#include "base/strings/sys_string_conversions.h"
-
-namespace {
-
-typedef BOOL (WINAPI* SetDllDirectoryFunc)(LPCTSTR lpPathName);
-
-// A helper class whose destructor calls SetDllDirectory(NULL) to undo the
-// effects of a previous SetDllDirectory call.
-class SetDllDirectoryCaller {
- public:
-  explicit SetDllDirectoryCaller() : func_(NULL) { }
-
-  ~SetDllDirectoryCaller() {
-    if (func_)
-      func_(NULL);
-  }
-
-  // Sets the SetDllDirectory function pointer to activates this object.
-  void set_func(SetDllDirectoryFunc func) { func_ = func; }
-
- private:
-  SetDllDirectoryFunc func_;
-};
-
-}  // namespace
-
-// static
-const wchar_t NSSDecryptor::kNSS3Library[] = L"nss3.dll";
-const wchar_t NSSDecryptor::kSoftokn3Library[] = L"softokn3.dll";
-const wchar_t NSSDecryptor::kPLDS4Library[] = L"plds4.dll";
-const wchar_t NSSDecryptor::kNSPR4Library[] = L"nspr4.dll";
-
-bool NSSDecryptor::Init(const base::FilePath& dll_path,
-                        const base::FilePath& db_path) {
-  // We call SetDllDirectory to work around a Purify bug (GetModuleHandle
-  // fails inside Purify under certain conditions).  SetDllDirectory only
-  // exists on Windows XP SP1 or later, so we look up its address at run time.
-  HMODULE kernel32_dll = GetModuleHandle(L"kernel32.dll");
-  if (kernel32_dll == NULL)
-    return false;
-  SetDllDirectoryFunc set_dll_directory =
-      (SetDllDirectoryFunc)GetProcAddress(kernel32_dll, "SetDllDirectoryW");
-  SetDllDirectoryCaller caller;
-
-  if (set_dll_directory != NULL) {
-    if (!set_dll_directory(dll_path.value().c_str()))
-      return false;
-    caller.set_func(set_dll_directory);
-    nss3_dll_ = LoadLibrary(kNSS3Library);
-    if (nss3_dll_ == NULL)
-      return false;
-  } else {
-    // Fall back on LoadLibraryEx if SetDllDirectory isn't available.  We
-    // actually prefer this method because it doesn't change the DLL search
-    // path, which is a process-wide property.
-    base::FilePath path = dll_path.Append(kNSS3Library);
-    nss3_dll_ = LoadLibraryEx(path.value().c_str(), NULL,
-                              LOAD_WITH_ALTERED_SEARCH_PATH);
-    if (nss3_dll_ == NULL)
-      return false;
-
-    // Firefox 2 uses NSS 3.11.  Firefox 3 uses NSS 3.12.  NSS 3.12 has two
-    // changes in its DLLs:
-    // 1. nss3.dll is not linked with softokn3.dll at build time, but rather
-    //    loads softokn3.dll using LoadLibrary in NSS_Init.
-    // 2. softokn3.dll has a new dependency sqlite3.dll.
-    // NSS_Init's LoadLibrary call has trouble finding sqlite3.dll.  To help
-    // it out, we preload softokn3.dll using LoadLibraryEx with the
-    // LOAD_WITH_ALTERED_SEARCH_PATH flag.  This helps because LoadLibrary
-    // doesn't load a DLL again if it's already loaded.  This workaround is
-    // harmless for NSS 3.11.
-    path = base::FilePath(dll_path).Append(kSoftokn3Library);
-    softokn3_dll_ = LoadLibraryEx(path.value().c_str(), NULL,
-                                  LOAD_WITH_ALTERED_SEARCH_PATH);
-    if (softokn3_dll_ == NULL) {
-      Free();
-      return false;
-    }
-  }
-  HMODULE plds4_dll = GetModuleHandle(kPLDS4Library);
-  HMODULE nspr4_dll = GetModuleHandle(kNSPR4Library);
-
-  return InitNSS(db_path, plds4_dll, nspr4_dll);
-}
-
-NSSDecryptor::NSSDecryptor()
-    : NSS_Init(NULL), NSS_Shutdown(NULL), PK11_GetInternalKeySlot(NULL),
-      PK11_CheckUserPassword(NULL), PK11_FreeSlot(NULL),
-      PK11_Authenticate(NULL), PK11SDR_Decrypt(NULL), SECITEM_FreeItem(NULL),
-      PL_ArenaFinish(NULL), PR_Cleanup(NULL),
-      nss3_dll_(NULL), softokn3_dll_(NULL),
-      is_nss_initialized_(false) {
-}
-
-NSSDecryptor::~NSSDecryptor() {
-  Free();
-}
-
-bool NSSDecryptor::InitNSS(const base::FilePath& db_path,
-                           base::NativeLibrary plds4_dll,
-                           base::NativeLibrary nspr4_dll) {
-  // NSPR DLLs are already loaded now.
-  if (plds4_dll == NULL || nspr4_dll == NULL) {
-    Free();
-    return false;
-  }
-
-  // Gets the function address.
-  NSS_Init = (NSSInitFunc)
-      base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "NSS_Init");
-  NSS_Shutdown = (NSSShutdownFunc)
-      base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "NSS_Shutdown");
-  PK11_GetInternalKeySlot = (PK11GetInternalKeySlotFunc)
-      base::GetFunctionPointerFromNativeLibrary(nss3_dll_,
-                                                "PK11_GetInternalKeySlot");
-  PK11_FreeSlot = (PK11FreeSlotFunc)
-      base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "PK11_FreeSlot");
-  PK11_Authenticate = (PK11AuthenticateFunc)
-      base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "PK11_Authenticate");
-  PK11SDR_Decrypt = (PK11SDRDecryptFunc)
-      base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "PK11SDR_Decrypt");
-  SECITEM_FreeItem = (SECITEMFreeItemFunc)
-      base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "SECITEM_FreeItem");
-  PL_ArenaFinish = (PLArenaFinishFunc)
-      base::GetFunctionPointerFromNativeLibrary(plds4_dll, "PL_ArenaFinish");
-  PR_Cleanup = (PRCleanupFunc)
-      base::GetFunctionPointerFromNativeLibrary(nspr4_dll, "PR_Cleanup");
-
-  if (NSS_Init == NULL || NSS_Shutdown == NULL ||
-      PK11_GetInternalKeySlot == NULL || PK11_FreeSlot == NULL ||
-      PK11_Authenticate == NULL || PK11SDR_Decrypt == NULL ||
-      SECITEM_FreeItem == NULL || PL_ArenaFinish == NULL ||
-      PR_Cleanup == NULL) {
-    Free();
-    return false;
-  }
-
-  SECStatus result = NSS_Init(base::SysWideToNativeMB(db_path.value()).c_str());
-  if (result != SECSuccess) {
-    Free();
-    return false;
-  }
-
-  is_nss_initialized_ = true;
-  return true;
-}
-
-void NSSDecryptor::Free() {
-  if (is_nss_initialized_) {
-    NSS_Shutdown();
-    PL_ArenaFinish();
-    PR_Cleanup();
-    is_nss_initialized_ = false;
-  }
-  if (softokn3_dll_ != NULL)
-    base::UnloadNativeLibrary(softokn3_dll_);
-  if (nss3_dll_ != NULL)
-    base::UnloadNativeLibrary(nss3_dll_);
-  NSS_Init = NULL;
-  NSS_Shutdown = NULL;
-  PK11_GetInternalKeySlot = NULL;
-  PK11_FreeSlot = NULL;
-  PK11_Authenticate = NULL;
-  PK11SDR_Decrypt = NULL;
-  SECITEM_FreeItem = NULL;
-  PL_ArenaFinish = NULL;
-  PR_Cleanup = NULL;
-  nss3_dll_ = NULL;
-  softokn3_dll_ = NULL;
-}
diff --git a/chrome/browser/importer/nss_decryptor_win.h b/chrome/browser/importer/nss_decryptor_win.h
deleted file mode 100644
index d8b208f..0000000
--- a/chrome/browser/importer/nss_decryptor_win.h
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_WIN_H_
-#define CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_WIN_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/native_library.h"
-#include "base/strings/string16.h"
-
-// The following declarations of functions and types are from Firefox
-// NSS library.
-// source code:
-//   security/nss/lib/util/seccomon.h
-//   security/nss/lib/nss/nss.h
-// The license block is:
-
-/* ***** BEGIN LICENSE BLOCK *****
-* Version: MPL 1.1/GPL 2.0/LGPL 2.1
-*
-* The contents of this file are subject to the Mozilla Public License Version
-* 1.1 (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-* http://www.mozilla.org/MPL/
-*
-* Software distributed under the License is distributed on an "AS IS" basis,
-* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-* for the specific language governing rights and limitations under the
-* License.
-*
-* The Original Code is the Netscape security libraries.
-*
-* The Initial Developer of the Original Code is
-* Netscape Communications Corporation.
-* Portions created by the Initial Developer are Copyright (C) 1994-2000
-* the Initial Developer. All Rights Reserved.
-*
-* Contributor(s):
-*
-* Alternatively, the contents of this file may be used under the terms of
-* either the GNU General Public License Version 2 or later (the "GPL"), or
-* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-* in which case the provisions of the GPL or the LGPL are applicable instead
-* of those above. If you wish to allow use of your version of this file only
-* under the terms of either the GPL or the LGPL, and not to allow others to
-* use your version of this file under the terms of the MPL, indicate your
-* decision by deleting the provisions above and replace them with the notice
-* and other provisions required by the GPL or the LGPL. If you do not delete
-* the provisions above, a recipient may use your version of this file under
-* the terms of any one of the MPL, the GPL or the LGPL.
-*
-* ***** END LICENSE BLOCK ***** */
-
-enum SECItemType {
-  siBuffer = 0,
-  siClearDataBuffer = 1,
-  siCipherDataBuffer = 2,
-  siDERCertBuffer = 3,
-  siEncodedCertBuffer = 4,
-  siDERNameBuffer = 5,
-  siEncodedNameBuffer = 6,
-  siAsciiNameString = 7,
-  siAsciiString = 8,
-  siDEROID = 9,
-  siUnsignedInteger = 10,
-  siUTCTime = 11,
-  siGeneralizedTime = 12
-};
-
-struct SECItem {
-  SECItemType type;
-  unsigned char *data;
-  unsigned int len;
-};
-
-enum SECStatus {
-  SECWouldBlock = -2,
-  SECFailure = -1,
-  SECSuccess = 0
-};
-
-typedef int PRBool;
-#define PR_TRUE 1
-#define PR_FALSE 0
-
-typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus;
-
-typedef struct PK11SlotInfoStr PK11SlotInfo;
-
-typedef SECStatus (*NSSInitFunc)(const char *configdir);
-typedef SECStatus (*NSSShutdownFunc)(void);
-typedef PK11SlotInfo* (*PK11GetInternalKeySlotFunc)(void);
-typedef void (*PK11FreeSlotFunc)(PK11SlotInfo *slot);
-typedef SECStatus (*PK11CheckUserPasswordFunc)(PK11SlotInfo *slot, char *pw);
-typedef SECStatus
-    (*PK11AuthenticateFunc)(PK11SlotInfo *slot, PRBool loadCerts, void *wincx);
-typedef SECStatus
-    (*PK11SDRDecryptFunc)(SECItem *data, SECItem *result, void *cx);
-typedef void (*SECITEMFreeItemFunc)(SECItem *item, PRBool free_it);
-typedef void (*PLArenaFinishFunc)(void);
-typedef PRStatus (*PRCleanupFunc)(void);
-
-namespace content {
-struct PasswordForm;
-}
-
-// A wrapper for Firefox NSS decrypt component.
-class NSSDecryptor {
- public:
-  NSSDecryptor();
-  ~NSSDecryptor();
-
-  // Loads NSS3 library and returns true if successful.
-  // |dll_path| indicates the location of NSS3 DLL files, and |db_path|
-  // is the location of the database file that stores the keys.
-  bool Init(const base::FilePath& dll_path, const base::FilePath& db_path);
-
-  // Frees the libraries.
-  void Free();
-
-  // Decrypts Firefox stored passwords. Before using this method,
-  // make sure Init() returns true.
-  string16 Decrypt(const std::string& crypt) const;
-
-  // Parses the Firefox password file content, decrypts the
-  // username/password and reads other related information.
-  // The result will be stored in |forms|.
-  void ParseSignons(const std::string& content,
-                    std::vector<content::PasswordForm>* forms);
-
-  // Reads and parses the Firefox password sqlite db, decrypts the
-  // username/password and reads other related information.
-  // The result will be stored in |forms|.
-  bool ReadAndParseSignons(const base::FilePath& sqlite_file,
-                           std::vector<content::PasswordForm>* forms);
-
- private:
-  // Call NSS initialization funcs.
-  bool InitNSS(const base::FilePath& db_path,
-               base::NativeLibrary plds4_dll,
-               base::NativeLibrary nspr4_dll);
-
-  PK11SlotInfo* GetKeySlotForDB() const { return PK11_GetInternalKeySlot(); }
-  void FreeSlot(PK11SlotInfo* slot) const { PK11_FreeSlot(slot); }
-
-  // Methods in Firefox security components.
-  NSSInitFunc NSS_Init;
-  NSSShutdownFunc NSS_Shutdown;
-  PK11GetInternalKeySlotFunc PK11_GetInternalKeySlot;
-  PK11CheckUserPasswordFunc PK11_CheckUserPassword;
-  PK11FreeSlotFunc PK11_FreeSlot;
-  PK11AuthenticateFunc PK11_Authenticate;
-  PK11SDRDecryptFunc PK11SDR_Decrypt;
-  SECITEMFreeItemFunc SECITEM_FreeItem;
-  PLArenaFinishFunc PL_ArenaFinish;
-  PRCleanupFunc PR_Cleanup;
-
-  // Libraries necessary for decrypting the passwords.
-  static const wchar_t kNSS3Library[];
-  static const wchar_t kSoftokn3Library[];
-  static const wchar_t kPLDS4Library[];
-  static const wchar_t kNSPR4Library[];
-
-  // NSS3 module handles.
-  base::NativeLibrary nss3_dll_;
-  base::NativeLibrary softokn3_dll_;
-
-  // True if NSS_Init() has been called
-  bool is_nss_initialized_;
-
-  DISALLOW_COPY_AND_ASSIGN(NSSDecryptor);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_NSS_DECRYPTOR_WIN_H_
diff --git a/chrome/browser/importer/profile_writer.cc b/chrome/browser/importer/profile_writer.cc
index ce85351..87f4c54 100644
--- a/chrome/browser/importer/profile_writer.cc
+++ b/chrome/browser/importer/profile_writer.cc
@@ -15,6 +15,7 @@
 #include "base/threading/thread.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_service.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/history/history_service.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/webdata/web_data_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/importer/imported_bookmark_entry.h"
 #include "chrome/common/importer/imported_favicon_usage.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/importer/pstore_declarations.h b/chrome/browser/importer/pstore_declarations.h
deleted file mode 100644
index 805e549..0000000
--- a/chrome/browser/importer/pstore_declarations.h
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_PSTORE_DECLARATIONS_H_
-#define CHROME_BROWSER_IMPORTER_PSTORE_DECLARATIONS_H_
-
-#ifdef __PSTORE_H__
-#error Should not include pstore.h and this file simultaneously.
-#endif
-
-#include <ole2.h>
-
-// pstore.h is no longer shipped in the Windows 8 SDK. Define a minimal set
-// here.
-
-// These types are referenced in interfaces we use, but our code does not use
-// refer to these types, so simply make them opaque.
-class IEnumPStoreTypes;
-struct PST_ACCESSRULESET;
-struct PST_PROMPTINFO;
-struct PST_PROVIDERINFO;
-struct PST_TYPEINFO;
-
-EXTERN_C const IID IID_IPStore;
-EXTERN_C const IID IID_IEnumPStoreItems;
-
-typedef DWORD PST_KEY;
-typedef DWORD PST_ACCESSMODE;
-#define PST_E_OK _HRESULT_TYPEDEF_(0x00000000L)
-
-interface IEnumPStoreItems : public IUnknown
-{
- public:
-  virtual HRESULT STDMETHODCALLTYPE Next(
-      DWORD celt,
-      LPWSTR __RPC_FAR *rgelt,
-      DWORD __RPC_FAR *pceltFetched) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE Skip(DWORD celt) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE Reset(void) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE Clone(
-      IEnumPStoreItems __RPC_FAR *__RPC_FAR *ppenum) = 0;
-};
-
-interface IPStore : public IUnknown
-{
- public:
-  virtual HRESULT STDMETHODCALLTYPE GetInfo(
-      PST_PROVIDERINFO* __RPC_FAR *ppProperties) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE GetProvParam(
-      DWORD dwParam,
-      DWORD __RPC_FAR *pcbData,
-      BYTE __RPC_FAR *__RPC_FAR *ppbData,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE SetProvParam(
-      DWORD dwParam,
-      DWORD cbData,
-      BYTE __RPC_FAR *pbData,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE CreateType(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pType,
-      PST_TYPEINFO* pInfo,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pType,
-      PST_TYPEINFO* __RPC_FAR *ppInfo,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE DeleteType(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pType,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE CreateSubtype(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pType,
-      const GUID __RPC_FAR *pSubtype,
-      PST_TYPEINFO* pInfo,
-      PST_ACCESSRULESET* pRules,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE GetSubtypeInfo(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pType,
-      const GUID __RPC_FAR *pSubtype,
-      PST_TYPEINFO* __RPC_FAR *ppInfo,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE DeleteSubtype(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pType,
-      const GUID __RPC_FAR *pSubtype,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE ReadAccessRuleset(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pType,
-      const GUID __RPC_FAR *pSubtype,
-      PST_ACCESSRULESET* __RPC_FAR *ppRules,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE WriteAccessRuleset(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pType,
-      const GUID __RPC_FAR *pSubtype,
-      PST_ACCESSRULESET* pRules,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE EnumTypes(
-      PST_KEY Key,
-      DWORD dwFlags,
-      IEnumPStoreTypes __RPC_FAR *__RPC_FAR *ppenum) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE EnumSubtypes(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pType,
-      DWORD dwFlags,
-      IEnumPStoreTypes __RPC_FAR *__RPC_FAR *ppenum) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE DeleteItem(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pItemType,
-      const GUID __RPC_FAR *pItemSubtype,
-      LPCWSTR szItemName,
-      PST_PROMPTINFO* pPromptInfo,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE ReadItem(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pItemType,
-      const GUID __RPC_FAR *pItemSubtype,
-      LPCWSTR szItemName,
-      DWORD __RPC_FAR *pcbData,
-      BYTE __RPC_FAR *__RPC_FAR *ppbData,
-      PST_PROMPTINFO* pPromptInfo,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE WriteItem(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pItemType,
-      const GUID __RPC_FAR *pItemSubtype,
-      LPCWSTR szItemName,
-      DWORD cbData,
-      BYTE __RPC_FAR *pbData,
-      PST_PROMPTINFO* pPromptInfo,
-      DWORD dwDefaultConfirmationStyle,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE OpenItem(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pItemType,
-      const GUID __RPC_FAR *pItemSubtype,
-      LPCWSTR szItemName,
-      PST_ACCESSMODE ModeFlags,
-      PST_PROMPTINFO* pPromptInfo,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE CloseItem(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pItemType,
-      const GUID __RPC_FAR *pItemSubtype,
-      LPCWSTR szItemName,
-      DWORD dwFlags) = 0;
-
-  virtual HRESULT STDMETHODCALLTYPE EnumItems(
-      PST_KEY Key,
-      const GUID __RPC_FAR *pItemType,
-      const GUID __RPC_FAR *pItemSubtype,
-      DWORD dwFlags,
-      IEnumPStoreItems __RPC_FAR *__RPC_FAR *ppenum) = 0;
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_PSTORE_DECLARATIONS_H_
diff --git a/chrome/browser/importer/safari_importer.h b/chrome/browser/importer/safari_importer.h
deleted file mode 100644
index fd83083..0000000
--- a/chrome/browser/importer/safari_importer.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_IMPORTER_SAFARI_IMPORTER_H_
-#define CHROME_BROWSER_IMPORTER_SAFARI_IMPORTER_H_
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/files/file_path.h"
-#include "base/gtest_prod_util.h"
-#include "chrome/browser/history/history_types.h"
-#include "chrome/browser/importer/importer.h"
-#include "chrome/common/importer/importer_url_row.h"
-
-#if __OBJC__
-@class NSDictionary;
-@class NSString;
-#else
-class NSDictionary;
-class NSString;
-#endif
-
-class GURL;
-struct ImportedBookmarkEntry;
-struct ImportedFaviconUsage;
-
-namespace history {
-class URLRow;
-}
-
-namespace sql {
-class Connection;
-}
-
-// Importer for Safari on OS X.
-class SafariImporter : public Importer {
- public:
-  // |library_dir| is the full path to the ~/Library directory,
-  // We pass it in as a parameter for testing purposes.
-  explicit SafariImporter(const base::FilePath& library_dir);
-
-  // Importer:
-  virtual void StartImport(const importer::SourceProfile& source_profile,
-                           uint16 items,
-                           ImporterBridge* bridge) OVERRIDE;
-
- // Does this user account have a Safari Profile and if so, what items
- // are supported?
- // in: library_dir - ~/Library or a standin for testing purposes.
- // out: services_supported - the service supported for import.
- // Returns true if we can import the Safari profile.
- static bool CanImport(const base::FilePath& library_dir,
-                       uint16* services_supported);
-
- private:
-  FRIEND_TEST_ALL_PREFIXES(SafariImporterTest, BookmarkImport);
-  FRIEND_TEST_ALL_PREFIXES(SafariImporterTest, FaviconImport);
-  FRIEND_TEST_ALL_PREFIXES(SafariImporterTest, HistoryImport);
-
-  virtual ~SafariImporter();
-
-  // Multiple URLs can share the same favicon; this is a map
-  // of URLs -> IconIDs that we load as a temporary step before
-  // actually loading the icons.
-  typedef std::map<int64, std::set<GURL> > FaviconMap;
-
-  void ImportBookmarks();
-  void ImportPasswords();
-  void ImportHistory();
-
-  // Parse Safari's stored bookmarks.
-  void ParseBookmarks(const string16& toolbar_name,
-                      std::vector<ImportedBookmarkEntry>* bookmarks);
-
-  // Function to recursively read Bookmarks out of Safari plist.
-  // |bookmark_folder| The dictionary containing a folder to parse.
-  // |parent_path_elements| Path elements up to this point.
-  // |is_in_toolbar| Is this folder in the toolbar.
-  // |out_bookmarks| BookMark element array to write into.
-  void RecursiveReadBookmarksFolder(
-      NSDictionary* bookmark_folder,
-      const std::vector<string16>& parent_path_elements,
-      bool is_in_toolbar,
-      const string16& toolbar_name,
-      std::vector<ImportedBookmarkEntry>* out_bookmarks);
-
-  // Converts history time stored by Safari as a double serialized as a string,
-  // to seconds-since-UNIX-Ephoch-format used by Chrome.
-  double HistoryTimeToEpochTime(NSString* history_time);
-
-  // Parses Safari's history and loads it into the input array.
-  void ParseHistoryItems(std::vector<ImporterURLRow>* history_items);
-
-  // Opens the favicon database file.
-  bool OpenDatabase(sql::Connection* db);
-
-  // Loads the urls associated with the favicons into favicon_map;
-  void ImportFaviconURLs(sql::Connection* db, FaviconMap* favicon_map);
-
-  // Loads and reencodes the individual favicons.
-  void LoadFaviconData(sql::Connection* db,
-                       const FaviconMap& favicon_map,
-                       std::vector<ImportedFaviconUsage>* favicons);
-
-  base::FilePath library_dir_;
-
-  DISALLOW_COPY_AND_ASSIGN(SafariImporter);
-};
-
-#endif  // CHROME_BROWSER_IMPORTER_SAFARI_IMPORTER_H_
diff --git a/chrome/browser/importer/safari_importer.mm b/chrome/browser/importer/safari_importer.mm
deleted file mode 100644
index 4a61298..0000000
--- a/chrome/browser/importer/safari_importer.mm
+++ /dev/null
@@ -1,399 +0,0 @@
-// Copyright (c) 2012 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 <Cocoa/Cocoa.h>
-
-#include "chrome/browser/importer/safari_importer.h"
-
-#include <map>
-#include <vector>
-
-#include "base/file_util.h"
-#include "base/mac/mac_util.h"
-#include "base/strings/string16.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
-#include "chrome/browser/favicon/favicon_util.h"
-#include "chrome/browser/importer/importer_bridge.h"
-#include "chrome/common/importer/imported_bookmark_entry.h"
-#include "chrome/common/importer/imported_favicon_usage.h"
-#include "chrome/common/url_constants.h"
-#include "grit/generated_resources.h"
-#include "net/base/data_url.h"
-#include "sql/statement.h"
-#include "url/gurl.h"
-
-namespace {
-
-// A function like this is used by other importers in order to filter out
-// URLS we don't want to import.
-// For now it's pretty basic, but I've split it out so it's easy to slot
-// in necessary logic for filtering URLS, should we need it.
-bool CanImportSafariURL(const GURL& url) {
-  // The URL is not valid.
-  if (!url.is_valid())
-    return false;
-
-  return true;
-}
-
-}  // namespace
-
-SafariImporter::SafariImporter(const base::FilePath& library_dir)
-    : library_dir_(library_dir) {
-}
-
-SafariImporter::~SafariImporter() {
-}
-
-// static
-bool SafariImporter::CanImport(const base::FilePath& library_dir,
-                               uint16* services_supported) {
-  DCHECK(services_supported);
-  *services_supported = importer::NONE;
-
-  // Import features are toggled by the following:
-  // bookmarks import: existence of ~/Library/Safari/Bookmarks.plist file.
-  // history import: existence of ~/Library/Safari/History.plist file.
-  base::FilePath safari_dir = library_dir.Append("Safari");
-  base::FilePath bookmarks_path = safari_dir.Append("Bookmarks.plist");
-  base::FilePath history_path = safari_dir.Append("History.plist");
-
-  if (file_util::PathExists(bookmarks_path))
-    *services_supported |= importer::FAVORITES;
-  if (file_util::PathExists(history_path))
-    *services_supported |= importer::HISTORY;
-
-  return *services_supported != importer::NONE;
-}
-
-void SafariImporter::StartImport(const importer::SourceProfile& source_profile,
-                                 uint16 items,
-                                 ImporterBridge* bridge) {
-  bridge_ = bridge;
-  // The order here is important!
-  bridge_->NotifyStarted();
-
-  // In keeping with import on other platforms (and for other browsers), we
-  // don't import the home page (since it may lead to a useless homepage); see
-  // crbug.com/25603.
-  if ((items & importer::HISTORY) && !cancelled()) {
-    bridge_->NotifyItemStarted(importer::HISTORY);
-    ImportHistory();
-    bridge_->NotifyItemEnded(importer::HISTORY);
-  }
-  if ((items & importer::FAVORITES) && !cancelled()) {
-    bridge_->NotifyItemStarted(importer::FAVORITES);
-    ImportBookmarks();
-    bridge_->NotifyItemEnded(importer::FAVORITES);
-  }
-  if ((items & importer::PASSWORDS) && !cancelled()) {
-    bridge_->NotifyItemStarted(importer::PASSWORDS);
-    ImportPasswords();
-    bridge_->NotifyItemEnded(importer::PASSWORDS);
-  }
-  bridge_->NotifyEnded();
-}
-
-void SafariImporter::ImportBookmarks() {
-  string16 toolbar_name =
-      bridge_->GetLocalizedString(IDS_BOOKMARK_BAR_FOLDER_NAME);
-  std::vector<ImportedBookmarkEntry> bookmarks;
-  ParseBookmarks(toolbar_name, &bookmarks);
-
-  // Write bookmarks into profile.
-  if (!bookmarks.empty() && !cancelled()) {
-    const string16& first_folder_name =
-        bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_SAFARI);
-    bridge_->AddBookmarks(bookmarks, first_folder_name);
-  }
-
-  // Import favicons.
-  sql::Connection db;
-  if (!OpenDatabase(&db))
-    return;
-
-  FaviconMap favicon_map;
-  ImportFaviconURLs(&db, &favicon_map);
-  // Write favicons into profile.
-  if (!favicon_map.empty() && !cancelled()) {
-    std::vector<ImportedFaviconUsage> favicons;
-    LoadFaviconData(&db, favicon_map, &favicons);
-    bridge_->SetFavicons(favicons);
-  }
-}
-
-bool SafariImporter::OpenDatabase(sql::Connection* db) {
-  // Construct ~/Library/Safari/WebIcons.db path.
-  NSString* library_dir = [NSString
-      stringWithUTF8String:library_dir_.value().c_str()];
-  NSString* safari_dir = [library_dir
-      stringByAppendingPathComponent:@"Safari"];
-  NSString* favicons_db_path = [safari_dir
-      stringByAppendingPathComponent:@"WebpageIcons.db"];
-
-  const char* db_path = [favicons_db_path fileSystemRepresentation];
-  return db->Open(base::FilePath(db_path));
-}
-
-void SafariImporter::ImportFaviconURLs(sql::Connection* db,
-                                       FaviconMap* favicon_map) {
-  const char* query = "SELECT iconID, url FROM PageURL;";
-  sql::Statement s(db->GetUniqueStatement(query));
-
-  while (s.Step() && !cancelled()) {
-    int64 icon_id = s.ColumnInt64(0);
-    GURL url = GURL(s.ColumnString(1));
-    (*favicon_map)[icon_id].insert(url);
-  }
-}
-
-void SafariImporter::LoadFaviconData(
-    sql::Connection* db,
-    const FaviconMap& favicon_map,
-    std::vector<ImportedFaviconUsage>* favicons) {
-  const char* query = "SELECT i.url, d.data "
-                      "FROM IconInfo i JOIN IconData d "
-                      "ON i.iconID = d.iconID "
-                      "WHERE i.iconID = ?;";
-  sql::Statement s(db->GetUniqueStatement(query));
-
-  for (FaviconMap::const_iterator i = favicon_map.begin();
-       i != favicon_map.end(); ++i) {
-    s.Reset(true);
-    s.BindInt64(0, i->first);
-    if (s.Step()) {
-      ImportedFaviconUsage usage;
-
-      usage.favicon_url = GURL(s.ColumnString(0));
-      if (!usage.favicon_url.is_valid())
-        continue;  // Don't bother importing favicons with invalid URLs.
-
-      std::vector<unsigned char> data;
-      s.ColumnBlobAsVector(1, &data);
-      if (data.empty())
-        continue;  // Data definitely invalid.
-
-      if (!FaviconUtil::ReencodeFavicon(&data[0], data.size(), &usage.png_data))
-        continue;  // Unable to decode.
-
-      usage.urls = i->second;
-      favicons->push_back(usage);
-    }
-  }
-}
-
-void SafariImporter::RecursiveReadBookmarksFolder(
-    NSDictionary* bookmark_folder,
-    const std::vector<string16>& parent_path_elements,
-    bool is_in_toolbar,
-    const string16& toolbar_name,
-    std::vector<ImportedBookmarkEntry>* out_bookmarks) {
-  DCHECK(bookmark_folder);
-
-  NSString* type = [bookmark_folder objectForKey:@"WebBookmarkType"];
-  NSString* title = [bookmark_folder objectForKey:@"Title"];
-
-  // Are we the dictionary that contains all other bookmarks?
-  // We need to know this so we don't add it to the path.
-  bool is_top_level_bookmarks_container = [bookmark_folder
-      objectForKey:@"WebBookmarkFileVersion"] != nil;
-
-  // We're expecting a list of bookmarks here, if that isn't what we got, fail.
-  if (!is_top_level_bookmarks_container) {
-    // Top level containers sometimes don't have title attributes.
-    if (![type isEqualToString:@"WebBookmarkTypeList"] || !title) {
-      NOTREACHED() << "Type=("
-                   << (type ? base::SysNSStringToUTF8(type) : "Null type")
-                   << ") Title=("
-                   << (title ? base::SysNSStringToUTF8(title) : "Null title")
-                   << ")";
-      return;
-    }
-  }
-
-  NSArray* elements = [bookmark_folder objectForKey:@"Children"];
-  if (!elements && (!parent_path_elements.empty() || !is_in_toolbar)) {
-    // This is an empty folder, so add it explicitly; but don't add the toolbar
-    // folder if it is empty.  Note that all non-empty folders are added
-    // implicitly when their children are added.
-    ImportedBookmarkEntry entry;
-    // Safari doesn't specify a creation time for the folder.
-    entry.creation_time = base::Time::Now();
-    entry.title = base::SysNSStringToUTF16(title);
-    entry.path = parent_path_elements;
-    entry.in_toolbar = is_in_toolbar;
-    entry.is_folder = true;
-
-    out_bookmarks->push_back(entry);
-    return;
-  }
-
-  std::vector<string16> path_elements(parent_path_elements);
-  // Create a folder for the toolbar, but not for the bookmarks menu.
-  if (path_elements.empty() && [title isEqualToString:@"BookmarksBar"]) {
-    is_in_toolbar = true;
-    path_elements.push_back(toolbar_name);
-  } else if (!is_top_level_bookmarks_container &&
-             !(path_elements.empty() &&
-               [title isEqualToString:@"BookmarksMenu"])) {
-    if (title)
-      path_elements.push_back(base::SysNSStringToUTF16(title));
-  }
-
-  // Iterate over individual bookmarks.
-  for (NSDictionary* bookmark in elements) {
-    NSString* type = [bookmark objectForKey:@"WebBookmarkType"];
-    if (!type)
-      continue;
-
-    // If this is a folder, recurse.
-    if ([type isEqualToString:@"WebBookmarkTypeList"]) {
-      RecursiveReadBookmarksFolder(bookmark,
-                                   path_elements,
-                                   is_in_toolbar,
-                                   toolbar_name,
-                                   out_bookmarks);
-    }
-
-    // If we didn't see a bookmark folder, then we're expecting a bookmark
-    // item.  If that's not what we got then ignore it.
-    if (![type isEqualToString:@"WebBookmarkTypeLeaf"])
-      continue;
-
-    NSString* url = [bookmark objectForKey:@"URLString"];
-    NSString* title = [[bookmark objectForKey:@"URIDictionary"]
-        objectForKey:@"title"];
-
-    if (!url || !title)
-      continue;
-
-    // Output Bookmark.
-    ImportedBookmarkEntry entry;
-    // Safari doesn't specify a creation time for the bookmark.
-    entry.creation_time = base::Time::Now();
-    entry.title = base::SysNSStringToUTF16(title);
-    entry.url = GURL(base::SysNSStringToUTF8(url));
-    entry.path = path_elements;
-    entry.in_toolbar = is_in_toolbar;
-
-    out_bookmarks->push_back(entry);
-  }
-}
-
-void SafariImporter::ParseBookmarks(
-    const string16& toolbar_name,
-    std::vector<ImportedBookmarkEntry>* bookmarks) {
-  DCHECK(bookmarks);
-
-  // Construct ~/Library/Safari/Bookmarks.plist path
-  NSString* library_dir = [NSString
-      stringWithUTF8String:library_dir_.value().c_str()];
-  NSString* safari_dir = [library_dir
-      stringByAppendingPathComponent:@"Safari"];
-  NSString* bookmarks_plist = [safari_dir
-    stringByAppendingPathComponent:@"Bookmarks.plist"];
-
-  // Load the plist file.
-  NSDictionary* bookmarks_dict = [NSDictionary
-      dictionaryWithContentsOfFile:bookmarks_plist];
-  if (!bookmarks_dict)
-    return;
-
-  // Recursively read in bookmarks.
-  std::vector<string16> parent_path_elements;
-  RecursiveReadBookmarksFolder(bookmarks_dict, parent_path_elements, false,
-                               toolbar_name, bookmarks);
-}
-
-void SafariImporter::ImportPasswords() {
-  // Safari stores it's passwords in the Keychain, same as us so we don't need
-  // to import them.
-  // Note: that we don't automatically pick them up, there is some logic around
-  // the user needing to explicitly input his username in a page and blurring
-  // the field before we pick it up, but the details of that are beyond the
-  // scope of this comment.
-}
-
-void SafariImporter::ImportHistory() {
-  std::vector<ImporterURLRow> rows;
-  ParseHistoryItems(&rows);
-
-  if (!rows.empty() && !cancelled()) {
-    bridge_->SetHistoryItems(rows, history::SOURCE_SAFARI_IMPORTED);
-  }
-}
-
-double SafariImporter::HistoryTimeToEpochTime(NSString* history_time) {
-  DCHECK(history_time);
-  // Add Difference between Unix epoch and CFAbsoluteTime epoch in seconds.
-  // Unix epoch is 1970-01-01 00:00:00.0 UTC,
-  // CF epoch is 2001-01-01 00:00:00.0 UTC.
-  return CFStringGetDoubleValue(base::mac::NSToCFCast(history_time)) +
-      kCFAbsoluteTimeIntervalSince1970;
-}
-
-void SafariImporter::ParseHistoryItems(
-    std::vector<ImporterURLRow>* history_items) {
-  DCHECK(history_items);
-
-  // Construct ~/Library/Safari/History.plist path
-  NSString* library_dir = [NSString
-      stringWithUTF8String:library_dir_.value().c_str()];
-  NSString* safari_dir = [library_dir
-      stringByAppendingPathComponent:@"Safari"];
-  NSString* history_plist = [safari_dir
-      stringByAppendingPathComponent:@"History.plist"];
-
-  // Load the plist file.
-  NSDictionary* history_dict = [NSDictionary
-      dictionaryWithContentsOfFile:history_plist];
-  if (!history_dict)
-    return;
-
-  NSArray* safari_history_items = [history_dict
-      objectForKey:@"WebHistoryDates"];
-
-  for (NSDictionary* history_item in safari_history_items) {
-    NSString* url_ns = [history_item objectForKey:@""];
-    if (!url_ns)
-      continue;
-
-    GURL url(base::SysNSStringToUTF8(url_ns));
-
-    if (!CanImportSafariURL(url))
-      continue;
-
-    ImporterURLRow row(url);
-    NSString* title_ns = [history_item objectForKey:@"title"];
-
-    // Sometimes items don't have a title, in which case we just substitue
-    // the url.
-    if (!title_ns)
-      title_ns = url_ns;
-
-    row.title = base::SysNSStringToUTF16(title_ns);
-    int visit_count = [[history_item objectForKey:@"visitCount"]
-                          intValue];
-    row.visit_count = visit_count;
-    // Include imported URLs in autocompletion - don't hide them.
-    row.hidden = 0;
-    // Item was never typed before in the omnibox.
-    row.typed_count = 0;
-
-    NSString* last_visit_str = [history_item objectForKey:@"lastVisitedDate"];
-    // The last visit time should always be in the history item, but if not
-    /// just continue without this item.
-    DCHECK(last_visit_str);
-    if (!last_visit_str)
-      continue;
-
-    // Convert Safari's last visit time to Unix Epoch time.
-    double seconds_since_unix_epoch = HistoryTimeToEpochTime(last_visit_str);
-    row.last_visit = base::Time::FromDoubleT(seconds_since_unix_epoch);
-
-    history_items->push_back(row);
-  }
-}
diff --git a/chrome/browser/importer/safari_importer_unittest.mm b/chrome/browser/importer/safari_importer_unittest.mm
deleted file mode 100644
index 93e110c..0000000
--- a/chrome/browser/importer/safari_importer_unittest.mm
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/importer/safari_importer.h"
-
-#include "base/basictypes.h"
-#include "base/file_util.h"
-#include "base/files/file_path.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/path_service.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_util.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/importer/importer_bridge.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/importer/imported_bookmark_entry.h"
-#include "chrome/common/importer/imported_favicon_usage.h"
-#include "sql/connection.h"
-#include "testing/platform_test.h"
-
-// In order to test the Safari import functionality effectively, we store a
-// simulated Library directory containing dummy data files in the same
-// structure as ~/Library in the Chrome test data directory.
-// This function returns the path to that directory.
-base::FilePath GetTestSafariLibraryPath() {
-  base::FilePath test_dir;
-  PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
-
-  // Our simulated ~/Library directory
-  test_dir = test_dir.AppendASCII("safari_import");
-  return test_dir;
-}
-
-class SafariImporterTest : public PlatformTest {
- public:
-  SafariImporter* GetSafariImporter() {
-    base::FilePath test_library_dir = GetTestSafariLibraryPath();
-    CHECK(file_util::PathExists(test_library_dir))  <<
-        "Missing test data directory";
-
-    return new SafariImporter(test_library_dir);
-  }
-};
-
-TEST_F(SafariImporterTest, HistoryImport) {
-  scoped_refptr<SafariImporter> importer(GetSafariImporter());
-
-  std::vector<ImporterURLRow> history_items;
-  importer->ParseHistoryItems(&history_items);
-
-  // Should be 2 history items.
-  ASSERT_EQ(history_items.size(), 2U);
-
-  ImporterURLRow& it1 = history_items[0];
-  EXPECT_EQ(it1.url, GURL("http://www.firsthistoryitem.com/"));
-  EXPECT_EQ(it1.title, UTF8ToUTF16("First History Item Title"));
-  EXPECT_EQ(it1.visit_count, 1);
-  EXPECT_EQ(it1.hidden, 0);
-  EXPECT_EQ(it1.typed_count, 0);
-  EXPECT_EQ(it1.last_visit.ToDoubleT(),
-      importer->HistoryTimeToEpochTime(@"270598264.4"));
-
-  ImporterURLRow& it2 = history_items[1];
-  std::string second_item_title("http://www.secondhistoryitem.com/");
-  EXPECT_EQ(it2.url, GURL(second_item_title));
-  // The second item lacks a title so we expect the URL to be substituted.
-  EXPECT_EQ(UTF16ToUTF8(it2.title), second_item_title.c_str());
-  EXPECT_EQ(it2.visit_count, 55);
-  EXPECT_EQ(it2.hidden, 0);
-  EXPECT_EQ(it2.typed_count, 0);
-  EXPECT_EQ(it2.last_visit.ToDoubleT(),
-      importer->HistoryTimeToEpochTime(@"270598231.4"));
-}
-
-TEST_F(SafariImporterTest, BookmarkImport) {
-  // Expected results
-  const struct {
-    bool in_toolbar;
-    GURL url;
-    // We store the path with levels of nesting delimited by forward slashes.
-    string16 path;
-    string16 title;
-  } kImportedBookmarksData[] = {
-    {
-      true,
-      GURL("http://www.apple.com/"),
-      ASCIIToUTF16("Toolbar/"),
-      ASCIIToUTF16("Apple")
-    },
-    {
-      true,
-      GURL("http://www.yahoo.com/"),
-      ASCIIToUTF16("Toolbar/"),
-      ASCIIToUTF16("Yahoo!")
-    },
-    {
-      true,
-      GURL("http://www.cnn.com/"),
-      ASCIIToUTF16("Toolbar/News"),
-      ASCIIToUTF16("CNN")
-    },
-    {
-      true,
-      GURL("http://www.nytimes.com/"),
-      ASCIIToUTF16("Toolbar/News"),
-      ASCIIToUTF16("The New York Times")
-    },
-    {
-      false,
-      GURL("http://www.reddit.com/"),
-      string16(),
-      ASCIIToUTF16("reddit.com: what's new online!")
-    },
-    {
-      false,
-      GURL(),
-      string16(),
-      ASCIIToUTF16("Empty Folder")
-    },
-    {
-      false,
-      GURL("http://www.webkit.org/blog/"),
-      string16(),
-      ASCIIToUTF16("Surfin' Safari - The WebKit Blog")
-    },
-  };
-
-  scoped_refptr<SafariImporter> importer(GetSafariImporter());
-  std::vector<ImportedBookmarkEntry> bookmarks;
-  importer->ParseBookmarks(ASCIIToUTF16("Toolbar"), &bookmarks);
-  size_t num_bookmarks = bookmarks.size();
-  ASSERT_EQ(ARRAYSIZE_UNSAFE(kImportedBookmarksData), num_bookmarks);
-
-  for (size_t i = 0; i < num_bookmarks; ++i) {
-    ImportedBookmarkEntry& entry = bookmarks[i];
-    EXPECT_EQ(kImportedBookmarksData[i].in_toolbar, entry.in_toolbar);
-    EXPECT_EQ(kImportedBookmarksData[i].url, entry.url);
-
-    std::vector<string16> path;
-    Tokenize(kImportedBookmarksData[i].path, ASCIIToUTF16("/"), &path);
-    ASSERT_EQ(path.size(), entry.path.size());
-    for (size_t j = 0; j < path.size(); ++j) {
-      EXPECT_EQ(path[j], entry.path[j]);
-    }
-
-    EXPECT_EQ(kImportedBookmarksData[i].title, entry.title);
-  }
-}
-
-TEST_F(SafariImporterTest, FaviconImport) {
-  scoped_refptr<SafariImporter> importer(GetSafariImporter());
-  sql::Connection db;
-  ASSERT_TRUE(importer->OpenDatabase(&db));
-
-  SafariImporter::FaviconMap favicon_map;
-  importer->ImportFaviconURLs(&db, &favicon_map);
-
-  std::vector<ImportedFaviconUsage> favicons;
-  importer->LoadFaviconData(&db, favicon_map, &favicons);
-
-  size_t num_favicons = favicons.size();
-  ASSERT_EQ(num_favicons, 2U);
-
-  ImportedFaviconUsage &fav0 = favicons[0];
-  EXPECT_EQ("http://s.ytimg.com/yt/favicon-vfl86270.ico",
-            fav0.favicon_url.spec());
-  EXPECT_GT(fav0.png_data.size(), 0U);
-  EXPECT_EQ(fav0.urls.size(), 1U);
-  EXPECT_TRUE(fav0.urls.find(GURL("http://www.youtube.com/"))
-      != fav0.urls.end());
-
-  ImportedFaviconUsage &fav1 = favicons[1];
-  EXPECT_EQ("http://www.opensearch.org/favicon.ico",
-            fav1.favicon_url.spec());
-  EXPECT_GT(fav1.png_data.size(), 0U);
-  EXPECT_EQ(fav1.urls.size(), 2U);
-  EXPECT_TRUE(fav1.urls.find(GURL("http://www.opensearch.org/Home"))
-      != fav1.urls.end());
-
-  EXPECT_TRUE(fav1.urls.find(
-      GURL("http://www.opensearch.org/Special:Search?search=lalala&go=Search"))
-          != fav1.urls.end());
-}
-
-TEST_F(SafariImporterTest, CanImport) {
-  uint16 items = importer::NONE;
-  EXPECT_TRUE(SafariImporter::CanImport(GetTestSafariLibraryPath(), &items));
-  EXPECT_EQ(items, importer::HISTORY | importer::FAVORITES);
-  EXPECT_EQ(items & importer::COOKIES, importer::NONE);
-  EXPECT_EQ(items & importer::PASSWORDS, importer::NONE);
-  EXPECT_EQ(items & importer::SEARCH_ENGINES, importer::NONE);
-  EXPECT_EQ(items & importer::HOME_PAGE, importer::NONE);
-
-  // Check that we don't import anything from a bogus library directory.
-  base::ScopedTempDir fake_library_dir;
-  ASSERT_TRUE(fake_library_dir.CreateUniqueTempDir());
-  EXPECT_FALSE(SafariImporter::CanImport(fake_library_dir.path(), &items));
-}
diff --git a/chrome/browser/infobars/infobar_container.cc b/chrome/browser/infobars/infobar_container.cc
index 9b8ce11..de9c943 100644
--- a/chrome/browser/infobars/infobar_container.cc
+++ b/chrome/browser/infobars/infobar_container.cc
@@ -12,12 +12,10 @@
 #include <algorithm>
 
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/infobar.h"
 #include "chrome/browser/infobars/infobar_delegate.h"
 #include "chrome/browser/infobars/infobar_service.h"
-#include "chrome/browser/ui/search/instant_overlay_model.h"
-#include "chrome/browser/ui/search/search_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "ui/base/animation/slide_animation.h"
@@ -25,42 +23,21 @@
 InfoBarContainer::Delegate::~Delegate() {
 }
 
-InfoBarContainer::InfoBarContainer(Delegate* delegate,
-                                   SearchModel* search_model)
+InfoBarContainer::InfoBarContainer(Delegate* delegate)
     : delegate_(delegate),
       infobar_service_(NULL),
-      infobars_shown_(true),
-      search_model_(search_model),
       top_arrow_target_height_(InfoBar::kDefaultArrowTargetHeight) {
-  if (search_model_)
-    search_model_->AddObserver(this);
 }
 
 InfoBarContainer::~InfoBarContainer() {
   // RemoveAllInfoBarsForDestruction() should have already cleared our infobars.
   DCHECK(infobars_.empty());
-  if (search_model_)
-    search_model_->RemoveObserver(this);
 }
 
 void InfoBarContainer::ChangeInfoBarService(InfoBarService* infobar_service) {
-  // We have to call HideAllInfoBars() here and not after the early exit below,
-  // to handle the case we're switching from a tab with visible infobars to one
-  // where the SearchModel directs us to hide infobars.
   HideAllInfoBars();
 
   infobar_service_ = infobar_service;
-
-  if (search_model_ && !search_model_->top_bars_visible())
-    return;
-
-  // Note that HideAllInfoBars() sets |infobars_shown_| to false, because that's
-  // what the other, Instant-related callers want; but here we actually
-  // explicitly want to reset this variable to true.  So do that after calling
-  // the function.
-  infobars_shown_ = true;
-  infobars_shown_time_ = base::TimeTicks();
-
   if (infobar_service_) {
     content::Source<InfoBarService> source(infobar_service_);
     registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
@@ -133,6 +110,7 @@
   // and at worst disastrous to call that.
   delegate_ = NULL;
 
+  // TODO(pkasting): Remove this once InfoBarService calls CloseSoon().
   for (size_t i = infobars_.size(); i > 0; --i)
     infobars_[i - 1]->CloseSoon();
 
@@ -142,9 +120,6 @@
 void InfoBarContainer::Observe(int type,
                                const content::NotificationSource& source,
                                const content::NotificationDetails& details) {
-  // When infobars are hidden, we shouldn't be listening for notifications.
-  DCHECK(infobars_shown_);
-
   switch (type) {
     case chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED:
       AddInfoBar(
@@ -174,26 +149,8 @@
   }
 }
 
-void InfoBarContainer::ModelChanged(const SearchModel::State& old_state,
-                                    const SearchModel::State& new_state) {
-  if (!SearchModel::ShouldChangeTopBarsVisibility(old_state, new_state))
-    return;
-
-  if (new_state.top_bars_visible && !infobars_shown_) {
-    ChangeInfoBarService(infobar_service_);
-    infobars_shown_time_ = base::TimeTicks::Now();
-  } else if (!new_state.top_bars_visible && infobars_shown_) {
-    HideAllInfoBars();
-    OnInfoBarStateChanged(false);
-  }
-}
-
 size_t InfoBarContainer::HideInfoBar(InfoBarDelegate* delegate,
                                      bool use_animation) {
-  bool should_animate = use_animation &&
-      ((base::TimeTicks::Now() - infobars_shown_time_) >
-          base::TimeDelta::FromMilliseconds(50));
-
   // Search for the infobar associated with |delegate|.  We cannot search for
   // |delegate| in |tab_helper_|, because an InfoBar remains alive until its
   // close animation completes, while the delegate is removed from the tab
@@ -204,7 +161,7 @@
       size_t position = i - infobars_.begin();
       // We merely need hide the infobar; it will call back to RemoveInfoBar()
       // itself once it's hidden.
-      infobar->Hide(should_animate);
+      infobar->Hide(use_animation);
       infobar->CloseSoon();
       UpdateInfoBarArrowTargetHeights();
       return position;
@@ -217,7 +174,6 @@
 void InfoBarContainer::HideAllInfoBars() {
   registrar_.RemoveAll();
 
-  infobars_shown_ = false;
   while (!infobars_.empty()) {
     InfoBar* infobar = infobars_.front();
     // Inform the infobar that it's hidden.  If it was already closing, this
diff --git a/chrome/browser/infobars/infobar_container.h b/chrome/browser/infobars/infobar_container.h
index 0f2b241..feafd13 100644
--- a/chrome/browser/infobars/infobar_container.h
+++ b/chrome/browser/infobars/infobar_container.h
@@ -9,8 +9,6 @@
 
 #include "base/compiler_specific.h"
 #include "base/time/time.h"
-#include "chrome/browser/ui/search/search_model_observer.h"
-#include "chrome/common/search_types.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -18,7 +16,6 @@
 class InfoBar;
 class InfoBarDelegate;
 class InfoBarService;
-class SearchModel;
 
 // InfoBarContainer is a cross-platform base class to handle the visibility-
 // related aspects of InfoBars.  While InfoBars own themselves, the
@@ -27,24 +24,7 @@
 //
 // Platforms need to subclass this to implement a few platform-specific
 // functions, which are pure virtual here.
-//
-// This class also observes changes to the SearchModel modes.  It hides infobars
-// temporarily if the user changes into |SEARCH_SUGGESTIONS| mode (refer to
-// SearchMode in chrome/common/search_types.h for all search modes)
-// when on a :
-// - |DEFAULT| page: when Instant overlay is ready;
-// - |NTP| or |SEARCH_RESULTS| page: immediately;
-//   TODO(kuan): this scenario requires more complex synchronization with
-//   renderer SearchBoxAPI and will be implemented as the next step;
-//   for now, hiding is immediate.
-// When the user changes back out of |SEARCH_SUGGESTIONS| mode, it reshows any
-// infobars, and starts a 50 ms window during which any attempts to re-hide any
-// infobars are handled without animation.  This prevents glitchy-looking
-// behavior when the user navigates following a mode change, which otherwise
-// would re-show the infobars only to instantly animate them closed.  The window
-// to re-hide infobars without animation is canceled if a tab change occurs.
-class InfoBarContainer : public content::NotificationObserver,
-                         public SearchModelObserver {
+class InfoBarContainer : public content::NotificationObserver {
  public:
   class Delegate {
    public:
@@ -63,15 +43,12 @@
     virtual ~Delegate();
   };
 
-  // |search_model| may be NULL if this class is used in a window that does not
-  // support Instant Extended.
-  InfoBarContainer(Delegate* delegate, SearchModel* search_model);
+  explicit InfoBarContainer(Delegate* delegate);
   virtual ~InfoBarContainer();
 
-  // Changes the InfoBarService for which this container is showing
-  // infobars.  This will remove all current infobars from the container, add
-  // the infobars from |infobar_service|, and show them all.  |infobar_service|
-  // may be NULL.
+  // Changes the InfoBarService for which this container is showing infobars.
+  // This will remove all current infobars from the container, add the infobars
+  // from |infobar_service|, and show them all.  |infobar_service| may be NULL.
   void ChangeInfoBarService(InfoBarService* infobar_service);
 
   // Returns the amount by which to overlap the toolbar above, and, when
@@ -125,17 +102,12 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
-  // SearchModelObserver:
-  virtual void ModelChanged(const SearchModel::State& old_state,
-                            const SearchModel::State& new_state) OVERRIDE;
-
   // Hides an InfoBar for the specified delegate, in response to a notification
   // from the selected InfoBarService.  The InfoBar's disappearance will be
-  // animated if |use_animation| is true and it has been more than 50ms since
-  // infobars were reshown due to an Instant Extended mode change. The InfoBar
-  // will call back to RemoveInfoBar() to remove itself once it's hidden (which
-  // may mean synchronously).  Returns the position within |infobars_| the
-  // infobar was previously at.
+  // animated if |use_animation| is true. The InfoBar will call back to
+  // RemoveInfoBar() to remove itself once it's hidden (which may mean
+  // synchronously).  Returns the position within |infobars_| the infobar was
+  // previously at.
   size_t HideInfoBar(InfoBarDelegate* delegate, bool use_animation);
 
   // Hides all infobars in this container without animation.
@@ -164,17 +136,6 @@
   InfoBarService* infobar_service_;
   InfoBars infobars_;
 
-  // Tracks whether infobars in the container are shown or hidden.
-  bool infobars_shown_;
-
-  // Tracks the most recent time infobars were re-shown after being hidden due
-  // to Instant Extended's ModeChanged.
-  base::TimeTicks infobars_shown_time_;
-
-  // Tracks which search mode is active, as well as mode changes, for Instant
-  // Extended.
-  SearchModel* search_model_;
-
   // Calculated in SetMaxTopArrowHeight().
   int top_arrow_target_height_;
 
diff --git a/chrome/browser/infobars/infobar_delegate.cc b/chrome/browser/infobars/infobar_delegate.cc
index 6bd2c20..afa5c95 100644
--- a/chrome/browser/infobars/infobar_delegate.cc
+++ b/chrome/browser/infobars/infobar_delegate.cc
@@ -100,10 +100,10 @@
       ResourceBundle::GetSharedInstance().GetNativeImageNamed(icon_id);
 }
 
-InfoBarDelegate::InfoBarDelegate(InfoBarService* infobar_service)
+InfoBarDelegate::InfoBarDelegate(InfoBarService* owner)
     : contents_unique_id_(0),
-      owner_(infobar_service) {
-  if (infobar_service)
+      owner_(owner) {
+  if (owner_)
     StoreActiveEntryUniqueID();
 }
 
diff --git a/chrome/browser/infobars/infobar_delegate.h b/chrome/browser/infobars/infobar_delegate.h
index 2ee34e3..0694f5e 100644
--- a/chrome/browser/infobars/infobar_delegate.h
+++ b/chrome/browser/infobars/infobar_delegate.h
@@ -113,7 +113,7 @@
  protected:
   // If |contents| is non-NULL, its active entry's unique ID will be stored
   // using StoreActiveEntryUniqueID automatically.
-  explicit InfoBarDelegate(InfoBarService* infobar_service);
+  explicit InfoBarDelegate(InfoBarService* owner);
 
   // Store the unique id for the active entry in our WebContents, to be used
   // later upon navigation to determine if this InfoBarDelegate should be
diff --git a/chrome/browser/infobars/infobar_service.cc b/chrome/browser/infobars/infobar_service.cc
index ad478ae..f52304f 100644
--- a/chrome/browser/infobars/infobar_service.cc
+++ b/chrome/browser/infobars/infobar_service.cc
@@ -4,10 +4,10 @@
 
 #include "chrome/browser/infobars/infobar_service.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/infobar.h"
 #include "chrome/browser/infobars/infobar_delegate.h"
 #include "chrome/browser/infobars/insecure_content_infobar_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/render_messages.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/notification_service.h"
@@ -18,6 +18,7 @@
 
 InfoBarDelegate* InfoBarService::AddInfoBar(
     scoped_ptr<InfoBarDelegate> delegate) {
+  DCHECK(delegate);
   if (!infobars_enabled_)
     return NULL;
 
@@ -29,13 +30,18 @@
     }
   }
 
-  // TODO(pkasting): Consider removing InfoBarService arg from delegate
-  // constructors and instead using a setter from here.
+  // TODO(pkasting): Remove InfoBarService arg from delegate constructors and
+  // instead use a setter from here.
   InfoBarDelegate* delegate_ptr = delegate.release();
   infobars_.push_back(delegate_ptr);
+
   // Add ourselves as an observer for navigations the first time a delegate is
   // added. We use this notification to expire InfoBars that need to expire on
-  // page transitions.
+  // page transitions.  We must do this before calling Notify() below;
+  // otherwise, if that call causes a call to RemoveInfoBar(), we'll try to
+  // unregister for the NAV_ENTRY_COMMITTED notification, which we won't have
+  // yet registered here, and we'll fail the "was registered" DCHECK in
+  // NotificationRegistrar::Remove().
   if (infobars_.size() == 1) {
     registrar_.Add(
         this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
@@ -57,8 +63,10 @@
 InfoBarDelegate* InfoBarService::ReplaceInfoBar(
     InfoBarDelegate* old_delegate,
     scoped_ptr<InfoBarDelegate> new_delegate) {
+  DCHECK(old_delegate);
   if (!infobars_enabled_)
     return AddInfoBar(new_delegate.Pass());  // Deletes the delegate.
+  DCHECK(new_delegate);
 
   InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(),
                                  old_delegate));
@@ -67,6 +75,7 @@
   InfoBarDelegate* new_delegate_ptr = new_delegate.release();
   i = infobars_.insert(i, new_delegate_ptr);
   InfoBarReplacedDetails replaced_details(old_delegate, new_delegate_ptr);
+
   // Remove the old delegate before notifying, so that if any observers call
   // back to AddInfoBar() or similar, we don't dupe-check against this delegate.
   infobars_.erase(++i);
@@ -98,7 +107,7 @@
   RemoveAllInfoBars(false);
 }
 
-void InfoBarService::RenderViewGone(base::TerminationStatus status) {
+void InfoBarService::RenderProcessGone(base::TerminationStatus status) {
   RemoveAllInfoBars(true);
 }
 
@@ -150,6 +159,7 @@
 
 void InfoBarService::RemoveInfoBarInternal(InfoBarDelegate* delegate,
                                            bool animate) {
+  DCHECK(delegate);
   if (!infobars_enabled_) {
     DCHECK(infobars_.empty());
     return;
@@ -162,7 +172,13 @@
   // Remove the delegate before notifying, so that if any observers call back to
   // AddInfoBar() or similar, we don't dupe-check against this delegate.
   infobars_.erase(i);
-  // Remove ourselves as an observer if we are tracking no more InfoBars.
+
+  // Remove ourselves as an observer if we are tracking no more InfoBars.  We
+  // must do this before calling Notify() below; otherwise, if that call
+  // causes a call to AddInfoBar(), we'll try to register for the
+  // NAV_ENTRY_COMMITTED notification, which we won't have yet unregistered
+  // here, and we'll fail the "not already registered" DCHECK in
+  // NotificationRegistrar::Add().
   if (infobars_.empty()) {
     registrar_.Remove(
         this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
diff --git a/chrome/browser/infobars/infobar_service.h b/chrome/browser/infobars/infobar_service.h
index 5ea6ce0..e0f40aa 100644
--- a/chrome/browser/infobars/infobar_service.h
+++ b/chrome/browser/infobars/infobar_service.h
@@ -78,7 +78,7 @@
   virtual ~InfoBarService();
 
   // content::WebContentsObserver:
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
 
   // content::NotificationObserver:
diff --git a/chrome/browser/infobars/infobars_browsertest.cc b/chrome/browser/infobars/infobars_browsertest.cc
index 6b2c481..f95fa56 100644
--- a/chrome/browser/infobars/infobars_browsertest.cc
+++ b/chrome/browser/infobars/infobars_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_install_prompt.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -11,7 +12,6 @@
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/infobars/insecure_content_infobar_delegate.cc b/chrome/browser/infobars/insecure_content_infobar_delegate.cc
index 2f1a039..9e56837 100644
--- a/chrome/browser/infobars/insecure_content_infobar_delegate.cc
+++ b/chrome/browser/infobars/insecure_content_infobar_delegate.cc
@@ -14,7 +14,6 @@
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
-using content::OpenURLParams;
 
 // static
 void InsecureContentInfoBarDelegate::Create(InfoBarService* infobar_service,
@@ -108,9 +107,9 @@
 
 bool InsecureContentInfoBarDelegate::LinkClicked(
     WindowOpenDisposition disposition) {
-  web_contents()->OpenURL(OpenURLParams(
-      google_util::AppendGoogleLocaleParam(GURL(
-      "https://www.google.com/support/chrome/bin/answer.py?answer=1342714")),
+  web_contents()->OpenURL(content::OpenURLParams(
+      google_util::AppendGoogleLocaleParam(GURL("https://www.google.com/"
+          "support/chrome/bin/answer.py?answer=1342714")),
       content::Referrer(),
       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
       content::PAGE_TRANSITION_LINK, false));
diff --git a/chrome/browser/invalidation/invalidation_service_android.cc b/chrome/browser/invalidation/invalidation_service_android.cc
index 664aef1..06cf3e7 100644
--- a/chrome/browser/invalidation/invalidation_service_android.cc
+++ b/chrome/browser/invalidation/invalidation_service_android.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/invalidation/invalidation_service_android.h"
 
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 
 namespace invalidation {
@@ -63,16 +63,10 @@
   DCHECK(CalledOnValidThread());
   DCHECK_EQ(type, chrome::NOTIFICATION_SYNC_REFRESH_REMOTE);
 
-  // TODO(akalin): Use ObjectIdInvalidationMap here instead.  We'll have to
-  // make sure all emitters of the relevant notifications also use
-  // ObjectIdInvalidationMap.
-  content::Details<const syncer::ModelTypeInvalidationMap>
+  content::Details<const syncer::ObjectIdInvalidationMap>
       state_details(details);
-  const syncer::ModelTypeInvalidationMap& model_type_invalidation_map =
+  const syncer::ObjectIdInvalidationMap object_invalidation_map =
       *(state_details.ptr());
-  syncer::ObjectIdInvalidationMap object_invalidation_map =
-      ModelTypeInvalidationMapToObjectIdInvalidationMap(
-          model_type_invalidation_map);
 
   // An empty map implies that we should invalidate all.
   const syncer::ObjectIdInvalidationMap& effective_invalidation_map =
diff --git a/chrome/browser/invalidation/invalidation_service_android_unittest.cc b/chrome/browser/invalidation/invalidation_service_android_unittest.cc
index 9e332b2..af9de1d 100644
--- a/chrome/browser/invalidation/invalidation_service_android_unittest.cc
+++ b/chrome/browser/invalidation/invalidation_service_android_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "chrome/browser/invalidation/invalidation_service_android.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/invalidation/invalidation_service_factory.h"
 #include "chrome/browser/invalidation/invalidation_service_test_template.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -41,13 +41,11 @@
 
   void TriggerOnIncomingInvalidation(
       const syncer::ObjectIdInvalidationMap& invalidation_map) {
-    syncer::ModelTypeInvalidationMap model_invalidation_map =
-            ObjectIdInvalidationMapToModelTypeInvalidationMap(invalidation_map);
     content::NotificationService::current()->Notify(
         chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
         content::Source<Profile>(profile_.get()),
-        content::Details<const syncer::ModelTypeInvalidationMap>(
-            &model_invalidation_map));
+        content::Details<const syncer::ObjectIdInvalidationMap>(
+            &invalidation_map));
   }
 
   scoped_ptr<TestingProfile> profile_;
diff --git a/chrome/browser/invalidation/invalidation_service_factory.cc b/chrome/browser/invalidation/invalidation_service_factory.cc
index 2085417..741e6fb 100644
--- a/chrome/browser/invalidation/invalidation_service_factory.cc
+++ b/chrome/browser/invalidation/invalidation_service_factory.cc
@@ -105,9 +105,9 @@
 #endif
 }
 
-void InvalidationServiceFactory::RegisterUserPrefs(
+void InvalidationServiceFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
-  InvalidatorStorage::RegisterUserPrefs(registry);
+  InvalidatorStorage::RegisterProfilePrefs(registry);
 }
 
 }  // namespace invalidation
diff --git a/chrome/browser/invalidation/invalidation_service_factory.h b/chrome/browser/invalidation/invalidation_service_factory.h
index fa2828a..caf8656 100644
--- a/chrome/browser/invalidation/invalidation_service_factory.h
+++ b/chrome/browser/invalidation/invalidation_service_factory.h
@@ -54,7 +54,7 @@
   // BrowserContextKeyedServiceFactory:
   virtual BrowserContextKeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
 
   // If true, this factory will return only FakeInvalidationService instances.
diff --git a/chrome/browser/invalidation/invalidation_service_test_template.h b/chrome/browser/invalidation/invalidation_service_test_template.h
index baad132..85a467c 100644
--- a/chrome/browser/invalidation/invalidation_service_test_template.h
+++ b/chrome/browser/invalidation/invalidation_service_test_template.h
@@ -84,14 +84,12 @@
 template <typename InvalidatorTestDelegate>
 class InvalidationServiceTest : public testing::Test {
  protected:
-  // Note: The IDs defined below must be valid.  Otherwise they won't make it
-  // through the round-trip to ModelTypeInvalidationMap and back that the
-  // AndroidInvalidation test requires.
   InvalidationServiceTest()
       : id1(ipc::invalidation::ObjectSource::CHROME_SYNC, "BOOKMARK"),
         id2(ipc::invalidation::ObjectSource::CHROME_SYNC, "PREFERENCE"),
         id3(ipc::invalidation::ObjectSource::CHROME_SYNC, "AUTOFILL"),
-        id4(ipc::invalidation::ObjectSource::CHROME_SYNC, "EXPERIMENTS") {
+        id4(ipc::invalidation::ObjectSource::CHROME_PUSH_MESSAGING,
+            "PUSH_MESSAGE") {
   }
 
   invalidation::InvalidationService*
diff --git a/chrome/browser/invalidation/invalidator_storage.cc b/chrome/browser/invalidation/invalidator_storage.cc
index 780ba12..2c6c2ae 100644
--- a/chrome/browser/invalidation/invalidator_storage.cc
+++ b/chrome/browser/invalidation/invalidator_storage.cc
@@ -95,7 +95,7 @@
 namespace invalidation {
 
 // static
-void InvalidatorStorage::RegisterUserPrefs(
+void InvalidatorStorage::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(prefs::kInvalidatorMaxInvalidationVersions,
                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
diff --git a/chrome/browser/invalidation/invalidator_storage.h b/chrome/browser/invalidation/invalidator_storage.h
index 2e5f420..d0b48a2 100644
--- a/chrome/browser/invalidation/invalidator_storage.h
+++ b/chrome/browser/invalidation/invalidator_storage.h
@@ -31,7 +31,7 @@
 class InvalidatorStorage : public base::SupportsWeakPtr<InvalidatorStorage>,
                            public syncer::InvalidationStateTracker {
  public:
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // |pref_service| may be NULL (for unit tests), but in that case no setter
   // methods should be called. Does not own |pref_service|.
diff --git a/chrome/browser/invalidation/invalidator_storage_unittest.cc b/chrome/browser/invalidation/invalidator_storage_unittest.cc
index 29b1daf..1bc015a 100644
--- a/chrome/browser/invalidation/invalidator_storage_unittest.cc
+++ b/chrome/browser/invalidation/invalidator_storage_unittest.cc
@@ -47,7 +47,7 @@
         kAutofillId_(kChromeSyncSourceId, "AUTOFILL") {}
 
   virtual void SetUp() {
-    InvalidatorStorage::RegisterUserPrefs(pref_service_.registry());
+    InvalidatorStorage::RegisterProfilePrefs(pref_service_.registry());
   }
 
  protected:
diff --git a/chrome/browser/invalidation/ticl_invalidation_service.cc b/chrome/browser/invalidation/ticl_invalidation_service.cc
index 11a9759..f1bd4e7 100644
--- a/chrome/browser/invalidation/ticl_invalidation_service.cc
+++ b/chrome/browser/invalidation/ticl_invalidation_service.cc
@@ -5,13 +5,13 @@
 #include "chrome/browser/invalidation/ticl_invalidation_service.h"
 
 #include "base/command_line.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/invalidation/invalidation_service_util.h"
 #include "chrome/browser/managed_mode/managed_user_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/profile_oauth2_token_service.h"
 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/signin/signin_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "google_apis/gaia/gaia_constants.h"
 #include "sync/notifier/invalidator.h"
@@ -344,7 +344,6 @@
   std::string email = signin_manager_->GetAuthenticatedUsername();
 
   DCHECK(!email.empty()) << "Expected user to be signed in.";
-  DCHECK(!access_token_.empty());
 
   DVLOG(2) << "UpdateCredentials: " << email;
   invalidator_->UpdateCredentials(email, access_token_);
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index d68b6e5..8b382c0 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -398,7 +398,8 @@
       prefs::kAuthNegotiateDelegateWhitelist);
   gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName);
   pref_proxy_config_tracker_.reset(
-      ProxyServiceFactory::CreatePrefProxyConfigTracker(local_state));
+      ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
+          local_state));
   ChromeNetworkDelegate::InitializePrefsOnUIThread(
       &system_enable_referrers_,
       NULL,
@@ -464,7 +465,12 @@
 }
 
 void IOThread::Init() {
-  TRACE_EVENT0("startup", "IOThread::Init");
+  // Prefer to use InitAsync unless you need initialization to block
+  // the UI thread
+}
+
+void IOThread::InitAsync() {
+  TRACE_EVENT0("startup", "IOThread::InitAsync");
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
 #if defined(USE_NSS) || defined(OS_IOS)
@@ -525,10 +531,10 @@
   globals_->http_user_agent_settings.reset(
       new BasicHttpUserAgentSettings(std::string()));
   if (command_line.HasSwitch(switches::kHostRules)) {
-    TRACE_EVENT_BEGIN0("startup", "IOThread::Init:SetRulesFromString");
+    TRACE_EVENT_BEGIN0("startup", "IOThread::InitAsync:SetRulesFromString");
     globals_->host_mapping_rules->SetRulesFromString(
         command_line.GetSwitchValueASCII(switches::kHostRules));
-    TRACE_EVENT_END0("startup", "IOThread::Init:SetRulesFromString");
+    TRACE_EVENT_END0("startup", "IOThread::InitAsync:SetRulesFromString");
   }
   if (command_line.HasSwitch(switches::kIgnoreCertificateErrors))
     globals_->ignore_certificate_errors = true;
@@ -540,7 +546,10 @@
     globals_->testing_fixed_https_port =
         GetSwitchValueAsInt(command_line, switches::kTestingFixedHttpsPort);
   }
-  globals_->enable_quic.set(ShouldEnableQuic(command_line));
+  bool enable_quic = ShouldEnableQuic(command_line);
+  globals_->enable_quic.set(enable_quic);
+  if (enable_quic && command_line.HasSwitch(switches::kEnableQuicHttps))
+    globals_->enable_quic_https.set(true);
   if (command_line.HasSwitch(switches::kOriginToForceQuicOn)) {
     net::HostPortPair quic_origin =
         net::HostPortPair::FromString(
@@ -561,12 +570,12 @@
   session_params.proxy_service =
       globals_->proxy_script_fetcher_proxy_service.get();
 
-  TRACE_EVENT_BEGIN0("startup", "IOThread::Init:HttpNetworkSession");
+  TRACE_EVENT_BEGIN0("startup", "IOThread::InitAsync:HttpNetworkSession");
   scoped_refptr<net::HttpNetworkSession> network_session(
       new net::HttpNetworkSession(session_params));
   globals_->proxy_script_fetcher_http_transaction_factory
       .reset(new net::HttpNetworkLayer(network_session.get()));
-  TRACE_EVENT_END0("startup", "IOThread::Init:HttpNetworkSession");
+  TRACE_EVENT_END0("startup", "IOThread::InitAsync:HttpNetworkSession");
   scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
       new net::URLRequestJobFactoryImpl());
   job_factory->SetProtocolHandler(chrome::kDataScheme,
@@ -655,54 +664,50 @@
     net::CookieMonster::EnableFileScheme();
   }
 
-  // If "spdy.disabled" preference is controlled via policy, then skip use-spdy
-  // command line flags.
-  if (is_spdy_disabled_by_policy_)
-    return;
+  // Only handle use-spdy command line flags if "spdy.disabled" preference is
+  // not disabled via policy.
+  if (!is_spdy_disabled_by_policy_) {
+    if (command_line.HasSwitch(switches::kEnableIPPooling))
+      globals_->enable_spdy_ip_pooling.set(true);
 
-  if (command_line.HasSwitch(switches::kEnableIPPooling))
-    globals_->enable_spdy_ip_pooling.set(true);
+    if (command_line.HasSwitch(switches::kDisableIPPooling))
+      globals_->enable_spdy_ip_pooling.set(false);
 
-  if (command_line.HasSwitch(switches::kDisableIPPooling))
-    globals_->enable_spdy_ip_pooling.set(false);
+    if (command_line.HasSwitch(switches::kEnableSpdyCredentialFrames))
+      globals_->enable_spdy_credential_frames.set(true);
 
-  if (command_line.HasSwitch(switches::kEnableSpdyCredentialFrames))
-    globals_->enable_spdy_credential_frames.set(true);
+    if (command_line.HasSwitch(switches::kEnableWebSocketOverSpdy)) {
+      // Enable WebSocket over SPDY.
+      net::WebSocketJob::set_websocket_over_spdy_enabled(true);
+    }
+    if (command_line.HasSwitch(switches::kMaxSpdyConcurrentStreams)) {
+      globals_->max_spdy_concurrent_streams_limit.set(
+          GetSwitchValueAsInt(command_line,
+                              switches::kMaxSpdyConcurrentStreams));
+    }
+    if (command_line.HasSwitch(switches::kTrustedSpdyProxy)) {
+      globals_->trusted_spdy_proxy.set(
+          command_line.GetSwitchValueASCII(switches::kTrustedSpdyProxy));
+    }
+    if (command_line.HasSwitch(switches::kIgnoreUrlFetcherCertRequests))
+      net::URLFetcher::SetIgnoreCertificateRequests(true);
 
-  if (command_line.HasSwitch(switches::kEnableWebSocketOverSpdy)) {
-    // Enable WebSocket over SPDY.
-    net::WebSocketJob::set_websocket_over_spdy_enabled(true);
-  }
-  if (command_line.HasSwitch(switches::kMaxSpdySessionsPerDomain)) {
-    globals_->max_spdy_sessions_per_domain.set(
-        GetSwitchValueAsInt(command_line, switches::kMaxSpdySessionsPerDomain));
-  }
-  if (command_line.HasSwitch(switches::kMaxSpdyConcurrentStreams)) {
-    globals_->max_spdy_concurrent_streams_limit.set(
-        GetSwitchValueAsInt(command_line, switches::kMaxSpdyConcurrentStreams));
-  }
-  if (command_line.HasSwitch(switches::kTrustedSpdyProxy)) {
-    globals_->trusted_spdy_proxy.set(
-        command_line.GetSwitchValueASCII(switches::kTrustedSpdyProxy));
-  }
-  if (command_line.HasSwitch(switches::kIgnoreUrlFetcherCertRequests))
-    net::URLFetcher::SetIgnoreCertificateRequests(true);
-
-  if (command_line.HasSwitch(switches::kUseSpdy)) {
-    std::string spdy_mode =
-        command_line.GetSwitchValueASCII(switches::kUseSpdy);
-    EnableSpdy(spdy_mode);
-  } else if (command_line.HasSwitch(switches::kEnableSpdy4a2)) {
-    net::HttpStreamFactory::EnableNpnSpdy4a2();
-  } else if (command_line.HasSwitch(switches::kDisableSpdy31)) {
-    net::HttpStreamFactory::EnableNpnSpdy3();
-  } else if (command_line.HasSwitch(switches::kEnableNpn)) {
-    net::HttpStreamFactory::EnableNpnSpdy();
-  } else if (command_line.HasSwitch(switches::kEnableNpnHttpOnly)) {
-    net::HttpStreamFactory::EnableNpnHttpOnly();
-  } else {
-    // Use SPDY/3.1 by default.
-    net::HttpStreamFactory::EnableNpnSpdy31();
+    if (command_line.HasSwitch(switches::kUseSpdy)) {
+      std::string spdy_mode =
+          command_line.GetSwitchValueASCII(switches::kUseSpdy);
+      EnableSpdy(spdy_mode);
+    } else if (command_line.HasSwitch(switches::kEnableSpdy4a2)) {
+      net::HttpStreamFactory::EnableNpnSpdy4a2();
+    } else if (command_line.HasSwitch(switches::kDisableSpdy31)) {
+      net::HttpStreamFactory::EnableNpnSpdy3();
+    } else if (command_line.HasSwitch(switches::kEnableNpn)) {
+      net::HttpStreamFactory::EnableNpnSpdy();
+    } else if (command_line.HasSwitch(switches::kEnableNpnHttpOnly)) {
+      net::HttpStreamFactory::EnableNpnHttpOnly();
+    } else {
+      // Use SPDY/3.1 by default.
+      net::HttpStreamFactory::EnableNpnSpdy31();
+    }
   }
 
   // TODO(rch): Make the client socket factory a per-network session
@@ -865,8 +870,6 @@
   params->testing_fixed_http_port = globals_->testing_fixed_http_port;
   params->testing_fixed_https_port = globals_->testing_fixed_https_port;
 
-  globals_->max_spdy_sessions_per_domain.CopyToIfSet(
-      &params->max_spdy_sessions_per_domain);
   globals_->initial_max_spdy_concurrent_streams.CopyToIfSet(
       &params->spdy_initial_max_concurrent_streams);
   globals_->max_spdy_concurrent_streams_limit.CopyToIfSet(
@@ -886,6 +889,7 @@
   globals_->trusted_spdy_proxy.CopyToIfSet(
       &params->trusted_spdy_proxy);
   globals_->enable_quic.CopyToIfSet(&params->enable_quic);
+  globals_->enable_quic_https.CopyToIfSet(&params->enable_quic_https);
   globals_->origin_to_force_quic_on.CopyToIfSet(
       &params->origin_to_force_quic_on);
   params->enable_user_alternate_protocol_ports =
@@ -968,8 +972,10 @@
   if (command_line.HasSwitch(switches::kDisableQuic))
     return false;
 
-  if (command_line.HasSwitch(switches::kEnableQuic))
+  if (command_line.HasSwitch(switches::kEnableQuic) ||
+      command_line.HasSwitch(switches::kEnableQuicHttps)) {
     return true;
+  }
 
   return quic_trial_group == kQuicFieldTrialEnabledGroupName;
 }
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index e0e5e4d..eed9d17 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -154,7 +154,6 @@
     bool http_pipelining_enabled;
     uint16 testing_fixed_http_port;
     uint16 testing_fixed_https_port;
-    Optional<size_t> max_spdy_sessions_per_domain;
     Optional<size_t> initial_max_spdy_concurrent_streams;
     Optional<size_t> max_spdy_concurrent_streams_limit;
     Optional<bool> force_spdy_single_domain;
@@ -165,6 +164,7 @@
     Optional<net::NextProto> spdy_default_protocol;
     Optional<string> trusted_spdy_proxy;
     Optional<bool> enable_quic;
+    Optional<bool> enable_quic_https;
     Optional<net::HostPortPair> origin_to_force_quic_on;
     bool enable_user_alternate_protocol_ports;
     // NetErrorTabHelper uses |dns_probe_service| to send DNS probes when a
@@ -211,6 +211,7 @@
   // This handles initialization and destruction of state that must
   // live on the IO thread.
   virtual void Init() OVERRIDE;
+  virtual void InitAsync() OVERRIDE;
   virtual void CleanUp() OVERRIDE;
 
   void InitializeNetworkOptions(const CommandLine& parsed_command_line);
diff --git a/chrome/browser/jumplist_win.cc b/chrome/browser/jumplist_win.cc
index 4447141..8507304 100644
--- a/chrome/browser/jumplist_win.cc
+++ b/chrome/browser/jumplist_win.cc
@@ -23,6 +23,7 @@
 #include "base/win/scoped_comptr.h"
 #include "base/win/scoped_propvariant.h"
 #include "base/win/windows_version.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_service.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/favicon/favicon_types.h"
@@ -35,7 +36,6 @@
 #include "chrome/browser/sessions/tab_restore_service_factory.h"
 #include "chrome/browser/shell_integration.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/browser_thread.h"
@@ -735,8 +735,8 @@
   // icon directory, and create a new directory which contains new JumpList
   // icon files.
   base::FilePath icon_dir_old(icon_dir_.value() + L"Old");
-  if (file_util::PathExists(icon_dir_old))
-    base::Delete(icon_dir_old, true);
+  if (base::PathExists(icon_dir_old))
+    base::DeleteFile(icon_dir_old, true);
   base::Move(icon_dir_, icon_dir_old);
   file_util::CreateDirectory(icon_dir_);
 
diff --git a/chrome/browser/lifetime/application_lifetime.cc b/chrome/browser/lifetime/application_lifetime.cc
index f0cd3d1..c594d8e 100644
--- a/chrome/browser/lifetime/application_lifetime.cc
+++ b/chrome/browser/lifetime/application_lifetime.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_service.h"
 #include "chrome/browser/metrics/thread_watcher.h"
 #include "chrome/browser/profiles/profile.h"
@@ -24,7 +25,6 @@
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_shutdown.h"
diff --git a/chrome/browser/local_discovery/local_domain_resolver.cc b/chrome/browser/local_discovery/local_domain_resolver.cc
deleted file mode 100644
index bb5e563..0000000
--- a/chrome/browser/local_discovery/local_domain_resolver.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/bind.h"
-#include "chrome/browser/local_discovery/local_domain_resolver.h"
-#include "net/dns/dns_protocol.h"
-#include "net/dns/record_parsed.h"
-#include "net/dns/record_rdata.h"
-
-namespace local_discovery {
-
-LocalDomainResolver::LocalDomainResolver(net::MDnsClient* mdns_client,
-                                         const std::string& domain,
-                                         net::AddressFamily address_family,
-                                         const IPAddressCallback& callback)
-    : domain_(domain), address_family_(address_family), callback_(callback),
-      transaction_failures_(0), mdns_client_(mdns_client) {
-}
-
-LocalDomainResolver::~LocalDomainResolver() {
-}
-
-bool LocalDomainResolver::Start() {
-  if (address_family_ == net::ADDRESS_FAMILY_IPV4 ||
-      address_family_ == net::ADDRESS_FAMILY_UNSPECIFIED) {
-    transaction_a_ = CreateTransaction(net::dns_protocol::kTypeA);
-    if (!transaction_a_->Start())
-      return false;
-  }
-
-  if (address_family_ == net::ADDRESS_FAMILY_IPV6 ||
-      address_family_ == net::ADDRESS_FAMILY_UNSPECIFIED) {
-    transaction_aaaa_ = CreateTransaction(net::dns_protocol::kTypeAAAA);
-    if (!transaction_aaaa_->Start())
-      return false;
-  }
-
-  return true;
-}
-
-scoped_ptr<net::MDnsTransaction> LocalDomainResolver::CreateTransaction(
-    uint16 type) {
-  return mdns_client_->CreateTransaction(
-      type, domain_, net::MDnsTransaction::SINGLE_RESULT |
-                     net::MDnsTransaction::QUERY_CACHE |
-                     net::MDnsTransaction::QUERY_NETWORK,
-      base::Bind(&LocalDomainResolver::OnTransactionComplete,
-                 base::Unretained(this)));
-}
-
-void LocalDomainResolver::OnTransactionComplete(
-    net::MDnsTransaction::Result result, const net::RecordParsed* record) {
-  if (result != net::MDnsTransaction::RESULT_RECORD &&
-      address_family_ == net::ADDRESS_FAMILY_UNSPECIFIED) {
-    transaction_failures_++;
-
-    if (transaction_failures_ < 2) {
-      return;
-    }
-  }
-
-  transaction_a_.reset();
-  transaction_aaaa_.reset();
-
-  net::IPAddressNumber address;
-  if (result == net::MDnsTransaction::RESULT_RECORD) {
-    if (record->type() == net::dns_protocol::kTypeA) {
-      const net::ARecordRdata* rdata = record->rdata<net::ARecordRdata>();
-      DCHECK(rdata);
-      address = rdata->address();
-    } else {
-      DCHECK(record->type() == net::dns_protocol::kTypeAAAA);
-      const net::AAAARecordRdata* rdata = record->rdata<net::AAAARecordRdata>();
-      address = rdata->address();
-    }
-  }
-
-  callback_.Run(result == net::MDnsTransaction::RESULT_RECORD, address);
-}
-
-}  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/local_domain_resolver.h b/chrome/browser/local_discovery/local_domain_resolver.h
deleted file mode 100644
index 6c0c50d..0000000
--- a/chrome/browser/local_discovery/local_domain_resolver.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "base/callback.h"
-#include "net/base/address_family.h"
-#include "net/base/net_util.h"
-#include "net/dns/mdns_client.h"
-
-#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_LOCAL_DOMAIN_RESOLVER_H_
-#define CHROME_BROWSER_LOCAL_DISCOVERY_LOCAL_DOMAIN_RESOLVER_H_
-
-namespace local_discovery {
-
-class LocalDomainResolver {
- public:
-  typedef base::Callback<void(bool, const net::IPAddressNumber&)>
-      IPAddressCallback;
-
-  // |mdns_client| must outlive the LocalDomainResolver.
-  LocalDomainResolver(net::MDnsClient* mdns_client,
-                      const std::string& domain,
-                      net::AddressFamily address_family,
-                      const IPAddressCallback& callback);
-  ~LocalDomainResolver();
-
-  bool Start();
-
-  const std::string& domain() { return domain_; }
-
- private:
-  void OnTransactionComplete(
-      net::MDnsTransaction::Result result,
-      const net::RecordParsed* record);
-
-  scoped_ptr<net::MDnsTransaction> CreateTransaction(uint16 type);
-
-  std::string domain_;
-  net::AddressFamily address_family_;
-  IPAddressCallback callback_;
-
-  scoped_ptr<net::MDnsTransaction> transaction_a_;
-  scoped_ptr<net::MDnsTransaction> transaction_aaaa_;
-
-  int transaction_failures_;
-
-  net::MDnsClient* mdns_client_;
-
-  DISALLOW_COPY_AND_ASSIGN(LocalDomainResolver);
-};
-
-}  // namespace local_discovery
-
-#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_LOCAL_DOMAIN_RESOLVER_H_
diff --git a/chrome/browser/local_discovery/local_domain_resolver_unittest.cc b/chrome/browser/local_discovery/local_domain_resolver_unittest.cc
deleted file mode 100644
index 96e6088..0000000
--- a/chrome/browser/local_discovery/local_domain_resolver_unittest.cc
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/local_discovery/local_domain_resolver.h"
-#include "net/dns/mdns_client_impl.h"
-#include "net/dns/mock_mdns_socket_factory.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::_;
-
-namespace local_discovery {
-
-namespace {
-
-const char kSamplePacketA[] = {
-  // Header
-  '\x00', '\x00',               // ID is zeroed out
-  '\x81', '\x80',               // Standard query response, RA, no error
-  '\x00', '\x00',               // No questions (for simplicity)
-  '\x00', '\x01',               // 1 RR (answers)
-  '\x00', '\x00',               // 0 authority RRs
-  '\x00', '\x00',               // 0 additional RRs
-
-  '\x07', 'm', 'y', 'h', 'e', 'l', 'l', 'o',
-  '\x05', 'l', 'o', 'c', 'a', 'l',
-  '\x00',
-  '\x00', '\x01',        // TYPE is A.
-  '\x00', '\x01',        // CLASS is IN.
-  '\x00', '\x00',        // TTL (4 bytes) is 16 seconds.
-  '\x00', '\x10',
-  '\x00', '\x04',        // RDLENGTH is 4 bytes.
-  '\x01', '\x02',
-  '\x03', '\x04',
-};
-
-const char kSamplePacketAAAA[] = {
-  // Header
-  '\x00', '\x00',               // ID is zeroed out
-  '\x81', '\x80',               // Standard query response, RA, no error
-  '\x00', '\x00',               // No questions (for simplicity)
-  '\x00', '\x01',               // 1 RR (answers)
-  '\x00', '\x00',               // 0 authority RRs
-  '\x00', '\x00',               // 0 additional RRs
-
-  '\x07', 'm', 'y', 'h', 'e', 'l', 'l', 'o',
-  '\x05', 'l', 'o', 'c', 'a', 'l',
-  '\x00',
-  '\x00', '\x1C',        // TYPE is AAAA.
-  '\x00', '\x01',        // CLASS is IN.
-  '\x00', '\x00',        // TTL (4 bytes) is 16 seconds.
-  '\x00', '\x10',
-  '\x00', '\x10',        // RDLENGTH is 4 bytes.
-  '\x00', '\x0A', '\x00', '\x00',
-  '\x00', '\x00', '\x00', '\x00',
-  '\x00', '\x01', '\x00', '\x02',
-  '\x00', '\x03', '\x00', '\x04',
-};
-
-class LocalDomainResolverTest : public testing::Test {
- public:
-  LocalDomainResolverTest() : socket_factory_(new net::MockMDnsSocketFactory),
-    mdns_client_(
-        scoped_ptr<net::MDnsConnection::SocketFactory>(
-            socket_factory_)) {
-  }
-
-  ~LocalDomainResolverTest() {
-  }
-
-  void AddressCallback(bool resolved, const net::IPAddressNumber& address) {
-    if (address == net::IPAddressNumber()) {
-      AddressCallbackInternal(resolved, "");
-    } else {
-      AddressCallbackInternal(resolved, net::IPAddressToString(address));
-    }
-  }
-
-  void RunFor(base::TimeDelta time_period) {
-    base::CancelableCallback<void()> callback(base::Bind(
-        &base::MessageLoop::Quit,
-        base::Unretained(base::MessageLoop::current())));
-    base::MessageLoop::current()->PostDelayedTask(
-        FROM_HERE, callback.callback(), time_period);
-
-    base::MessageLoop::current()->Run();
-    callback.Cancel();
-  }
-
-  MOCK_METHOD2(AddressCallbackInternal,
-               void(bool resolved, std::string address));
-
-  net::MockMDnsSocketFactory* socket_factory_;
-  net::MDnsClientImpl mdns_client_;
-  base::MessageLoop message_loop_;
-};
-
-TEST_F(LocalDomainResolverTest, ResolveDomainA) {
-  LocalDomainResolver resolver(
-      &mdns_client_, "myhello.local", net::ADDRESS_FAMILY_IPV4,
-      base::Bind(&LocalDomainResolverTest::AddressCallback,
-                 base::Unretained(this)));
-
-  EXPECT_CALL(*socket_factory_, OnSendTo(_))
-      .Times(2);  // Twice per query
-
-  EXPECT_TRUE(resolver.Start());
-
-  EXPECT_CALL(*this, AddressCallbackInternal(true, "1.2.3.4"));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketA, sizeof(kSamplePacketA));
-}
-
-TEST_F(LocalDomainResolverTest, ResolveDomainAAAA) {
-  LocalDomainResolver resolver(
-      &mdns_client_, "myhello.local", net::ADDRESS_FAMILY_IPV6,
-      base::Bind(&LocalDomainResolverTest::AddressCallback,
-                 base::Unretained(this)));
-
-  EXPECT_CALL(*socket_factory_, OnSendTo(_))
-      .Times(2);  // Twice per query
-
-  EXPECT_TRUE(resolver.Start());
-
-  EXPECT_CALL(*this, AddressCallbackInternal(true, "a::1:2:3:4"));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketAAAA, sizeof(kSamplePacketAAAA));
-}
-
-TEST_F(LocalDomainResolverTest, ResolveDomainAny) {
-  LocalDomainResolver resolver(
-      &mdns_client_, "myhello.local", net::ADDRESS_FAMILY_UNSPECIFIED,
-      base::Bind(&LocalDomainResolverTest::AddressCallback,
-                 base::Unretained(this)));
-
-  EXPECT_CALL(*socket_factory_, OnSendTo(_))
-      .Times(4);  // Twice per query
-
-  EXPECT_TRUE(resolver.Start());
-
-  EXPECT_CALL(*this, AddressCallbackInternal(true, "a::1:2:3:4"));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketAAAA, sizeof(kSamplePacketAAAA));
-}
-
-TEST_F(LocalDomainResolverTest, ResolveDomainNone) {
-  LocalDomainResolver resolver(
-      &mdns_client_, "myhello.local", net::ADDRESS_FAMILY_UNSPECIFIED,
-      base::Bind(&LocalDomainResolverTest::AddressCallback,
-                 base::Unretained(this)));
-
-  EXPECT_CALL(*socket_factory_, OnSendTo(_))
-      .Times(4);  // Twice per query
-
-  EXPECT_TRUE(resolver.Start());
-
-  EXPECT_CALL(*this, AddressCallbackInternal(false, ""));
-
-  RunFor(base::TimeDelta::FromSeconds(4));
-}
-
-}  // namespace
-
-}  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/privet_constants.cc b/chrome/browser/local_discovery/privet_constants.cc
new file mode 100644
index 0000000..d9c3d9f
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_constants.cc
@@ -0,0 +1,39 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/local_discovery/privet_constants.h"
+
+namespace local_discovery {
+
+const char kPrivetKeyError[] = "error";
+const char kPrivetInfoKeyToken[] = "x-privet-token";
+const char kPrivetKeyDeviceID[] = "device_id";
+const char kPrivetKeyClaimURL[] = "claim_url";
+const char kPrivetKeyClaimToken[] = "token";
+const char kPrivetKeyTimeout[] = "timeout";
+
+const char kPrivetErrorDeviceBusy[] = "device_busy";
+const char kPrivetErrorPendingUserAction[] = "pending_user_action";
+const char kPrivetErrorInvalidXPrivetToken[] = "invalid_x_privet_token";
+
+const char kPrivetActionStart[] = "start";
+const char kPrivetActionGetClaimToken[] = "getClaimToken";
+const char kPrivetActionComplete[] = "complete";
+
+extern const char kPrivetDefaultDeviceType[] = "_privet._tcp.local";
+extern const char kPrivetSubtypeTemplate[] = "%s._sub._privet._tcp.local";
+
+const char kPrivetTxtKeyName[] = "ty";
+const char kPrivetTxtKeyDescription[] = "note";
+const char kPrivetTxtKeyURL[] = "url";
+const char kPrivetTxtKeyType[] = "type";
+const char kPrivetTxtKeyID[] = "id";
+const char kPrivetTxtKeyConnectionState[] = "cs";
+
+const char kPrivetConnectionStatusOnline[] = "online";
+const char kPrivetConnectionStatusOffline[] = "offline";
+const char kPrivetConnectionStatusConnecting[] = "connecting";
+const char kPrivetConnectionStatusNotConfigured[] = "not-configured";
+
+}  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/privet_constants.h b/chrome/browser/local_discovery/privet_constants.h
new file mode 100644
index 0000000..4c8465d
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_constants.h
@@ -0,0 +1,48 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_CONSTANTS_H_
+#define CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_CONSTANTS_H_
+
+namespace local_discovery {
+
+extern const char kPrivetKeyError[];
+extern const char kPrivetInfoKeyToken[];
+extern const char kPrivetKeyDeviceID[];
+extern const char kPrivetKeyClaimURL[];
+extern const char kPrivetKeyClaimToken[];
+extern const char kPrivetKeyTimeout[];
+
+extern const char kPrivetErrorDeviceBusy[];
+extern const char kPrivetErrorPendingUserAction[];
+extern const char kPrivetErrorInvalidXPrivetToken[];
+
+extern const char kPrivetActionStart[];
+extern const char kPrivetActionGetClaimToken[];
+extern const char kPrivetActionComplete[];
+
+extern const char kPrivetDefaultDeviceType[];
+extern const char kPrivetSubtypeTemplate[];
+
+const double kPrivetMaximumTimeScaling = 1.2;
+
+extern const char kPrivetTxtKeyName[];
+extern const char kPrivetTxtKeyDescription[];
+extern const char kPrivetTxtKeyURL[];
+extern const char kPrivetTxtKeyType[];
+extern const char kPrivetTxtKeyID[];
+extern const char kPrivetTxtKeyConnectionState[];
+
+extern const char kPrivetConnectionStatusOnline[];
+extern const char kPrivetConnectionStatusOffline[];
+extern const char kPrivetConnectionStatusConnecting[];
+extern const char kPrivetConnectionStatusNotConfigured[];
+
+const int kPrivetDefaultTimeout = 15;
+
+const double kPrivetMaximumTimeRandomAddition = 0.2;
+
+}  // namespace local_discovery
+
+#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_CONSTANTS_H_
diff --git a/chrome/browser/local_discovery/privet_device_lister.cc b/chrome/browser/local_discovery/privet_device_lister.cc
new file mode 100644
index 0000000..022af16
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_device_lister.cc
@@ -0,0 +1,15 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/local_discovery/privet_device_lister.h"
+
+namespace local_discovery {
+
+DeviceDescription::DeviceDescription() : connection_state(UNKNOWN) {
+}
+
+DeviceDescription::~DeviceDescription() {
+}
+
+}
diff --git a/chrome/browser/local_discovery/privet_device_lister.h b/chrome/browser/local_discovery/privet_device_lister.h
new file mode 100644
index 0000000..11c59b7
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_device_lister.h
@@ -0,0 +1,66 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_DEVICE_LISTER_H_
+#define CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_DEVICE_LISTER_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/time/time.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/net_util.h"
+
+namespace local_discovery {
+
+struct DeviceDescription {
+  enum ConnectionState {
+    ONLINE,
+    OFFLINE,
+    CONNECTING,
+    NOT_CONFIGURED,
+    UNKNOWN
+  };
+
+  DeviceDescription();
+  ~DeviceDescription();
+
+  // Display attributes
+  std::string name;
+  std::string description;
+
+  // Functional attributes
+  std::string url;
+  std::string id;
+  std::string type;
+  ConnectionState connection_state;
+
+  // Attributes related to local HTTP
+  net::HostPortPair address;
+  net::IPAddressNumber ip_address;
+  base::Time last_seen;
+};
+
+class PrivetDeviceLister {
+ public:
+  class Delegate {
+   public:
+    virtual void DeviceChanged(bool added,
+                               const std::string& name,
+                               const DeviceDescription& description) = 0;
+    virtual void DeviceRemoved(const std::string& name) = 0;
+  };
+
+
+  virtual ~PrivetDeviceLister() {}
+
+  // Start the PrivetServiceLister.
+  virtual void Start() = 0;
+
+  virtual void DiscoverNewDevices(bool force_update) = 0;
+};
+
+}  // namespace local_discovery
+
+#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_DEVICE_LISTER_H_
diff --git a/chrome/browser/local_discovery/privet_device_lister_impl.cc b/chrome/browser/local_discovery/privet_device_lister_impl.cc
new file mode 100644
index 0000000..1d4e4d7
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_device_lister_impl.cc
@@ -0,0 +1,146 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/local_discovery/privet_device_lister_impl.h"
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "chrome/browser/local_discovery/privet_constants.h"
+
+namespace local_discovery {
+
+PrivetDeviceListerImpl::PrivetDeviceListerImpl(
+    ServiceDiscoveryClient* service_discovery_client,
+    PrivetDeviceLister::Delegate* delegate)
+    : delegate_(delegate),
+      service_discovery_client_(service_discovery_client),
+      service_type_(kPrivetDefaultDeviceType) {
+}
+
+PrivetDeviceListerImpl::PrivetDeviceListerImpl(
+    ServiceDiscoveryClient* service_discovery_client,
+    PrivetDeviceLister::Delegate* delegate,
+    std::string subtype) : delegate_(delegate),
+                           service_discovery_client_(service_discovery_client),
+                           service_type_(
+                               base::StringPrintf(kPrivetSubtypeTemplate,
+                                                  subtype.c_str())) {
+}
+
+PrivetDeviceListerImpl::~PrivetDeviceListerImpl() {
+}
+
+void PrivetDeviceListerImpl::Start() {
+  service_watcher_ =
+      service_discovery_client_->CreateServiceWatcher(
+          service_type_,
+          base::Bind(&PrivetDeviceListerImpl::OnServiceUpdated,
+                     base::Unretained(this)));
+  service_watcher_->Start();
+}
+
+void PrivetDeviceListerImpl::DiscoverNewDevices(bool force_update) {
+  service_watcher_->DiscoverNewServices(force_update);
+}
+
+void PrivetDeviceListerImpl::OnServiceUpdated(
+    ServiceWatcher::UpdateType update,
+    const std::string& service_name) {
+  if (update != ServiceWatcher::UPDATE_REMOVED) {
+    bool added = (update == ServiceWatcher::UPDATE_ADDED);
+    std::pair<ServiceResolverMap::iterator, bool> insert_result =
+        resolvers_.insert(make_pair(service_name,
+                                    linked_ptr<ServiceResolver>(NULL)));
+
+    // If there is already a resolver working on this service, don't add one.
+    if (insert_result.second) {
+      scoped_ptr<ServiceResolver> resolver =
+          service_discovery_client_->CreateServiceResolver(
+          service_name, base::Bind(
+              &PrivetDeviceListerImpl::OnResolveComplete,
+              base::Unretained(this),
+              added));
+
+      insert_result.first->second.reset(resolver.release());
+      insert_result.first->second->StartResolving();
+    }
+  } else {
+    delegate_->DeviceRemoved(service_name);
+  }
+}
+
+void PrivetDeviceListerImpl::OnResolveComplete(
+    bool added,
+    ServiceResolver::RequestStatus status,
+    const ServiceDescription& service_description) {
+  if (status != ServiceResolver::STATUS_SUCCESS) {
+    resolvers_.erase(service_description.service_name);
+
+    // TODO(noamsml): Add retry logic.
+    return;
+  }
+
+  DeviceDescription device_description;
+  FillDeviceDescription(service_description, &device_description);
+
+  std::string service_name = service_description.service_name;
+  resolvers_.erase(service_name);
+  delegate_->DeviceChanged(added, service_name, device_description);
+}
+
+void PrivetDeviceListerImpl::FillDeviceDescription(
+    const ServiceDescription& service_description,
+    DeviceDescription* device_description) {
+  device_description->address = service_description.address;
+  device_description->ip_address = service_description.ip_address;
+  device_description->last_seen = service_description.last_seen;
+
+  for (std::vector<std::string>::const_iterator i =
+           service_description.metadata.begin();
+       i < service_description.metadata.end();
+       i++) {
+    size_t equals_pos = i->find_first_of('=');
+    if (equals_pos == std::string::npos)
+      continue;  // We do not parse non key-value TXT records
+
+    std::string key = i->substr(0, equals_pos);
+    std::string value = i->substr(equals_pos + 1);
+
+    if (LowerCaseEqualsASCII(key, kPrivetTxtKeyName)) {
+      device_description->name = value;
+    } else if (LowerCaseEqualsASCII(key, kPrivetTxtKeyDescription)) {
+      device_description->description = value;
+    } else if (LowerCaseEqualsASCII(key, kPrivetTxtKeyURL)) {
+      device_description->url = value;
+    } else if (LowerCaseEqualsASCII(key, kPrivetTxtKeyType)) {
+      device_description->type = value;
+    } else if (LowerCaseEqualsASCII(key, kPrivetTxtKeyID)) {
+      device_description->id = value;
+    } else if (LowerCaseEqualsASCII(key, kPrivetTxtKeyConnectionState)) {
+      device_description->connection_state = ConnectionStateFromString(value);
+    }
+  }
+}
+
+DeviceDescription::ConnectionState
+PrivetDeviceListerImpl::ConnectionStateFromString(const std::string& str) {
+  if (LowerCaseEqualsASCII(str, kPrivetConnectionStatusOnline)) {
+    return DeviceDescription::ONLINE;
+  } else if (LowerCaseEqualsASCII(str, kPrivetConnectionStatusOffline)) {
+    return DeviceDescription::OFFLINE;
+  } else if (LowerCaseEqualsASCII(str, kPrivetConnectionStatusConnecting)) {
+    return DeviceDescription::CONNECTING;
+  } else if (LowerCaseEqualsASCII(str, kPrivetConnectionStatusNotConfigured)) {
+    return DeviceDescription::NOT_CONFIGURED;
+  }
+
+  return DeviceDescription::UNKNOWN;
+}
+
+}  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/privet_device_lister_impl.h b/chrome/browser/local_discovery/privet_device_lister_impl.h
new file mode 100644
index 0000000..7fa0333
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_device_lister_impl.h
@@ -0,0 +1,64 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_DEVICE_LISTER_IMPL_H_
+#define CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_DEVICE_LISTER_IMPL_H_
+
+#include <map>
+#include <string>
+
+#include "base/callback.h"
+#include "base/memory/linked_ptr.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/local_discovery/privet_device_lister.h"
+#include "chrome/common/local_discovery/service_discovery_client.h"
+
+namespace local_discovery {
+
+class PrivetDeviceListerImpl : public PrivetDeviceLister {
+ public:
+  PrivetDeviceListerImpl(
+      ServiceDiscoveryClient* service_discovery_client,
+      PrivetDeviceLister::Delegate* delegate,
+      std::string subtype);
+
+  PrivetDeviceListerImpl(
+      ServiceDiscoveryClient* service_discovery_client,
+      PrivetDeviceLister::Delegate* delegate);
+
+  virtual ~PrivetDeviceListerImpl();
+
+  virtual void Start() OVERRIDE;
+
+  virtual void DiscoverNewDevices(bool force_update) OVERRIDE;
+
+ private:
+  typedef std::map<std::string, linked_ptr<ServiceResolver> >
+     ServiceResolverMap;
+
+  void OnServiceUpdated(ServiceWatcher::UpdateType update,
+                        const std::string& service_name);
+
+  void OnResolveComplete(
+      bool added,
+      ServiceResolver::RequestStatus status,
+      const ServiceDescription& description);
+
+  void FillDeviceDescription(const ServiceDescription& service_description,
+                             DeviceDescription* device_description);
+
+  DeviceDescription::ConnectionState ConnectionStateFromString(
+      const std::string& str);
+
+  PrivetDeviceLister::Delegate* delegate_;
+
+  ServiceDiscoveryClient* service_discovery_client_;
+  scoped_ptr<ServiceWatcher> service_watcher_;
+  ServiceResolverMap resolvers_;
+  std::string service_type_;
+};
+
+}  // namespace local_discovery
+
+#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_DEVICE_LISTER_IMPL_H_
diff --git a/chrome/browser/local_discovery/privet_device_lister_unittest.cc b/chrome/browser/local_discovery/privet_device_lister_unittest.cc
new file mode 100644
index 0000000..48e18f4
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_device_lister_unittest.cc
@@ -0,0 +1,307 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "chrome/browser/local_discovery/privet_device_lister_impl.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::SaveArg;
+using testing::_;
+
+namespace local_discovery {
+
+namespace {
+
+class MockServiceResolver;
+class MockServiceWatcher;
+
+class ServiceDiscoveryMockDelegate {
+ public:
+  virtual void ServiceWatcherStarted(const std::string& service_type,
+                                     MockServiceWatcher* watcher) = 0;
+  virtual void ServiceResolverStarted(const std::string& service_type,
+                                      MockServiceResolver* resolver) = 0;
+};
+
+class MockServiceWatcher : public ServiceWatcher {
+ public:
+  MockServiceWatcher(const std::string& service_type,
+                     const ServiceWatcher::UpdatedCallback& callback,
+                     ServiceDiscoveryMockDelegate* mock_delegate)
+      : started_(false), service_type_(service_type),  callback_(callback),
+        mock_delegate_(mock_delegate) {
+  }
+
+  virtual ~MockServiceWatcher() {
+  }
+
+  virtual void Start() {
+    DCHECK(!started_);
+    started_ = true;
+    mock_delegate_->ServiceWatcherStarted(service_type_, this);
+  }
+
+  MOCK_METHOD1(DiscoverNewServices, void(bool force_update));
+
+  virtual std::string GetServiceType() const {
+    return service_type_;
+  }
+
+  bool started() {
+    return started_;
+  }
+
+  ServiceWatcher::UpdatedCallback callback() {
+    return callback_;
+  }
+
+ private:
+  bool started_;
+  std::string service_type_;
+  ServiceWatcher::UpdatedCallback callback_;
+  ServiceDiscoveryMockDelegate* mock_delegate_;
+};
+
+class MockServiceResolver : public ServiceResolver {
+ public:
+  MockServiceResolver(const std::string& service_name,
+                      const ServiceResolver::ResolveCompleteCallback& callback,
+                      ServiceDiscoveryMockDelegate* mock_delegate)
+      : started_resolving_(false), service_name_(service_name),
+        callback_(callback), mock_delegate_(mock_delegate) {
+  }
+
+  virtual ~MockServiceResolver() {
+  }
+
+  virtual void StartResolving() OVERRIDE {
+    started_resolving_ = true;
+    mock_delegate_->ServiceResolverStarted(service_name_, this);
+  }
+
+  bool IsResolving() const {
+    return started_resolving_;
+  }
+
+  virtual std::string GetName() const OVERRIDE {
+    return service_name_;
+  }
+
+  const ServiceResolver::ResolveCompleteCallback& callback() {
+    return callback_; }
+
+ private:
+  bool started_resolving_;
+  std::string service_name_;
+  ServiceResolver::ResolveCompleteCallback callback_;
+  ServiceDiscoveryMockDelegate* mock_delegate_;
+};
+
+class MockServiceDiscoveryClient : public ServiceDiscoveryClient {
+ public:
+  explicit MockServiceDiscoveryClient(
+      ServiceDiscoveryMockDelegate* mock_delegate)
+      : mock_delegate_(mock_delegate) {
+  }
+
+  virtual ~MockServiceDiscoveryClient() {
+  }
+
+  // Create a service watcher object listening for DNS-SD service announcements
+  // on service type |service_type|.
+  virtual scoped_ptr<ServiceWatcher> CreateServiceWatcher(
+      const std::string& service_type,
+      const ServiceWatcher::UpdatedCallback& callback) OVERRIDE {
+    scoped_ptr<MockServiceWatcher> mock_service_watcher(
+        new MockServiceWatcher(service_type, callback, mock_delegate_));
+    return mock_service_watcher.PassAs<ServiceWatcher>();
+  }
+
+  // Create a service resolver object for getting detailed service information
+  // for the service called |service_name|.
+  virtual scoped_ptr<ServiceResolver> CreateServiceResolver(
+      const std::string& service_name,
+      const ServiceResolver::ResolveCompleteCallback& callback) OVERRIDE {
+    scoped_ptr<MockServiceResolver> mock_service_resolver(
+        new MockServiceResolver(service_name, callback, mock_delegate_));
+    return mock_service_resolver.PassAs<ServiceResolver>();
+  }
+
+ private:
+  ServiceDiscoveryMockDelegate* mock_delegate_;
+};
+
+class MockServiceDiscoveryMockDelegate : public ServiceDiscoveryMockDelegate {
+ public:
+  MOCK_METHOD2(ServiceWatcherStarted, void(const std::string& service_type,
+                                           MockServiceWatcher* watcher));
+  MOCK_METHOD2(ServiceResolverStarted, void(const std::string& service_type,
+                                            MockServiceResolver* resolver));
+};
+
+class MockDeviceListerDelegate : public PrivetDeviceLister::Delegate {
+ public:
+  MockDeviceListerDelegate() {
+  }
+
+  virtual ~MockDeviceListerDelegate() {
+  }
+
+  MOCK_METHOD3(DeviceChanged, void(bool added,
+                                   const std::string& name,
+                                   const DeviceDescription& description));
+
+  MOCK_METHOD1(DeviceRemoved, void(const std::string& name));
+};
+
+class PrivetDeviceListerTest : public testing::Test {
+ public:
+  PrivetDeviceListerTest() : mock_client_(&mock_delegate_) {
+  }
+
+  virtual ~PrivetDeviceListerTest() {
+  }
+
+  virtual void SetUp() OVERRIDE {
+    example_attrs_.push_back("tXtvers=1");
+    example_attrs_.push_back("ty=My Printer");
+    example_attrs_.push_back("nOte=This is my Printer");
+    example_attrs_.push_back("CS=ONlInE");
+    example_attrs_.push_back("id=");
+
+    service_description_.service_name = "myprinter._privet._tcp.local";
+    service_description_.address = net::HostPortPair("myprinter.local", 6006);
+    service_description_.metadata = example_attrs_;
+    service_description_.last_seen = base::Time() +
+        base::TimeDelta::FromSeconds(5);
+    service_description_.ip_address.push_back(1);
+    service_description_.ip_address.push_back(2);
+    service_description_.ip_address.push_back(3);
+    service_description_.ip_address.push_back(4);
+  }
+
+ protected:
+  testing::StrictMock<MockServiceDiscoveryMockDelegate> mock_delegate_;
+  MockServiceDiscoveryClient mock_client_;
+  MockDeviceListerDelegate delegate_;
+  std::vector<std::string> example_attrs_;
+  ServiceDescription service_description_;
+};
+
+TEST_F(PrivetDeviceListerTest, SimpleUpdateTest) {
+  DeviceDescription outgoing_description;
+
+  MockServiceWatcher* service_watcher;
+  MockServiceResolver* service_resolver;
+
+  EXPECT_CALL(mock_delegate_,
+              ServiceWatcherStarted("_privet._tcp.local", _))
+      .WillOnce(SaveArg<1>(&service_watcher));
+  PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
+  privet_lister.Start();
+  testing::Mock::VerifyAndClear(&mock_delegate_);
+
+  EXPECT_CALL(mock_delegate_,
+              ServiceResolverStarted("myprinter._privet._tcp.local", _))
+      .WillOnce(SaveArg<1>(&service_resolver));
+  service_watcher->callback().Run(ServiceWatcher::UPDATE_ADDED,
+                                  "myprinter._privet._tcp.local");
+  testing::Mock::VerifyAndClear(&mock_delegate_);
+
+  EXPECT_CALL(delegate_, DeviceChanged(true,
+                                       "myprinter._privet._tcp.local",
+                                       _))
+              .WillOnce(SaveArg<2>(&outgoing_description));
+
+  service_resolver->callback().Run(ServiceResolver::STATUS_SUCCESS,
+                                   service_description_);
+
+  EXPECT_EQ(service_description_.address.host(),
+            outgoing_description.address.host());
+  EXPECT_EQ(service_description_.address.port(),
+            outgoing_description.address.port());
+  EXPECT_EQ(service_description_.ip_address, outgoing_description.ip_address);
+  EXPECT_EQ(service_description_.last_seen, outgoing_description.last_seen);
+  EXPECT_EQ("My Printer", outgoing_description.name);
+  EXPECT_EQ("This is my Printer", outgoing_description.description);
+  EXPECT_EQ("", outgoing_description.id);
+  EXPECT_EQ(DeviceDescription::ONLINE, outgoing_description.connection_state);
+
+  EXPECT_CALL(delegate_, DeviceRemoved("myprinter._privet._tcp.local"));
+
+  service_watcher->callback().Run(ServiceWatcher::UPDATE_REMOVED,
+                                  "myprinter._privet._tcp.local");
+}
+
+TEST_F(PrivetDeviceListerTest, MultipleUpdatesPostResolve) {
+  MockServiceWatcher* service_watcher;
+  MockServiceResolver* service_resolver;
+
+  EXPECT_CALL(mock_delegate_,
+              ServiceWatcherStarted("_privet._tcp.local", _))
+      .WillOnce(SaveArg<1>(&service_watcher));
+  PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
+  privet_lister.Start();
+  testing::Mock::VerifyAndClear(&mock_delegate_);
+
+  EXPECT_CALL(mock_delegate_,
+              ServiceResolverStarted("myprinter._privet._tcp.local", _))
+      .WillOnce(SaveArg<1>(&service_resolver));
+
+  service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
+                                  "myprinter._privet._tcp.local");
+  testing::Mock::VerifyAndClear(&mock_delegate_);
+
+  EXPECT_CALL(delegate_, DeviceChanged(false,
+                                       "myprinter._privet._tcp.local",
+                                       _));
+  service_resolver->callback().Run(ServiceResolver::STATUS_SUCCESS,
+                                   service_description_);
+
+  EXPECT_CALL(mock_delegate_,
+              ServiceResolverStarted("myprinter._privet._tcp.local", _));
+  service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
+                                  "myprinter._privet._tcp.local");
+  testing::Mock::VerifyAndClear(&mock_delegate_);
+}
+
+// Check that the device lister does not create a still-working resolver
+TEST_F(PrivetDeviceListerTest, MultipleUpdatesPreResolve) {
+  MockServiceWatcher* service_watcher;
+
+  EXPECT_CALL(mock_delegate_,
+              ServiceWatcherStarted("_privet._tcp.local", _))
+      .WillOnce(SaveArg<1>(&service_watcher));
+  PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
+  privet_lister.Start();
+  testing::Mock::VerifyAndClear(&mock_delegate_);
+
+  EXPECT_CALL(mock_delegate_,
+              ServiceResolverStarted("myprinter._privet._tcp.local", _))
+      .Times(1);
+  service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
+                                  "myprinter._privet._tcp.local");
+  service_watcher->callback().Run(ServiceWatcher::UPDATE_CHANGED,
+                                  "myprinter._privet._tcp.local");
+}
+
+TEST_F(PrivetDeviceListerTest, DiscoverNewDevices) {
+  MockServiceWatcher* service_watcher;
+
+  EXPECT_CALL(mock_delegate_,
+              ServiceWatcherStarted("_privet._tcp.local", _))
+      .WillOnce(SaveArg<1>(&service_watcher));
+  PrivetDeviceListerImpl privet_lister(&mock_client_, &delegate_);
+  privet_lister.Start();
+  testing::Mock::VerifyAndClear(&mock_delegate_);
+
+  EXPECT_CALL(*service_watcher, DiscoverNewServices(false));
+  privet_lister.DiscoverNewDevices(false);
+}
+
+
+}  // namespace
+
+}  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/privet_http.h b/chrome/browser/local_discovery/privet_http.h
new file mode 100644
index 0000000..d600f47
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_http.h
@@ -0,0 +1,93 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_HTTP_H_
+#define CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_HTTP_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "chrome/browser/local_discovery/privet_url_fetcher.h"
+#include "net/base/host_port_pair.h"
+
+namespace local_discovery {
+
+class PrivetHTTPImpl;
+
+// Represents a request to /privet/info. Will store a cached response and token
+// in the PrivetHTTPClient that created.
+class PrivetInfoOperation {
+ public:
+  class Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // In case of non-HTTP errors, |http_code| will be -1.
+    virtual void OnPrivetInfoDone(int http_code,
+                                  const base::DictionaryValue* json_value) = 0;
+  };
+
+  virtual ~PrivetInfoOperation() {}
+
+  virtual void Start() = 0;
+};
+
+// Represents a full registration flow (/privet/register), normally consisting
+// of calling the start action, the getClaimToken action, and calling the
+// complete action. Some intervention from the caller is required to display the
+// claim URL to the user (noted in OnPrivetRegisterClaimURL).
+class PrivetRegisterOperation {
+ public:
+  enum FailureReason {
+    FAILURE_NETWORK,
+    FAILURE_HTTP_ERROR,
+    FAILURE_JSON_ERROR,
+    FAILURE_MALFORMED_RESPONSE
+  };
+
+  class Delegate {
+   public:
+    ~Delegate() {}
+
+    // Called when a user needs to claim the printer by visiting the given URL.
+    virtual void OnPrivetRegisterClaimToken(const std::string& token,
+                                            const GURL& url) = 0;
+
+    // Called in case of an error while registering.  |action| is the
+    // registration action taken during the error. |reason| is the reason for
+    // the failure. |printer_http_code| is the http code returned from the
+    // printer. If it is -1, an internal error occurred while trying to complete
+    // the request. |json| may be null if printer_http_code signifies an error.
+    virtual void OnPrivetRegisterError(const std::string& action,
+                                       FailureReason reason,
+                                       int printer_http_code,
+                                       const DictionaryValue* json) = 0;
+
+    // Called when the registration is done.
+    virtual void OnPrivetRegisterDone(const std::string& device_id) = 0;
+  };
+
+  virtual ~PrivetRegisterOperation() {}
+
+  virtual void Start() = 0;
+  // Owner SHOULD call explicitly before destroying operation.
+  virtual void Cancel() = 0;
+  virtual void CompleteRegistration() = 0;
+};
+
+// Privet HTTP client. Must not outlive the operations it creates.
+class PrivetHTTPClient {
+ public:
+  virtual ~PrivetHTTPClient() {}
+  virtual const base::DictionaryValue* GetCachedInfo() const = 0;
+
+  virtual scoped_ptr<PrivetRegisterOperation> CreateRegisterOperation(
+      const std::string& user,
+      PrivetRegisterOperation::Delegate* delegate) = 0;
+  virtual scoped_ptr<PrivetInfoOperation> CreateInfoOperation(
+      PrivetInfoOperation::Delegate* delegate) = 0;
+};
+
+}  // namespace local_discovery
+#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_HTTP_H_
diff --git a/chrome/browser/local_discovery/privet_http_impl.cc b/chrome/browser/local_discovery/privet_http_impl.cc
new file mode 100644
index 0000000..6c781f1
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_http_impl.cc
@@ -0,0 +1,290 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/local_discovery/privet_http_impl.h"
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "base/rand_util.h"
+#include "base/strings/stringprintf.h"
+#include "chrome/browser/local_discovery/privet_constants.h"
+#include "url/gurl.h"
+
+namespace local_discovery {
+
+namespace {
+// First format argument (string) is the host, second format argument (int) is
+// the port.
+const char kPrivetInfoURLFormat[] = "http://%s:%d/privet/info";
+// First format argument (string) is the host, second format argument (int) is
+// the port, third argument (string) is the action name, fourth argument
+// (string) is the user name.
+const char kPrivetRegisterURLFormat[] =
+    "http://%s:%d/privet/register?action=%s&user=%s";
+}  // namespace
+
+PrivetInfoOperationImpl::PrivetInfoOperationImpl(
+    PrivetHTTPClientImpl* privet_client,
+    PrivetInfoOperation::Delegate* delegate)
+    : privet_client_(privet_client), delegate_(delegate) {
+}
+
+PrivetInfoOperationImpl::~PrivetInfoOperationImpl() {
+}
+
+void PrivetInfoOperationImpl::Start() {
+  std::string url = base::StringPrintf(
+      kPrivetInfoURLFormat,
+      privet_client_->host_port().host().c_str(),
+      privet_client_->host_port().port());
+
+  url_fetcher_ = privet_client_->fetcher_factory().CreateURLFetcher(
+      GURL(url), net::URLFetcher::GET, this);
+
+  url_fetcher_->Start();
+}
+
+void PrivetInfoOperationImpl::OnError(PrivetURLFetcher* fetcher,
+                                      PrivetURLFetcher::ErrorType error) {
+  if (error == PrivetURLFetcher::RESPONSE_CODE_ERROR) {
+    delegate_->OnPrivetInfoDone(fetcher->response_code(), NULL);
+  } else {
+    delegate_->OnPrivetInfoDone(kPrivetHTTPCodeInternalFailure, NULL);
+  }
+}
+
+void PrivetInfoOperationImpl::OnParsedJson(PrivetURLFetcher* fetcher,
+                                           const base::DictionaryValue* value,
+                                           bool has_error) {
+  if (!has_error)
+    privet_client_->CacheInfo(value);
+  delegate_->OnPrivetInfoDone(fetcher->response_code(), value);
+}
+
+PrivetRegisterOperationImpl::PrivetRegisterOperationImpl(
+    PrivetHTTPClientImpl* privet_client,
+    const std::string& user,
+    PrivetRegisterOperation::Delegate* delegate)
+    : user_(user), delegate_(delegate), privet_client_(privet_client),
+      ongoing_(false) {
+}
+
+PrivetRegisterOperationImpl::~PrivetRegisterOperationImpl() {
+}
+
+void PrivetRegisterOperationImpl::Start() {
+  if (privet_client_->fetcher_factory().get_token() == "") {
+    StartInfoOperation();
+    return;
+  }
+
+  ongoing_ = true;
+  next_response_handler_ =
+      base::Bind(&PrivetRegisterOperationImpl::StartResponse,
+                 base::Unretained(this));
+  SendRequest(kPrivetActionStart);
+}
+
+void PrivetRegisterOperationImpl::Cancel() {
+  url_fetcher_.reset();
+  // TODO(noamsml): Proper cancelation.
+}
+
+void PrivetRegisterOperationImpl::CompleteRegistration() {
+  next_response_handler_ =
+      base::Bind(&PrivetRegisterOperationImpl::CompleteResponse,
+                 base::Unretained(this));
+  SendRequest(kPrivetActionComplete);
+}
+
+void PrivetRegisterOperationImpl::OnError(PrivetURLFetcher* fetcher,
+                                          PrivetURLFetcher::ErrorType error) {
+  ongoing_ = false;
+  int visible_http_code = -1;
+  FailureReason reason = FAILURE_NETWORK;
+
+  if (error == PrivetURLFetcher::RESPONSE_CODE_ERROR) {
+    visible_http_code = fetcher->response_code();
+    reason = FAILURE_HTTP_ERROR;
+  } else if (error == PrivetURLFetcher::JSON_PARSE_ERROR) {
+    reason = FAILURE_MALFORMED_RESPONSE;
+  }
+
+  delegate_->OnPrivetRegisterError(current_action_,
+                                   reason,
+                                   visible_http_code,
+                                   NULL);
+}
+
+void PrivetRegisterOperationImpl::OnParsedJson(
+    PrivetURLFetcher* fetcher,
+    const base::DictionaryValue* value,
+    bool has_error) {
+  if (has_error) {
+    std::string error;
+    value->GetString(kPrivetKeyError, &error);
+
+    if (error == kPrivetErrorInvalidXPrivetToken) {
+      StartInfoOperation();
+
+      // Use a list of transient error names, but also detect if a "timeout"
+      // key is present as a fallback.
+    } else if (PrivetErrorTransient(error) ||
+               value->HasKey(kPrivetKeyTimeout)) {
+      int timeout_seconds;
+      double random_scaling_factor =
+          1 + base::RandDouble() * kPrivetMaximumTimeRandomAddition;
+
+      if (!value->GetInteger(kPrivetKeyTimeout, &timeout_seconds)) {
+        timeout_seconds = kPrivetDefaultTimeout;
+      }
+
+      int timeout_seconds_randomized =
+          static_cast<int>(timeout_seconds * random_scaling_factor);
+
+      base::MessageLoop::current()->PostDelayedTask(
+          FROM_HERE,
+          base::Bind(&PrivetRegisterOperationImpl::SendRequest,
+                     AsWeakPtr(), current_action_),
+                     base::TimeDelta::FromSeconds(timeout_seconds_randomized));
+    } else  {
+      ongoing_ = false;
+      delegate_->OnPrivetRegisterError(current_action_,
+                                       FAILURE_JSON_ERROR,
+                                       fetcher->response_code(),
+                                       value);
+    }
+
+    return;
+  }
+
+  // TODO(noamsml): Match the user&action with the user&action in the object,
+  // and fail if different.
+
+  next_response_handler_.Run(*value);
+}
+
+void PrivetRegisterOperationImpl::SendRequest(const std::string& action) {
+  std::string url = base::StringPrintf(
+      kPrivetRegisterURLFormat,
+      privet_client_->host_port().host().c_str(),
+      privet_client_->host_port().port(),
+      action.c_str(),
+      user_.c_str());
+
+  current_action_ = action;
+  url_fetcher_ = privet_client_->fetcher_factory().CreateURLFetcher(
+      GURL(url), net::URLFetcher::POST, this);
+  url_fetcher_->Start();
+}
+
+void PrivetRegisterOperationImpl::StartResponse(
+    const base::DictionaryValue& value) {
+  next_response_handler_ =
+      base::Bind(&PrivetRegisterOperationImpl::GetClaimTokenResponse,
+                 base::Unretained(this));
+
+  SendRequest(kPrivetActionGetClaimToken);
+}
+
+void PrivetRegisterOperationImpl::GetClaimTokenResponse(
+    const base::DictionaryValue& value) {
+  std::string claimUrl;
+  std::string claimToken;
+  bool got_url = value.GetString(kPrivetKeyClaimURL, &claimUrl);
+  bool got_token = value.GetString(kPrivetKeyClaimToken, &claimToken);
+  if (got_url || got_token) {
+    delegate_->OnPrivetRegisterClaimToken(claimToken, GURL(claimUrl));
+  } else {
+    delegate_->OnPrivetRegisterError(current_action_,
+                                     FAILURE_MALFORMED_RESPONSE,
+                                     -1,
+                                     NULL);
+  }
+}
+
+void PrivetRegisterOperationImpl::CompleteResponse(
+    const base::DictionaryValue& value) {
+  std::string id;
+  value.GetString(kPrivetKeyDeviceID, &id);
+  ongoing_ = false;
+  delegate_->OnPrivetRegisterDone(id);
+}
+
+void PrivetRegisterOperationImpl::OnPrivetInfoDone(
+    int http_code,
+    const base::DictionaryValue* value) {
+  // If there is a key in the info response, the InfoOperation
+  // has stored it in the client.
+  if (!value || !value->HasKey(kPrivetInfoKeyToken)) {
+    if (value->HasKey(kPrivetKeyError)) {
+      delegate_->OnPrivetRegisterError(current_action_,
+                                       FAILURE_JSON_ERROR,
+                                       http_code,
+                                       value);
+    } else {
+      delegate_->OnPrivetRegisterError(current_action_,
+                                       FAILURE_MALFORMED_RESPONSE,
+                                       -1,
+                                       NULL);
+    }
+
+    return;
+  }
+
+  if (!ongoing_) {
+    Start();
+  } else {
+    SendRequest(current_action_);
+  }
+}
+
+void PrivetRegisterOperationImpl::StartInfoOperation() {
+  info_operation_ = privet_client_->CreateInfoOperation(this);
+  info_operation_->Start();
+}
+
+bool PrivetRegisterOperationImpl::PrivetErrorTransient(
+    const std::string& error) {
+  return (error == kPrivetErrorDeviceBusy) ||
+         (error == kPrivetErrorPendingUserAction);
+}
+
+PrivetHTTPClientImpl::PrivetHTTPClientImpl(
+    const net::HostPortPair& host_port,
+    net::URLRequestContextGetter* request_context)
+    : fetcher_factory_(request_context),
+      host_port_(host_port) {
+}
+
+PrivetHTTPClientImpl::~PrivetHTTPClientImpl() {
+}
+
+const base::DictionaryValue* PrivetHTTPClientImpl::GetCachedInfo() const {
+  return cached_info_.get();
+}
+
+scoped_ptr<PrivetRegisterOperation>
+PrivetHTTPClientImpl::CreateRegisterOperation(
+    const std::string& user,
+    PrivetRegisterOperation::Delegate* delegate) {
+  return scoped_ptr<PrivetRegisterOperation>(
+      new PrivetRegisterOperationImpl(this, user, delegate));
+}
+
+scoped_ptr<PrivetInfoOperation> PrivetHTTPClientImpl::CreateInfoOperation(
+    PrivetInfoOperation::Delegate* delegate) {
+  return scoped_ptr<PrivetInfoOperation>(
+      new PrivetInfoOperationImpl(this, delegate));
+}
+
+void PrivetHTTPClientImpl::CacheInfo(const base::DictionaryValue* cached_info) {
+  cached_info_.reset(cached_info->DeepCopy());
+  std::string token;
+  if (cached_info_->GetString(kPrivetInfoKeyToken, &token)) {
+    fetcher_factory_.set_token(token);
+  }
+}
+
+}  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/privet_http_impl.h b/chrome/browser/local_discovery/privet_http_impl.h
new file mode 100644
index 0000000..08c11a1
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_http_impl.h
@@ -0,0 +1,119 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_HTTP_IMPL_H_
+#define CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_HTTP_IMPL_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/local_discovery/privet_http.h"
+
+namespace local_discovery {
+
+class PrivetHTTPClientImpl;
+
+class PrivetInfoOperationImpl : public PrivetInfoOperation,
+                                public PrivetURLFetcher::Delegate {
+ public:
+  PrivetInfoOperationImpl(PrivetHTTPClientImpl* privet_client,
+                          PrivetInfoOperation::Delegate* delegate);
+  virtual ~PrivetInfoOperationImpl();
+
+  virtual void Start() OVERRIDE;
+
+  virtual void OnError(PrivetURLFetcher* fetcher,
+                       PrivetURLFetcher::ErrorType error) OVERRIDE;
+  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
+                            const base::DictionaryValue* value,
+                            bool has_error) OVERRIDE;
+
+ private:
+  PrivetHTTPClientImpl* privet_client_;
+  PrivetInfoOperation::Delegate* delegate_;
+  scoped_ptr<PrivetURLFetcher> url_fetcher_;
+};
+
+class PrivetRegisterOperationImpl
+    : public PrivetRegisterOperation,
+      public PrivetURLFetcher::Delegate,
+      public PrivetInfoOperation::Delegate,
+      public base::SupportsWeakPtr<PrivetRegisterOperationImpl> {
+ public:
+  PrivetRegisterOperationImpl(PrivetHTTPClientImpl* privet_client,
+                              const std::string& user,
+                              PrivetRegisterOperation::Delegate* delegate);
+  virtual ~PrivetRegisterOperationImpl();
+
+  virtual void Start() OVERRIDE;
+  virtual void Cancel() OVERRIDE;
+  virtual void CompleteRegistration() OVERRIDE;
+
+  virtual void OnError(PrivetURLFetcher* fetcher,
+                       PrivetURLFetcher::ErrorType error) OVERRIDE;
+
+  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
+                            const base::DictionaryValue* value,
+                            bool has_error) OVERRIDE;
+
+  virtual void OnPrivetInfoDone(int http_code,
+                                const base::DictionaryValue* value) OVERRIDE;
+ private:
+  // Arguments is JSON value from request.
+  typedef base::Callback<void(const base::DictionaryValue&)>
+      ResponseHandler;
+
+  void StartResponse(const base::DictionaryValue& value);
+  void GetClaimTokenResponse(const base::DictionaryValue& value);
+  void CompleteResponse(const base::DictionaryValue& value);
+
+  void StartInfoOperation();
+
+  void SendRequest(const std::string& action);
+
+  bool PrivetErrorTransient(const std::string& error);
+
+  std::string user_;
+  std::string current_action_;
+  scoped_ptr<PrivetURLFetcher> url_fetcher_;
+  PrivetRegisterOperation::Delegate* delegate_;
+  PrivetHTTPClientImpl* privet_client_;
+  ResponseHandler next_response_handler_;
+  // Required to ensure destroying completed register operations doesn't cause
+  // extraneous cancelations.
+  bool ongoing_;
+  scoped_ptr<PrivetInfoOperation> info_operation_;
+};
+
+class PrivetHTTPClientImpl : public PrivetHTTPClient {
+ public:
+  PrivetHTTPClientImpl(const net::HostPortPair& host_port,
+                       net::URLRequestContextGetter* request_context);
+  virtual ~PrivetHTTPClientImpl();
+
+  virtual const base::DictionaryValue* GetCachedInfo() const OVERRIDE;
+
+  virtual scoped_ptr<PrivetRegisterOperation> CreateRegisterOperation(
+      const std::string& user,
+      PrivetRegisterOperation::Delegate* delegate) OVERRIDE;
+
+  virtual scoped_ptr<PrivetInfoOperation> CreateInfoOperation(
+      PrivetInfoOperation::Delegate* delegate) OVERRIDE;
+
+  const PrivetURLFetcherFactory& fetcher_factory() const {
+    return fetcher_factory_;
+  }
+  const net::HostPortPair& host_port() const { return host_port_; }
+
+  void CacheInfo(const base::DictionaryValue* cached_info);
+
+ private:
+  PrivetURLFetcherFactory fetcher_factory_;
+  net::HostPortPair host_port_;
+  scoped_ptr<base::DictionaryValue> cached_info_;
+};
+
+}  // namespace local_discovery
+#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_HTTP_IMPL_H_
diff --git a/chrome/browser/local_discovery/privet_http_unittest.cc b/chrome/browser/local_discovery/privet_http_unittest.cc
new file mode 100644
index 0000000..97d28e5
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_http_unittest.cc
@@ -0,0 +1,428 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "chrome/browser/local_discovery/privet_http_impl.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/net_errors.h"
+#include "net/url_request/test_url_fetcher_factory.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::StrictMock;
+using testing::NiceMock;
+
+namespace local_discovery {
+
+namespace {
+
+const char kSampleInfoResponse[] = "{"
+    "       \"version\": \"1.0\","
+    "       \"name\": \"Common printer\","
+    "       \"description\": \"Printer connected through Chrome connector\","
+    "       \"url\": \"https://www.google.com/cloudprint\","
+    "       \"type\": ["
+    "               \"printer\""
+    "       ],"
+    "       \"id\": \"11111111-2222-3333-4444-555555555555\","
+    "       \"device_state\": \"idle\","
+    "       \"connection_state\": \"online\","
+    "       \"manufacturer\": \"Google\","
+    "       \"model\": \"Google Chrome\","
+    "       \"serial_number\": \"1111-22222-33333-4444\","
+    "       \"firmware\": \"24.0.1312.52\","
+    "       \"uptime\": 600,"
+    "       \"setup_url\": \"http://support.google.com/\","
+    "       \"support_url\": \"http://support.google.com/cloudprint/?hl=en\","
+    "       \"update_url\": \"http://support.google.com/cloudprint/?hl=en\","
+    "       \"x-privet-token\": \"SampleTokenForTesting\","
+    "       \"api\": ["
+    "               \"/privet/accesstoken\","
+    "               \"/privet/capabilities\","
+    "               \"/privet/printer/submitdoc\","
+    "       ]"
+    "}";
+
+const char kSampleRegisterStartResponse[] = "{"
+    "\"user\": \"example@google.com\","
+    "\"action\": \"start\""
+    "}";
+
+const char kSampleRegisterGetClaimTokenResponse[] = "{"
+    "       \"action\": \"getClaimToken\","
+    "       \"user\": \"example@google.com\","
+    "       \"token\": \"MySampleToken\","
+    "       \"claim_url\": \"https://domain.com/SoMeUrL\""
+    "}";
+
+const char kSampleRegisterCompleteResponse[] = "{"
+    "\"user\": \"example@google.com\","
+    "\"action\": \"complete\","
+    "\"device_id\": \"MyDeviceID\""
+    "}";
+
+const char kSampleXPrivetErrorResponse[] =
+    "{ \"error\": \"invalid_x_privet_token\" }";
+
+const char kSampleRegisterErrorTransient[] =
+    "{ \"error\": \"device_busy\", \"timeout\": 1}";
+
+const char kSampleRegisterErrorPermanent[] =
+    "{ \"error\": \"user_cancel\" }";
+
+class MockTestURLFetcherFactoryDelegate
+    : public net::TestURLFetcher::DelegateForTests {
+ public:
+  // Callback issued correspondingly to the call to the |Start()| method.
+  MOCK_METHOD1(OnRequestStart, void(int fetcher_id));
+
+  // Callback issued correspondingly to the call to |AppendChunkToUpload|.
+  // Uploaded chunks can be retrieved with the |upload_chunks()| getter.
+  MOCK_METHOD1(OnChunkUpload, void(int fetcher_id));
+
+  // Callback issued correspondingly to the destructor.
+  MOCK_METHOD1(OnRequestEnd, void(int fetcher_id));
+};
+
+class PrivetHTTPTest : public ::testing::Test {
+ public:
+  PrivetHTTPTest() {
+    request_context_= new net::TestURLRequestContextGetter(
+        base::MessageLoopProxy::current());
+    privet_client_.reset(new PrivetHTTPClientImpl(
+        net::HostPortPair("10.0.0.8", 6006),
+        request_context_.get()));
+    fetcher_factory_.SetDelegateForTests(&fetcher_delegate_);
+  }
+  virtual ~PrivetHTTPTest() {
+  }
+
+ protected:
+  base::MessageLoop loop_;
+  scoped_refptr<net::TestURLRequestContextGetter> request_context_;
+  net::TestURLFetcherFactory fetcher_factory_;
+  scoped_ptr<PrivetHTTPClient> privet_client_;
+  NiceMock<MockTestURLFetcherFactoryDelegate> fetcher_delegate_;
+};
+
+class MockInfoDelegate : public PrivetInfoOperation::Delegate {
+ public:
+  MockInfoDelegate() {}
+  ~MockInfoDelegate() {}
+
+  virtual void OnPrivetInfoDone(int response_code,
+                                const base::DictionaryValue* value) OVERRIDE {
+    if (!value) {
+      value_.reset();
+    } else {
+      value_.reset(value->DeepCopy());
+    }
+
+    OnPrivetInfoDoneInternal(response_code);
+  }
+
+  MOCK_METHOD1(OnPrivetInfoDoneInternal, void(int response_code));
+
+  const base::DictionaryValue* value() { return value_.get(); }
+ protected:
+  scoped_ptr<base::DictionaryValue> value_;
+};
+
+class MockRegisterDelegate : public PrivetRegisterOperation::Delegate {
+ public:
+  MockRegisterDelegate() {
+  }
+  ~MockRegisterDelegate() {
+  }
+
+  MOCK_METHOD2(OnPrivetRegisterClaimToken, void(const std::string& token,
+                                                const GURL& url));
+
+  virtual void OnPrivetRegisterError(
+      const std::string& action,
+      PrivetRegisterOperation::FailureReason reason,
+      int printer_http_code,
+      const DictionaryValue* json) OVERRIDE {
+    // TODO(noamsml): Save and test for JSON?
+    OnPrivetRegisterErrorInternal(action, reason, printer_http_code);
+  }
+
+  MOCK_METHOD3(OnPrivetRegisterErrorInternal,
+               void(const std::string& action,
+                    PrivetRegisterOperation::FailureReason reason,
+                    int printer_http_code));
+
+  MOCK_METHOD1(OnPrivetRegisterDone, void(const std::string& device_id));
+};
+
+class PrivetInfoTest : public PrivetHTTPTest {
+ public:
+  PrivetInfoTest() {}
+
+  virtual ~PrivetInfoTest() {}
+
+  virtual void SetUp() OVERRIDE {
+    info_operation_ = privet_client_->CreateInfoOperation(&info_delegate_);
+  }
+
+ protected:
+  scoped_ptr<PrivetInfoOperation> info_operation_;
+  StrictMock<MockInfoDelegate> info_delegate_;
+};
+
+TEST_F(PrivetInfoTest, SuccessfulInfo) {
+  info_operation_->Start();
+
+  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_TRUE(fetcher != NULL);
+  EXPECT_EQ(GURL("http://10.0.0.8:6006/privet/info"),
+            fetcher->GetOriginalURL());
+
+  fetcher->SetResponseString(kSampleInfoResponse);
+  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
+                                            net::OK));
+  fetcher->set_response_code(200);
+
+  EXPECT_CALL(info_delegate_, OnPrivetInfoDoneInternal(200));
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+
+  std::string name;
+
+  privet_client_->GetCachedInfo()->GetString("name", &name);
+  EXPECT_EQ("Common printer", name);
+};
+
+TEST_F(PrivetInfoTest, InfoSaveToken) {
+  info_operation_->Start();
+
+  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_TRUE(fetcher != NULL);
+  fetcher->SetResponseString(kSampleInfoResponse);
+  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
+                                            net::OK));
+  fetcher->set_response_code(200);
+
+  EXPECT_CALL(info_delegate_, OnPrivetInfoDoneInternal(200));
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+
+  info_operation_ = privet_client_->CreateInfoOperation(&info_delegate_);
+  info_operation_->Start();
+
+  fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_TRUE(fetcher != NULL);
+  net::HttpRequestHeaders headers;
+  fetcher->GetExtraRequestHeaders(&headers);
+  std::string header_token;
+  ASSERT_TRUE(headers.GetHeader("X-Privet-Token", &header_token));
+  EXPECT_EQ("SampleTokenForTesting", header_token);
+};
+
+TEST_F(PrivetInfoTest, InfoFailureHTTP) {
+  info_operation_->Start();
+
+  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_TRUE(fetcher != NULL);
+  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
+                                            net::OK));
+  fetcher->set_response_code(404);
+
+  EXPECT_CALL(info_delegate_, OnPrivetInfoDoneInternal(404));
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+  EXPECT_EQ(NULL, privet_client_->GetCachedInfo());
+};
+
+TEST_F(PrivetInfoTest, InfoFailureInternal) {
+  info_operation_->Start();
+
+  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_TRUE(fetcher != NULL);
+  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED,
+                                            net::OK));
+  fetcher->set_response_code(200);
+
+  EXPECT_CALL(info_delegate_, OnPrivetInfoDoneInternal(-1));
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+  EXPECT_EQ(NULL, privet_client_->GetCachedInfo());
+};
+
+class PrivetRegisterTest : public PrivetHTTPTest {
+ public:
+  PrivetRegisterTest() {
+  }
+  virtual ~PrivetRegisterTest() {
+  }
+
+  virtual void SetUp() OVERRIDE {
+    info_operation_ = privet_client_->CreateInfoOperation(&info_delegate_);
+    register_operation_ =
+        privet_client_->CreateRegisterOperation("example@google.com",
+                                                &register_delegate_);
+  }
+
+ protected:
+  bool SuccessfulResponseToURL(const GURL& url,
+                                         const std::string& response) {
+    net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
+    if (!fetcher || url != fetcher->GetOriginalURL())
+      return false;
+
+    fetcher->SetResponseString(response);
+    fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
+                                              net::OK));
+    fetcher->set_response_code(200);
+    fetcher->delegate()->OnURLFetchComplete(fetcher);
+    return true;
+  }
+
+  void RunFor(base::TimeDelta time_period) {
+    base::CancelableCallback<void()> callback(base::Bind(
+        &PrivetRegisterTest::Stop, base::Unretained(this)));
+    base::MessageLoop::current()->PostDelayedTask(
+        FROM_HERE, callback.callback(), time_period);
+
+    base::MessageLoop::current()->Run();
+    callback.Cancel();
+  }
+
+  void Stop() {
+    base::MessageLoop::current()->Quit();
+  }
+
+  scoped_ptr<PrivetInfoOperation> info_operation_;
+  NiceMock<MockInfoDelegate> info_delegate_;
+  scoped_ptr<PrivetRegisterOperation> register_operation_;
+  StrictMock<MockRegisterDelegate> register_delegate_;
+};
+
+TEST_F(PrivetRegisterTest, RegisterSuccessSimple) {
+  // Start with info request first to populate XSRF token.
+  info_operation_->Start();
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/info"),
+      kSampleInfoResponse));
+
+  register_operation_->Start();
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/register?"
+           "action=start&user=example@google.com"),
+      kSampleRegisterStartResponse));
+
+  EXPECT_CALL(register_delegate_, OnPrivetRegisterClaimToken(
+      "MySampleToken",
+      GURL("https://domain.com/SoMeUrL")));
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/register?"
+           "action=getClaimToken&user=example@google.com"),
+      kSampleRegisterGetClaimTokenResponse));
+
+  register_operation_->CompleteRegistration();
+
+  EXPECT_CALL(register_delegate_, OnPrivetRegisterDone(
+      "MyDeviceID"));
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/register?"
+           "action=complete&user=example@google.com"),
+      kSampleRegisterCompleteResponse));
+}
+
+TEST_F(PrivetRegisterTest, RegisterNoInfoCall) {
+  register_operation_->Start();
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/info"),
+      kSampleInfoResponse));
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/register?"
+           "action=start&user=example@google.com"),
+      kSampleRegisterStartResponse));
+}
+
+TEST_F(PrivetRegisterTest, RegisterXSRFFailure) {
+  register_operation_->Start();
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/info"),
+      kSampleInfoResponse));
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/register?"
+           "action=start&user=example@google.com"),
+      kSampleRegisterStartResponse));
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/register?"
+           "action=getClaimToken&user=example@google.com"),
+      kSampleXPrivetErrorResponse));
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/info"),
+      kSampleInfoResponse));
+
+  EXPECT_CALL(register_delegate_, OnPrivetRegisterClaimToken(
+      "MySampleToken", GURL("https://domain.com/SoMeUrL")));
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/register?"
+           "action=getClaimToken&user=example@google.com"),
+      kSampleRegisterGetClaimTokenResponse));
+}
+
+TEST_F(PrivetRegisterTest, TransientFailure) {
+  register_operation_->Start();
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/info"),
+      kSampleInfoResponse));
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/register?"
+           "action=start&user=example@google.com"),
+      kSampleRegisterErrorTransient));
+
+  EXPECT_CALL(fetcher_delegate_, OnRequestStart(0));
+
+  RunFor(base::TimeDelta::FromSeconds(2));
+
+  testing::Mock::VerifyAndClearExpectations(&fetcher_delegate_);
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/register?"
+           "action=start&user=example@google.com"),
+      kSampleRegisterStartResponse));
+}
+
+TEST_F(PrivetRegisterTest, PermanentFailure) {
+    register_operation_->Start();
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/info"),
+      kSampleInfoResponse));
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/register?"
+           "action=start&user=example@google.com"),
+      kSampleRegisterStartResponse));
+
+  EXPECT_CALL(register_delegate_,
+              OnPrivetRegisterErrorInternal(
+                  "getClaimToken",
+                  PrivetRegisterOperation::FAILURE_JSON_ERROR,
+                  200));
+
+  EXPECT_TRUE(SuccessfulResponseToURL(
+      GURL("http://10.0.0.8:6006/privet/register?"
+           "action=getClaimToken&user=example@google.com"),
+      kSampleRegisterErrorPermanent));
+}
+
+}  // namespace
+
+}  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/privet_url_fetcher.cc b/chrome/browser/local_discovery/privet_url_fetcher.cc
new file mode 100644
index 0000000..d0a74b5
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_url_fetcher.cc
@@ -0,0 +1,94 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/local_discovery/privet_url_fetcher.h"
+
+#include "base/json/json_reader.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/local_discovery/privet_constants.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_request_status.h"
+
+namespace local_discovery {
+
+namespace {
+const char kXPrivetTokenHeaderPrefix[] = "X-Privet-Token: ";
+}
+
+PrivetURLFetcher::PrivetURLFetcher(
+    const std::string& token,
+    const GURL& url,
+    net::URLFetcher::RequestType request_type,
+    net::URLRequestContextGetter* request_context,
+    PrivetURLFetcher::Delegate* delegate)
+    : privet_access_token_(token), delegate_(delegate) {
+  url_fetcher_.reset(net::URLFetcher::Create(url, request_type, this));
+  url_fetcher_->SetRequestContext(request_context);
+  url_fetcher_->AddExtraRequestHeader(std::string(kXPrivetTokenHeaderPrefix) +
+                                      token);
+}
+
+PrivetURLFetcher::~PrivetURLFetcher() {
+}
+
+void PrivetURLFetcher::Start() {
+  url_fetcher_->Start();
+}
+
+void PrivetURLFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
+  if (source->GetStatus().status() != net::URLRequestStatus::SUCCESS) {
+    delegate_->OnError(this, URL_FETCH_ERROR);
+    return;
+  }
+
+  if (source->GetResponseCode() != net::HTTP_OK) {
+    delegate_->OnError(this, RESPONSE_CODE_ERROR);
+    return;
+  }
+
+  std::string response_str;
+
+  if (!source->GetResponseAsString(&response_str)) {
+    delegate_->OnError(this, URL_FETCH_ERROR);
+    return;
+  }
+
+  base::JSONReader json_reader(base::JSON_ALLOW_TRAILING_COMMAS);
+  scoped_ptr<base::Value> value;
+
+  value.reset(json_reader.ReadToValue(response_str));
+
+  if (!value) {
+    delegate_->OnError(this, JSON_PARSE_ERROR);
+    return;
+  }
+
+  const base::DictionaryValue* dictionary_value;
+
+  if (!value->GetAsDictionary(&dictionary_value)) {
+    delegate_->OnError(this, JSON_PARSE_ERROR);
+    return;
+  }
+
+  delegate_->OnParsedJson(this, dictionary_value,
+                          dictionary_value->HasKey(kPrivetKeyError));
+}
+
+PrivetURLFetcherFactory::PrivetURLFetcherFactory(
+    net::URLRequestContextGetter* request_context)
+    : request_context_(request_context) {
+}
+
+PrivetURLFetcherFactory::~PrivetURLFetcherFactory() {
+}
+
+scoped_ptr<PrivetURLFetcher> PrivetURLFetcherFactory::CreateURLFetcher(
+    const GURL& url, net::URLFetcher::RequestType request_type,
+    PrivetURLFetcher::Delegate* delegate) const {
+  return scoped_ptr<PrivetURLFetcher>(
+      new PrivetURLFetcher(token_, url, request_type,
+                           request_context_.get(), delegate));
+}
+
+}  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/privet_url_fetcher.h b/chrome/browser/local_discovery/privet_url_fetcher.h
new file mode 100644
index 0000000..c96b894
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_url_fetcher.h
@@ -0,0 +1,85 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_URL_FETCHER_H_
+#define CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_URL_FETCHER_H_
+
+#include <string>
+
+#include "base/values.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace local_discovery {
+
+const int kPrivetHTTPCodeInternalFailure = -1;
+
+// Privet-specific URLFetcher adapter. Currently supports only the subset
+// of HTTP features required by Privet for GCP 1.5
+// (/privet/info and /privet/register).
+class PrivetURLFetcher : public net::URLFetcherDelegate {
+ public:
+  enum ErrorType {
+    JSON_PARSE_ERROR,
+    URL_FETCH_ERROR,
+    RESPONSE_CODE_ERROR
+  };
+
+  class Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    virtual void OnError(PrivetURLFetcher* fetcher, ErrorType error) = 0;
+    virtual void OnParsedJson(PrivetURLFetcher* fetcher,
+                              const base::DictionaryValue* value,
+                              bool has_error) = 0;
+  };
+
+  PrivetURLFetcher(
+      const std::string& token,
+      const GURL& url,
+      net::URLFetcher::RequestType request_type,
+      net::URLRequestContextGetter* request_context,
+      Delegate* delegate);
+  virtual ~PrivetURLFetcher();
+
+  void Start();
+
+  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
+
+  const GURL& url() const { return url_fetcher_->GetOriginalURL(); }
+  int response_code() const { return url_fetcher_->GetResponseCode(); }
+
+ private:
+  scoped_ptr<net::URLFetcher> url_fetcher_;
+  std::string privet_access_token_;
+  Delegate* delegate_;
+
+  DISALLOW_COPY_AND_ASSIGN(PrivetURLFetcher);
+};
+
+class PrivetURLFetcherFactory {
+ public:
+  explicit PrivetURLFetcherFactory(
+      net::URLRequestContextGetter* request_context);
+  ~PrivetURLFetcherFactory();
+
+  scoped_ptr<PrivetURLFetcher> CreateURLFetcher(
+      const GURL& url, net::URLFetcher::RequestType request_type,
+      PrivetURLFetcher::Delegate* delegate) const;
+
+  void set_token(const std::string& token) { token_ = token; }
+  const std::string& get_token() const { return token_; }
+
+ private:
+  scoped_refptr<net::URLRequestContextGetter> request_context_;
+  std::string token_;
+
+  DISALLOW_COPY_AND_ASSIGN(PrivetURLFetcherFactory);
+};
+
+}  // namespace local_discovery
+
+#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_URL_FETCHER_H_
diff --git a/chrome/browser/local_discovery/privet_url_fetcher_unittest.cc b/chrome/browser/local_discovery/privet_url_fetcher_unittest.cc
new file mode 100644
index 0000000..da9b743
--- /dev/null
+++ b/chrome/browser/local_discovery/privet_url_fetcher_unittest.cc
@@ -0,0 +1,159 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/local_discovery/privet_url_fetcher.h"
+#include "net/url_request/test_url_fetcher_factory.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::StrictMock;
+
+namespace local_discovery {
+
+namespace {
+
+const char kSamplePrivetURL[] =
+    "http://10.0.0.8:7676/privet/register?action=start";
+const char kSamplePrivetToken[] = "MyToken";
+
+const char kSampleParsableJSON[] = "{ \"hello\" : 2 }";
+const char kSampleUnparsableJSON[] = "{ \"hello\" : }";
+const char kSampleJSONWithError[] = "{ \"error\" : \"unittest_example\" }";
+
+class MockPrivetURLFetcherDelegate : public PrivetURLFetcher::Delegate {
+ public:
+  virtual void OnError(PrivetURLFetcher* fetcher,
+                       PrivetURLFetcher::ErrorType error) OVERRIDE {
+    OnErrorInternal(error);
+  }
+
+  MOCK_METHOD1(OnErrorInternal, void(PrivetURLFetcher::ErrorType error));
+
+  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
+                            const base::DictionaryValue* value,
+                            bool has_error) OVERRIDE {
+    saved_value_.reset(value->DeepCopy());
+    OnParsedJsonInternal(has_error);
+  }
+
+  MOCK_METHOD1(OnParsedJsonInternal, void(bool has_error));
+
+  const DictionaryValue* saved_value() { return saved_value_.get(); }
+
+ private:
+  scoped_ptr<DictionaryValue> saved_value_;
+};
+
+class PrivetURLFetcherTest : public ::testing::Test {
+ public:
+  PrivetURLFetcherTest() {
+    request_context_= new net::TestURLRequestContextGetter(
+        base::MessageLoopProxy::current());
+    privet_urlfetcher_.reset(new PrivetURLFetcher(
+        kSamplePrivetToken,
+        GURL(kSamplePrivetURL),
+        net::URLFetcher::POST,
+        request_context_.get(),
+        &delegate_));
+  }
+  virtual ~PrivetURLFetcherTest() {
+  }
+
+ protected:
+  base::MessageLoop loop_;
+  scoped_refptr<net::TestURLRequestContextGetter> request_context_;
+  net::TestURLFetcherFactory fetcher_factory_;
+  scoped_ptr<PrivetURLFetcher> privet_urlfetcher_;
+  StrictMock<MockPrivetURLFetcherDelegate> delegate_;
+};
+
+TEST_F(PrivetURLFetcherTest, FetchSuccess) {
+  privet_urlfetcher_->Start();
+  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_TRUE(fetcher != NULL);
+  fetcher->SetResponseString(kSampleParsableJSON);
+  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
+                                            net::OK));
+  fetcher->set_response_code(200);
+
+  EXPECT_CALL(delegate_, OnParsedJsonInternal(false));
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+
+  const base::DictionaryValue* value = delegate_.saved_value();
+  int hello_value;
+  ASSERT_TRUE(value != NULL);
+  ASSERT_TRUE(value->GetInteger("hello", &hello_value));
+  EXPECT_EQ(2, hello_value);
+}
+
+TEST_F(PrivetURLFetcherTest, URLFetcherError) {
+  privet_urlfetcher_->Start();
+  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_TRUE(fetcher != NULL);
+  fetcher->SetResponseString(kSampleParsableJSON);
+  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED,
+                                            net::ERR_TIMED_OUT));
+  fetcher->set_response_code(-1);
+
+  EXPECT_CALL(delegate_, OnErrorInternal(PrivetURLFetcher::URL_FETCH_ERROR));
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+}
+
+TEST_F(PrivetURLFetcherTest, ResponseCodeError) {
+  privet_urlfetcher_->Start();
+  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_TRUE(fetcher != NULL);
+  fetcher->SetResponseString(kSampleParsableJSON);
+  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
+                                            net::OK));
+  fetcher->set_response_code(404);
+
+  EXPECT_CALL(delegate_,
+              OnErrorInternal(PrivetURLFetcher::RESPONSE_CODE_ERROR));
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+}
+
+TEST_F(PrivetURLFetcherTest, JsonParseError) {
+  privet_urlfetcher_->Start();
+  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_TRUE(fetcher != NULL);
+  fetcher->SetResponseString(kSampleUnparsableJSON);
+  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
+                                            net::OK));
+  fetcher->set_response_code(200);
+
+  EXPECT_CALL(delegate_,
+              OnErrorInternal(PrivetURLFetcher::JSON_PARSE_ERROR));
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+}
+
+TEST_F(PrivetURLFetcherTest, Header) {
+  privet_urlfetcher_->Start();
+  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_TRUE(fetcher != NULL);
+  net::HttpRequestHeaders headers;
+  fetcher->GetExtraRequestHeaders(&headers);
+
+  std::string header_token;
+  ASSERT_TRUE(headers.GetHeader("X-Privet-Token", &header_token));
+  EXPECT_EQ(kSamplePrivetToken, header_token);
+}
+
+TEST_F(PrivetURLFetcherTest, FetchHasError) {
+  privet_urlfetcher_->Start();
+  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
+  ASSERT_TRUE(fetcher != NULL);
+  fetcher->SetResponseString(kSampleJSONWithError);
+  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
+                                            net::OK));
+  fetcher->set_response_code(200);
+
+  EXPECT_CALL(delegate_, OnParsedJsonInternal(true));
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+}
+
+}  // namespace
+
+}  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/service_discovery_client.cc b/chrome/browser/local_discovery/service_discovery_client.cc
deleted file mode 100644
index 0b63b85..0000000
--- a/chrome/browser/local_discovery/service_discovery_client.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/local_discovery/service_discovery_client.h"
-
-namespace local_discovery {
-
-ServiceDescription::ServiceDescription() {
-}
-
-ServiceDescription::~ServiceDescription() {
-}
-
-std::string ServiceDescription::instance_name() const {
-  // TODO(noamsml): Once we have escaping working, get this to
-  // parse escaped domains.
-  size_t first_period = service_name.find_first_of('.');
-  return service_name.substr(0, first_period);
-}
-
-std::string ServiceDescription::service_type() const {
-  // TODO(noamsml): Once we have escaping working, get this to
-  // parse escaped domains.
-  size_t first_period = service_name.find_first_of('.');
-  if (first_period == std::string::npos)
-    return "";
-  return service_name.substr(first_period+1);
-}
-
-}  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/service_discovery_client.h b/chrome/browser/local_discovery/service_discovery_client.h
deleted file mode 100644
index ceeca7a..0000000
--- a/chrome/browser/local_discovery/service_discovery_client.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_H_
-#define CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_H_
-
-#include <string>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/time/time.h"
-#include "net/base/host_port_pair.h"
-#include "net/base/net_util.h"
-
-namespace net {
-class MDnsClient;
-}
-
-namespace local_discovery {
-
-struct ServiceDescription {
- public:
-  ServiceDescription();
-  ~ServiceDescription();
-
-  // Convenience function to get useful parts of the service name. A service
-  // name follows the format <instance_name>.<service_type>.
-  std::string instance_name() const;
-  std::string service_type() const;
-
-  // The name of the service.
-  std::string service_name;
-  // The address (in host/port format) for the service (from SRV record).
-  net::HostPortPair address;
-  // The metadata (from TXT record) of the service.
-  std::vector<std::string> metadata;
-  // IP address of the service, if available from cache. May be empty.
-  net::IPAddressNumber ip_address;
-  // Last time the service was seen.
-  base::Time last_seen;
-};
-
-// Lets users browse the network for services of interest or listen for changes
-// in the services they are interested in. See
-// |ServiceDiscoveryClient::CreateServiceWatcher|.
-class ServiceWatcher {
- public:
-  enum UpdateType {
-    UPDATE_ADDED,
-    UPDATE_CHANGED,
-    UPDATE_REMOVED
-  };
-
-  class Delegate {
-   public:
-    virtual ~Delegate() {}
-
-    // A service has been added or removed for a certain service name.
-    virtual void OnServiceUpdated(UpdateType update,
-                                  const std::string& service_name) = 0;
-  };
-
-  // Listening will automatically stop when the destructor is called.
-  virtual ~ServiceWatcher() {}
-
-  // Start the service type watcher.
-  virtual bool Start() = 0;
-
-  // Get all known services names of this watcher's type. Return them in
-  // |services|.
-  virtual void GetAvailableServices(
-      std::vector<std::string>* services) const = 0;
-
-  // Read services from the cache, alerting the delegate to any service that
-  // is not yet known.
-  virtual void ReadCachedServices() = 0;
-
-  // Probe for services of this type.
-  virtual void DiscoverNewServices(bool force_update) = 0;
-
-  virtual std::string GetServiceType() const = 0;
-};
-
-// Represents a service on the network and allows users to access the service's
-// address and metadata. See |ServiceDiscoveryClient::CreateServiceResolver|.
-class ServiceResolver {
- public:
-  enum RequestStatus {
-    STATUS_SUCCESS = 0,
-    STATUS_REQUEST_TIMEOUT = 1,
-    STATUS_KNOWN_NONEXISTENT = 2
-  };
-
-  // A callback called once the service has been resolved.
-  typedef base::Callback<void(RequestStatus, const ServiceDescription&)>
-      ResolveCompleteCallback;
-
-  // Listening will automatically stop when the destructor is called.
-  virtual ~ServiceResolver() {}
-
-  // Start the service reader.
-  virtual bool StartResolving() = 0;
-
-  // Check whether the resolver is currently resolving. Can be called multiple
-  // times.
-  virtual bool IsResolving() const = 0;
-
-  // Check wheteher the resolver has resolved the service already.
-  virtual bool HasResolved() const = 0;
-
-  virtual std::string GetName() const = 0;
-
-  virtual const ServiceDescription& GetServiceDescription() const = 0;
-};
-
-class ServiceDiscoveryClient {
- public:
-  virtual ~ServiceDiscoveryClient() {}
-
-  // Create a service watcher object listening for DNS-SD service announcements
-  // on service type |service_type|.
-  virtual scoped_ptr<ServiceWatcher> CreateServiceWatcher(
-      const std::string& service_type,
-      ServiceWatcher::Delegate* delegate) = 0;
-
-  // Create a service resolver object for getting detailed service information
-  // for the service called |service_name|.
-  virtual scoped_ptr<ServiceResolver> CreateServiceResolver(
-      const std::string& service_name,
-      const ServiceResolver::ResolveCompleteCallback& callback) = 0;
-};
-
-}  // namespace local_discovery
-
-#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_H_
diff --git a/chrome/browser/local_discovery/service_discovery_client_impl.cc b/chrome/browser/local_discovery/service_discovery_client_impl.cc
deleted file mode 100644
index 219f5ed..0000000
--- a/chrome/browser/local_discovery/service_discovery_client_impl.cc
+++ /dev/null
@@ -1,411 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <utility>
-
-#include "base/logging.h"
-#include "base/memory/singleton.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "base/stl_util.h"
-#include "chrome/browser/local_discovery/service_discovery_client_impl.h"
-#include "net/dns/dns_protocol.h"
-#include "net/dns/record_rdata.h"
-
-namespace local_discovery {
-
-ServiceDiscoveryClientImpl::ServiceDiscoveryClientImpl(
-    net::MDnsClient* mdns_client) : mdns_client_(mdns_client) {
-}
-
-ServiceDiscoveryClientImpl::~ServiceDiscoveryClientImpl() {
-}
-
-scoped_ptr<ServiceWatcher> ServiceDiscoveryClientImpl::CreateServiceWatcher(
-    const std::string& service_type,
-    ServiceWatcher::Delegate* delegate) {
-  return scoped_ptr<ServiceWatcher>(new ServiceWatcherImpl(
-      service_type,  delegate, mdns_client_));
-}
-
-scoped_ptr<ServiceResolver> ServiceDiscoveryClientImpl::CreateServiceResolver(
-    const std::string& service_name,
-    const ServiceResolver::ResolveCompleteCallback& callback) {
-  return scoped_ptr<ServiceResolver>(new ServiceResolverImpl(
-      service_name, callback, mdns_client_));
-}
-
-ServiceWatcherImpl::ServiceWatcherImpl(
-    const std::string& service_type,
-    ServiceWatcher::Delegate* delegate,
-    net::MDnsClient* mdns_client)
-    : service_type_(service_type), delegate_(delegate), started_(false),
-      mdns_client_(mdns_client) {
-}
-
-bool ServiceWatcherImpl::Start() {
-  DCHECK(!started_);
-  listener_ = mdns_client_->CreateListener(
-      net::dns_protocol::kTypePTR, service_type_, this);
-  if (!listener_->Start())
-    return false;
-
-  started_ = true;
-  return true;
-}
-
-ServiceWatcherImpl::~ServiceWatcherImpl() {
-}
-
-void ServiceWatcherImpl::GetAvailableServices(
-    std::vector<std::string>* services) const {
-  DCHECK(started_);
-  DCHECK(services);
-  services->reserve(services_.size());
-  for (ServiceListenersMap::const_iterator i = services_.begin();
-       i != services_.end(); i++) {
-    services->push_back(i->first);
-  }
-}
-
-void ServiceWatcherImpl::DiscoverNewServices(bool force_update) {
-  DCHECK(started_);
-  if (force_update)
-    services_.clear();
-  CreateTransaction(true /*network*/, false /*cache*/, force_update,
-                    &transaction_network_);
-}
-
-void ServiceWatcherImpl::ReadCachedServices() {
-  DCHECK(started_);
-  CreateTransaction(false /*network*/, true /*cache*/, false /*force refresh*/,
-                    &transaction_cache_);
-}
-
-bool ServiceWatcherImpl::CreateTransaction(
-    bool network, bool cache, bool force_refresh,
-    scoped_ptr<net::MDnsTransaction>* transaction) {
-  int transaction_flags = 0;
-  if (network)
-    transaction_flags |= net::MDnsTransaction::QUERY_NETWORK;
-
-  if (cache)
-    transaction_flags |= net::MDnsTransaction::QUERY_CACHE;
-
-  // TODO(noamsml): Add flag for force_refresh when supported.
-
-  if (transaction_flags) {
-    *transaction = mdns_client_->CreateTransaction(
-        net::dns_protocol::kTypePTR, service_type_, transaction_flags,
-        base::Bind(&ServiceWatcherImpl::OnTransactionResponse,
-                   base::Unretained(this), transaction));
-    return (*transaction)->Start();
-  }
-
-  return true;
-}
-
-std::string ServiceWatcherImpl::GetServiceType() const {
-  return listener_->GetName();
-}
-
-void ServiceWatcherImpl::OnRecordUpdate(
-    net::MDnsListener::UpdateType update,
-    const net::RecordParsed* record) {
-  DCHECK(started_);
-  if (record->type() == net::dns_protocol::kTypePTR) {
-    DCHECK(record->name() == GetServiceType());
-    const net::PtrRecordRdata* rdata = record->rdata<net::PtrRecordRdata>();
-
-    switch (update) {
-      case net::MDnsListener::RECORD_ADDED:
-        AddService(rdata->ptrdomain());
-        break;
-      case net::MDnsListener::RECORD_CHANGED:
-        NOTREACHED();
-        break;
-      case net::MDnsListener::RECORD_REMOVED:
-        RemoveService(rdata->ptrdomain());
-        break;
-    }
-  } else {
-    DCHECK(record->type() == net::dns_protocol::kTypeSRV ||
-           record->type() == net::dns_protocol::kTypeTXT);
-    DCHECK(services_.find(record->name()) != services_.end());
-
-    DeferUpdate(UPDATE_CHANGED, record->name());
-  }
-}
-
-void ServiceWatcherImpl::OnCachePurged() {
-  // Not yet implemented.
-}
-
-void ServiceWatcherImpl::OnTransactionResponse(
-    scoped_ptr<net::MDnsTransaction>* transaction,
-    net::MDnsTransaction::Result result,
-    const net::RecordParsed* record) {
-  DCHECK(started_);
-  if (result == net::MDnsTransaction::RESULT_RECORD) {
-    const net::PtrRecordRdata* rdata = record->rdata<net::PtrRecordRdata>();
-    DCHECK(rdata);
-    AddService(rdata->ptrdomain());
-  } else if (result == net::MDnsTransaction::RESULT_DONE) {
-    transaction->reset();
-  }
-
-  // Do nothing for NSEC records. It is an error for hosts to broadcast an NSEC
-  // record for PTR records on any name.
-}
-
-ServiceWatcherImpl::ServiceListeners::ServiceListeners(
-    const std::string& service_name,
-    ServiceWatcherImpl* watcher,
-    net::MDnsClient* mdns_client) : update_pending_(false) {
-  srv_listener_ = mdns_client->CreateListener(
-      net::dns_protocol::kTypeSRV, service_name, watcher);
-  txt_listener_ = mdns_client->CreateListener(
-      net::dns_protocol::kTypeTXT, service_name, watcher);
-}
-
-ServiceWatcherImpl::ServiceListeners::~ServiceListeners() {
-}
-
-bool ServiceWatcherImpl::ServiceListeners::Start() {
-  if (!srv_listener_->Start())
-    return false;
-  return txt_listener_->Start();
-}
-
-void ServiceWatcherImpl::AddService(const std::string& service) {
-  DCHECK(started_);
-  std::pair<ServiceListenersMap::iterator, bool> found = services_.insert(
-      make_pair(service, static_cast<ServiceListeners*>(NULL)));
-  if (found.second) {  // Newly inserted.
-    found.first->second = linked_ptr<ServiceListeners>(
-        new ServiceListeners(service, this, mdns_client_));
-    bool success = found.first->second->Start();
-
-    DeferUpdate(UPDATE_ADDED, service);
-
-    DCHECK(success);
-  }
-}
-
-void ServiceWatcherImpl::DeferUpdate(ServiceWatcher::UpdateType update_type,
-                                     const std::string& service_name) {
-  ServiceListenersMap::iterator found = services_.find(service_name);
-
-  if (found != services_.end() && !found->second->update_pending()) {
-    found->second->set_update_pending(true);
-    base::MessageLoop::current()->PostTask(
-        FROM_HERE,
-        base::Bind(&ServiceWatcherImpl::DeliverDeferredUpdate, AsWeakPtr(),
-                   update_type, service_name));
-  }
-}
-
-void ServiceWatcherImpl::DeliverDeferredUpdate(
-    ServiceWatcher::UpdateType update_type, const std::string& service_name) {
-  ServiceListenersMap::iterator found = services_.find(service_name);
-
-  if (found != services_.end()) {
-    found->second->set_update_pending(false);
-    delegate_->OnServiceUpdated(update_type, service_name);
-  }
-}
-
-void ServiceWatcherImpl::RemoveService(const std::string& service) {
-  DCHECK(started_);
-  ServiceListenersMap::iterator found = services_.find(service);
-  if (found != services_.end()) {
-    services_.erase(found);
-    delegate_->OnServiceUpdated(UPDATE_REMOVED, service);
-  }
-}
-
-void ServiceWatcherImpl::OnNsecRecord(const std::string& name,
-                                      unsigned rrtype) {
-  // Do nothing. It is an error for hosts to broadcast an NSEC record for PTR
-  // on any name.
-}
-
-ServiceResolverImpl::ServiceResolverImpl(
-    const std::string& service_name,
-    const ResolveCompleteCallback& callback,
-    net::MDnsClient* mdns_client)
-    : service_name_(service_name), callback_(callback),
-      is_resolving_(false), has_resolved_(false), metadata_resolved_(false),
-      address_resolved_(false), service_staging_(new ServiceDescription),
-      service_final_(new ServiceDescription), mdns_client_(mdns_client) {
-  service_staging_->service_name = service_name_;
-  service_final_->service_name = service_name_;
-}
-
-bool ServiceResolverImpl::StartResolving() {
-  is_resolving_ = true;
-  address_resolved_ = false;
-  metadata_resolved_ = false;
-
-  if (!CreateTxtTransaction())
-    return false;
-  if (!CreateSrvTransaction())
-    return false;
-  return true;
-}
-
-bool ServiceResolverImpl::IsResolving() const {
-  return is_resolving_;
-}
-
-bool ServiceResolverImpl::HasResolved() const {
-  return has_resolved_;
-}
-
-ServiceResolverImpl::~ServiceResolverImpl() {
-}
-
-bool ServiceResolverImpl::CreateTxtTransaction() {
-  txt_transaction_ = mdns_client_->CreateTransaction(
-      net::dns_protocol::kTypeTXT, service_name_,
-      net::MDnsTransaction::SINGLE_RESULT | net::MDnsTransaction::QUERY_CACHE |
-      net::MDnsTransaction::QUERY_NETWORK,
-      base::Bind(&ServiceResolverImpl::TxtRecordTransactionResponse,
-                 AsWeakPtr()));
-  return txt_transaction_->Start();
-}
-
-// TODO(noamsml): quick-resolve for AAAA records.  Since A records tend to be in
-void ServiceResolverImpl::CreateATransaction() {
-  a_transaction_ = mdns_client_->CreateTransaction(
-      net::dns_protocol::kTypeA,
-      service_staging_.get()->address.host(),
-      net::MDnsTransaction::SINGLE_RESULT | net::MDnsTransaction::QUERY_CACHE,
-      base::Bind(&ServiceResolverImpl::ARecordTransactionResponse,
-                 AsWeakPtr()));
-  a_transaction_->Start();
-}
-
-bool ServiceResolverImpl::CreateSrvTransaction() {
-  srv_transaction_ = mdns_client_->CreateTransaction(
-      net::dns_protocol::kTypeSRV, service_name_,
-      net::MDnsTransaction::SINGLE_RESULT | net::MDnsTransaction::QUERY_CACHE |
-      net::MDnsTransaction::QUERY_NETWORK,
-      base::Bind(&ServiceResolverImpl::SrvRecordTransactionResponse,
-                 AsWeakPtr()));
-  return srv_transaction_->Start();
-}
-
-std::string ServiceResolverImpl::GetName() const {
-  return service_name_;
-}
-
-void ServiceResolverImpl::SrvRecordTransactionResponse(
-    net::MDnsTransaction::Result status, const net::RecordParsed* record) {
-  srv_transaction_.reset();
-  if (status == net::MDnsTransaction::RESULT_RECORD) {
-    DCHECK(record);
-    service_staging_.get()->address = RecordToAddress(record);
-    service_staging_.get()->last_seen = record->time_created();
-    CreateATransaction();
-  } else {
-    ServiceNotFound(MDnsStatusToRequestStatus(status));
-  }
-}
-
-void ServiceResolverImpl::TxtRecordTransactionResponse(
-    net::MDnsTransaction::Result status, const net::RecordParsed* record) {
-  txt_transaction_.reset();
-  if (status == net::MDnsTransaction::RESULT_RECORD) {
-    DCHECK(record);
-    service_staging_.get()->metadata = RecordToMetadata(record);
-  } else {
-    service_staging_.get()->metadata = std::vector<std::string>();
-  }
-
-  metadata_resolved_ = true;
-  AlertCallbackIfReady();
-}
-
-void ServiceResolverImpl::ARecordTransactionResponse(
-    net::MDnsTransaction::Result status, const net::RecordParsed* record) {
-  a_transaction_.reset();
-
-  if (status == net::MDnsTransaction::RESULT_RECORD) {
-    DCHECK(record);
-    service_staging_.get()->ip_address = RecordToIPAddress(record);
-  } else {
-    service_staging_.get()->ip_address = net::IPAddressNumber();
-  }
-
-  address_resolved_ = true;
-  AlertCallbackIfReady();
-}
-
-void ServiceResolverImpl::AlertCallbackIfReady() {
-  if (metadata_resolved_ && address_resolved_) {
-    txt_transaction_.reset();
-    srv_transaction_.reset();
-    a_transaction_.reset();
-    has_resolved_ = true;
-    is_resolving_ = false;
-    service_final_.swap(service_staging_);
-    callback_.Run(STATUS_SUCCESS, GetServiceDescription());
-  }
-}
-
-void ServiceResolverImpl::ServiceNotFound(
-    ServiceResolver::RequestStatus status) {
-  txt_transaction_.reset();
-  srv_transaction_.reset();
-  a_transaction_.reset();
-  is_resolving_ = false;
-
-  callback_.Run(status, GetServiceDescription());
-}
-
-const ServiceDescription& ServiceResolverImpl::GetServiceDescription() const {
-  return *service_final_.get();
-}
-
-ServiceResolver::RequestStatus ServiceResolverImpl::MDnsStatusToRequestStatus(
-    net::MDnsTransaction::Result status) const {
-  switch (status) {
-    case net::MDnsTransaction::RESULT_RECORD:
-      return ServiceResolver::STATUS_SUCCESS;
-    case net::MDnsTransaction::RESULT_NO_RESULTS:
-      return ServiceResolver::STATUS_REQUEST_TIMEOUT;
-    case net::MDnsTransaction::RESULT_NSEC:
-      return ServiceResolver::STATUS_KNOWN_NONEXISTENT;
-    case net::MDnsTransaction::RESULT_DONE:  // Pass through.
-    default:
-      NOTREACHED();
-      return ServiceResolver::STATUS_REQUEST_TIMEOUT;
-  }
-}
-
-const std::vector<std::string>& ServiceResolverImpl::RecordToMetadata(
-    const net::RecordParsed* record) const {
-  DCHECK(record->type() == net::dns_protocol::kTypeTXT);
-  const net::TxtRecordRdata* txt_rdata = record->rdata<net::TxtRecordRdata>();
-  DCHECK(txt_rdata);
-  return txt_rdata->texts();
-}
-
-net::HostPortPair ServiceResolverImpl::RecordToAddress(
-    const net::RecordParsed* record) const {
-  DCHECK(record->type() == net::dns_protocol::kTypeSRV);
-  const net::SrvRecordRdata* srv_rdata = record->rdata<net::SrvRecordRdata>();
-  DCHECK(srv_rdata);
-  return net::HostPortPair(srv_rdata->target(), srv_rdata->port());
-}
-
-const net::IPAddressNumber& ServiceResolverImpl::RecordToIPAddress(
-    const net::RecordParsed* record) const {
-  DCHECK(record->type() == net::dns_protocol::kTypeA);
-  const net::ARecordRdata* a_rdata = record->rdata<net::ARecordRdata>();
-  DCHECK(a_rdata);
-  return a_rdata->address();
-}
-
-}  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/service_discovery_client_impl.h b/chrome/browser/local_discovery/service_discovery_client_impl.h
deleted file mode 100644
index 13765e0..0000000
--- a/chrome/browser/local_discovery/service_discovery_client_impl.h
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_
-#define CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/cancelable_callback.h"
-#include "base/memory/linked_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
-#include "chrome/browser/local_discovery/service_discovery_client.h"
-#include "net/dns/mdns_client.h"
-
-namespace local_discovery {
-
-class ServiceDiscoveryClientImpl : public ServiceDiscoveryClient {
- public:
-  // |mdns_client| must outlive the Service Discovery Client.
-  explicit ServiceDiscoveryClientImpl(net::MDnsClient* mdns_client);
-  virtual ~ServiceDiscoveryClientImpl();
-
-  // ServiceDiscoveryClient implementation:
-  virtual scoped_ptr<ServiceWatcher> CreateServiceWatcher(
-      const std::string& service_type,
-      ServiceWatcher::Delegate* delegate) OVERRIDE;
-
-  virtual scoped_ptr<ServiceResolver> CreateServiceResolver(
-      const std::string& service_name,
-      const ServiceResolver::ResolveCompleteCallback& callback) OVERRIDE;
- private:
-  net::MDnsClient* mdns_client_;
-
-  DISALLOW_COPY_AND_ASSIGN(ServiceDiscoveryClientImpl);
-};
-
-class ServiceWatcherImpl : public ServiceWatcher,
-                           public net::MDnsListener::Delegate,
-                           public base::SupportsWeakPtr<ServiceWatcherImpl> {
- public:
-  ServiceWatcherImpl(const std::string& service_type,
-                     ServiceWatcher::Delegate* delegate,
-                     net::MDnsClient* mdns_client);
-  // Listening will automatically stop when the destructor is called.
-  virtual ~ServiceWatcherImpl();
-
-  // ServiceWatcher implementation:
-  virtual bool Start() OVERRIDE;
-
-  virtual void GetAvailableServices(
-      std::vector<std::string>* services) const OVERRIDE;
-
-  virtual void DiscoverNewServices(bool force_update) OVERRIDE;
-
-  virtual std::string GetServiceType() const OVERRIDE;
-
-  virtual void ReadCachedServices() OVERRIDE;
-
-  virtual void OnRecordUpdate(net::MDnsListener::UpdateType update,
-                              const net::RecordParsed* record) OVERRIDE;
-
-  virtual void OnNsecRecord(const std::string& name, unsigned rrtype) OVERRIDE;
-
-  virtual void OnCachePurged() OVERRIDE;
-
-  virtual void OnTransactionResponse(
-      scoped_ptr<net::MDnsTransaction>* transaction,
-      net::MDnsTransaction::Result result,
-      const net::RecordParsed* record);
-
- private:
-  struct ServiceListeners {
-    ServiceListeners(const std::string& service_name,
-                     ServiceWatcherImpl* watcher,
-                     net::MDnsClient* mdns_client);
-    ~ServiceListeners();
-    bool Start();
-
-    void set_update_pending(bool update_pending) {
-      update_pending_ = update_pending;
-    }
-
-    bool update_pending() { return update_pending_; }
-   private:
-    scoped_ptr<net::MDnsListener> srv_listener_;
-    scoped_ptr<net::MDnsListener> txt_listener_;
-    bool update_pending_;
-  };
-
-  typedef std::map<std::string, linked_ptr<ServiceListeners> >
-      ServiceListenersMap;
-
-  void AddService(const std::string& service);
-  void RemoveService(const std::string& service);
-  bool CreateTransaction(bool active, bool alert_existing_services,
-                         bool force_refresh,
-                         scoped_ptr<net::MDnsTransaction>* transaction);
-
-  void DeferUpdate(ServiceWatcher::UpdateType update_type,
-                   const std::string& service_name);
-  void DeliverDeferredUpdate(ServiceWatcher::UpdateType update_type,
-                             const std::string& service_name);
-
-  std::string service_type_;
-  ServiceListenersMap services_;
-  scoped_ptr<net::MDnsTransaction> transaction_network_;
-  scoped_ptr<net::MDnsTransaction> transaction_cache_;
-  scoped_ptr<net::MDnsListener> listener_;
-
-  ServiceWatcher::Delegate* delegate_;
-  bool started_;
-
-  net::MDnsClient* mdns_client_;
-
-  DISALLOW_COPY_AND_ASSIGN(ServiceWatcherImpl);
-};
-
-class ServiceResolverImpl
-    : public ServiceResolver,
-      public base::SupportsWeakPtr<ServiceResolverImpl> {
- public:
-  ServiceResolverImpl(const std::string& service_name,
-                      const ServiceResolver::ResolveCompleteCallback& callback,
-                      net::MDnsClient* mdns_client);
-
-  virtual ~ServiceResolverImpl();
-
-  // ServiceResolver implementation:
-  virtual bool StartResolving() OVERRIDE;
-
-  virtual bool IsResolving() const OVERRIDE;
-
-  virtual bool HasResolved() const OVERRIDE;
-
-  virtual std::string GetName() const OVERRIDE;
-
-  virtual const ServiceDescription& GetServiceDescription() const OVERRIDE;
-
- private:
-  // Respond to transaction finishing for SRV records.
-  void SrvRecordTransactionResponse(net::MDnsTransaction::Result status,
-                                    const net::RecordParsed* record);
-
-  // Respond to transaction finishing for TXT records.
-  void TxtRecordTransactionResponse(net::MDnsTransaction::Result status,
-                                    const net::RecordParsed* record);
-
-  // Respond to transaction finishing for A records.
-  void ARecordTransactionResponse(net::MDnsTransaction::Result status,
-                                  const net::RecordParsed* record);
-
-  void AlertCallbackIfReady();
-
-  void ServiceNotFound(RequestStatus status);
-
-  // Convert a TXT record to a vector of strings (metadata).
-  const std::vector<std::string>& RecordToMetadata(
-      const net::RecordParsed* record) const;
-
-  // Convert an SRV record to a host and port pair.
-  net::HostPortPair RecordToAddress(
-      const net::RecordParsed* record) const;
-
-  // Convert an A record to an IP address.
-  const net::IPAddressNumber& RecordToIPAddress(
-      const net::RecordParsed* record) const;
-
-  // Convert an MDns status to a service discovery status.
-  RequestStatus MDnsStatusToRequestStatus(
-      net::MDnsTransaction::Result status) const;
-
-  bool CreateTxtTransaction();
-  bool CreateSrvTransaction();
-  void CreateATransaction();
-
-  std::string service_name_;
-  ResolveCompleteCallback callback_;
-
-  bool is_resolving_;
-  bool has_resolved_;
-
-  bool metadata_resolved_;
-  bool address_resolved_;
-
-  scoped_ptr<net::MDnsTransaction> txt_transaction_;
-  scoped_ptr<net::MDnsTransaction> srv_transaction_;
-  scoped_ptr<net::MDnsTransaction> a_transaction_;
-
-  scoped_ptr<ServiceDescription> service_staging_;
-  scoped_ptr<ServiceDescription> service_final_;
-
-  net::MDnsClient* mdns_client_;
-
-  DISALLOW_COPY_AND_ASSIGN(ServiceResolverImpl);
-};
-
-}  // namespace local_discovery
-
-#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_
diff --git a/chrome/browser/local_discovery/service_discovery_client_unittest.cc b/chrome/browser/local_discovery/service_discovery_client_unittest.cc
deleted file mode 100644
index 9a7d90a..0000000
--- a/chrome/browser/local_discovery/service_discovery_client_unittest.cc
+++ /dev/null
@@ -1,468 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/local_discovery/service_discovery_client_impl.h"
-#include "net/base/net_errors.h"
-#include "net/dns/dns_protocol.h"
-#include "net/dns/mdns_client_impl.h"
-#include "net/dns/mock_mdns_socket_factory.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::_;
-using ::testing::Invoke;
-using ::testing::StrictMock;
-using ::testing::NiceMock;
-using ::testing::Mock;
-using ::testing::SaveArg;
-using ::testing::SetArgPointee;
-using ::testing::Return;
-using ::testing::Exactly;
-
-namespace local_discovery {
-
-namespace {
-
-const char kSamplePacketPTR[] = {
-  // Header
-  '\x00', '\x00',               // ID is zeroed out
-  '\x81', '\x80',               // Standard query response, RA, no error
-  '\x00', '\x00',               // No questions (for simplicity)
-  '\x00', '\x01',               // 1 RR (answers)
-  '\x00', '\x00',               // 0 authority RRs
-  '\x00', '\x00',               // 0 additional RRs
-
-  '\x07', '_', 'p', 'r', 'i', 'v', 'e', 't',
-  '\x04', '_', 't', 'c', 'p',
-  '\x05', 'l', 'o', 'c', 'a', 'l',
-  '\x00',
-  '\x00', '\x0c',        // TYPE is PTR.
-  '\x00', '\x01',        // CLASS is IN.
-  '\x00', '\x00',        // TTL (4 bytes) is 1 second.
-  '\x00', '\x01',
-  '\x00', '\x08',        // RDLENGTH is 8 bytes.
-  '\x05', 'h', 'e', 'l', 'l', 'o',
-  '\xc0', '\x0c'
-};
-
-const char kSamplePacketSRV[] = {
-  // Header
-  '\x00', '\x00',               // ID is zeroed out
-  '\x81', '\x80',               // Standard query response, RA, no error
-  '\x00', '\x00',               // No questions (for simplicity)
-  '\x00', '\x01',               // 1 RR (answers)
-  '\x00', '\x00',               // 0 authority RRs
-  '\x00', '\x00',               // 0 additional RRs
-
-  '\x05', 'h', 'e', 'l', 'l', 'o',
-  '\x07', '_', 'p', 'r', 'i', 'v', 'e', 't',
-  '\x04', '_', 't', 'c', 'p',
-  '\x05', 'l', 'o', 'c', 'a', 'l',
-  '\x00',
-  '\x00', '\x21',        // TYPE is SRV.
-  '\x00', '\x01',        // CLASS is IN.
-  '\x00', '\x00',        // TTL (4 bytes) is 1 second.
-  '\x00', '\x01',
-  '\x00', '\x15',        // RDLENGTH is 21 bytes.
-  '\x00', '\x00',
-  '\x00', '\x00',
-  '\x22', '\xb8',  // port 8888
-  '\x07', 'm', 'y', 'h', 'e', 'l', 'l', 'o',
-  '\x05', 'l', 'o', 'c', 'a', 'l',
-  '\x00',
-};
-
-const char kSamplePacketTXT[] = {
-  // Header
-  '\x00', '\x00',               // ID is zeroed out
-  '\x81', '\x80',               // Standard query response, RA, no error
-  '\x00', '\x00',               // No questions (for simplicity)
-  '\x00', '\x01',               // 1 RR (answers)
-  '\x00', '\x00',               // 0 authority RRs
-  '\x00', '\x00',               // 0 additional RRs
-
-  '\x05', 'h', 'e', 'l', 'l', 'o',
-  '\x07', '_', 'p', 'r', 'i', 'v', 'e', 't',
-  '\x04', '_', 't', 'c', 'p',
-  '\x05', 'l', 'o', 'c', 'a', 'l',
-  '\x00',
-  '\x00', '\x10',        // TYPE is PTR.
-  '\x00', '\x01',        // CLASS is IN.
-  '\x00', '\x00',        // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
-  '\x00', '\x01',
-  '\x00', '\x06',        // RDLENGTH is 21 bytes.
-  '\x05', 'h', 'e', 'l', 'l', 'o'
-};
-
-const char kSamplePacketSRVA[] = {
-  // Header
-  '\x00', '\x00',               // ID is zeroed out
-  '\x81', '\x80',               // Standard query response, RA, no error
-  '\x00', '\x00',               // No questions (for simplicity)
-  '\x00', '\x02',               // 2 RR (answers)
-  '\x00', '\x00',               // 0 authority RRs
-  '\x00', '\x00',               // 0 additional RRs
-
-  '\x05', 'h', 'e', 'l', 'l', 'o',
-  '\x07', '_', 'p', 'r', 'i', 'v', 'e', 't',
-  '\x04', '_', 't', 'c', 'p',
-  '\x05', 'l', 'o', 'c', 'a', 'l',
-  '\x00',
-  '\x00', '\x21',        // TYPE is SRV.
-  '\x00', '\x01',        // CLASS is IN.
-  '\x00', '\x00',        // TTL (4 bytes) is 16 seconds.
-  '\x00', '\x10',
-  '\x00', '\x15',        // RDLENGTH is 21 bytes.
-  '\x00', '\x00',
-  '\x00', '\x00',
-  '\x22', '\xb8',  // port 8888
-  '\x07', 'm', 'y', 'h', 'e', 'l', 'l', 'o',
-  '\x05', 'l', 'o', 'c', 'a', 'l',
-  '\x00',
-
-  '\x07', 'm', 'y', 'h', 'e', 'l', 'l', 'o',
-  '\x05', 'l', 'o', 'c', 'a', 'l',
-  '\x00',
-  '\x00', '\x01',        // TYPE is A.
-  '\x00', '\x01',        // CLASS is IN.
-  '\x00', '\x00',        // TTL (4 bytes) is 16 seconds.
-  '\x00', '\x10',
-  '\x00', '\x04',        // RDLENGTH is 4 bytes.
-  '\x01', '\x02',
-  '\x03', '\x04',
-};
-
-class MockServiceWatcherDelegate : public ServiceWatcher::Delegate {
- public:
-  MockServiceWatcherDelegate() {}
-  virtual ~MockServiceWatcherDelegate() {}
-
-  MOCK_METHOD2(OnServiceUpdated, void(ServiceWatcher::UpdateType,
-                                      const std::string&));
-};
-
-class ServiceDiscoveryTest : public ::testing::Test {
- public:
-  ServiceDiscoveryTest()
-      : socket_factory_(new net::MockMDnsSocketFactory),
-        mdns_client_(
-            scoped_ptr<net::MDnsConnection::SocketFactory>(
-                socket_factory_)),
-        service_discovery_client_(&mdns_client_) {
-    mdns_client_.StartListening();
-  }
-
-  virtual ~ServiceDiscoveryTest() {
-  }
-
- protected:
-  void RunFor(base::TimeDelta time_period) {
-    base::CancelableCallback<void()> callback(base::Bind(
-        &ServiceDiscoveryTest::Stop, base::Unretained(this)));
-    base::MessageLoop::current()->PostDelayedTask(
-        FROM_HERE, callback.callback(), time_period);
-
-    base::MessageLoop::current()->Run();
-    callback.Cancel();
-  }
-
-  void Stop() {
-    base::MessageLoop::current()->Quit();
-  }
-
-  net::MockMDnsSocketFactory* socket_factory_;
-  net::MDnsClientImpl mdns_client_;
-  ServiceDiscoveryClientImpl service_discovery_client_;
-  base::MessageLoop loop_;
-};
-
-TEST_F(ServiceDiscoveryTest, AddRemoveService) {
-  scoped_ptr<ServiceWatcher> watcher;
-  StrictMock<MockServiceWatcherDelegate> delegate;
-
-  watcher = service_discovery_client_.CreateServiceWatcher(
-      "_privet._tcp.local", &delegate);
-
-  watcher->Start();
-
-  EXPECT_CALL(delegate, OnServiceUpdated(ServiceWatcher::UPDATE_ADDED,
-                                         "hello._privet._tcp.local"))
-      .Times(Exactly(1));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketPTR, sizeof(kSamplePacketPTR));
-
-  EXPECT_CALL(delegate, OnServiceUpdated(ServiceWatcher::UPDATE_REMOVED,
-                                         "hello._privet._tcp.local"))
-      .Times(Exactly(1));
-
-  RunFor(base::TimeDelta::FromSeconds(2));
-};
-
-TEST_F(ServiceDiscoveryTest, DiscoverNewServices) {
-  scoped_ptr<ServiceWatcher> watcher;
-  StrictMock<MockServiceWatcherDelegate> delegate;
-
-  watcher = service_discovery_client_.CreateServiceWatcher(
-      "_privet._tcp.local", &delegate);
-
-  watcher->Start();
-
-  EXPECT_CALL(*socket_factory_, OnSendTo(_))
-      .Times(2);
-
-  watcher->DiscoverNewServices(false);
-};
-
-TEST_F(ServiceDiscoveryTest, GetAvailableServices) {
-  NiceMock<MockServiceWatcherDelegate> delegate;
-
-  std::vector<std::string> data_expected;
-  std::vector<std::string> data;
-
-  data_expected.push_back("hello._privet._tcp.local");
-
-  scoped_ptr<ServiceWatcher> watcher =
-      service_discovery_client_.CreateServiceWatcher(
-          "_privet._tcp.local", &delegate);
-
-  watcher->Start();
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketPTR, sizeof(kSamplePacketPTR));
-
-  watcher->GetAvailableServices(&data);
-
-  EXPECT_EQ(data, data_expected);
-};
-
-TEST_F(ServiceDiscoveryTest, ReadCachedServices) {
-  NiceMock<MockServiceWatcherDelegate> delegate_irrelevant;
-  scoped_ptr<ServiceWatcher> watcher_irrelevant =
-      service_discovery_client_.CreateServiceWatcher(
-          "_privet._tcp.local", &delegate_irrelevant);
-
-  watcher_irrelevant->Start();
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketPTR, sizeof(kSamplePacketPTR));
-
-  StrictMock<MockServiceWatcherDelegate> delegate;
-  scoped_ptr<ServiceWatcher> watcher =
-      service_discovery_client_.CreateServiceWatcher(
-          "_privet._tcp.local", &delegate);
-
-  watcher->Start();
-
-  EXPECT_CALL(delegate, OnServiceUpdated(ServiceWatcher::UPDATE_ADDED,
-                                         "hello._privet._tcp.local"))
-      .Times(Exactly(1));
-
-  watcher->ReadCachedServices();
-
-  base::MessageLoop::current()->RunUntilIdle();
-};
-
-TEST_F(ServiceDiscoveryTest, OnServiceChanged) {
-  StrictMock<MockServiceWatcherDelegate> delegate;
-  scoped_ptr<ServiceWatcher> watcher =
-      service_discovery_client_.CreateServiceWatcher(
-          "_privet._tcp.local", &delegate);
-
-  watcher->Start();
-
-  EXPECT_CALL(delegate, OnServiceUpdated(ServiceWatcher::UPDATE_ADDED,
-                                         "hello._privet._tcp.local"))
-      .Times(Exactly(1));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketPTR, sizeof(kSamplePacketPTR));
-
-  base::MessageLoop::current()->RunUntilIdle();
-
-  EXPECT_CALL(delegate, OnServiceUpdated(ServiceWatcher::UPDATE_CHANGED,
-                                         "hello._privet._tcp.local"))
-      .Times(Exactly(1));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketSRV, sizeof(kSamplePacketSRV));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketTXT, sizeof(kSamplePacketTXT));
-
-  base::MessageLoop::current()->RunUntilIdle();
-};
-
-TEST_F(ServiceDiscoveryTest, SinglePacket) {
-  StrictMock<MockServiceWatcherDelegate> delegate;
-  scoped_ptr<ServiceWatcher> watcher =
-      service_discovery_client_.CreateServiceWatcher(
-          "_privet._tcp.local", &delegate);
-
-  watcher->Start();
-
-  EXPECT_CALL(delegate, OnServiceUpdated(ServiceWatcher::UPDATE_ADDED,
-                                         "hello._privet._tcp.local"))
-      .Times(Exactly(1));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketPTR, sizeof(kSamplePacketPTR));
-
-  // Reset the "already updated" flag.
-  base::MessageLoop::current()->RunUntilIdle();
-
-  EXPECT_CALL(delegate, OnServiceUpdated(ServiceWatcher::UPDATE_CHANGED,
-                                         "hello._privet._tcp.local"))
-      .Times(Exactly(1));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketSRV, sizeof(kSamplePacketSRV));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketTXT, sizeof(kSamplePacketTXT));
-
-  base::MessageLoop::current()->RunUntilIdle();
-};
-
-class ServiceResolverTest : public ServiceDiscoveryTest {
- public:
-  ServiceResolverTest() {
-    metadata_expected_.push_back("hello");
-    address_expected_ = net::HostPortPair("myhello.local", 8888);
-    ip_address_expected_.push_back(1);
-    ip_address_expected_.push_back(2);
-    ip_address_expected_.push_back(3);
-    ip_address_expected_.push_back(4);
-  }
-
-  ~ServiceResolverTest() {
-  }
-
-  void SetUp()  {
-    resolver_ = service_discovery_client_.CreateServiceResolver(
-        "hello._privet._tcp.local",
-        base::Bind(&ServiceResolverTest::OnFinishedResolving,
-                   base::Unretained(this)));
-  }
-
-  void OnFinishedResolving(ServiceResolver::RequestStatus request_status,
-                           const ServiceDescription& service_description) {
-    OnFinishedResolvingInternal(request_status);
-  }
-
-  MOCK_METHOD1(OnFinishedResolvingInternal, void(
-      ServiceResolver::RequestStatus));
-
- protected:
-  scoped_ptr<ServiceResolver> resolver_;
-  net::IPAddressNumber ip_address_;
-  net::HostPortPair address_expected_;
-  std::vector<std::string> metadata_expected_;
-  net::IPAddressNumber ip_address_expected_;
-};
-
-TEST_F(ServiceResolverTest, TxtAndSrvButNoA) {
-  EXPECT_CALL(*socket_factory_, OnSendTo(_))
-      .Times(4);
-
-  EXPECT_FALSE(resolver_->IsResolving());
-  EXPECT_FALSE(resolver_->HasResolved());
-  EXPECT_TRUE(resolver_->StartResolving());
-  EXPECT_TRUE(resolver_->IsResolving());
-  EXPECT_FALSE(resolver_->HasResolved());
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketSRV, sizeof(kSamplePacketSRV));
-
-  base::MessageLoop::current()->RunUntilIdle();
-
-  EXPECT_CALL(*this, OnFinishedResolvingInternal(
-      ServiceResolver::STATUS_SUCCESS));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketTXT, sizeof(kSamplePacketTXT));
-
-  EXPECT_EQ(address_expected_.ToString(),
-            resolver_->GetServiceDescription().address.ToString());
-  EXPECT_EQ(metadata_expected_, resolver_->GetServiceDescription().metadata);
-  EXPECT_EQ(net::IPAddressNumber(),
-            resolver_->GetServiceDescription().ip_address);
-};
-
-TEST_F(ServiceResolverTest, TxtSrvAndA) {
-  EXPECT_CALL(*socket_factory_, OnSendTo(_))
-      .Times(4);
-
-  EXPECT_FALSE(resolver_->IsResolving());
-  EXPECT_FALSE(resolver_->HasResolved());
-  EXPECT_TRUE(resolver_->StartResolving());
-  EXPECT_TRUE(resolver_->IsResolving());
-  EXPECT_FALSE(resolver_->HasResolved());
-
-  EXPECT_CALL(*this, OnFinishedResolvingInternal(
-      ServiceResolver::STATUS_SUCCESS));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketTXT, sizeof(kSamplePacketTXT));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketSRVA, sizeof(kSamplePacketSRVA));
-
-  EXPECT_EQ(address_expected_.ToString(),
-            resolver_->GetServiceDescription().address.ToString());
-  EXPECT_EQ(metadata_expected_, resolver_->GetServiceDescription().metadata);
-  EXPECT_EQ(ip_address_expected_,
-            resolver_->GetServiceDescription().ip_address);
-};
-
-TEST_F(ServiceResolverTest, JustSrv) {
-  EXPECT_CALL(*socket_factory_, OnSendTo(_))
-      .Times(4);
-
-  EXPECT_FALSE(resolver_->IsResolving());
-  EXPECT_FALSE(resolver_->HasResolved());
-  EXPECT_TRUE(resolver_->StartResolving());
-  EXPECT_TRUE(resolver_->IsResolving());
-  EXPECT_FALSE(resolver_->HasResolved());
-
-  EXPECT_CALL(*this, OnFinishedResolvingInternal(
-      ServiceResolver::STATUS_SUCCESS));
-
-  socket_factory_->SimulateReceive(
-      kSamplePacketSRVA, sizeof(kSamplePacketSRVA));
-
-  // TODO(noamsml): When NSEC record support is added, change this to use an
-  // NSEC record.
-  RunFor(base::TimeDelta::FromSeconds(4));
-
-  EXPECT_EQ(address_expected_.ToString(),
-            resolver_->GetServiceDescription().address.ToString());
-  EXPECT_EQ(std::vector<std::string>() ,
-            resolver_->GetServiceDescription().metadata);
-  EXPECT_EQ(ip_address_expected_,
-            resolver_->GetServiceDescription().ip_address);
-};
-
-TEST_F(ServiceResolverTest, WithNothing) {
-  EXPECT_CALL(*socket_factory_, OnSendTo(_))
-      .Times(4);
-
-  EXPECT_FALSE(resolver_->IsResolving());
-  EXPECT_FALSE(resolver_->HasResolved());
-  EXPECT_TRUE(resolver_->StartResolving());
-  EXPECT_TRUE(resolver_->IsResolving());
-  EXPECT_FALSE(resolver_->HasResolved());
-
-  EXPECT_CALL(*this, OnFinishedResolvingInternal(
-      ServiceResolver::STATUS_REQUEST_TIMEOUT));
-
-  // TODO(noamsml): When NSEC record support is added, change this to use an
-  // NSEC record.
-  RunFor(base::TimeDelta::FromSeconds(4));
-};
-
-}  // namespace
-
-}  // namespace local_discovery
diff --git a/chrome/browser/mac/master_prefs.mm b/chrome/browser/mac/master_prefs.mm
index 2355b2c..cd22a67 100644
--- a/chrome/browser/mac/master_prefs.mm
+++ b/chrome/browser/mac/master_prefs.mm
@@ -45,7 +45,7 @@
   if (chrome::GetDefaultUserDataDirectory(&user_application_support_path)) {
     user_application_support_path =
         user_application_support_path.Append(kMasterPreferencesFileName);
-    if (file_util::PathExists(user_application_support_path))
+    if (base::PathExists(user_application_support_path))
       return user_application_support_path;
   }
 
diff --git a/chrome/browser/managed_mode/managed_mode.cc b/chrome/browser/managed_mode/managed_mode.cc
index 4375615..b0015ad 100644
--- a/chrome/browser/managed_mode/managed_mode.cc
+++ b/chrome/browser/managed_mode/managed_mode.cc
@@ -10,6 +10,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/sequenced_task_runner.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/managed_mode/managed_mode_site_list.h"
 #include "chrome/browser/managed_mode/managed_user_service.h"
 #include "chrome/browser/policy/url_blacklist_manager.h"
@@ -18,7 +19,6 @@
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/managed_mode/managed_mode_browsertest.cc b/chrome/browser/managed_mode/managed_mode_browsertest.cc
index c019a84..86cb72e 100644
--- a/chrome/browser/managed_mode/managed_mode_browsertest.cc
+++ b/chrome/browser/managed_mode/managed_mode_browsertest.cc
@@ -6,6 +6,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/common/cancelable_request.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/managed_mode/managed_mode_navigation_observer.cc b/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
index 7681a11..c3bc2b3 100644
--- a/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
+++ b/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
@@ -37,9 +37,7 @@
 #include "ui/base/l10n/l10n_util.h"
 
 using base::Time;
-using content::BrowserThread;
 using content::NavigationEntry;
-using content::UserMetricsAction;
 
 namespace {
 
@@ -73,19 +71,19 @@
 }
 
 
-// ManagedModeWarningInfobarDelegate ------------------------------------------
+// ManagedModeWarningInfoBarDelegate ------------------------------------------
 
-class ManagedModeWarningInfobarDelegate : public ConfirmInfoBarDelegate {
+class ManagedModeWarningInfoBarDelegate : public ConfirmInfoBarDelegate {
  public:
   // Creates a managed mode warning delegate and adds it to |infobar_service|.
   // Returns the delegate if it was successfully added.
   static InfoBarDelegate* Create(InfoBarService* infobar_service);
 
  private:
-  explicit ManagedModeWarningInfobarDelegate(InfoBarService* infobar_service);
-  virtual ~ManagedModeWarningInfobarDelegate();
+  explicit ManagedModeWarningInfoBarDelegate(InfoBarService* infobar_service);
+  virtual ~ManagedModeWarningInfoBarDelegate();
 
-  // ConfirmInfoBarDelegate overrides:
+  // ConfirmInfoBarDelegate:
   virtual bool ShouldExpire(
       const content::LoadCommittedDetails& details) const OVERRIDE;
   virtual void InfoBarDismissed() OVERRIDE;
@@ -93,65 +91,59 @@
   virtual int GetButtons() const OVERRIDE;
   virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
   virtual bool Accept() OVERRIDE;
-  virtual bool Cancel() OVERRIDE;
 
-  DISALLOW_COPY_AND_ASSIGN(ManagedModeWarningInfobarDelegate);
+  DISALLOW_COPY_AND_ASSIGN(ManagedModeWarningInfoBarDelegate);
 };
 
 // static
-InfoBarDelegate* ManagedModeWarningInfobarDelegate::Create(
+InfoBarDelegate* ManagedModeWarningInfoBarDelegate::Create(
     InfoBarService* infobar_service) {
-  scoped_ptr<InfoBarDelegate> delegate(
-    new ManagedModeWarningInfobarDelegate(infobar_service));
-  return infobar_service->AddInfoBar(delegate.Pass());
+  return infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
+      new ManagedModeWarningInfoBarDelegate(infobar_service)));
 }
 
-ManagedModeWarningInfobarDelegate::ManagedModeWarningInfobarDelegate(
+ManagedModeWarningInfoBarDelegate::ManagedModeWarningInfoBarDelegate(
     InfoBarService* infobar_service)
-    : ConfirmInfoBarDelegate(infobar_service) {}
+    : ConfirmInfoBarDelegate(infobar_service) {
+}
 
-ManagedModeWarningInfobarDelegate::~ManagedModeWarningInfobarDelegate() {}
+ManagedModeWarningInfoBarDelegate::~ManagedModeWarningInfoBarDelegate() {
+}
 
-bool ManagedModeWarningInfobarDelegate::ShouldExpire(
+bool ManagedModeWarningInfoBarDelegate::ShouldExpire(
     const content::LoadCommittedDetails& details) const {
   // ManagedModeNavigationObserver removes us below.
   return false;
 }
 
-void ManagedModeWarningInfobarDelegate::InfoBarDismissed() {
-  ManagedModeNavigationObserver* observer =
-      ManagedModeNavigationObserver::FromWebContents(web_contents());
-  observer->WarnInfobarDismissed();
+void ManagedModeWarningInfoBarDelegate::InfoBarDismissed() {
+  ManagedModeNavigationObserver::FromWebContents(
+      web_contents())->WarnInfoBarDismissed();
 }
 
-string16 ManagedModeWarningInfobarDelegate::GetMessageText() const {
+string16 ManagedModeWarningInfoBarDelegate::GetMessageText() const {
   return l10n_util::GetStringUTF16(IDS_MANAGED_USER_WARN_INFOBAR_MESSAGE);
 }
 
-int ManagedModeWarningInfobarDelegate::GetButtons() const {
+int ManagedModeWarningInfoBarDelegate::GetButtons() const {
   return BUTTON_OK;
 }
 
-string16 ManagedModeWarningInfobarDelegate::GetButtonLabel(
+string16 ManagedModeWarningInfoBarDelegate::GetButtonLabel(
     InfoBarButton button) const {
   DCHECK_EQ(BUTTON_OK, button);
   return l10n_util::GetStringUTF16(IDS_MANAGED_USER_WARN_INFOBAR_GO_BACK);
 }
 
-bool ManagedModeWarningInfobarDelegate::Accept() {
+bool ManagedModeWarningInfoBarDelegate::Accept() {
   GoBackToSafety(web_contents());
 
   return false;
 }
 
-bool ManagedModeWarningInfobarDelegate::Cancel() {
-  NOTREACHED();
-  return false;
-}
 
 }  // namespace
 
-
 // ManagedModeNavigationObserver ----------------------------------------------
 
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ManagedModeNavigationObserver);
@@ -169,7 +161,7 @@
   url_filter_ = managed_user_service_->GetURLFilterForUIThread();
 }
 
-void ManagedModeNavigationObserver::WarnInfobarDismissed() {
+void ManagedModeNavigationObserver::WarnInfoBarDismissed() {
   DCHECK(warn_infobar_delegate_);
   warn_infobar_delegate_ = NULL;
 }
@@ -204,7 +196,7 @@
       url_filter_->GetFilteringBehaviorForURL(url);
 
   if (behavior == ManagedModeURLFilter::WARN && !warn_infobar_delegate_) {
-    warn_infobar_delegate_ = ManagedModeWarningInfobarDelegate::Create(
+    warn_infobar_delegate_ = ManagedModeWarningInfoBarDelegate::Create(
         InfoBarService::FromWebContents(web_contents()));
   }
 }
@@ -218,8 +210,8 @@
   content::WebContents* web_contents =
       tab_util::GetWebContentsByID(render_process_host_id, render_view_id);
   if (!web_contents) {
-    BrowserThread::PostTask(
-        BrowserThread::IO, FROM_HERE, base::Bind(callback, false));
+    content::BrowserThread::PostTask(
+        content::BrowserThread::IO, FROM_HERE, base::Bind(callback, false));
     return;
   }
 
diff --git a/chrome/browser/managed_mode/managed_mode_navigation_observer.h b/chrome/browser/managed_mode/managed_mode_navigation_observer.h
index ab14e73..59015e4 100644
--- a/chrome/browser/managed_mode/managed_mode_navigation_observer.h
+++ b/chrome/browser/managed_mode/managed_mode_navigation_observer.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_MANAGED_MODE_MANAGED_MODE_NAVIGATION_OBSERVER_H_
 
 #include <set>
+#include <vector>
 
 #include "base/memory/scoped_vector.h"
 #include "base/values.h"
@@ -27,10 +28,10 @@
   virtual ~ManagedModeNavigationObserver();
 
   // Sets the specific infobar as dismissed.
-  void WarnInfobarDismissed();
+  void WarnInfoBarDismissed();
 
-  const std::vector<const content::NavigationEntry*>* blocked_navigations()
-      const {
+  const std::vector<const content::NavigationEntry*>*
+      blocked_navigations() const {
     return &blocked_navigations_.get();
   }
 
diff --git a/chrome/browser/managed_mode/managed_user_registration_service.cc b/chrome/browser/managed_mode/managed_user_registration_service.cc
index ae0da0e..fb0d14e 100644
--- a/chrome/browser/managed_mode/managed_user_registration_service.cc
+++ b/chrome/browser/managed_mode/managed_user_registration_service.cc
@@ -89,7 +89,7 @@
 }
 
 // static
-void ManagedUserRegistrationService::RegisterUserPrefs(
+void ManagedUserRegistrationService::RegisterProfilePrefs(
     PrefRegistrySyncable* registry) {
   registry->RegisterDictionaryPref(prefs::kManagedUsers,
                                    PrefRegistrySyncable::UNSYNCABLE_PREF);
@@ -139,7 +139,7 @@
     DCHECK(!error.IsSet()) << error.ToString();
   }
 
-  browser_sync::DeviceInfo::CreateLocalDeviceInfo(
+  browser_sync::DeviceInfo::GetClientName(
       base::Bind(&ManagedUserRegistrationService::FetchToken,
                  weak_ptr_factory_.GetWeakPtr(), info.name));
 }
@@ -340,9 +340,9 @@
 
 void ManagedUserRegistrationService::FetchToken(
     const string16& name,
-    const browser_sync::DeviceInfo& device_info) {
+    const std::string& client_name) {
   token_fetcher_->Start(
-      pending_managed_user_id_, name, device_info.client_name(),
+      pending_managed_user_id_, name, client_name,
       base::Bind(&ManagedUserRegistrationService::OnReceivedToken,
                  weak_ptr_factory_.GetWeakPtr()));
 }
diff --git a/chrome/browser/managed_mode/managed_user_registration_service.h b/chrome/browser/managed_mode/managed_user_registration_service.h
index c069ff4..99ba735 100644
--- a/chrome/browser/managed_mode/managed_user_registration_service.h
+++ b/chrome/browser/managed_mode/managed_user_registration_service.h
@@ -73,7 +73,7 @@
       ProfileDownloader* downloader,
       ProfileDownloaderDelegate::FailureReason reason) OVERRIDE;
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Registers a new managed user with the server. |info| contains necessary
   // information like the display name of the  the user. |callback| is called
@@ -118,9 +118,9 @@
   // Called when the Sync server has acknowledged a newly created managed user.
   void OnManagedUserAcknowledged(const std::string& managed_user_id);
 
-  // Fetches the managed user token when we have the device info.
+  // Fetches the managed user token when we have the device name.
   void FetchToken(const string16& name,
-                  const browser_sync::DeviceInfo& device_info);
+                  const std::string& client_name);
 
   // Called when we have received a token for the managed user.
   void OnReceivedToken(const GoogleServiceAuthError& error,
diff --git a/chrome/browser/managed_mode/managed_user_registration_service_unittest.cc b/chrome/browser/managed_mode/managed_user_registration_service_unittest.cc
index 0edb308..ef188c5 100644
--- a/chrome/browser/managed_mode/managed_user_registration_service_unittest.cc
+++ b/chrome/browser/managed_mode/managed_user_registration_service_unittest.cc
@@ -145,7 +145,7 @@
       sync_data_id_(0),
       received_callback_(false),
       error_(GoogleServiceAuthError::NUM_STATES) {
-  ManagedUserRegistrationService::RegisterUserPrefs(prefs_.registry());
+  ManagedUserRegistrationService::RegisterProfilePrefs(prefs_.registry());
   scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher(
       new MockManagedUserRefreshTokenFetcher);
   service_.reset(
@@ -180,7 +180,7 @@
   specifics.mutable_managed_user()->set_id(id);
   specifics.mutable_managed_user()->set_name(name);
   specifics.mutable_managed_user()->set_acknowledged(true);
-  return SyncData::CreateRemoteData(++sync_data_id_, specifics);
+  return SyncData::CreateRemoteData(++sync_data_id_, specifics, base::Time());
 }
 
 SyncMergeResult ManagedUserRegistrationServiceTest::StartInitialSync() {
@@ -212,7 +212,9 @@
     specifics.mutable_managed_user()->set_acknowledged(true);
     new_changes.push_back(
         SyncChange(FROM_HERE, SyncChange::ACTION_UPDATE,
-                   SyncData::CreateRemoteData(++sync_data_id_, specifics)));
+                   SyncData::CreateRemoteData(++sync_data_id_,
+                                              specifics,
+                                              base::Time())));
   }
   service()->ProcessSyncChanges(FROM_HERE, new_changes);
 
diff --git a/chrome/browser/managed_mode/managed_user_service.cc b/chrome/browser/managed_mode/managed_user_service.cc
index 6d2e45f..2755095 100644
--- a/chrome/browser/managed_mode/managed_user_service.cc
+++ b/chrome/browser/managed_mode/managed_user_service.cc
@@ -9,7 +9,9 @@
 #include "base/metrics/field_trial.h"
 #include "base/prefs/pref_service.h"
 #include "base/sequenced_task_runner.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/managed_mode/managed_mode_site_list.h"
@@ -29,8 +31,8 @@
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/api/managed_mode_private/managed_mode_handler.h"
 #include "chrome/common/extensions/extension_set.h"
@@ -59,6 +61,11 @@
     "X-ManagedUser-AccessRequests";
 const char kManagedUserAccessRequestTime[] = "timestamp";
 const char kManagedUserPseudoEmail[] = "managed_user@localhost";
+const char kOpenManagedProfileKeyPrefix[] = "X-ManagedUser-Events-OpenProfile";
+const char kQuitBrowserKeyPrefix[] = "X-ManagedUser-Events-QuitBrowser";
+const char kSwitchFromManagedProfileKeyPrefix[] =
+    "X-ManagedUser-Events-SwitchProfile";
+const char kEventTimestamp[] = "timestamp";
 
 std::string CanonicalizeHostname(const std::string& hostname) {
   std::string canonicalized;
@@ -140,12 +147,22 @@
     : weak_ptr_factory_(this),
       profile_(profile),
       waiting_for_sync_initialization_(false),
-      elevated_for_testing_(false) {
+      is_profile_active_(false),
+      elevated_for_testing_(false),
+      did_shutdown_(false) {
 }
 
-ManagedUserService::~ManagedUserService() {}
+ManagedUserService::~ManagedUserService() {
+  DCHECK(did_shutdown_);
+}
 
 void ManagedUserService::Shutdown() {
+  did_shutdown_ = true;
+  if (ProfileIsManaged()) {
+    RecordProfileAndBrowserEventsHelper(kQuitBrowserKeyPrefix);
+    BrowserList::RemoveObserver(this);
+  }
+
   if (!waiting_for_sync_initialization_)
     return;
 
@@ -164,7 +181,7 @@
 }
 
 // static
-void ManagedUserService::RegisterUserPrefs(
+void ManagedUserService::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterDictionaryPref(
       prefs::kManagedModeManualHosts,
@@ -534,6 +551,8 @@
       base::Bind(&ManagedUserService::UpdateManualURLs,
                  base::Unretained(this)));
 
+  BrowserList::AddObserver(this);
+
   if (policy_provider)
     policy_provider->InitLocalPolicies();
 
@@ -619,3 +638,29 @@
   }
   url_filter_context_.SetManualURLs(url_map.Pass());
 }
+
+void ManagedUserService::OnBrowserSetLastActive(Browser* browser) {
+  bool profile_became_active = profile_->IsSameProfile(browser->profile());
+  if (!is_profile_active_ && profile_became_active)
+    RecordProfileAndBrowserEventsHelper(kOpenManagedProfileKeyPrefix);
+  else if (is_profile_active_ && !profile_became_active)
+    RecordProfileAndBrowserEventsHelper(kSwitchFromManagedProfileKeyPrefix);
+
+  is_profile_active_ = profile_became_active;
+}
+
+void ManagedUserService::RecordProfileAndBrowserEventsHelper(
+    const char* key_prefix) {
+  std::string key = ManagedModePolicyProvider::MakeSplitSettingKey(key_prefix,
+      base::Int64ToString(base::TimeTicks::Now().ToInternalValue()));
+
+  scoped_ptr<DictionaryValue> dict(new DictionaryValue);
+
+  // TODO(bauerb): Use sane time when ready.
+  dict->SetDouble(kEventTimestamp, base::Time::Now().ToJsTime());
+
+  ManagedModePolicyProvider* provider = GetPolicyProvider();
+  // It is NULL in tests.
+  if (provider)
+    provider->UploadItem(key, dict.PassAs<Value>());
+}
diff --git a/chrome/browser/managed_mode/managed_user_service.h b/chrome/browser/managed_mode/managed_user_service.h
index 7c6da2a..0566ed4 100644
--- a/chrome/browser/managed_mode/managed_user_service.h
+++ b/chrome/browser/managed_mode/managed_user_service.h
@@ -41,7 +41,8 @@
 class ManagedUserService : public BrowserContextKeyedService,
                            public extensions::ManagementPolicy::Provider,
                            public ProfileSyncServiceObserver,
-                           public content::NotificationObserver {
+                           public content::NotificationObserver,
+                           public chrome::BrowserListObserver {
  public:
   typedef std::vector<string16> CategoryList;
 
@@ -51,7 +52,6 @@
     MANUAL_BLOCK
   };
 
-  explicit ManagedUserService(Profile* profile);
   virtual ~ManagedUserService();
 
   // ProfileKeyedService override:
@@ -63,7 +63,7 @@
   // ManagedUserService (which could lead to cyclic dependencies).
   static bool ProfileIsManaged(Profile* profile);
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Returns true if managed users are enabled by either Finch or the command
   // line flag.
@@ -156,8 +156,12 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
+  // chrome::BrowserListObserver implementation:
+  virtual void OnBrowserSetLastActive(Browser* browser) OVERRIDE;
+
  private:
   friend class ManagedUserServiceExtensionTest;
+  friend class ManagedUserServiceFactory;
 
   // A bridge from ManagedMode (which lives on the UI thread) to the
   // ManagedModeURLFilters, one of which lives on the IO thread. This class
@@ -189,6 +193,10 @@
     DISALLOW_COPY_AND_ASSIGN(URLFilterContext);
   };
 
+  // Use |ManagedUserServiceFactory::GetForProfile(..)| to get
+  // an instance of this service.
+  explicit ManagedUserService(Profile* profile);
+
   void OnCustodianProfileDownloaded(const string16& full_name);
 
   void OnManagedUserRegistered(const ProfileManager::CreateCallback& callback,
@@ -222,6 +230,12 @@
   // corresponding preference is changed.
   void UpdateManualURLs();
 
+  // Records some events (opening the managed user profile, switching from the
+  // managed user profile, and quitting the browser); each is stored
+  // using a key with a prefix (|key_prefix|) indicating the type of the event.
+  // Each entry is a dictionary which has the timestamp of the event.
+  void RecordProfileAndBrowserEventsHelper(const char* key_prefix);
+
   base::WeakPtrFactory<ManagedUserService> weak_ptr_factory_;
 
   // Owns us via the BrowserContextKeyedService mechanism.
@@ -232,10 +246,14 @@
 
   // True iff we're waiting for the Sync service to be initialized.
   bool waiting_for_sync_initialization_;
+  bool is_profile_active_;
 
   // Sets a profile in elevated state for testing if set to true.
   bool elevated_for_testing_;
 
+  // True only when |Shutdown()| method has been called.
+  bool did_shutdown_;
+
   URLFilterContext url_filter_context_;
 };
 
diff --git a/chrome/browser/managed_mode/managed_user_service_unittest.cc b/chrome/browser/managed_mode/managed_user_service_unittest.cc
index caff2c8..6a51281 100644
--- a/chrome/browser/managed_mode/managed_user_service_unittest.cc
+++ b/chrome/browser/managed_mode/managed_user_service_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/path_service.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service_unittest.h"
 #include "chrome/browser/extensions/unpacked_installer.h"
 #include "chrome/browser/managed_mode/managed_user_service.h"
@@ -12,7 +13,6 @@
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_list.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
@@ -58,47 +58,49 @@
 class ManagedUserServiceTest : public ::testing::Test {
  public:
   ManagedUserServiceTest() : ui_thread_(content::BrowserThread::UI,
-                                        &message_loop_),
-                             managed_user_service_(&profile_) {}
+                                        &message_loop_) {
+    managed_user_service_ = ManagedUserServiceFactory::GetForProfile(&profile_);
+  }
+
   virtual ~ManagedUserServiceTest() {}
 
  protected:
   base::MessageLoop message_loop_;
   content::TestBrowserThread ui_thread_;
   TestingProfile profile_;
-  ManagedUserService managed_user_service_;
+  ManagedUserService* managed_user_service_;
 };
 
 }  // namespace
 
 TEST_F(ManagedUserServiceTest, ExtensionManagementPolicyProviderUnmanaged) {
-  EXPECT_FALSE(managed_user_service_.ProfileIsManaged());
+  EXPECT_FALSE(managed_user_service_->ProfileIsManaged());
 
   string16 error_1;
-  EXPECT_TRUE(managed_user_service_.UserMayLoad(NULL, &error_1));
+  EXPECT_TRUE(managed_user_service_->UserMayLoad(NULL, &error_1));
   EXPECT_EQ(string16(), error_1);
 
   string16 error_2;
-  EXPECT_TRUE(managed_user_service_.UserMayModifySettings(NULL, &error_2));
+  EXPECT_TRUE(managed_user_service_->UserMayModifySettings(NULL, &error_2));
   EXPECT_EQ(string16(), error_2);
 }
 
 TEST_F(ManagedUserServiceTest, ExtensionManagementPolicyProviderManaged) {
   ManagedModeURLFilterObserver observer(
-      managed_user_service_.GetURLFilterForUIThread());
-  managed_user_service_.InitForTesting();
-  EXPECT_TRUE(managed_user_service_.ProfileIsManaged());
+      managed_user_service_->GetURLFilterForUIThread());
+  managed_user_service_->InitForTesting();
+  EXPECT_TRUE(managed_user_service_->ProfileIsManaged());
 
   string16 error_1;
-  EXPECT_FALSE(managed_user_service_.UserMayLoad(NULL, &error_1));
+  EXPECT_FALSE(managed_user_service_->UserMayLoad(NULL, &error_1));
   EXPECT_FALSE(error_1.empty());
 
   string16 error_2;
-  EXPECT_FALSE(managed_user_service_.UserMayModifySettings(NULL, &error_2));
+  EXPECT_FALSE(managed_user_service_->UserMayModifySettings(NULL, &error_2));
   EXPECT_FALSE(error_2.empty());
 
 #ifndef NDEBUG
-  EXPECT_FALSE(managed_user_service_.GetDebugPolicyProviderName().empty());
+  EXPECT_FALSE(managed_user_service_->GetDebugPolicyProviderName().empty());
 #endif
   // Wait for the initial update to finish (otherwise we'll get leaks).
   observer.Wait();
@@ -121,18 +123,19 @@
   }
 
   EXPECT_EQ(ManagedUserService::MANUAL_ALLOW,
-            managed_user_service_.GetManualBehaviorForURL(kExampleFooURL));
+            managed_user_service_->GetManualBehaviorForURL(kExampleFooURL));
   EXPECT_EQ(ManagedUserService::MANUAL_BLOCK,
-            managed_user_service_.GetManualBehaviorForURL(kExampleBarURL));
+            managed_user_service_->GetManualBehaviorForURL(kExampleBarURL));
   EXPECT_EQ(ManagedUserService::MANUAL_ALLOW,
-            managed_user_service_.GetManualBehaviorForURL(kExampleFooNoWWWURL));
+            managed_user_service_->GetManualBehaviorForURL(
+                kExampleFooNoWWWURL));
   EXPECT_EQ(ManagedUserService::MANUAL_ALLOW,
-            managed_user_service_.GetManualBehaviorForURL(kBlurpURL));
+            managed_user_service_->GetManualBehaviorForURL(kBlurpURL));
   EXPECT_EQ(ManagedUserService::MANUAL_NONE,
-            managed_user_service_.GetManualBehaviorForURL(kMooseURL));
+            managed_user_service_->GetManualBehaviorForURL(kMooseURL));
   std::vector<GURL> exceptions;
-  managed_user_service_.GetManualExceptionsForHost("www.example.com",
-                                                   &exceptions);
+  managed_user_service_->GetManualExceptionsForHost("www.example.com",
+                                                    &exceptions);
   ASSERT_EQ(2u, exceptions.size());
   EXPECT_EQ(kExampleBarURL, exceptions[0]);
   EXPECT_EQ(kExampleFooURL, exceptions[1]);
@@ -148,15 +151,16 @@
   }
 
   EXPECT_EQ(ManagedUserService::MANUAL_NONE,
-            managed_user_service_.GetManualBehaviorForURL(kExampleFooURL));
+            managed_user_service_->GetManualBehaviorForURL(kExampleFooURL));
   EXPECT_EQ(ManagedUserService::MANUAL_NONE,
-            managed_user_service_.GetManualBehaviorForURL(kExampleBarURL));
+            managed_user_service_->GetManualBehaviorForURL(kExampleBarURL));
   EXPECT_EQ(ManagedUserService::MANUAL_ALLOW,
-            managed_user_service_.GetManualBehaviorForURL(kExampleFooNoWWWURL));
+            managed_user_service_->GetManualBehaviorForURL(
+                kExampleFooNoWWWURL));
   EXPECT_EQ(ManagedUserService::MANUAL_ALLOW,
-            managed_user_service_.GetManualBehaviorForURL(kBlurpURL));
+            managed_user_service_->GetManualBehaviorForURL(kBlurpURL));
   EXPECT_EQ(ManagedUserService::MANUAL_NONE,
-            managed_user_service_.GetManualBehaviorForURL(kMooseURL));
+            managed_user_service_->GetManualBehaviorForURL(kMooseURL));
 }
 
 class ManagedUserServiceExtensionTest : public ExtensionServiceTestBase {
@@ -181,14 +185,15 @@
 };
 
 TEST_F(ManagedUserServiceExtensionTest, NoContentPacks) {
-  ManagedUserService managed_user_service(profile_.get());
-  managed_user_service.Init();
+  ManagedUserService* managed_user_service =
+      ManagedUserServiceFactory::GetForProfile(profile_.get());
+  managed_user_service->Init();
   ManagedModeURLFilter* url_filter =
-      managed_user_service.GetURLFilterForUIThread();
+      managed_user_service->GetURLFilterForUIThread();
 
   GURL url("http://youtube.com");
   ScopedVector<ManagedModeSiteList> site_lists =
-      GetActiveSiteLists(&managed_user_service);
+      GetActiveSiteLists(managed_user_service);
   ASSERT_EQ(0u, site_lists.size());
   EXPECT_EQ(ManagedModeURLFilter::ALLOW,
             url_filter->GetFilteringBehaviorForURL(url));
diff --git a/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc b/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
index 1e85475..24410c2 100644
--- a/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
+++ b/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
@@ -8,6 +8,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/test/test_timeouts.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/infobars/infobar.h"
 #include "chrome/browser/infobars/infobar_service.h"
@@ -16,7 +17,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/content_settings_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/media/chrome_webrtc_browsertest.cc b/chrome/browser/media/chrome_webrtc_browsertest.cc
index fe63cd6..2b6eb8e 100644
--- a/chrome/browser/media/chrome_webrtc_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_browsertest.cc
@@ -2,24 +2,32 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/command_line.h"
 #include "base/file_util.h"
 #include "base/path_service.h"
 #include "base/process_util.h"
+#include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/test/test_timeouts.h"
 #include "base/time/time.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/infobar.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/media/media_stream_infobar_delegate.h"
+#include "chrome/browser/media/webrtc_log_uploader.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "chrome/test/ui/ui_test.h"
+#include "content/public/browser/browser_message_filter.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/browser/render_process_host.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 
@@ -33,11 +41,39 @@
 static const char kMainWebrtcTestHtmlPage[] =
     "/webrtc/webrtc_jsep01_test.html";
 
+static const char kTestLoggingSessionId[] = "0123456789abcdef";
+
 // Top-level integration test for WebRTC. Requires a real webcam and microphone
 // on the running system. This test is not meant to run in the main browser
 // test suite since normal tester machines do not have webcams.
 class WebrtcBrowserTest : public InProcessBrowserTest {
  public:
+  // See comment in test where this class is used for purpose.
+  class BrowserMessageFilter : public content::BrowserMessageFilter {
+   public:
+    explicit BrowserMessageFilter(
+        const base::Closure& on_channel_closing)
+        : on_channel_closing_(on_channel_closing) {}
+
+    virtual void OnChannelClosing() OVERRIDE {
+      // Posting on the file thread ensures that the callback is run after
+      // WebRtcLogUploader::UploadLog has finished. See also comment in
+      // MANUAL_RunsAudioVideoWebRTCCallInTwoTabsWithLogging test.
+      content::BrowserThread::PostTask(content::BrowserThread::FILE,
+          FROM_HERE, on_channel_closing_);
+    }
+
+    virtual bool OnMessageReceived(const IPC::Message& message,
+                                   bool* message_was_ok) OVERRIDE {
+      return false;
+    }
+
+  private:
+    virtual ~BrowserMessageFilter() {}
+
+    base::Closure on_channel_closing_;
+  };
+
   WebrtcBrowserTest() : peerconnection_server_(0) {}
 
   virtual void SetUp() OVERRIDE {
@@ -137,9 +173,14 @@
   }
 
   void EstablishCall(content::WebContents* from_tab,
-                     content::WebContents* to_tab) {
+                     content::WebContents* to_tab,
+                     bool enable_logging = false) {
+    std::string javascript = enable_logging ?
+        base::StringPrintf("preparePeerConnection(\"%s\")",
+            kTestLoggingSessionId) :
+        "preparePeerConnection(false)";
     EXPECT_EQ("ok-peerconnection-created",
-              ExecuteJavascript("preparePeerConnection()", from_tab));
+              ExecuteJavascript(javascript, from_tab));
     EXPECT_EQ("ok-added",
               ExecuteJavascript("addLocalStream()", from_tab));
     EXPECT_EQ("ok-negotiating",
@@ -199,7 +240,7 @@
     EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &peerconnection_server));
     peerconnection_server = peerconnection_server.Append(kPeerConnectionServer);
 
-    EXPECT_TRUE(file_util::PathExists(peerconnection_server)) <<
+    EXPECT_TRUE(base::PathExists(peerconnection_server)) <<
         "Missing peerconnection_server. You must build "
         "it so it ends up next to the browser test binary.";
     EXPECT_TRUE(base::LaunchProcess(
@@ -301,3 +342,173 @@
   AssertNoAsynchronousErrors(left_tab);
   AssertNoAsynchronousErrors(right_tab);
 }
+
+// Tests WebRTC diagnostic logging. Sets up the browser to save the multipart
+// contents to a buffer instead of uploading it, then verifies it after a call.
+// Example of multipart contents:
+// ------**--yradnuoBgoLtrapitluMklaTelgooG--**----
+// Content-Disposition: form-data; name="prod"
+//
+// Chrome_Linux
+// ------**--yradnuoBgoLtrapitluMklaTelgooG--**----
+// Content-Disposition: form-data; name="ver"
+//
+// 30.0.1554.0
+// ------**--yradnuoBgoLtrapitluMklaTelgooG--**----
+// Content-Disposition: form-data; name="guid"
+//
+// 0
+// ------**--yradnuoBgoLtrapitluMklaTelgooG--**----
+// Content-Disposition: form-data; name="type"
+//
+// webrtc_log
+// ------**--yradnuoBgoLtrapitluMklaTelgooG--**----
+// Content-Disposition: form-data; name="app_session_id"
+//
+// 0123456789abcdef
+// ------**--yradnuoBgoLtrapitluMklaTelgooG--**----
+// Content-Disposition: form-data; name="url"
+//
+// http://127.0.0.1:43213/webrtc/webrtc_jsep01_test.html
+// ------**--yradnuoBgoLtrapitluMklaTelgooG--**----
+// Content-Disposition: form-data; name="webrtc_log"; filename="webrtc_log.gz"
+// Content-Type: application/gzip
+//
+// <compressed data (zip)>
+// ------**--yradnuoBgoLtrapitluMklaTelgooG--**------
+IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
+                       MANUAL_RunsAudioVideoWebRTCCallInTwoTabsWithLogging) {
+  EXPECT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+  // Add command line switch that forces allowing log uploads.
+  CommandLine* command_line = CommandLine::ForCurrentProcess();
+  command_line->AppendSwitch(switches::kEnableMetricsReportingForTesting);
+
+  // Tell the uploader to save the multipart to a buffer instead of uploading.
+  std::string multipart;
+  g_browser_process->webrtc_log_uploader()->
+      OverrideUploadWithBufferForTesting(&multipart);
+  ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage));
+  content::WebContents* left_tab =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  GetUserMedia(left_tab);
+
+  chrome::AddBlankTabAt(browser(), -1, true);
+  content::WebContents* right_tab =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage));
+  GetUserMedia(right_tab);
+
+  ConnectToPeerConnectionServer("peer 1", left_tab);
+  ConnectToPeerConnectionServer("peer 2", right_tab);
+
+  EstablishCall(left_tab, right_tab, true);
+
+  AssertNoAsynchronousErrors(left_tab);
+  AssertNoAsynchronousErrors(right_tab);
+
+  StartDetectingVideo(left_tab, "remote-view");
+  StartDetectingVideo(right_tab, "remote-view");
+
+  WaitForVideoToPlay(left_tab);
+  WaitForVideoToPlay(right_tab);
+
+  HangUp(left_tab);
+  WaitUntilHangupVerified(left_tab);
+  WaitUntilHangupVerified(right_tab);
+
+  AssertNoAsynchronousErrors(left_tab);
+  AssertNoAsynchronousErrors(right_tab);
+
+  // Uploading (or storing to our buffer in our test case) is triggered when
+  // the tab is closed. We must ensure that WebRtcLogUploader::UploadLog, which
+  // runs on the FILE thread, has finished after closing the tab before
+  // continuing.
+  // 1. Add a filter which just acts as a listener. It's added after
+  //    WebRtcLoggingHandlerHost, which is the filter that posts a task for
+  //    WebRtcLogUploader::UploadLog. So it's guarantueed to be removed after
+  //    WebRtcLoggingHandlerHost.
+  // 2. When the filter goes away post a task on the file thread to signal the
+  //    event.
+  base::WaitableEvent ipc_channel_closed(false, false);
+  left_tab->GetRenderProcessHost()->GetChannel()->AddFilter(
+      new BrowserMessageFilter(base::Bind(
+          &base::WaitableEvent::Signal,
+          base::Unretained(&ipc_channel_closed))));
+  chrome::CloseWebContents(browser(), left_tab, false);
+  ASSERT_TRUE(ipc_channel_closed.TimedWait(TestTimeouts::action_timeout()));
+
+  const char boundary[] = "------**--yradnuoBgoLtrapitluMklaTelgooG--**----";
+
+  // Remove the compressed data, it may contain "\r\n". Just verify that its
+  // size is > 0.
+  const char zip_content_type[] = "Content-Type: application/gzip";
+  size_t zip_pos = multipart.find(&zip_content_type[0]);
+  ASSERT_NE(std::string::npos, zip_pos);
+  // Move pos to where the zip begins. - 1 to remove '\0', + 4 for two "\r\n".
+  zip_pos += sizeof(zip_content_type) + 3;
+  size_t zip_length = multipart.find(boundary, zip_pos);
+  ASSERT_NE(std::string::npos, zip_length);
+  // Calculate length, adjust for a "\r\n".
+  zip_length -= zip_pos + 2;
+  ASSERT_GT(zip_length, 0u);
+  multipart.erase(zip_pos, zip_length);
+
+  // Check the multipart contents.
+  std::vector<std::string> multipart_lines;
+  base::SplitStringUsingSubstr(multipart, "\r\n", &multipart_lines);
+  ASSERT_EQ(31, static_cast<int>(multipart_lines.size()));
+
+  EXPECT_STREQ(&boundary[0], multipart_lines[0].c_str());
+  EXPECT_STREQ("Content-Disposition: form-data; name=\"prod\"",
+               multipart_lines[1].c_str());
+  EXPECT_TRUE(multipart_lines[2].empty());
+  EXPECT_NE(std::string::npos, multipart_lines[3].find("Chrome"));
+
+  EXPECT_STREQ(&boundary[0], multipart_lines[4].c_str());
+  EXPECT_STREQ("Content-Disposition: form-data; name=\"ver\"",
+               multipart_lines[5].c_str());
+  EXPECT_TRUE(multipart_lines[6].empty());
+  // Just check that the version contains a dot.
+  EXPECT_NE(std::string::npos, multipart_lines[7].find('.'));
+
+  EXPECT_STREQ(&boundary[0], multipart_lines[8].c_str());
+  EXPECT_STREQ("Content-Disposition: form-data; name=\"guid\"",
+               multipart_lines[9].c_str());
+  EXPECT_TRUE(multipart_lines[10].empty());
+  EXPECT_STREQ("0", multipart_lines[11].c_str());
+
+  EXPECT_STREQ(&boundary[0], multipart_lines[12].c_str());
+  EXPECT_STREQ("Content-Disposition: form-data; name=\"type\"",
+               multipart_lines[13].c_str());
+  EXPECT_TRUE(multipart_lines[14].empty());
+  EXPECT_STREQ("webrtc_log", multipart_lines[15].c_str());
+
+  EXPECT_STREQ(&boundary[0], multipart_lines[16].c_str());
+  EXPECT_STREQ("Content-Disposition: form-data; name=\"app_session_id\"",
+               multipart_lines[17].c_str());
+  EXPECT_TRUE(multipart_lines[18].empty());
+  EXPECT_STREQ(kTestLoggingSessionId, multipart_lines[19].c_str());
+
+  EXPECT_STREQ(&boundary[0], multipart_lines[20].c_str());
+  EXPECT_STREQ("Content-Disposition: form-data; name=\"url\"",
+               multipart_lines[21].c_str());
+  EXPECT_TRUE(multipart_lines[22].empty());
+  EXPECT_NE(std::string::npos,
+            multipart_lines[23].find(&kMainWebrtcTestHtmlPage[0]));
+
+  EXPECT_STREQ(&boundary[0], multipart_lines[24].c_str());
+  EXPECT_STREQ("Content-Disposition: form-data; name=\"webrtc_log\";"
+               " filename=\"webrtc_log.gz\"",
+               multipart_lines[25].c_str());
+  EXPECT_STREQ("Content-Type: application/gzip",
+               multipart_lines[26].c_str());
+  EXPECT_TRUE(multipart_lines[27].empty());
+  EXPECT_TRUE(multipart_lines[28].empty());  // The removed zip part.
+  std::string final_delimiter = boundary;
+  final_delimiter += "--";
+  EXPECT_STREQ(final_delimiter.c_str(), multipart_lines[29].c_str());
+  EXPECT_TRUE(multipart_lines[30].empty());
+}
diff --git a/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc b/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
index 68f9057..8e5b3e4 100644
--- a/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
@@ -10,6 +10,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/test/test_timeouts.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/infobar.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/media/media_stream_infobar_delegate.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -109,12 +109,12 @@
     InProcessBrowserTest::SetUp();
 
     // Ensure we have the stuff we need.
-    EXPECT_TRUE(file_util::PathExists(GetWorkingDir()))
+    EXPECT_TRUE(base::PathExists(GetWorkingDir()))
         << "Cannot find the working directory for the reference video and "
            "the temporary files:" << GetWorkingDir().value();
     base::FilePath reference_file =
         GetWorkingDir().Append(kReferenceYuvFileName);
-    EXPECT_TRUE(file_util::PathExists(reference_file))
+    EXPECT_TRUE(base::PathExists(reference_file))
         << "Cannot find the reference file to be used for video quality "
         << "comparison: " << reference_file.value();
   }
@@ -144,9 +144,9 @@
     base::FilePath path_to_data_handler =
         GetSourceDir().Append(FILE_PATH_LITERAL("chrome/test/functional"));
 
-    EXPECT_TRUE(file_util::PathExists(pywebsocket_server))
+    EXPECT_TRUE(base::PathExists(pywebsocket_server))
         << "Fatal: missing pywebsocket server.";
-    EXPECT_TRUE(file_util::PathExists(path_to_data_handler))
+    EXPECT_TRUE(base::PathExists(path_to_data_handler))
         << "Fatal: missing data handler for pywebsocket server.";
 
     AppendToPythonPath(path_pywebsocket_dir);
@@ -277,7 +277,7 @@
                               const base::FilePath& captured_video_filename) {
     base::FilePath path_to_converter = base::MakeAbsoluteFilePath(
         GetBrowserDir().Append(kArgbToI420ConverterExecutable));
-    EXPECT_TRUE(file_util::PathExists(path_to_converter))
+    EXPECT_TRUE(base::PathExists(path_to_converter))
         << "Missing ARGB->I420 converter: should be in "
         << path_to_converter.value();
 
@@ -315,9 +315,9 @@
     base::FilePath path_to_compare_script = GetSourceDir().Append(
         FILE_PATH_LITERAL("third_party/webrtc/tools/compare_videos.py"));
 
-    EXPECT_TRUE(file_util::PathExists(path_to_analyzer))
+    EXPECT_TRUE(base::PathExists(path_to_analyzer))
         << "Missing frame analyzer: should be in " << path_to_analyzer.value();
-    EXPECT_TRUE(file_util::PathExists(path_to_compare_script))
+    EXPECT_TRUE(base::PathExists(path_to_compare_script))
         << "Missing video compare script: should be in "
         << path_to_compare_script.value();
 
@@ -427,7 +427,7 @@
     base::FilePath peerconnection_server =
         GetBrowserDir().Append(kPeerConnectionServer);
 
-    EXPECT_TRUE(file_util::PathExists(peerconnection_server))
+    EXPECT_TRUE(base::PathExists(peerconnection_server))
         << "Missing peerconnection_server. You must build "
            "it so it ends up next to the browser test binary.";
     EXPECT_TRUE(base::LaunchProcess(CommandLine(peerconnection_server),
@@ -466,12 +466,8 @@
   scoped_ptr<base::Environment> environment_;
 };
 
-#if defined(OS_WIN)
 // Broken on Win: failing to start pywebsocket_server. http://crbug.com/255499.
 #define MAYBE_MANUAL_TestVGAVideoQuality DISABLED_MANUAL_TestVGAVideoQuality
-#else
-#define MAYBE_MANUAL_TestVGAVideoQuality MANUAL_TestVGAVideoQuality
-#endif
 
 IN_PROC_BROWSER_TEST_F(WebrtcVideoQualityBrowserTest,
                        MAYBE_MANUAL_TestVGAVideoQuality) {
diff --git a/chrome/browser/media/media_capture_devices_dispatcher.cc b/chrome/browser/media/media_capture_devices_dispatcher.cc
index 788d79d..6d49f98 100644
--- a/chrome/browser/media/media_capture_devices_dispatcher.cc
+++ b/chrome/browser/media/media_capture_devices_dispatcher.cc
@@ -40,20 +40,17 @@
 
 namespace {
 
-const content::MediaStreamDevice* FindDefaultDeviceWithId(
+// Finds a device in |devices| that has |device_id|, or NULL if not found.
+const content::MediaStreamDevice* FindDeviceWithId(
     const content::MediaStreamDevices& devices,
     const std::string& device_id) {
-  if (devices.empty())
-    return NULL;
-
   content::MediaStreamDevices::const_iterator iter = devices.begin();
   for (; iter != devices.end(); ++iter) {
     if (iter->id == device_id) {
       return &(*iter);
     }
   }
-
-  return &(*devices.begin());
+  return NULL;
 };
 
 // This is a short-term solution to allow testing of the the Screen Capture API
@@ -103,6 +100,11 @@
       is_device_enumeration_disabled_(false),
       media_stream_capture_indicator_(new MediaStreamCaptureIndicator()),
       audio_stream_indicator_(new AudioStreamIndicator()) {
+  // MediaCaptureDevicesDispatcher is a singleton. It should be created on
+  // UI thread. Otherwise, it will not receive
+  // content::NOTIFICATION_WEB_CONTENTS_DESTROYED, and that will result in
+  // possible use after free.
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   notifications_registrar_.Add(
       this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
       content::NotificationService::AllSources());
@@ -110,7 +112,7 @@
 
 MediaCaptureDevicesDispatcher::~MediaCaptureDevicesDispatcher() {}
 
-void MediaCaptureDevicesDispatcher::RegisterUserPrefs(
+void MediaCaptureDevicesDispatcher::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterStringPref(
       prefs::kDefaultAudioCaptureDevice,
@@ -237,7 +239,6 @@
   content::MediaStreamDevices devices;
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
-  PrefService* prefs = profile->GetPrefs();
 
 #if defined(OS_ANDROID)
   // Tab capture is not supported on Android.
@@ -259,9 +260,7 @@
   } else if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE &&
              extension->HasAPIPermission(
                  extensions::APIPermission::kAudioCapture)) {
-    std::string default_device =
-        prefs->GetString(prefs::kDefaultAudioCaptureDevice);
-    GetRequestedDevice(default_device, true, false, &devices);
+    GetDefaultDevicesForProfile(profile, true, false, &devices);
   }
 
   if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE &&
@@ -272,9 +271,7 @@
         content::MEDIA_TAB_VIDEO_CAPTURE, std::string(), std::string()));
   } else if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE &&
        extension->HasAPIPermission(extensions::APIPermission::kVideoCapture)) {
-    std::string default_device = prefs->GetString(
-        prefs::kDefaultVideoCaptureDevice);
-    GetRequestedDevice(default_device, false, true, &devices);
+    GetDefaultDevicesForProfile(profile, false, true, &devices);
   }
 
   scoped_ptr<content::MediaStreamUI> ui;
@@ -292,7 +289,7 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   RequestsQueue& queue = pending_requests_[web_contents];
-  queue.push(PendingAccessRequest(request, callback));
+  queue.push_back(PendingAccessRequest(request, callback));
 
   // If this is the only request then show the infobar.
   if (queue.size() == 1)
@@ -333,8 +330,11 @@
   }
 
   RequestsQueue& queue(it->second);
+  if (queue.empty())
+    return;
+
   content::MediaResponseCallback callback = queue.front().callback;
-  queue.pop();
+  queue.pop_front();
 
   if (!queue.empty()) {
     // Post a task to process next queued request. It has to be done
@@ -361,37 +361,61 @@
   std::string default_device;
   if (audio) {
     default_device = prefs->GetString(prefs::kDefaultAudioCaptureDevice);
-    GetRequestedDevice(default_device, true, false, devices);
+    const content::MediaStreamDevice* device =
+        GetRequestedAudioDevice(default_device);
+    if (!device)
+      device = GetFirstAvailableAudioDevice();
+    if (device)
+      devices->push_back(*device);
   }
 
   if (video) {
     default_device = prefs->GetString(prefs::kDefaultVideoCaptureDevice);
-    GetRequestedDevice(default_device, false, true, devices);
+    const content::MediaStreamDevice* device =
+        GetRequestedVideoDevice(default_device);
+    if (!device)
+      device = GetFirstAvailableVideoDevice();
+    if (device)
+      devices->push_back(*device);
   }
 }
 
-void MediaCaptureDevicesDispatcher::GetRequestedDevice(
-    const std::string& requested_device_id,
-    bool audio,
-    bool video,
-    content::MediaStreamDevices* devices) {
+const content::MediaStreamDevice*
+MediaCaptureDevicesDispatcher::GetRequestedAudioDevice(
+    const std::string& requested_audio_device_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(audio || video);
+  const content::MediaStreamDevices& audio_devices = GetAudioCaptureDevices();
+  const content::MediaStreamDevice* const device =
+      FindDeviceWithId(audio_devices, requested_audio_device_id);
+  return device;
+}
 
-  if (audio) {
-    const content::MediaStreamDevices& audio_devices = GetAudioCaptureDevices();
-    const content::MediaStreamDevice* const device =
-        FindDefaultDeviceWithId(audio_devices, requested_device_id);
-    if (device)
-      devices->push_back(*device);
-  }
-  if (video) {
-    const content::MediaStreamDevices& video_devices = GetVideoCaptureDevices();
-    const content::MediaStreamDevice* const device =
-        FindDefaultDeviceWithId(video_devices, requested_device_id);
-    if (device)
-      devices->push_back(*device);
-  }
+const content::MediaStreamDevice*
+MediaCaptureDevicesDispatcher::GetFirstAvailableAudioDevice() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  const content::MediaStreamDevices& audio_devices = GetAudioCaptureDevices();
+  if (audio_devices.empty())
+    return NULL;
+  return &(*audio_devices.begin());
+}
+
+const content::MediaStreamDevice*
+MediaCaptureDevicesDispatcher::GetRequestedVideoDevice(
+    const std::string& requested_video_device_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  const content::MediaStreamDevices& video_devices = GetVideoCaptureDevices();
+  const content::MediaStreamDevice* const device =
+      FindDeviceWithId(video_devices, requested_video_device_id);
+  return device;
+}
+
+const content::MediaStreamDevice*
+MediaCaptureDevicesDispatcher::GetFirstAvailableVideoDevice() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  const content::MediaStreamDevices& video_devices = GetVideoCaptureDevices();
+  if (video_devices.empty())
+    return NULL;
+  return &(*video_devices.begin());
 }
 
 void MediaCaptureDevicesDispatcher::DisableDeviceEnumerationForTesting() {
@@ -429,6 +453,7 @@
 void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged(
     int render_process_id,
     int render_view_id,
+    int page_request_id,
     const content::MediaStreamDevice& device,
     content::MediaRequestState state) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -436,8 +461,8 @@
       BrowserThread::UI, FROM_HERE,
       base::Bind(
           &MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread,
-          base::Unretained(this), render_process_id, render_view_id, device,
-          state));
+          base::Unretained(this), render_process_id, render_view_id,
+          page_request_id, device, state));
 
 }
 
@@ -471,8 +496,30 @@
 void MediaCaptureDevicesDispatcher::UpdateMediaRequestStateOnUIThread(
     int render_process_id,
     int render_view_id,
+    int page_request_id,
     const content::MediaStreamDevice& device,
     content::MediaRequestState state) {
+  // Cancel the request.
+  if (state == content::MEDIA_REQUEST_STATE_CLOSING) {
+    bool found = false;
+    for (RequestsQueues::iterator rqs_it = pending_requests_.begin();
+         rqs_it != pending_requests_.end(); ++rqs_it) {
+      RequestsQueue& queue = rqs_it->second;
+      for (RequestsQueue::iterator it = queue.begin();
+           it != queue.end(); ++it) {
+        if (it->request.render_process_id == render_process_id &&
+            it->request.render_view_id == render_view_id &&
+            it->request.page_request_id == page_request_id) {
+          queue.erase(it);
+          found = true;
+          break;
+        }
+      }
+      if (found)
+        break;
+    }
+  }
+
   FOR_EACH_OBSERVER(Observer, observers_,
                     OnRequestUpdate(render_process_id,
                                     render_view_id,
diff --git a/chrome/browser/media/media_capture_devices_dispatcher.h b/chrome/browser/media/media_capture_devices_dispatcher.h
index 1f0937e..6054a30 100644
--- a/chrome/browser/media/media_capture_devices_dispatcher.h
+++ b/chrome/browser/media/media_capture_devices_dispatcher.h
@@ -5,7 +5,8 @@
 #ifndef CHROME_BROWSER_MEDIA_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_
 #define CHROME_BROWSER_MEDIA_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_
 
-#include <queue>
+#include <deque>
+#include <map>
 
 #include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
@@ -59,7 +60,7 @@
   static MediaCaptureDevicesDispatcher* GetInstance();
 
   // Registers the preferences related to Media Stream default devices.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Methods for observers. Called on UI thread.
   // Observers should add themselves on construction and remove themselves
@@ -78,8 +79,9 @@
       const content::MediaResponseCallback& callback,
       const extensions::Extension* extension);
 
-  // Helper to get the default devices which can be used by the media request,
-  // if the return list is empty, it means there is no available device on the
+  // Helper to get the default devices which can be used by the media request.
+  // Uses the first available devices if the default devices are not available.
+  // If the return list is empty, it means there is no available device on the
   // OS.
   // Called on the UI thread.
   void GetDefaultDevicesForProfile(Profile* profile,
@@ -87,14 +89,17 @@
                                    bool video,
                                    content::MediaStreamDevices* devices);
 
-  // Helper for picking the device that was requested for an OpenDevice request.
-  // If the device requested is not available it will revert to using the first
-  // available one instead or will return an empty list if no devices of the
-  // requested kind are present.
-  void GetRequestedDevice(const std::string& requested_device_id,
-                          bool audio,
-                          bool video,
-                          content::MediaStreamDevices* devices);
+  // Helpers for picking particular requested devices, identified by raw id.
+  // If the device requested is not available it will return NULL.
+  const content::MediaStreamDevice*
+  GetRequestedAudioDevice(const std::string& requested_audio_device_id);
+  const content::MediaStreamDevice*
+  GetRequestedVideoDevice(const std::string& requested_video_device_id);
+
+  // Returns the first available audio or video device, or NULL if no devices
+  // are available.
+  const content::MediaStreamDevice* GetFirstAvailableAudioDevice();
+  const content::MediaStreamDevice* GetFirstAvailableVideoDevice();
 
   // Unittests that do not require actual device enumeration should call this
   // API on the singleton. It is safe to call this multiple times on the
@@ -109,6 +114,7 @@
   virtual void OnMediaRequestStateChanged(
       int render_process_id,
       int render_view_id,
+      int page_request_id,
       const content::MediaStreamDevice& device,
       content::MediaRequestState state) OVERRIDE;
   virtual void OnAudioStreamPlayingChanged(
@@ -132,7 +138,8 @@
     content::MediaStreamRequest request;
     content::MediaResponseCallback callback;
   };
-  typedef std::queue<PendingAccessRequest> RequestsQueue;
+  typedef std::deque<PendingAccessRequest> RequestsQueue;
+  typedef std::map<content::WebContents*, RequestsQueue> RequestsQueues;
 
   MediaCaptureDevicesDispatcher();
   virtual ~MediaCaptureDevicesDispatcher();
@@ -167,6 +174,7 @@
   void UpdateMediaRequestStateOnUIThread(
       int render_process_id,
       int render_view_id,
+      int page_request_id,
       const content::MediaStreamDevice& device,
       content::MediaRequestState state);
 
@@ -186,7 +194,7 @@
   // Flag used by unittests to disable device enumeration.
   bool is_device_enumeration_disabled_;
 
-  std::map<content::WebContents*, RequestsQueue> pending_requests_;
+  RequestsQueues pending_requests_;
 
   scoped_refptr<MediaStreamCaptureIndicator> media_stream_capture_indicator_;
 
diff --git a/chrome/browser/media/media_stream_devices_controller.cc b/chrome/browser/media/media_stream_devices_controller.cc
index 8c56abe..04c5cf6 100644
--- a/chrome/browser/media/media_stream_devices_controller.cc
+++ b/chrome/browser/media/media_stream_devices_controller.cc
@@ -95,7 +95,7 @@
 }
 
 // static
-void MediaStreamDevicesController::RegisterUserPrefs(
+void MediaStreamDevicesController::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* prefs) {
   prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed,
                              true,
@@ -138,8 +138,9 @@
     return true;
   }
 
-  // Check if any block exception has been made for this request.
-  if (IsRequestBlockedByDefault()) {
+  // Filter any parts of the request that have been blocked by default and deny
+  // it if nothing is left to accept.
+  if (FilterBlockedByDefaultDevices() == 0) {
     Deny(false);
     return true;
   }
@@ -165,18 +166,66 @@
   content::MediaStreamDevices devices;
   if (microphone_requested_ || webcam_requested_) {
     switch (request_.request_type) {
-      case content::MEDIA_OPEN_DEVICE:
+      case content::MEDIA_OPEN_DEVICE: {
+        const content::MediaStreamDevice* device = NULL;
         // For open device request pick the desired device or fall back to the
         // first available of the given type.
-        MediaCaptureDevicesDispatcher::GetInstance()->GetRequestedDevice(
-            request_.requested_device_id,
-            request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE,
-            request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE,
-            &devices);
+        if (request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
+          device = MediaCaptureDevicesDispatcher::GetInstance()->
+              GetRequestedAudioDevice(request_.requested_audio_device_id);
+          // TODO(wjia): Confirm this is the intended behavior.
+          if (!device) {
+            device = MediaCaptureDevicesDispatcher::GetInstance()->
+                GetFirstAvailableAudioDevice();
+          }
+        } else if (request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
+          // Pepper API opens only one device at a time.
+          device = MediaCaptureDevicesDispatcher::GetInstance()->
+              GetRequestedVideoDevice(request_.requested_video_device_id);
+          // TODO(wjia): Confirm this is the intended behavior.
+          if (!device) {
+            device = MediaCaptureDevicesDispatcher::GetInstance()->
+                GetFirstAvailableVideoDevice();
+          }
+        }
+        if (device)
+          devices.push_back(*device);
         break;
-      case content::MEDIA_DEVICE_ACCESS:
-      case content::MEDIA_GENERATE_STREAM:
-      case content::MEDIA_ENUMERATE_DEVICES:
+      } case content::MEDIA_GENERATE_STREAM: {
+        bool needs_audio_device = microphone_requested_;
+        bool needs_video_device = webcam_requested_;
+
+        // Get the exact audio or video device if an id is specified.
+        if (!request_.requested_audio_device_id.empty()) {
+          const content::MediaStreamDevice* audio_device =
+              MediaCaptureDevicesDispatcher::GetInstance()->
+                  GetRequestedAudioDevice(request_.requested_audio_device_id);
+          if (audio_device) {
+            devices.push_back(*audio_device);
+            needs_audio_device = false;
+          }
+        }
+        if (!request_.requested_video_device_id.empty()) {
+          const content::MediaStreamDevice* video_device =
+              MediaCaptureDevicesDispatcher::GetInstance()->
+                  GetRequestedVideoDevice(request_.requested_video_device_id);
+          if (video_device) {
+            devices.push_back(*video_device);
+            needs_video_device = false;
+          }
+        }
+
+        // If either or both audio and video devices were requested but not
+        // specified by id, get the default devices.
+        if (needs_audio_device || needs_video_device) {
+          MediaCaptureDevicesDispatcher::GetInstance()->
+              GetDefaultDevicesForProfile(profile_,
+                                          needs_audio_device,
+                                          needs_video_device,
+                                          &devices);
+        }
+        break;
+      } case content::MEDIA_DEVICE_ACCESS:
         // Get the default devices for the request.
         MediaCaptureDevicesDispatcher::GetInstance()->
             GetDefaultDevicesForProfile(profile_,
@@ -184,6 +233,10 @@
                                         webcam_requested_,
                                         &devices);
         break;
+      case content::MEDIA_ENUMERATE_DEVICES:
+        // Do nothing.
+        NOTREACHED();
+        break;
     }
 
     // TODO(raymes): We currently set the content permission for non-https
@@ -310,14 +363,16 @@
   return true;
 }
 
-bool MediaStreamDevicesController::IsRequestBlockedByDefault() const {
+int MediaStreamDevicesController::FilterBlockedByDefaultDevices() {
+  int requested_devices = microphone_requested_ + webcam_requested_;
   if (microphone_requested_ &&
       profile_->GetHostContentSettingsMap()->GetContentSetting(
           request_.security_origin,
           request_.security_origin,
           CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
-          NO_RESOURCE_IDENTIFIER) != CONTENT_SETTING_BLOCK) {
-    return false;
+          NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) {
+    requested_devices--;
+    microphone_requested_ = false;
   }
 
   if (webcam_requested_ &&
@@ -325,11 +380,12 @@
           request_.security_origin,
           request_.security_origin,
           CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
-          NO_RESOURCE_IDENTIFIER) != CONTENT_SETTING_BLOCK) {
-    return false;
+          NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) {
+    requested_devices--;
+    webcam_requested_ = false;
   }
 
-  return true;
+  return requested_devices;
 }
 
 bool MediaStreamDevicesController::IsDefaultMediaAccessBlocked() const {
diff --git a/chrome/browser/media/media_stream_devices_controller.h b/chrome/browser/media/media_stream_devices_controller.h
index d423d74..6291385 100644
--- a/chrome/browser/media/media_stream_devices_controller.h
+++ b/chrome/browser/media/media_stream_devices_controller.h
@@ -33,7 +33,7 @@
   // and the code cleaner.  crbug.com/244389.
 
   // Registers the prefs backing the audio and video policies.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Public method to be called before creating the MediaStreamInfoBarDelegate.
   // This function will check the content settings exceptions and take the
@@ -63,9 +63,12 @@
   // access before, otherwise returns false.
   bool IsRequestAllowedByDefault() const;
 
-  // Returns true if the media access for the origin of the request has been
-  // blocked before. Otherwise returns false.
-  bool IsRequestBlockedByDefault() const;
+  // Check if any device of the request has been blocked for the origin of the
+  // request and clears |microphone_requested_| or |webcam_requested_| flags if
+  // they are not allowed anymore. Returns the number of devices that are
+  // allowed after this step. If the count reaches zero the request can be
+  // denied completely, else it still has to be partially fullfilled.
+  int FilterBlockedByDefaultDevices();
 
   // Returns true if the media section in content settings is set to
   // |CONTENT_SETTING_BLOCK|, otherwise returns false.
diff --git a/chrome/browser/media/media_stream_infobar_delegate.cc b/chrome/browser/media/media_stream_infobar_delegate.cc
index 36bfa97..3fc8661 100644
--- a/chrome/browser/media/media_stream_infobar_delegate.cc
+++ b/chrome/browser/media/media_stream_infobar_delegate.cc
@@ -28,7 +28,8 @@
 
 }  // namespace
 
-MediaStreamInfoBarDelegate::~MediaStreamInfoBarDelegate() {}
+MediaStreamInfoBarDelegate::~MediaStreamInfoBarDelegate() {
+}
 
 // static
 bool MediaStreamInfoBarDelegate::Create(
@@ -42,32 +43,28 @@
 
   InfoBarService* infobar_service =
       InfoBarService::FromWebContents(web_contents);
-  InfoBarDelegate* old_infobar = NULL;
-  for (size_t i = 0; i < infobar_service->infobar_count(); ++i) {
-    old_infobar =
-        infobar_service->infobar_at(i)->AsMediaStreamInfoBarDelegate();
-    if (old_infobar)
-      break;
-  }
   scoped_ptr<InfoBarDelegate> infobar(
-      new MediaStreamInfoBarDelegate(infobar_service, controller.release()));
-  if (old_infobar)
-    infobar_service->ReplaceInfoBar(old_infobar, infobar.Pass());
-  else
-    infobar_service->AddInfoBar(infobar.Pass());
-
+      new MediaStreamInfoBarDelegate(infobar_service, controller.Pass()));
+  for (size_t i = 0; i < infobar_service->infobar_count(); ++i) {
+    InfoBarDelegate* old_infobar =
+        infobar_service->infobar_at(i)->AsMediaStreamInfoBarDelegate();
+    if (old_infobar) {
+      infobar_service->ReplaceInfoBar(old_infobar, infobar.Pass());
+      return true;
+    }
+  }
+  infobar_service->AddInfoBar(infobar.Pass());
   return true;
 }
 
 MediaStreamInfoBarDelegate::MediaStreamInfoBarDelegate(
     InfoBarService* infobar_service,
-    MediaStreamDevicesController* controller)
+    scoped_ptr<MediaStreamDevicesController> controller)
     : ConfirmInfoBarDelegate(infobar_service),
-      controller_(controller) {
+      controller_(controller.Pass()) {
   DCHECK(controller_.get());
   DCHECK(controller_->has_audio() || controller_->has_video());
 }
-
 void MediaStreamInfoBarDelegate::InfoBarDismissed() {
   // Deny the request if the infobar was closed with the 'x' button, since
   // we don't want WebRTC to be waiting for an answer that will never come.
@@ -132,14 +129,13 @@
 
 bool MediaStreamInfoBarDelegate::LinkClicked(
     WindowOpenDisposition disposition) {
-  content::OpenURLParams params(
+  web_contents()->OpenURL(content::OpenURLParams(
       google_util::AppendGoogleLocaleParam(
           GURL(chrome::kMediaAccessLearnMoreUrl)),
       content::Referrer(),
       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
       content::PAGE_TRANSITION_LINK,
-      false);
-  web_contents()->OpenURL(params);
+      false));
 
   return false;  // Do not dismiss the info bar.
 }
diff --git a/chrome/browser/media/media_stream_infobar_delegate.h b/chrome/browser/media/media_stream_infobar_delegate.h
index 146c7536..02992e7 100644
--- a/chrome/browser/media/media_stream_infobar_delegate.h
+++ b/chrome/browser/media/media_stream_infobar_delegate.h
@@ -35,10 +35,9 @@
   friend class WebrtcBrowserTest;
   friend class WebrtcVideoQualityBrowserTest;
 
-  // MediaStreamInfoBarDelegate takes the ownership of the |controller|.
   MediaStreamInfoBarDelegate(
       InfoBarService* infobar_service,
-      MediaStreamDevicesController* controller);
+      scoped_ptr<MediaStreamDevicesController> controller);
 
   // ConfirmInfoBarDelegate:
   virtual void InfoBarDismissed() OVERRIDE;
diff --git a/chrome/browser/media/webrtc_log_uploader.cc b/chrome/browser/media/webrtc_log_uploader.cc
index f88e382..268afd6 100644
--- a/chrome/browser/media/webrtc_log_uploader.cc
+++ b/chrome/browser/media/webrtc_log_uploader.cc
@@ -4,9 +4,17 @@
 
 #include "chrome/browser/media/webrtc_log_uploader.h"
 
+#include "base/file_util.h"
+#include "base/files/file_path.h"
 #include "base/logging.h"
-#include "base/shared_memory.h"
+#include "base/memory/shared_memory.h"
+#include "base/path_service.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
+#include "base/time/time.h"
+#include "chrome/browser/media/webrtc_log_upload_list.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/partial_circular_buffer.h"
 #include "content/public/browser/browser_thread.h"
@@ -24,6 +32,7 @@
 
 const int kLogCountLimit = 5;
 const uint32 kIntermediateCompressionBufferBytes = 256 * 1024;  // 256 KB
+const int kLogListLimitLines = 50;
 
 const char kUploadURL[] = "https://clients2.google.com/cr/report";
 const char kUploadContentType[] = "multipart/form-data";
@@ -33,14 +42,22 @@
 }  // namespace
 
 WebRtcLogUploader::WebRtcLogUploader()
-    : log_count_(0) {
+    : log_count_(0),
+      post_data_(NULL) {
+  base::FilePath log_dir_path;
+  PathService::Get(chrome::DIR_USER_DATA, &log_dir_path);
+  upload_list_path_ =
+      log_dir_path.AppendASCII(WebRtcLogUploadList::kWebRtcLogListFilename);
 }
 
-WebRtcLogUploader::~WebRtcLogUploader() {
-}
+WebRtcLogUploader::~WebRtcLogUploader() {}
 
 void WebRtcLogUploader::OnURLFetchComplete(
     const net::URLFetcher* source) {
+  int response_code = source->GetResponseCode();
+  std::string report_id;
+  if (response_code == 200 && source->GetResponseAsString(&report_id))
+    AddUploadedLogInfoToUploadListFile(report_id);
 }
 
 void WebRtcLogUploader::OnURLFetchUploadProgress(
@@ -69,6 +86,14 @@
   SetupMultipart(&post_data, reinterpret_cast<uint8*>(shared_memory->memory()),
                  length, app_session_id, app_url);
 
+  // If a test has set the test string pointer, write to it and skip uploading.
+  // This will be removed when the browser test for this feature is fully done
+  // according to the test plan. See http://crbug.com/257329.
+  if (post_data_) {
+    *post_data_ = post_data;
+    return;
+  }
+
   std::string content_type = kUploadContentType;
   content_type.append("; boundary=");
   content_type.append(kMultipartBoundary);
@@ -196,3 +221,37 @@
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   --log_count_;
 }
+
+void WebRtcLogUploader::AddUploadedLogInfoToUploadListFile(
+    const std::string& report_id) {
+  std::string contents;
+
+  if (base::PathExists(upload_list_path_)) {
+    bool read_ok = file_util::ReadFileToString(upload_list_path_, &contents);
+    DPCHECK(read_ok);
+
+    // Limit the number of log entries to |kLogListLimitLines| - 1, to make room
+    // for the new entry. Each line including the last ends with a '\n', so hit
+    // n will be before line n-1 (from the back).
+    int lf_count = 0;
+    int i = contents.size() - 1;
+    for (; i >= 0 && lf_count < kLogListLimitLines; --i) {
+      if (contents[i] == '\n')
+        ++lf_count;
+    }
+    if (lf_count >= kLogListLimitLines) {
+      // + 1 to compensate for the for loop decrease before the conditional
+      // check and + 1 to get the length.
+      contents.erase(0, i + 2);
+    }
+  }
+
+  // Write the Unix time and report ID to the log list file.
+  base::Time time_now = base::Time::Now();
+  contents += base::DoubleToString(time_now.ToDoubleT()) +
+              "," + report_id + '\n';
+
+  int written = file_util::WriteFile(upload_list_path_, &contents[0],
+                                     contents.size());
+  DPCHECK(written == static_cast<int>(contents.size()));
+}
diff --git a/chrome/browser/media/webrtc_log_uploader.h b/chrome/browser/media/webrtc_log_uploader.h
index 60225c6..ecd53d6 100644
--- a/chrome/browser/media/webrtc_log_uploader.h
+++ b/chrome/browser/media/webrtc_log_uploader.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/platform_file.h"
 #include "net/url_request/url_fetcher_delegate.h"
@@ -27,8 +28,9 @@
 class WebRtcLogURLRequestContextGetter;
 
 // WebRtcLogUploader uploads WebRTC logs, keeps count of how many logs have
-// been started and denies further logs if a limit is reached. There must only
-// be one object of this type.
+// been started and denies further logs if a limit is reached. It also adds
+// the timestamp and report ID of the uploded log to a text file. There must
+// only be one object of this type.
 class WebRtcLogUploader : public net::URLFetcherDelegate {
  public:
   WebRtcLogUploader();
@@ -53,7 +55,16 @@
                  const std::string& app_session_id,
                  const std::string& app_url);
 
+  // For testing purposes. If called, the multipart will not be uploaded, but
+  // written to |post_data_| instead.
+  void OverrideUploadWithBufferForTesting(std::string* post_data) {
+    post_data_ = post_data;
+  }
+
  private:
+  FRIEND_TEST_ALL_PREFIXES(WebRtcLogUploaderTest,
+                           AddUploadedLogInfoToUploadListFile);
+
   // Sets up a multipart body to be uploaded. The body is produced according
   // to RFC 2046.
   void SetupMultipart(std::string* post_data, uint8* log_buffer,
@@ -67,7 +78,26 @@
   void ResizeForNextOutput(std::string* post_data, z_stream* stream);
   void DecreaseLogCount();
 
+  // Append information (time and report ID) about this uploaded log to a log
+  // list file, limited to |kLogListLimitLines| entries. This list is used for
+  // viewing the uploaded logs under chrome://webrtc-logs, see
+  // WebRtcLogUploadList. The list has the format
+  // time,id
+  // time,id
+  // etc.
+  // where each line represents an uploaded log and "time" is Unix time.
+  void AddUploadedLogInfoToUploadListFile(const std::string& report_id);
+
+  void SetUploadPathForTesting(const base::FilePath& path) {
+    upload_list_path_ = path;
+  }
+
   int log_count_;
+  base::FilePath upload_list_path_;
+
+  // For testing purposes, see OverrideUploadWithBufferForTesting. Only accessed
+  // on the FILE thread.
+  std::string* post_data_;
 
   DISALLOW_COPY_AND_ASSIGN(WebRtcLogUploader);
 };
diff --git a/chrome/browser/media/webrtc_log_uploader_unittest.cc b/chrome/browser/media/webrtc_log_uploader_unittest.cc
new file mode 100644
index 0000000..2c8ecc0
--- /dev/null
+++ b/chrome/browser/media/webrtc_log_uploader_unittest.cc
@@ -0,0 +1,113 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/platform_file.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/time/time.h"
+#include "chrome/browser/media/webrtc_log_uploader.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+const char kTestReportId[] = "123456789";
+const char kTestTime[] = "987654321";
+
+class WebRtcLogUploaderTest : public testing::Test {
+ public:
+  WebRtcLogUploaderTest() {}
+
+  bool VerifyNumberOfLinesAndContentsOfLastLine(int expected_lines) {
+    std::string contents;
+    int read = file_util::ReadFileToString(test_list_path_, &contents);
+    EXPECT_GT(read, 0);
+    if (read <= 0)
+      return false;
+
+    // Verify expected number of lines. Since every line should end with '\n',
+    // there should be an additional empty line after splitting.
+    std::vector<std::string> lines;
+    base::SplitString(contents, '\n', &lines);
+    EXPECT_EQ(expected_lines + 1, static_cast<int>(lines.size()));
+    if (expected_lines + 1 != static_cast<int>(lines.size()))
+      return false;
+    EXPECT_TRUE(lines[expected_lines].empty());
+
+    // Verify the contents of the last line. The time (line_parts[0]) is the
+    // time when the info was written to the file which we don't know, so just
+    // verify that it's not empty.
+    std::vector<std::string> line_parts;
+    base::SplitString(lines[expected_lines - 1], ',', &line_parts);
+    EXPECT_EQ(2u, line_parts.size());
+    if (2u != line_parts.size())
+      return false;
+    EXPECT_FALSE(line_parts[0].empty());
+    EXPECT_STREQ(kTestReportId, line_parts[1].c_str());
+
+    return true;
+  }
+
+  bool AddLinesToTestFile(int number_of_lines) {
+    int flags = base::PLATFORM_FILE_OPEN |
+                base::PLATFORM_FILE_APPEND;
+    base::PlatformFileError error = base::PLATFORM_FILE_OK;
+    base::PlatformFile test_list_file =
+        base::CreatePlatformFile(test_list_path_, flags, NULL, &error);
+    EXPECT_EQ(base::PLATFORM_FILE_OK, error);
+    EXPECT_NE(base::kInvalidPlatformFileValue, test_list_file);
+    if (base::PLATFORM_FILE_OK != error ||
+        base::kInvalidPlatformFileValue == test_list_file) {
+      return false;
+    }
+
+    for (int i = 0; i < number_of_lines; ++i) {
+      EXPECT_EQ(static_cast<int>(sizeof(kTestTime)) - 1,
+                base::WritePlatformFileAtCurrentPos(test_list_file,
+                                                    kTestTime,
+                                                    sizeof(kTestTime) - 1));
+      EXPECT_EQ(1, base::WritePlatformFileAtCurrentPos(test_list_file, ",", 1));
+      EXPECT_EQ(static_cast<int>(sizeof(kTestReportId)) - 1,
+                base::WritePlatformFileAtCurrentPos(test_list_file,
+                                                    kTestReportId,
+                                                    sizeof(kTestReportId) - 1));
+      EXPECT_EQ(1, base::WritePlatformFileAtCurrentPos(test_list_file,
+                                                       "\n", 1));
+    }
+    EXPECT_TRUE(base::ClosePlatformFile(test_list_file));
+
+    return true;
+  }
+
+  base::FilePath test_list_path_;
+};
+
+TEST_F(WebRtcLogUploaderTest, AddUploadedLogInfoToUploadListFile) {
+  // Get a temporary filename. We don't want the file to exist to begin with
+  // since that's the normal use case, hence the delete.
+  ASSERT_TRUE(file_util::CreateTemporaryFile(&test_list_path_));
+  EXPECT_TRUE(base::DeleteFile(test_list_path_, false));
+  scoped_ptr<WebRtcLogUploader> webrtc_log_uploader_(
+      new WebRtcLogUploader());
+  webrtc_log_uploader_->SetUploadPathForTesting(test_list_path_);
+
+  webrtc_log_uploader_->AddUploadedLogInfoToUploadListFile(kTestReportId);
+  webrtc_log_uploader_->AddUploadedLogInfoToUploadListFile(kTestReportId);
+  ASSERT_TRUE(VerifyNumberOfLinesAndContentsOfLastLine(2));
+
+  const int expected_line_limit = 50;
+  ASSERT_TRUE(AddLinesToTestFile(expected_line_limit - 2));
+  ASSERT_TRUE(VerifyNumberOfLinesAndContentsOfLastLine(expected_line_limit));
+
+  webrtc_log_uploader_->AddUploadedLogInfoToUploadListFile(kTestReportId);
+  ASSERT_TRUE(VerifyNumberOfLinesAndContentsOfLastLine(expected_line_limit));
+
+  ASSERT_TRUE(AddLinesToTestFile(10));
+  ASSERT_TRUE(VerifyNumberOfLinesAndContentsOfLastLine(60));
+
+  webrtc_log_uploader_->AddUploadedLogInfoToUploadListFile(kTestReportId);
+  ASSERT_TRUE(VerifyNumberOfLinesAndContentsOfLastLine(expected_line_limit));
+}
diff --git a/chrome/browser/media/webrtc_logging_handler_host.cc b/chrome/browser/media/webrtc_logging_handler_host.cc
index c46ae32..7339ccf 100644
--- a/chrome/browser/media/webrtc_logging_handler_host.cc
+++ b/chrome/browser/media/webrtc_logging_handler_host.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "base/bind.h"
+#include "base/command_line.h"
 #include "base/cpu.h"
 #include "base/logging.h"
 #include "base/prefs/pref_service.h"
@@ -16,6 +17,7 @@
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
 #include "chrome/browser/media/webrtc_log_uploader.h"
+#include "chrome/common/chrome_switches.h"
 #include "chrome/common/media/webrtc_logging_messages.h"
 #include "chrome/common/partial_circular_buffer.h"
 #include "chrome/common/pref_names.h"
@@ -124,26 +126,28 @@
 void WebRtcLoggingHandlerHost::OpenLogIfAllowed() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  bool enabled = false;
-
   // If the user permits metrics reporting / crash uploading with the checkbox
   // in the prefs, we allow uploading automatically. We disable uploading
-  // completely for non-official builds.
+  // completely for non-official builds. Allowing can be forced with a flag.
+  const CommandLine* command_line = CommandLine::ForCurrentProcess();
+  if (!command_line->HasSwitch(switches::kEnableMetricsReportingForTesting)) {
+    bool enabled = false;
 #if defined(GOOGLE_CHROME_BUILD)
 #if defined(OS_CHROMEOS)
-  chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref,
-                                            &enabled);
+    chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref,
+                                              &enabled);
 #elif defined(OS_ANDROID)
-  // Android has its own settings for metrics / crash uploading.
-  enabled = g_browser_process->local_state()->GetBoolean(
-      prefs::kCrashReportingEnabled);
+    // Android has its own settings for metrics / crash uploading.
+    enabled = g_browser_process->local_state()->GetBoolean(
+        prefs::kCrashReportingEnabled);
 #else
-  enabled = g_browser_process->local_state()->GetBoolean(
-      prefs::kMetricsReportingEnabled);
+    enabled = g_browser_process->local_state()->GetBoolean(
+        prefs::kMetricsReportingEnabled);
 #endif  // #if defined(OS_CHROMEOS)
 #endif  // defined(GOOGLE_CHROME_BUILD)
-  if (!enabled)
-    return;
+    if (!enabled)
+      return;
+  }
 
   if (!g_browser_process->webrtc_log_uploader()->ApplyForStartLogging())
     return;
@@ -165,7 +169,7 @@
     return;
   }
 
-  if (!shared_memory_->ShareToProcess(peer_handle(),
+  if (!shared_memory_->ShareToProcess(PeerHandle(),
                                      &foreign_memory_handle_)) {
     Send(new WebRtcLoggingMsg_OpenLogFailed());
     return;
diff --git a/chrome/browser/media/webrtc_logging_handler_host.h b/chrome/browser/media/webrtc_logging_handler_host.h
index 940b6e6..a35bf3e 100644
--- a/chrome/browser/media/webrtc_logging_handler_host.h
+++ b/chrome/browser/media/webrtc_logging_handler_host.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_MEDIA_WEBRTC_LOGGING_HANDLER_HOST_H_
 
 #include "base/basictypes.h"
-#include "base/shared_memory.h"
+#include "base/memory/shared_memory.h"
 #include "content/public/browser/browser_message_filter.h"
 
 namespace net {
diff --git a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc
index 29a7f11..9f4b4a0 100644
--- a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc
+++ b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.cc
@@ -8,7 +8,7 @@
 #include "base/file_util.h"
 #include "base/single_thread_task_runner.h"
 #include "base/task_runner_util.h"
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
 #include "chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h"
 #include "chrome/browser/media_galleries/fileapi/mtp_device_map_service.h"
@@ -44,7 +44,7 @@
   DCHECK(IsOnIOThread(context));
   return MTPDeviceMapService::GetInstance()->GetMTPDeviceAsyncDelegate(
       context->GetUserValue<std::string>(
-          MediaFileSystemMountPointProvider::kMTPDeviceDelegateURLKey));
+          MediaFileSystemBackend::kMTPDeviceDelegateURLKey));
 }
 
 // Called on a blocking pool thread to create a snapshot file to hold the
@@ -81,33 +81,29 @@
   return new DeviceMediaAsyncFileUtil(profile_path);
 }
 
-bool DeviceMediaAsyncFileUtil::CreateOrOpen(
+void DeviceMediaAsyncFileUtil::CreateOrOpen(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& url,
     int file_flags,
     const CreateOrOpenCallback& callback) {
   DCHECK(IsOnIOThread(context.get()));
   NOTIMPLEMENTED();
-  if (!callback.is_null()) {
-    base::PlatformFile invalid_file = base::kInvalidPlatformFileValue;
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY,
-                 base::PassPlatformFile(&invalid_file));
-  }
-  return true;
+  base::PlatformFile invalid_file = base::kInvalidPlatformFileValue;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY,
+               base::PassPlatformFile(&invalid_file),
+               base::Closure());
 }
 
-bool DeviceMediaAsyncFileUtil::EnsureFileExists(
+void DeviceMediaAsyncFileUtil::EnsureFileExists(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& url,
     const EnsureFileExistsCallback& callback) {
   DCHECK(IsOnIOThread(context.get()));
   NOTIMPLEMENTED();
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, false);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, false);
 }
 
-bool DeviceMediaAsyncFileUtil::CreateDirectory(
+void DeviceMediaAsyncFileUtil::CreateDirectory(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& url,
     bool exclusive,
@@ -115,12 +111,10 @@
     const StatusCallback& callback) {
   DCHECK(IsOnIOThread(context.get()));
   NOTIMPLEMENTED();
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
 }
 
-bool DeviceMediaAsyncFileUtil::GetFileInfo(
+void DeviceMediaAsyncFileUtil::GetFileInfo(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& url,
     const GetFileInfoCallback& callback) {
@@ -129,7 +123,7 @@
   if (!delegate) {
     OnGetFileInfoError(callback, url.path(),
                        base::PLATFORM_FILE_ERROR_NOT_FOUND);
-    return true;
+    return;
   }
   delegate->GetFileInfo(
       url.path(),
@@ -141,10 +135,9 @@
                  weak_ptr_factory_.GetWeakPtr(),
                  callback,
                  url.path()));
-  return true;
 }
 
-bool DeviceMediaAsyncFileUtil::ReadDirectory(
+void DeviceMediaAsyncFileUtil::ReadDirectory(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& url,
     const ReadDirectoryCallback& callback) {
@@ -152,7 +145,7 @@
   MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(context.get());
   if (!delegate) {
     OnReadDirectoryError(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
-    return true;
+    return;
   }
   delegate->ReadDirectory(
       url.path(),
@@ -162,10 +155,9 @@
       base::Bind(&DeviceMediaAsyncFileUtil::OnReadDirectoryError,
                  weak_ptr_factory_.GetWeakPtr(),
                  callback));
-  return true;
 }
 
-bool DeviceMediaAsyncFileUtil::Touch(
+void DeviceMediaAsyncFileUtil::Touch(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& url,
     const base::Time& last_access_time,
@@ -173,92 +165,76 @@
     const StatusCallback& callback) {
   DCHECK(IsOnIOThread(context.get()));
   NOTIMPLEMENTED();
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
 }
 
-bool DeviceMediaAsyncFileUtil::Truncate(
+void DeviceMediaAsyncFileUtil::Truncate(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& url,
     int64 length,
     const StatusCallback& callback) {
   DCHECK(IsOnIOThread(context.get()));
   NOTIMPLEMENTED();
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
 }
 
-bool DeviceMediaAsyncFileUtil::CopyFileLocal(
+void DeviceMediaAsyncFileUtil::CopyFileLocal(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& src_url,
     const FileSystemURL& dest_url,
     const StatusCallback& callback) {
   DCHECK(IsOnIOThread(context.get()));
   NOTIMPLEMENTED();
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
 }
 
-bool DeviceMediaAsyncFileUtil::MoveFileLocal(
+void DeviceMediaAsyncFileUtil::MoveFileLocal(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& src_url,
     const FileSystemURL& dest_url,
     const StatusCallback& callback) {
   DCHECK(IsOnIOThread(context.get()));
   NOTIMPLEMENTED();
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
 }
 
-bool DeviceMediaAsyncFileUtil::CopyInForeignFile(
+void DeviceMediaAsyncFileUtil::CopyInForeignFile(
     scoped_ptr<FileSystemOperationContext> context,
     const base::FilePath& src_file_path,
     const FileSystemURL& dest_url,
     const StatusCallback& callback) {
   DCHECK(IsOnIOThread(context.get()));
   NOTIMPLEMENTED();
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
 }
 
-bool DeviceMediaAsyncFileUtil::DeleteFile(
+void DeviceMediaAsyncFileUtil::DeleteFile(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& url,
     const StatusCallback& callback) {
   DCHECK(IsOnIOThread(context.get()));
   NOTIMPLEMENTED();
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
 }
 
-bool DeviceMediaAsyncFileUtil::DeleteDirectory(
+void DeviceMediaAsyncFileUtil::DeleteDirectory(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& url,
     const StatusCallback& callback) {
   DCHECK(IsOnIOThread(context.get()));
   NOTIMPLEMENTED();
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
 }
 
-bool DeviceMediaAsyncFileUtil::DeleteRecursively(
+void DeviceMediaAsyncFileUtil::DeleteRecursively(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& url,
     const StatusCallback& callback) {
   DCHECK(IsOnIOThread(context.get()));
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
 }
 
-bool DeviceMediaAsyncFileUtil::CreateSnapshotFile(
+void DeviceMediaAsyncFileUtil::CreateSnapshotFile(
     scoped_ptr<FileSystemOperationContext> context,
     const FileSystemURL& url,
     const CreateSnapshotFileCallback& callback) {
@@ -266,11 +242,11 @@
   MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(context.get());
   if (!delegate) {
     OnCreateSnapshotFileError(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND);
-    return true;
+    return;
   }
   base::FilePath* snapshot_file_path = new base::FilePath;
   base::SequencedTaskRunner* task_runner = context->task_runner();
-  return task_runner->PostTaskAndReply(
+  const bool success = task_runner->PostTaskAndReply(
           FROM_HERE,
           base::Bind(&CreateSnapshotFileOnBlockingPool,
                      url.path(),
@@ -282,6 +258,7 @@
                      callback,
                      url.path(),
                      base::Owned(snapshot_file_path)));
+  DCHECK(success);
 }
 
 DeviceMediaAsyncFileUtil::DeviceMediaAsyncFileUtil(
@@ -295,8 +272,7 @@
     // TODO(thestig): remove this.
     const base::FilePath& platform_path,
     const base::PlatformFileInfo& file_info) {
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_OK, file_info);
+  callback.Run(base::PLATFORM_FILE_OK, file_info);
 }
 
 void DeviceMediaAsyncFileUtil::OnGetFileInfoError(
@@ -304,23 +280,20 @@
     // TODO(thestig): remove this.
     const base::FilePath& platform_path,
     base::PlatformFileError error) {
-  if (!callback.is_null())
-    callback.Run(error, base::PlatformFileInfo());
+  callback.Run(error, base::PlatformFileInfo());
 }
 
 void DeviceMediaAsyncFileUtil::OnDidReadDirectory(
     const AsyncFileUtil::ReadDirectoryCallback& callback,
     const AsyncFileUtil::EntryList& file_list,
     bool has_more) {
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_OK, file_list, has_more);
+  callback.Run(base::PLATFORM_FILE_OK, file_list, has_more);
 }
 
 void DeviceMediaAsyncFileUtil::OnReadDirectoryError(
     const AsyncFileUtil::ReadDirectoryCallback& callback,
     base::PlatformFileError error) {
-  if (!callback.is_null())
-    callback.Run(error, AsyncFileUtil::EntryList(), false /*no more*/);
+  callback.Run(error, AsyncFileUtil::EntryList(), false /*no more*/);
 }
 
 void DeviceMediaAsyncFileUtil::OnDidCreateSnapshotFile(
@@ -328,8 +301,6 @@
     base::SequencedTaskRunner* media_task_runner,
     const base::PlatformFileInfo& file_info,
     const base::FilePath& platform_path) {
-  if (callback.is_null())
-    return;
   base::PostTaskAndReplyWithResult(
       media_task_runner,
       FROM_HERE,
@@ -349,8 +320,6 @@
     const base::PlatformFileInfo& file_info,
     scoped_refptr<webkit_blob::ShareableFileReference> platform_file,
     base::PlatformFileError error) {
-  if (callback.is_null())
-    return;
   base::FilePath platform_path(platform_file.get()->path());
   if (error != base::PLATFORM_FILE_OK)
     platform_file = NULL;
@@ -360,9 +329,8 @@
 void DeviceMediaAsyncFileUtil::OnCreateSnapshotFileError(
     const AsyncFileUtil::CreateSnapshotFileCallback& callback,
     base::PlatformFileError error) {
-  if (!callback.is_null())
-    callback.Run(error, base::PlatformFileInfo(), base::FilePath(),
-                 scoped_refptr<ShareableFileReference>());
+  callback.Run(error, base::PlatformFileInfo(), base::FilePath(),
+               scoped_refptr<ShareableFileReference>());
 }
 
 void DeviceMediaAsyncFileUtil::OnSnapshotFileCreatedRunTask(
diff --git a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h
index e109c64..f6e2e9f 100644
--- a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h
+++ b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h
@@ -34,68 +34,68 @@
   static DeviceMediaAsyncFileUtil* Create(const base::FilePath& profile_path);
 
   // AsyncFileUtil overrides.
-  virtual bool CreateOrOpen(
+  virtual void CreateOrOpen(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       int file_flags,
       const CreateOrOpenCallback& callback) OVERRIDE;
-  virtual bool EnsureFileExists(
+  virtual void EnsureFileExists(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const EnsureFileExistsCallback& callback) OVERRIDE;
-  virtual bool CreateDirectory(
+  virtual void CreateDirectory(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       bool exclusive,
       bool recursive,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool GetFileInfo(
+  virtual void GetFileInfo(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const GetFileInfoCallback& callback) OVERRIDE;
-  virtual bool ReadDirectory(
+  virtual void ReadDirectory(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const ReadDirectoryCallback& callback) OVERRIDE;
-  virtual bool Touch(
+  virtual void Touch(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const base::Time& last_access_time,
       const base::Time& last_modified_time,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool Truncate(
+  virtual void Truncate(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       int64 length,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool CopyFileLocal(
+  virtual void CopyFileLocal(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& src_url,
       const fileapi::FileSystemURL& dest_url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool MoveFileLocal(
+  virtual void MoveFileLocal(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& src_url,
       const fileapi::FileSystemURL& dest_url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool CopyInForeignFile(
+  virtual void CopyInForeignFile(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const base::FilePath& src_file_path,
       const fileapi::FileSystemURL& dest_url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool DeleteFile(
+  virtual void DeleteFile(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool DeleteDirectory(
+  virtual void DeleteDirectory(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool DeleteRecursively(
+  virtual void DeleteRecursively(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool CreateSnapshotFile(
+  virtual void CreateSnapshotFile(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const CreateSnapshotFileCallback& callback) OVERRIDE;
diff --git a/chrome/browser/media_galleries/fileapi/itunes_data_provider.cc b/chrome/browser/media_galleries/fileapi/itunes_data_provider.cc
index 951e91b..5ecc091 100644
--- a/chrome/browser/media_galleries/fileapi/itunes_data_provider.cc
+++ b/chrome/browser/media_galleries/fileapi/itunes_data_provider.cc
@@ -13,12 +13,12 @@
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/thread_restrictions.h"
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
 #include "chrome/common/itunes_library.h"
 #include "content/public/browser/browser_thread.h"
 
-using chrome::MediaFileSystemMountPointProvider;
+using chrome::MediaFileSystemBackend;
 
 namespace itunes {
 
@@ -72,7 +72,7 @@
                       const base::FilePath& path,
                       bool error) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
-  MediaFileSystemMountPointProvider::MediaTaskRunner()->PostTask(
+  MediaFileSystemBackend::MediaTaskRunner()->PostTask(
       FROM_HERE, base::Bind(callback, path, error));
 }
 
@@ -89,7 +89,7 @@
       base::Bind(&OnLibraryChanged, library_changed_callback));
   if (!success)
     LOG(ERROR) << "Adding watch for " << library_path.value() << " failed";
-  MediaFileSystemMountPointProvider::MediaTaskRunner()->PostTask(
+  MediaFileSystemBackend::MediaTaskRunner()->PostTask(
       FROM_HERE,
       base::Bind(watch_started_callback, base::Passed(&watcher)));
 }
@@ -100,7 +100,7 @@
     : library_path_(library_path),
       needs_refresh_(true),
       is_valid_(false) {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(!library_path_.empty());
 
   content::BrowserThread::PostTask(
@@ -117,7 +117,7 @@
 // TODO(vandebo): add a file watch that resets |needs_refresh_| when the
 // file changes.
 void ITunesDataProvider::RefreshData(const ReadyCallback& ready_callback) {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   if (!needs_refresh_) {
     ready_callback.Run(is_valid_);
     return;
@@ -135,14 +135,14 @@
 }
 
 bool ITunesDataProvider::KnownArtist(const ArtistName& artist) const {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(is_valid_);
   return ContainsKey(library_, artist);
 }
 
 bool ITunesDataProvider::KnownAlbum(const ArtistName& artist,
                                     const AlbumName& album) const {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(is_valid_);
   Library::const_iterator library_it = library_.find(artist);
   if (library_it == library_.end())
@@ -153,7 +153,7 @@
 base::FilePath ITunesDataProvider::GetTrackLocation(
     const ArtistName& artist, const AlbumName& album,
     const TrackName& track) const {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(is_valid_);
   Library::const_iterator library_it = library_.find(artist);
   if (library_it == library_.end())
@@ -171,7 +171,7 @@
 
 std::set<ITunesDataProvider::ArtistName>
 ITunesDataProvider::GetArtistNames() const {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(is_valid_);
   std::set<ArtistName> result;
   Library::const_iterator it;
@@ -183,7 +183,7 @@
 
 std::set<ITunesDataProvider::AlbumName> ITunesDataProvider::GetAlbumNames(
     const ArtistName& artist) const {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(is_valid_);
   std::set<AlbumName> result;
   Library::const_iterator artist_lookup = library_.find(artist);
@@ -200,7 +200,7 @@
 
 ITunesDataProvider::Album ITunesDataProvider::GetAlbum(
     const ArtistName& artist, const AlbumName& album) const {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(is_valid_);
   Album result;
   Library::const_iterator artist_lookup = library_.find(artist);
@@ -215,7 +215,7 @@
 // static
 void ITunesDataProvider::OnLibraryWatchStartedCallback(
     scoped_ptr<base::FilePathWatcher> library_watcher) {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   ITunesDataProvider* provider =
       chrome::ImportedMediaGalleryRegistry::ITunesDataProvider();
   if (provider)
@@ -225,7 +225,7 @@
 // static
 void ITunesDataProvider::OnLibraryChangedCallback(const base::FilePath& path,
                                                   bool error) {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   ITunesDataProvider* provider =
       chrome::ImportedMediaGalleryRegistry::ITunesDataProvider();
   if (provider)
@@ -237,7 +237,7 @@
     const ReadyCallback& ready_callback,
     bool result,
     const parser::Library& library) {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   ITunesDataProvider* provider =
       chrome::ImportedMediaGalleryRegistry::ITunesDataProvider();
   if (!provider) {
@@ -249,13 +249,13 @@
 
 void ITunesDataProvider::OnLibraryWatchStarted(
     scoped_ptr<base::FilePathWatcher> library_watcher) {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   library_watcher_.reset(library_watcher.release());
 }
 
 void ITunesDataProvider::OnLibraryChanged(const base::FilePath& path,
                                           bool error) {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK_EQ(library_path_.value(), path.value());
   if (error)
     LOG(ERROR) << "Error watching " << library_path_.value();
@@ -265,7 +265,7 @@
 void ITunesDataProvider::OnLibraryParsed(const ReadyCallback& ready_callback,
                                          bool result,
                                          const parser::Library& library) {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   is_valid_ = result;
   if (is_valid_) {
     library_.clear();
diff --git a/chrome/browser/media_galleries/fileapi/itunes_file_util.cc b/chrome/browser/media_galleries/fileapi/itunes_file_util.cc
index d5e247d..88c32a1 100644
--- a/chrome/browser/media_galleries/fileapi/itunes_file_util.cc
+++ b/chrome/browser/media_galleries/fileapi/itunes_file_util.cc
@@ -12,7 +12,7 @@
 #include "base/file_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h"
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
 #include "content/public/browser/browser_thread.h"
@@ -197,7 +197,7 @@
       return base::PLATFORM_FILE_ERROR_NOT_FOUND;
     chrome::MediaPathFilter* path_filter =
         context->GetUserValue<chrome::MediaPathFilter*>(
-            chrome::MediaFileSystemMountPointProvider::kMediaPathFilterKey);
+            chrome::MediaFileSystemBackend::kMediaPathFilterKey);
     ITunesDataProvider::Album::const_iterator it;
     for (it = album.begin(); it != album.end(); ++it) {
       base::PlatformFileInfo file_info;
diff --git a/chrome/browser/media_galleries/fileapi/itunes_finder_win.cc b/chrome/browser/media_galleries/fileapi/itunes_finder_win.cc
index 40016a5..ea02812 100644
--- a/chrome/browser/media_galleries/fileapi/itunes_finder_win.cc
+++ b/chrome/browser/media_galleries/fileapi/itunes_finder_win.cc
@@ -70,7 +70,7 @@
   base::FilePath library_file =
       music_dir.AppendASCII("iTunes").AppendASCII("iTunes Music Library.xml");
 
-  if (!file_util::PathExists(library_file)) {
+  if (!base::PathExists(library_file)) {
     PostResultToUIThread(std::string());
     return;
   }
@@ -81,7 +81,7 @@
     const base::FilePath& library_file) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
 
-  if (library_file.empty() || !file_util::PathExists(library_file)) {
+  if (library_file.empty() || !base::PathExists(library_file)) {
     TryDefaultLocation();
     return;
   }
diff --git a/chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.cc b/chrome/browser/media_galleries/fileapi/media_file_system_backend.cc
similarity index 81%
rename from chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.cc
rename to chrome/browser/media_galleries/fileapi/media_file_system_backend.cc
index 7d65431..308b252 100644
--- a/chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.cc
+++ b/chrome/browser/media_galleries/fileapi/media_file_system_backend.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 
 #include <string>
 
@@ -43,14 +43,14 @@
 
 namespace chrome {
 
-const char MediaFileSystemMountPointProvider::kMediaTaskRunnerName[] =
+const char MediaFileSystemBackend::kMediaTaskRunnerName[] =
     "media-task-runner";
-const char MediaFileSystemMountPointProvider::kMediaPathFilterKey[] =
+const char MediaFileSystemBackend::kMediaPathFilterKey[] =
     "MediaPathFilterKey";
-const char MediaFileSystemMountPointProvider::kMTPDeviceDelegateURLKey[] =
+const char MediaFileSystemBackend::kMTPDeviceDelegateURLKey[] =
     "MTPDeviceDelegateKey";
 
-MediaFileSystemMountPointProvider::MediaFileSystemMountPointProvider(
+MediaFileSystemBackend::MediaFileSystemBackend(
     const base::FilePath& profile_path,
     base::SequencedTaskRunner* media_task_runner)
     : profile_path_(profile_path),
@@ -68,11 +68,11 @@
 {
 }
 
-MediaFileSystemMountPointProvider::~MediaFileSystemMountPointProvider() {
+MediaFileSystemBackend::~MediaFileSystemBackend() {
 }
 
 // static
-bool MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread() {
+bool MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread() {
   base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
   base::SequencedWorkerPool::SequenceToken media_sequence_token =
       pool->GetNamedSequenceToken(kMediaTaskRunnerName);
@@ -81,14 +81,14 @@
 
 // static
 scoped_refptr<base::SequencedTaskRunner>
-MediaFileSystemMountPointProvider::MediaTaskRunner() {
+MediaFileSystemBackend::MediaTaskRunner() {
   base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
   base::SequencedWorkerPool::SequenceToken media_sequence_token =
       pool->GetNamedSequenceToken(kMediaTaskRunnerName);
   return pool->GetSequencedTaskRunner(media_sequence_token);
 }
 
-bool MediaFileSystemMountPointProvider::CanHandleType(
+bool MediaFileSystemBackend::CanHandleType(
     fileapi::FileSystemType type) const {
   switch (type) {
     case fileapi::kFileSystemTypeNativeMedia:
@@ -103,24 +103,28 @@
   }
 }
 
-void MediaFileSystemMountPointProvider::OpenFileSystem(
+void MediaFileSystemBackend::InitializeFileSystem(
     const GURL& origin_url,
     fileapi::FileSystemType type,
     fileapi::OpenFileSystemMode mode,
-    const OpenFileSystemCallback& callback) {
+    fileapi::FileSystemContext* context,
+    const InitializeFileSystemCallback& callback) {
   // We never allow opening a new isolated FileSystem via usual OpenFileSystem.
   base::MessageLoopProxy::current()->PostTask(
       FROM_HERE,
-      base::Bind(callback, base::PLATFORM_FILE_ERROR_SECURITY));
+      base::Bind(callback,
+                 GetFileSystemRootURI(origin_url, type),
+                 GetFileSystemName(origin_url, type),
+                 base::PLATFORM_FILE_ERROR_SECURITY));
 }
 
-fileapi::FileSystemFileUtil* MediaFileSystemMountPointProvider::GetFileUtil(
+fileapi::FileSystemFileUtil* MediaFileSystemBackend::GetFileUtil(
     fileapi::FileSystemType type) {
   NOTREACHED();
   return NULL;
 }
 
-fileapi::AsyncFileUtil* MediaFileSystemMountPointProvider::GetAsyncFileUtil(
+fileapi::AsyncFileUtil* MediaFileSystemBackend::GetAsyncFileUtil(
     fileapi::FileSystemType type) {
   switch (type) {
     case fileapi::kFileSystemTypeNativeMedia:
@@ -140,7 +144,7 @@
 }
 
 fileapi::CopyOrMoveFileValidatorFactory*
-MediaFileSystemMountPointProvider::GetCopyOrMoveFileValidatorFactory(
+MediaFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
     fileapi::FileSystemType type, base::PlatformFileError* error_code) {
   DCHECK(error_code);
   *error_code = base::PLATFORM_FILE_OK;
@@ -160,7 +164,7 @@
 }
 
 fileapi::FileSystemOperation*
-MediaFileSystemMountPointProvider::CreateFileSystemOperation(
+MediaFileSystemBackend::CreateFileSystemOperation(
     const FileSystemURL& url,
     FileSystemContext* context,
     base::PlatformFileError* error_code) const {
@@ -180,7 +184,7 @@
 }
 
 scoped_ptr<webkit_blob::FileStreamReader>
-MediaFileSystemMountPointProvider::CreateFileStreamReader(
+MediaFileSystemBackend::CreateFileStreamReader(
     const FileSystemURL& url,
     int64 offset,
     const base::Time& expected_modification_time,
@@ -192,7 +196,7 @@
 }
 
 scoped_ptr<fileapi::FileStreamWriter>
-MediaFileSystemMountPointProvider::CreateFileStreamWriter(
+MediaFileSystemBackend::CreateFileStreamWriter(
     const FileSystemURL& url,
     int64 offset,
     FileSystemContext* context) const {
@@ -203,18 +207,9 @@
 }
 
 fileapi::FileSystemQuotaUtil*
-MediaFileSystemMountPointProvider::GetQuotaUtil() {
+MediaFileSystemBackend::GetQuotaUtil() {
   // No quota support.
   return NULL;
 }
 
-void MediaFileSystemMountPointProvider::DeleteFileSystem(
-    const GURL& origin_url,
-    fileapi::FileSystemType type,
-    FileSystemContext* context,
-    const DeleteFileSystemCallback& callback) {
-  NOTREACHED();
-  callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
-}
-
 }  // namespace chrome
diff --git a/chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h b/chrome/browser/media_galleries/fileapi/media_file_system_backend.h
similarity index 81%
rename from chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h
rename to chrome/browser/media_galleries/fileapi/media_file_system_backend.h
index dbe18cf..3026664 100644
--- a/chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h
+++ b/chrome/browser/media_galleries/fileapi/media_file_system_backend.h
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_MEDIA_FILE_SYSTEM_MOUNT_POINT_PROVIDER_H_
-#define CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_MEDIA_FILE_SYSTEM_MOUNT_POINT_PROVIDER_H_
+#ifndef CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_MEDIA_FILE_SYSTEM_BACKEND_H_
+#define CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_MEDIA_FILE_SYSTEM_BACKEND_H_
 
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "webkit/browser/fileapi/file_system_mount_point_provider.h"
+#include "webkit/browser/fileapi/file_system_backend.h"
 
 namespace base {
 class SequencedTaskRunner;
@@ -23,28 +23,28 @@
 
 class DeviceMediaAsyncFileUtil;
 
-class MediaFileSystemMountPointProvider
-    : public fileapi::FileSystemMountPointProvider {
+class MediaFileSystemBackend : public fileapi::FileSystemBackend {
  public:
   static const char kMediaTaskRunnerName[];
   static const char kMediaPathFilterKey[];
   static const char kMTPDeviceDelegateURLKey[];
 
-  MediaFileSystemMountPointProvider(
+  MediaFileSystemBackend(
       const base::FilePath& profile_path,
       base::SequencedTaskRunner* media_task_runner);
-  virtual ~MediaFileSystemMountPointProvider();
+  virtual ~MediaFileSystemBackend();
 
   static bool CurrentlyOnMediaTaskRunnerThread();
   static scoped_refptr<base::SequencedTaskRunner> MediaTaskRunner();
 
-  // FileSystemMountPointProvider implementation.
+  // FileSystemBackend implementation.
   virtual bool CanHandleType(fileapi::FileSystemType type) const OVERRIDE;
-  virtual void OpenFileSystem(
+  virtual void InitializeFileSystem(
       const GURL& origin_url,
       fileapi::FileSystemType type,
       fileapi::OpenFileSystemMode mode,
-      const OpenFileSystemCallback& callback) OVERRIDE;
+      fileapi::FileSystemContext* context,
+      const InitializeFileSystemCallback& callback) OVERRIDE;
   virtual fileapi::FileSystemFileUtil* GetFileUtil(
       fileapi::FileSystemType type) OVERRIDE;
   virtual fileapi::AsyncFileUtil* GetAsyncFileUtil(
@@ -67,11 +67,6 @@
       int64 offset,
       fileapi::FileSystemContext* context) const OVERRIDE;
   virtual fileapi::FileSystemQuotaUtil* GetQuotaUtil() OVERRIDE;
-  virtual void DeleteFileSystem(
-      const GURL& origin_url,
-      fileapi::FileSystemType type,
-      fileapi::FileSystemContext* context,
-      const DeleteFileSystemCallback& callback) OVERRIDE;
 
  private:
   // Store the profile path. We need this to create temporary snapshot files.
@@ -90,9 +85,9 @@
   scoped_ptr<fileapi::AsyncFileUtil> itunes_file_util_;
 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
 
-  DISALLOW_COPY_AND_ASSIGN(MediaFileSystemMountPointProvider);
+  DISALLOW_COPY_AND_ASSIGN(MediaFileSystemBackend);
 };
 
 }  // namespace chrome
 
-#endif  // CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_MEDIA_FILE_SYSTEM_MOUNT_POINT_PROVIDER_H_
+#endif  // CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_MEDIA_FILE_SYSTEM_BACKEND_H_
diff --git a/chrome/browser/media_galleries/fileapi/media_file_validator_unittest.cc b/chrome/browser/media_galleries/fileapi/media_file_validator_unittest.cc
index 79d030f..5fde5e4 100644
--- a/chrome/browser/media_galleries/fileapi/media_file_validator_unittest.cc
+++ b/chrome/browser/media_galleries/fileapi/media_file_validator_unittest.cc
@@ -9,19 +9,19 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/message_loop/message_loop.h"
 #include "base/message_loop/message_loop_proxy.h"
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "webkit/browser/fileapi/copy_or_move_file_validator.h"
+#include "webkit/browser/fileapi/file_system_backend.h"
 #include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/browser/fileapi/file_system_mount_point_provider.h"
 #include "webkit/browser/fileapi/file_system_operation_runner.h"
 #include "webkit/browser/fileapi/file_system_url.h"
 #include "webkit/browser/fileapi/isolated_context.h"
 #include "webkit/browser/fileapi/mock_file_system_context.h"
-#include "webkit/browser/fileapi/test_mount_point_provider.h"
+#include "webkit/browser/fileapi/test_file_system_backend.h"
 #include "webkit/common/fileapi/file_system_types.h"
 
 namespace {
@@ -88,10 +88,10 @@
     base::FilePath src_path = base.AppendASCII("src_fs");
     ASSERT_TRUE(file_util::CreateDirectory(src_path));
 
-    ScopedVector<fileapi::FileSystemMountPointProvider> additional_providers;
-    additional_providers.push_back(new fileapi::TestMountPointProvider(
+    ScopedVector<fileapi::FileSystemBackend> additional_providers;
+    additional_providers.push_back(new fileapi::TestFileSystemBackend(
         base::MessageLoopProxy::current().get(), src_path));
-    additional_providers.push_back(new MediaFileSystemMountPointProvider(
+    additional_providers.push_back(new MediaFileSystemBackend(
         base, base::MessageLoopProxy::current().get()));
     file_system_context_ =
         fileapi::CreateFileSystemContextWithAdditionalProvidersForTesting(
diff --git a/chrome/browser/media_galleries/fileapi/native_media_file_util.cc b/chrome/browser/media_galleries/fileapi/native_media_file_util.cc
index 29e33dc..c9e1d6f 100644
--- a/chrome/browser/media_galleries/fileapi/native_media_file_util.cc
+++ b/chrome/browser/media_galleries/fileapi/native_media_file_util.cc
@@ -12,7 +12,7 @@
 #include "base/files/file_enumerator.h"
 #include "base/strings/string_util.h"
 #include "base/task_runner_util.h"
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/base/mime_sniffer.h"
@@ -90,7 +90,7 @@
 MediaPathFilter* GetMediaPathFilter(
     fileapi::FileSystemOperationContext* context) {
   return context->GetUserValue<MediaPathFilter*>(
-          MediaFileSystemMountPointProvider::kMediaPathFilterKey);
+          MediaFileSystemBackend::kMediaPathFilterKey);
 }
 
 }  // namespace
@@ -135,7 +135,7 @@
   return base::PLATFORM_FILE_ERROR_SECURITY;
 }
 
-bool NativeMediaFileUtil::CreateOrOpen(
+void NativeMediaFileUtil::CreateOrOpen(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     int file_flags,
@@ -143,24 +143,20 @@
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   // Only called by NaCl, which should not have access to media file systems.
   base::PlatformFile invalid_file(base::kInvalidPlatformFileValue);
-  if (!callback.is_null()) {
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY,
-                 base::PassPlatformFile(&invalid_file));
-  }
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY,
+               base::PassPlatformFile(&invalid_file),
+               base::Closure());
 }
 
-bool NativeMediaFileUtil::EnsureFileExists(
+void NativeMediaFileUtil::EnsureFileExists(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const EnsureFileExistsCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, false);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, false);
 }
 
-bool NativeMediaFileUtil::CreateDirectory(
+void NativeMediaFileUtil::CreateDirectory(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     bool exclusive,
@@ -168,149 +164,149 @@
     const StatusCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   fileapi::FileSystemOperationContext* context_ptr = context.get();
-  return context_ptr->task_runner()->PostTask(
+  const bool success = context_ptr->task_runner()->PostTask(
       FROM_HERE,
       base::Bind(&NativeMediaFileUtil::CreateDirectoryOnTaskRunnerThread,
                  weak_factory_.GetWeakPtr(), base::Passed(&context),
                  url, exclusive, recursive, callback));
+  DCHECK(success);
 }
 
-bool NativeMediaFileUtil::GetFileInfo(
+void NativeMediaFileUtil::GetFileInfo(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const GetFileInfoCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   fileapi::FileSystemOperationContext* context_ptr = context.get();
-  return context_ptr->task_runner()->PostTask(
+  const bool success = context_ptr->task_runner()->PostTask(
       FROM_HERE,
       base::Bind(&NativeMediaFileUtil::GetFileInfoOnTaskRunnerThread,
                  weak_factory_.GetWeakPtr(), base::Passed(&context),
                  url, callback));
+  DCHECK(success);
 }
 
-bool NativeMediaFileUtil::ReadDirectory(
+void NativeMediaFileUtil::ReadDirectory(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const ReadDirectoryCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   fileapi::FileSystemOperationContext* context_ptr = context.get();
-  return context_ptr->task_runner()->PostTask(
+  const bool success = context_ptr->task_runner()->PostTask(
       FROM_HERE,
       base::Bind(&NativeMediaFileUtil::ReadDirectoryOnTaskRunnerThread,
                  weak_factory_.GetWeakPtr(), base::Passed(&context),
                  url, callback));
+  DCHECK(success);
 }
 
-bool NativeMediaFileUtil::Touch(
+void NativeMediaFileUtil::Touch(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const base::Time& last_access_time,
     const base::Time& last_modified_time,
     const StatusCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
 }
 
-bool NativeMediaFileUtil::Truncate(
+void NativeMediaFileUtil::Truncate(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     int64 length,
     const StatusCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
 }
 
-bool NativeMediaFileUtil::CopyFileLocal(
+void NativeMediaFileUtil::CopyFileLocal(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& src_url,
     const fileapi::FileSystemURL& dest_url,
     const StatusCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   fileapi::FileSystemOperationContext* context_ptr = context.get();
-  return context_ptr->task_runner()->PostTask(
+  const bool success = context_ptr->task_runner()->PostTask(
       FROM_HERE,
       base::Bind(&NativeMediaFileUtil::CopyOrMoveFileLocalOnTaskRunnerThread,
                  weak_factory_.GetWeakPtr(), base::Passed(&context),
                  src_url, dest_url, true /* copy */, callback));
+  DCHECK(success);
 }
 
-bool NativeMediaFileUtil::MoveFileLocal(
+void NativeMediaFileUtil::MoveFileLocal(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& src_url,
     const fileapi::FileSystemURL& dest_url,
     const StatusCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   fileapi::FileSystemOperationContext* context_ptr = context.get();
-  return context_ptr->task_runner()->PostTask(
+  const bool success = context_ptr->task_runner()->PostTask(
       FROM_HERE,
       base::Bind(&NativeMediaFileUtil::CopyOrMoveFileLocalOnTaskRunnerThread,
                  weak_factory_.GetWeakPtr(), base::Passed(&context),
                  src_url, dest_url, false /* copy */, callback));
+  DCHECK(success);
 }
 
-bool NativeMediaFileUtil::CopyInForeignFile(
+void NativeMediaFileUtil::CopyInForeignFile(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const base::FilePath& src_file_path,
     const fileapi::FileSystemURL& dest_url,
     const StatusCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   fileapi::FileSystemOperationContext* context_ptr = context.get();
-  return context_ptr->task_runner()->PostTask(
+  const bool success = context_ptr->task_runner()->PostTask(
       FROM_HERE,
       base::Bind(&NativeMediaFileUtil::CopyInForeignFileOnTaskRunnerThread,
                  weak_factory_.GetWeakPtr(), base::Passed(&context),
                  src_file_path, dest_url, callback));
+  DCHECK(success);
 }
 
-bool NativeMediaFileUtil::DeleteFile(
+void NativeMediaFileUtil::DeleteFile(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const StatusCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
 }
 
 // This is needed to support Copy and Move.
-bool NativeMediaFileUtil::DeleteDirectory(
+void NativeMediaFileUtil::DeleteDirectory(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const StatusCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   fileapi::FileSystemOperationContext* context_ptr = context.get();
-  return context_ptr->task_runner()->PostTask(
+  const bool success = context_ptr->task_runner()->PostTask(
       FROM_HERE,
       base::Bind(&NativeMediaFileUtil::DeleteDirectoryOnTaskRunnerThread,
                  weak_factory_.GetWeakPtr(), base::Passed(&context),
                  url, callback));
+  DCHECK(success);
 }
 
-bool NativeMediaFileUtil::DeleteRecursively(
+void NativeMediaFileUtil::DeleteRecursively(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const StatusCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
-  if (!callback.is_null())
-    callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
-  return true;
+  callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
 }
 
-bool NativeMediaFileUtil::CreateSnapshotFile(
+void NativeMediaFileUtil::CreateSnapshotFile(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const CreateSnapshotFileCallback& callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   fileapi::FileSystemOperationContext* context_ptr = context.get();
-  return context_ptr->task_runner()->PostTask(
+  const bool success = context_ptr->task_runner()->PostTask(
       FROM_HERE,
       base::Bind(&NativeMediaFileUtil::CreateSnapshotFileOnTaskRunnerThread,
                  weak_factory_.GetWeakPtr(), base::Passed(&context),
                  url, callback));
+  DCHECK(success);
 }
 
 void NativeMediaFileUtil::CreateDirectoryOnTaskRunnerThread(
@@ -322,8 +318,6 @@
   DCHECK(IsOnTaskRunnerThread(context.get()));
   base::PlatformFileError error =
       CreateDirectorySync(context.get(), url, exclusive, recursive);
-  if (callback.is_null())
-    return;
   content::BrowserThread::PostTask(
       content::BrowserThread::IO,
       FROM_HERE,
@@ -340,8 +334,6 @@
   base::FilePath platform_path;
   base::PlatformFileError error =
       GetFileInfoSync(context.get(), url, &file_info, &platform_path);
-  if (callback.is_null())
-    return;
   content::BrowserThread::PostTask(
       content::BrowserThread::IO,
       FROM_HERE,
@@ -356,8 +348,6 @@
   EntryList entry_list;
   base::PlatformFileError error =
       ReadDirectorySync(context.get(), url, &entry_list);
-  if (callback.is_null())
-    return;
   content::BrowserThread::PostTask(
       content::BrowserThread::IO,
       FROM_HERE,
@@ -373,8 +363,6 @@
   DCHECK(IsOnTaskRunnerThread(context.get()));
   base::PlatformFileError error =
       CopyOrMoveFileSync(context.get(), src_url, dest_url, copy);
-  if (callback.is_null())
-    return;
   content::BrowserThread::PostTask(
       content::BrowserThread::IO,
       FROM_HERE,
@@ -389,8 +377,6 @@
   DCHECK(IsOnTaskRunnerThread(context.get()));
   base::PlatformFileError error =
       CopyInForeignFileSync(context.get(), src_file_path, dest_url);
-  if (callback.is_null())
-    return;
   content::BrowserThread::PostTask(
       content::BrowserThread::IO,
       FROM_HERE,
@@ -403,8 +389,6 @@
     const StatusCallback& callback) {
   DCHECK(IsOnTaskRunnerThread(context.get()));
   base::PlatformFileError error = DeleteDirectorySync(context.get(), url);
-  if (callback.is_null())
-    return;
   content::BrowserThread::PostTask(
       content::BrowserThread::IO,
       FROM_HERE,
@@ -422,8 +406,6 @@
   base::PlatformFileError error =
       CreateSnapshotFileSync(context.get(), url, &file_info, &platform_path,
                              &file_ref);
-  if (callback.is_null())
-    return;
   content::BrowserThread::PostTask(
       content::BrowserThread::IO,
       FROM_HERE,
@@ -648,7 +630,7 @@
   if (error != base::PLATFORM_FILE_OK)
     return error;
 
-  if (!file_util::PathExists(file_path))
+  if (!base::PathExists(file_path))
     return failure_error;
   base::PlatformFileInfo file_info;
   if (!file_util::GetFileInfo(file_path, &file_info))
diff --git a/chrome/browser/media_galleries/fileapi/native_media_file_util.h b/chrome/browser/media_galleries/fileapi/native_media_file_util.h
index 731bdb9..29de6e6 100644
--- a/chrome/browser/media_galleries/fileapi/native_media_file_util.h
+++ b/chrome/browser/media_galleries/fileapi/native_media_file_util.h
@@ -25,68 +25,68 @@
   static base::PlatformFileError IsMediaFile(const base::FilePath& path);
 
   // AsyncFileUtil overrides.
-  virtual bool CreateOrOpen(
+  virtual void CreateOrOpen(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       int file_flags,
       const CreateOrOpenCallback& callback) OVERRIDE;
-  virtual bool EnsureFileExists(
+  virtual void EnsureFileExists(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const EnsureFileExistsCallback& callback) OVERRIDE;
-  virtual bool CreateDirectory(
+  virtual void CreateDirectory(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       bool exclusive,
       bool recursive,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool GetFileInfo(
+  virtual void GetFileInfo(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const GetFileInfoCallback& callback) OVERRIDE;
-  virtual bool ReadDirectory(
+  virtual void ReadDirectory(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const ReadDirectoryCallback& callback) OVERRIDE;
-  virtual bool Touch(
+  virtual void Touch(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const base::Time& last_access_time,
       const base::Time& last_modified_time,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool Truncate(
+  virtual void Truncate(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       int64 length,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool CopyFileLocal(
+  virtual void CopyFileLocal(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& src_url,
       const fileapi::FileSystemURL& dest_url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool MoveFileLocal(
+  virtual void MoveFileLocal(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& src_url,
       const fileapi::FileSystemURL& dest_url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool CopyInForeignFile(
+  virtual void CopyInForeignFile(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const base::FilePath& src_file_path,
       const fileapi::FileSystemURL& dest_url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool DeleteFile(
+  virtual void DeleteFile(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool DeleteDirectory(
+  virtual void DeleteDirectory(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool DeleteRecursively(
+  virtual void DeleteRecursively(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const StatusCallback& callback) OVERRIDE;
-  virtual bool CreateSnapshotFile(
+  virtual void CreateSnapshotFile(
       scoped_ptr<fileapi::FileSystemOperationContext> context,
       const fileapi::FileSystemURL& url,
       const CreateSnapshotFileCallback& callback) OVERRIDE;
diff --git a/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc b/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
index 71f752f..a023b75 100644
--- a/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
+++ b/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
@@ -13,13 +13,13 @@
 #include "base/message_loop/message_loop_proxy.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/browser/media_galleries/fileapi/native_media_file_util.h"
 #include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "webkit/browser/fileapi/external_mount_points.h"
+#include "webkit/browser/fileapi/file_system_backend.h"
 #include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/browser/fileapi/file_system_mount_point_provider.h"
 #include "webkit/browser/fileapi/file_system_operation_runner.h"
 #include "webkit/browser/fileapi/file_system_task_runners.h"
 #include "webkit/browser/fileapi/file_system_url.h"
@@ -125,8 +125,8 @@
     scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
         new quota::MockSpecialStoragePolicy();
 
-    ScopedVector<fileapi::FileSystemMountPointProvider> additional_providers;
-    additional_providers.push_back(new MediaFileSystemMountPointProvider(
+    ScopedVector<fileapi::FileSystemBackend> additional_providers;
+    additional_providers.push_back(new MediaFileSystemBackend(
         data_dir_.path(), base::MessageLoopProxy::current().get()));
 
     file_system_context_ = new fileapi::FileSystemContext(
@@ -288,7 +288,7 @@
     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
       // Always start with an empty destination directory.
       // Copying to a non-empty destination directory is an invalid operation.
-      ASSERT_TRUE(base::Delete(dest_path, true));
+      ASSERT_TRUE(base::DeleteFile(dest_path, true));
       ASSERT_TRUE(file_util::CreateDirectory(dest_path));
 
       FileSystemURL root_url = CreateURL(FPL(""));
@@ -318,7 +318,7 @@
     if (loop_count == 1) {
       // Reset the test directory between the two loops to remove old
       // directories and create new ones that should pre-exist.
-      ASSERT_TRUE(base::Delete(root_path(), true));
+      ASSERT_TRUE(base::DeleteFile(root_path(), true));
       ASSERT_TRUE(file_util::CreateDirectory(root_path()));
       PopulateDirectoryWithTestCases(root_path(),
                                      kFilteringTestCases,
@@ -387,7 +387,7 @@
     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
       // Always start with an empty destination directory.
       // Moving to a non-empty destination directory is an invalid operation.
-      ASSERT_TRUE(base::Delete(dest_path, true));
+      ASSERT_TRUE(base::DeleteFile(dest_path, true));
       ASSERT_TRUE(file_util::CreateDirectory(dest_path));
 
       FileSystemURL root_url = CreateURL(FPL(""));
@@ -417,7 +417,7 @@
     if (loop_count == 1) {
       // Reset the test directory between the two loops to remove old
       // directories and create new ones that should pre-exist.
-      ASSERT_TRUE(base::Delete(root_path(), true));
+      ASSERT_TRUE(base::DeleteFile(root_path(), true));
       ASSERT_TRUE(file_util::CreateDirectory(root_path()));
       PopulateDirectoryWithTestCases(root_path(),
                                      kFilteringTestCases,
diff --git a/chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.cc b/chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.cc
index 3cd4f8e..a2f503c 100644
--- a/chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.cc
+++ b/chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.cc
@@ -9,43 +9,63 @@
 #include "base/basictypes.h"
 #include "base/callback.h"
 #include "base/strings/stringprintf.h"
-#include "chrome/common/media_galleries/picasa_types.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
+#include "chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.h"
+#include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
 #include "webkit/browser/fileapi/file_system_operation_context.h"
 #include "webkit/browser/fileapi/file_system_url.h"
 
+using chrome::MediaFileSystemBackend;
+
 namespace picasa {
 
 PicasaDataProvider::PicasaDataProvider(const base::FilePath& database_path)
     : database_path_(database_path),
-      needs_refresh_(true) {
+      needs_refresh_(true),
+      weak_factory_(this) {
 }
 
 PicasaDataProvider::~PicasaDataProvider() {}
 
 void PicasaDataProvider::RefreshData(const base::Closure& ready_callback) {
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   // TODO(tommycli): Need to watch the database_path_ folder and handle
   // rereading the data when it changes.
-  if (needs_refresh_) {
-    if (ReadData()) {
-      needs_refresh_ = false;
-    }
+  if (!needs_refresh_) {
+    ready_callback.Run();
+    return;
   }
 
-  ready_callback.Run();
+  needs_refresh_ = false;
+  album_table_reader_ = new SafePicasaAlbumTableReader(
+      AlbumTableFiles(database_path_),
+      base::Bind(&PicasaDataProvider::OnDataRefreshed,
+                 weak_factory_.GetWeakPtr(),
+                 ready_callback));
+  album_table_reader_->Start();
 }
 
 scoped_ptr<AlbumMap> PicasaDataProvider::GetFolders() {
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   return make_scoped_ptr(new AlbumMap(folder_map_));
 }
 
 scoped_ptr<AlbumMap> PicasaDataProvider::GetAlbums() {
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   return make_scoped_ptr(new AlbumMap(album_map_));
 }
 
-void PicasaDataProvider::InitializeWith(const std::vector<AlbumInfo>& albums,
-                                        const std::vector<AlbumInfo>& folders) {
-  UniquifyNames(albums, &album_map_);
-  UniquifyNames(folders, &folder_map_);
+void PicasaDataProvider::OnDataRefreshed(
+    const base::Closure& ready_callback,
+    bool parse_success,
+    const std::vector<AlbumInfo>& albums,
+    const std::vector<AlbumInfo>& folders) {
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
+  if (parse_success) {
+    UniquifyNames(albums, &album_map_);
+    UniquifyNames(folders, &folder_map_);
+  }
+  ready_callback.Run();
 }
 
 // static
@@ -88,23 +108,4 @@
   }
 }
 
-bool PicasaDataProvider::ReadData() {
-  // TODO(tommycli): Disabled until utility process host client implemented.
-  // PicasaAlbumTableFiles album_table_files(database_path_);
-  // PicasaAlbumTableReader album_table_reader((album_table_files));
-  //
-  // bool read_success = album_table_reader.Init();
-  //
-  // ClosePicasaAlbumTableFiles(&album_table_files);
-  //
-  // if (read_success) {
-  //   InitializeWith(album_table_reader.albums(),
-  //                  album_table_reader.folders());
-  // }
-  //
-  //  return read_success;
-
-  return true;
-}
-
 }  // namespace picasa
diff --git a/chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h b/chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h
index 40a9bd1..1a4494b 100644
--- a/chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h
+++ b/chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h
@@ -11,12 +11,16 @@
 
 #include "base/callback_forward.h"
 #include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
+#include "chrome/common/media_galleries/picasa_types.h"
 
 namespace picasa {
 
 struct AlbumInfo;
+class SafePicasaAlbumTableReader;
 
 typedef std::map<std::string, AlbumInfo> AlbumMap;
 
@@ -28,6 +32,8 @@
 
   // Ask the data provider to refresh the data if necessary. |ready_callback|
   // will be called when the data is up to date
+  // TODO(tommycli): Investigate having the callback return a bool indicating
+  // success or failure - and handling it intelligently in PicasaFileUtil.
   void RefreshData(const base::Closure& ready_callback);
 
   scoped_ptr<AlbumMap> GetAlbums();
@@ -35,8 +41,10 @@
   // TODO(tommycli): Implement album contents. GetAlbumContents(...)
 
  protected:
-  void InitializeWith(const std::vector<AlbumInfo>& albums,
-                      const std::vector<AlbumInfo>& folder);
+  // Protected for test class usage.
+  void OnDataRefreshed(const base::Closure& ready_callback,
+                       bool parse_success, const std::vector<AlbumInfo>& albums,
+                       const std::vector<AlbumInfo>& folder);
 
  private:
   friend class PicasaFileUtilTest;
@@ -45,15 +53,16 @@
   static void UniquifyNames(const std::vector<AlbumInfo>& info_list,
                             AlbumMap* result_map);
 
-  // This can be overidden by a test version of this class.
-  virtual bool ReadData();
-
   AlbumMap album_map_;
   AlbumMap folder_map_;
 
   base::FilePath database_path_;
   bool needs_refresh_;
 
+  scoped_refptr<SafePicasaAlbumTableReader> album_table_reader_;
+
+  base::WeakPtrFactory<PicasaDataProvider> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(PicasaDataProvider);
 };
 
diff --git a/chrome/browser/media_galleries/fileapi/picasa/picasa_file_util.cc b/chrome/browser/media_galleries/fileapi/picasa/picasa_file_util.cc
index 15ce254..d15cb78 100644
--- a/chrome/browser/media_galleries/fileapi/picasa/picasa_file_util.cc
+++ b/chrome/browser/media_galleries/fileapi/picasa/picasa_file_util.cc
@@ -13,7 +13,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h"
 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
 #include "chrome/common/media_galleries/picasa_types.h"
diff --git a/chrome/browser/media_galleries/fileapi/picasa/picasa_file_util_unittest.cc b/chrome/browser/media_galleries/fileapi/picasa/picasa_file_util_unittest.cc
index 10ebb3a..695dcc2 100644
--- a/chrome/browser/media_galleries/fileapi/picasa/picasa_file_util_unittest.cc
+++ b/chrome/browser/media_galleries/fileapi/picasa/picasa_file_util_unittest.cc
@@ -14,7 +14,7 @@
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h"
 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_file_util.h"
@@ -128,6 +128,11 @@
 
   virtual ~TestPicasaDataProvider() {}
 
+  void RefreshData(const base::Closure& ready_callback) OVERRIDE {
+    DCHECK(initialized_);
+    ready_callback.Run();
+  }
+
   void Init(const std::vector<AlbumInfo>& albums,
             const std::vector<AlbumInfo>& folders) {
     InitializeWith(albums, folders);
@@ -135,11 +140,6 @@
   }
 
  private:
-  virtual bool ReadData() OVERRIDE {
-    DCHECK(initialized_);
-    return true;
-  }
-
   bool initialized_;
 };
 
@@ -157,12 +157,12 @@
   PicasaDataProvider* data_provider_;
 };
 
-class TestMediaFileSystemMountPointProvider
-    : public chrome::MediaFileSystemMountPointProvider {
+class TestMediaFileSystemBackend
+    : public chrome::MediaFileSystemBackend {
  public:
-  TestMediaFileSystemMountPointProvider(const base::FilePath& profile_path,
+  TestMediaFileSystemBackend(const base::FilePath& profile_path,
                                         PicasaFileUtil* picasa_file_util)
-      : chrome::MediaFileSystemMountPointProvider(
+      : chrome::MediaFileSystemBackend(
             profile_path,
             base::MessageLoopProxy::current().get()),
         test_file_util_(picasa_file_util) {}
@@ -234,8 +234,8 @@
 
     picasa_data_provider_.reset(new TestPicasaDataProvider());
 
-    ScopedVector<fileapi::FileSystemMountPointProvider> additional_providers;
-    additional_providers.push_back(new TestMediaFileSystemMountPointProvider(
+    ScopedVector<fileapi::FileSystemBackend> additional_providers;
+    additional_providers.push_back(new TestMediaFileSystemBackend(
         profile_dir_.path(),
         new TestPicasaFileUtil(picasa_data_provider_.get())));
 
@@ -399,7 +399,7 @@
       new chrome::MediaPathFilter());
 
   operation_context->SetUserValue(
-      chrome::MediaFileSystemMountPointProvider::kMediaPathFilterKey,
+      chrome::MediaFileSystemBackend::kMediaPathFilterKey,
       media_path_filter.get());
 
   scoped_ptr<TestPicasaDataProvider> test_picasa_data_provider(
diff --git a/chrome/browser/media_galleries/fileapi/picasa/picasa_finder.cc b/chrome/browser/media_galleries/fileapi/picasa/picasa_finder.cc
index 6a0a657..400eef1 100644
--- a/chrome/browser/media_galleries/fileapi/picasa/picasa_finder.cc
+++ b/chrome/browser/media_galleries/fileapi/picasa/picasa_finder.cc
@@ -36,7 +36,7 @@
   path = path.AppendASCII("Google").AppendASCII("Picasa2").AppendASCII("db3");
 
   // Verify actual existence
-  if (!file_util::DirectoryExists(path))
+  if (!base::DirectoryExists(path))
     path.clear();
 
   return path;
diff --git a/chrome/browser/media_galleries/fileapi/safe_itunes_library_parser.cc b/chrome/browser/media_galleries/fileapi/safe_itunes_library_parser.cc
index 1935336..0ae9ef4 100644
--- a/chrome/browser/media_galleries/fileapi/safe_itunes_library_parser.cc
+++ b/chrome/browser/media_galleries/fileapi/safe_itunes_library_parser.cc
@@ -4,13 +4,13 @@
 
 #include "chrome/browser/media_galleries/fileapi/safe_itunes_library_parser.h"
 
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/common/chrome_utility_messages.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_data.h"
 #include "ipc/ipc_platform_file.h"
 
-using chrome::MediaFileSystemMountPointProvider;
+using chrome::MediaFileSystemBackend;
 using content::BrowserThread;
 using content::UtilityProcessHost;
 
@@ -24,7 +24,7 @@
       parser_state_(INITIAL_STATE) {}
 
 void SafeITunesLibraryParser::Start() {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
 
   // |itunes_library_platform_file_| will be closed on the IO thread once it
   // has been handed off to the child process.
@@ -87,7 +87,7 @@
   if (parser_state_ != STARTED_PARSING_STATE)
     return;
 
-  MediaFileSystemMountPointProvider::MediaTaskRunner()->PostTask(
+  MediaFileSystemBackend::MediaTaskRunner()->PostTask(
       FROM_HERE,
       base::Bind(callback_, result, library));
   parser_state_ = FINISHED_PARSING_STATE;
diff --git a/chrome/browser/media_galleries/fileapi/safe_itunes_library_parser.h b/chrome/browser/media_galleries/fileapi/safe_itunes_library_parser.h
index 26e2e59..6a0e7f0 100644
--- a/chrome/browser/media_galleries/fileapi/safe_itunes_library_parser.h
+++ b/chrome/browser/media_galleries/fileapi/safe_itunes_library_parser.h
@@ -89,7 +89,6 @@
   // Initialized on the Media Task Runner, but only accessed on the IO thread.
   ParserState parser_state_;
 
-
   DISALLOW_COPY_AND_ASSIGN(SafeITunesLibraryParser);
 };
 
diff --git a/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.cc b/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.cc
new file mode 100644
index 0000000..0485116
--- /dev/null
+++ b/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.cc
@@ -0,0 +1,128 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.h"
+
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
+#include "chrome/common/chrome_utility_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/child_process_data.h"
+
+using chrome::MediaFileSystemBackend;
+using content::BrowserThread;
+
+namespace picasa {
+
+SafePicasaAlbumTableReader::SafePicasaAlbumTableReader(
+    const AlbumTableFiles& album_table_files,
+    const ParserCallback& callback)
+    : album_table_files_(album_table_files),
+      callback_(callback),
+      parser_state_(INITIAL_STATE) {
+  // TODO(tommycli): Add DCHECK to make sure |album_table_files| are all
+  // opened read-only once security adds ability to check PlatformFiles.
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(!callback_.is_null());
+}
+
+void SafePicasaAlbumTableReader::Start() {
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
+  BrowserThread::PostTask(
+      BrowserThread::IO,
+      FROM_HERE,
+      base::Bind(&SafePicasaAlbumTableReader::StartWorkOnIOThread, this));
+}
+
+SafePicasaAlbumTableReader::~SafePicasaAlbumTableReader() {
+}
+
+void SafePicasaAlbumTableReader::StartWorkOnIOThread() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_EQ(INITIAL_STATE, parser_state_);
+
+  utility_process_host_ = content::UtilityProcessHost::Create(
+      this,
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get())
+      ->AsWeakPtr();
+  // Wait for the startup notification before sending the main IPC to the
+  // utility process, so that we can dup the file handle.
+  utility_process_host_->Send(new ChromeUtilityMsg_StartupPing);
+  parser_state_ = PINGED_UTILITY_PROCESS_STATE;
+}
+
+void SafePicasaAlbumTableReader::OnProcessStarted() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  if (parser_state_ != PINGED_UTILITY_PROCESS_STATE)
+    return;
+
+  if (utility_process_host_->GetData().handle == base::kNullProcessHandle) {
+    DLOG(ERROR) << "Child process handle is null";
+  }
+  AlbumTableFilesForTransit files_for_transit;
+  files_for_transit.indicator_file = IPC::GetFileHandleForProcess(
+      album_table_files_.indicator_file,
+      utility_process_host_->GetData().handle,
+      true /* close_source_handle */);
+  files_for_transit.category_file = IPC::GetFileHandleForProcess(
+      album_table_files_.category_file,
+      utility_process_host_->GetData().handle,
+      true /* close_source_handle */);
+  files_for_transit.date_file = IPC::GetFileHandleForProcess(
+      album_table_files_.date_file,
+      utility_process_host_->GetData().handle,
+      true /* close_source_handle */);
+  files_for_transit.filename_file = IPC::GetFileHandleForProcess(
+      album_table_files_.filename_file,
+      utility_process_host_->GetData().handle,
+      true /* close_source_handle */);
+  files_for_transit.name_file = IPC::GetFileHandleForProcess(
+      album_table_files_.name_file,
+      utility_process_host_->GetData().handle,
+      true /* close_source_handle */);
+  files_for_transit.token_file = IPC::GetFileHandleForProcess(
+      album_table_files_.token_file,
+      utility_process_host_->GetData().handle,
+      true /* close_source_handle */);
+  files_for_transit.uid_file = IPC::GetFileHandleForProcess(
+      album_table_files_.uid_file,
+      utility_process_host_->GetData().handle,
+      true /* close_source_handle */);
+  utility_process_host_->Send(new ChromeUtilityMsg_ParsePicasaPMPDatabase(
+      files_for_transit));
+  parser_state_ = STARTED_PARSING_STATE;
+}
+
+void SafePicasaAlbumTableReader::OnParsePicasaPMPDatabaseFinished(
+    bool parse_success,
+    const std::vector<AlbumInfo>& albums,
+    const std::vector<AlbumInfo>& folders) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  if (parser_state_ != STARTED_PARSING_STATE)
+    return;
+
+  MediaFileSystemBackend::MediaTaskRunner()->PostTask(
+      FROM_HERE,
+      base::Bind(callback_, parse_success, albums, folders));
+  parser_state_ = FINISHED_PARSING_STATE;
+}
+
+void SafePicasaAlbumTableReader::OnProcessCrashed(int exit_code) {
+  OnParsePicasaPMPDatabaseFinished(false, std::vector<AlbumInfo>(),
+                                   std::vector<AlbumInfo>());
+}
+
+bool SafePicasaAlbumTableReader::OnMessageReceived(
+    const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(SafePicasaAlbumTableReader, message)
+    IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ProcessStarted,
+                        OnProcessStarted)
+    IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParsePicasaPMPDatabase_Finished,
+                        OnParsePicasaPMPDatabaseFinished)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+}  // namespace picasa
diff --git a/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.h b/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.h
new file mode 100644
index 0000000..7ba5764
--- /dev/null
+++ b/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.h
@@ -0,0 +1,91 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_SAFE_PICASA_ALBUM_TABLE_READER_H_
+#define CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_SAFE_PICASA_ALBUM_TABLE_READER_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/common/media_galleries/picasa_types.h"
+#include "content/public/browser/utility_process_host.h"
+#include "content/public/browser/utility_process_host_client.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace IPC {
+class Message;
+}
+
+namespace picasa {
+
+// SafePicasaAlbumTableReader parses the given Picasa PMP Album Table safely
+// via a utility process. The SafePicasaAlbumTableReader object is ref-counted
+// and kept alive after Start() is called until the ParserCallback is called.
+// The ParserCallback is guaranteed to be called eventually either when the
+// utility process replies or when it dies.
+class SafePicasaAlbumTableReader : public content::UtilityProcessHostClient {
+ public:
+  typedef base::Callback<void(bool,
+                              const std::vector<AlbumInfo>&,
+                              const std::vector<AlbumInfo>&)> ParserCallback;
+
+  SafePicasaAlbumTableReader(const AlbumTableFiles& album_table_files,
+                             const ParserCallback& callback);
+
+  void Start();
+
+ private:
+  enum ParserState {
+    INITIAL_STATE,
+    PINGED_UTILITY_PROCESS_STATE,
+    STARTED_PARSING_STATE,
+    FINISHED_PARSING_STATE,
+  };
+
+  // Private because content::UtilityProcessHostClient is ref-counted.
+  virtual ~SafePicasaAlbumTableReader();
+
+  // Launches the utility process.  Must run on the IO thread.
+  void StartWorkOnIOThread();
+
+  // Notification that the utility process is running, and we can now get its
+  // process handle.
+  // Runs on the IO thread.
+  void OnProcessStarted();
+
+  // Notification from the utility process when it finshes parsing the PMP
+  // database. This is received even if PMP parsing fails.
+  // Runs on the IO thread.
+  void OnParsePicasaPMPDatabaseFinished(bool parse_success,
+                                        const std::vector<AlbumInfo>& albums,
+                                        const std::vector<AlbumInfo>& folders);
+
+  // UtilityProcessHostClient implementation.
+  // Runs on the IO thread.
+  virtual void OnProcessCrashed(int exit_code) OVERRIDE;
+  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
+  const AlbumTableFiles album_table_files_;
+
+  // Only accessed on the IO thread.
+  base::WeakPtr<content::UtilityProcessHost> utility_process_host_;
+
+  // Only accessed on the Media Task Runner.
+  const ParserCallback callback_;
+
+  // Verifies the messages from the utility process came at the right time.
+  // Initialized on the Media Task Runner, but only accessed on the IO thread.
+  ParserState parser_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(SafePicasaAlbumTableReader);
+};
+
+}  // namespace picasa
+
+#endif  // CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_SAFE_PICASA_ALBUM_TABLE_READER_H_
diff --git a/chrome/browser/media_galleries/imported_media_gallery_registry.cc b/chrome/browser/media_galleries/imported_media_gallery_registry.cc
index b9f6c13..5f4b435 100644
--- a/chrome/browser/media_galleries/imported_media_gallery_registry.cc
+++ b/chrome/browser/media_galleries/imported_media_gallery_registry.cc
@@ -7,7 +7,7 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h"
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "content/public/browser/browser_thread.h"
@@ -49,7 +49,7 @@
   picasa_fsids_.insert(fsid);
 
   if (picasa_fsids_.size() == 1) {
-    MediaFileSystemMountPointProvider::MediaTaskRunner()->PostTask(
+    MediaFileSystemBackend::MediaTaskRunner()->PostTask(
         FROM_HERE,
         Bind(&ImportedMediaGalleryRegistry::RegisterPicasaFileSystem,
              base::Unretained(this), database_path));
@@ -83,7 +83,7 @@
   itunes_fsids_.insert(fsid);
 
   if (itunes_fsids_.size() == 1) {
-    MediaFileSystemMountPointProvider::MediaTaskRunner()->PostTask(
+    MediaFileSystemBackend::MediaTaskRunner()->PostTask(
         FROM_HERE,
         Bind(&ImportedMediaGalleryRegistry::RegisterITunesFileSystem,
              base::Unretained(this), library_xml_path));
@@ -105,7 +105,7 @@
 #if defined(OS_WIN) || defined(OS_MACOSX)
   if (picasa_fsids_.erase(fsid)) {
     if (picasa_fsids_.empty()) {
-      MediaFileSystemMountPointProvider::MediaTaskRunner()->PostTask(
+      MediaFileSystemBackend::MediaTaskRunner()->PostTask(
           FROM_HERE,
           Bind(&ImportedMediaGalleryRegistry::RevokePicasaFileSystem,
                base::Unretained(this)));
@@ -115,7 +115,7 @@
 
   if (itunes_fsids_.erase(fsid)) {
     if (itunes_fsids_.empty()) {
-      MediaFileSystemMountPointProvider::MediaTaskRunner()->PostTask(
+      MediaFileSystemBackend::MediaTaskRunner()->PostTask(
           FROM_HERE,
           Bind(&ImportedMediaGalleryRegistry::RevokeITunesFileSystem,
                base::Unretained(this)));
@@ -131,7 +131,7 @@
 // static
 picasa::PicasaDataProvider*
 ImportedMediaGalleryRegistry::PicasaDataProvider() {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(GetInstance()->picasa_data_provider_);
   return GetInstance()->picasa_data_provider_.get();
 }
@@ -139,7 +139,7 @@
 // static
 itunes::ITunesDataProvider*
 ImportedMediaGalleryRegistry::ITunesDataProvider() {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(GetInstance()->itunes_data_provider_);
   return GetInstance()->itunes_data_provider_.get();
 }
@@ -157,26 +157,26 @@
 #if defined(OS_WIN) || defined(OS_MACOSX)
 void ImportedMediaGalleryRegistry::RegisterPicasaFileSystem(
     const base::FilePath& database_path) {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(!picasa_data_provider_);
   picasa_data_provider_.reset(new picasa::PicasaDataProvider(database_path));
 }
 
 void ImportedMediaGalleryRegistry::RevokePicasaFileSystem() {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(picasa_data_provider_);
   picasa_data_provider_.reset();
 }
 
 void ImportedMediaGalleryRegistry::RegisterITunesFileSystem(
     const base::FilePath& xml_library_path) {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(!itunes_data_provider_);
   itunes_data_provider_.reset(new itunes::ITunesDataProvider(xml_library_path));
 }
 
 void ImportedMediaGalleryRegistry::RevokeITunesFileSystem() {
-  DCHECK(MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread());
+  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
   DCHECK(itunes_data_provider_);
   itunes_data_provider_.reset();
 }
diff --git a/chrome/browser/media_galleries/media_file_system_registry.cc b/chrome/browser/media_galleries/media_file_system_registry.cc
index b1a2f9d..232f89b 100644
--- a/chrome/browser/media_galleries/media_file_system_registry.cc
+++ b/chrome/browser/media_galleries/media_file_system_registry.cc
@@ -14,6 +14,7 @@
 #include "base/files/file_path.h"
 #include "base/prefs/pref_service.h"
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
@@ -24,7 +25,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/storage_monitor/media_storage_util.h"
 #include "chrome/browser/storage_monitor/storage_monitor.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
diff --git a/chrome/browser/media_galleries/media_galleries_preferences.cc b/chrome/browser/media_galleries/media_galleries_preferences.cc
index 451b617..cf64556 100644
--- a/chrome/browser/media_galleries/media_galleries_preferences.cc
+++ b/chrome/browser/media_galleries/media_galleries_preferences.cc
@@ -827,7 +827,7 @@
 }
 
 // static
-void MediaGalleriesPreferences::RegisterUserPrefs(
+void MediaGalleriesPreferences::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(prefs::kMediaGalleriesRememberedGalleries,
                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
diff --git a/chrome/browser/media_galleries/media_galleries_preferences.h b/chrome/browser/media_galleries/media_galleries_preferences.h
index f15dc9b..f737c4b 100644
--- a/chrome/browser/media_galleries/media_galleries_preferences.h
+++ b/chrome/browser/media_galleries/media_galleries_preferences.h
@@ -199,7 +199,7 @@
   // BrowserContextKeyedService implementation:
   virtual void Shutdown() OVERRIDE;
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Returns true if the media gallery preferences system has ever been used
   // for this profile. To be exact, it checks if a gallery has ever been added
diff --git a/chrome/browser/media_galleries/media_galleries_preferences_factory.cc b/chrome/browser/media_galleries/media_galleries_preferences_factory.cc
index ab64aaa..03fefe2 100644
--- a/chrome/browser/media_galleries/media_galleries_preferences_factory.cc
+++ b/chrome/browser/media_galleries/media_galleries_preferences_factory.cc
@@ -36,9 +36,9 @@
   return new chrome::MediaGalleriesPreferences(static_cast<Profile*>(profile));
 }
 
-void MediaGalleriesPreferencesFactory::RegisterUserPrefs(
+void MediaGalleriesPreferencesFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* prefs) {
-  chrome::MediaGalleriesPreferences::RegisterUserPrefs(prefs);
+  chrome::MediaGalleriesPreferences::RegisterProfilePrefs(prefs);
 }
 
 content::BrowserContext*
diff --git a/chrome/browser/media_galleries/media_galleries_preferences_factory.h b/chrome/browser/media_galleries/media_galleries_preferences_factory.h
index 2c98619..797198f 100644
--- a/chrome/browser/media_galleries/media_galleries_preferences_factory.h
+++ b/chrome/browser/media_galleries/media_galleries_preferences_factory.h
@@ -35,7 +35,7 @@
   // BrowserContextKeyedServiceFactory:
   virtual BrowserContextKeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const OVERRIDE;
diff --git a/chrome/browser/media_galleries/scoped_mtp_device_map_entry.cc b/chrome/browser/media_galleries/scoped_mtp_device_map_entry.cc
index 703efad..c29d4ae 100644
--- a/chrome/browser/media_galleries/scoped_mtp_device_map_entry.cc
+++ b/chrome/browser/media_galleries/scoped_mtp_device_map_entry.cc
@@ -5,8 +5,7 @@
 #include "chrome/browser/media_galleries/scoped_mtp_device_map_entry.h"
 
 #include "base/bind.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/browser/media_galleries/fileapi/mtp_device_map_service.h"
 #include "chrome/browser/media_galleries/mtp_device_delegate_impl.h"
 #include "content/public/browser/browser_thread.h"
@@ -15,22 +14,6 @@
 
 namespace {
 
-bool IsMediaTaskRunnerThread() {
-  base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
-  base::SequencedWorkerPool::SequenceToken media_sequence_token =
-      pool->GetNamedSequenceToken(
-          MediaFileSystemMountPointProvider::kMediaTaskRunnerName);
-  return pool->IsRunningSequenceOnCurrentThread(media_sequence_token);
-}
-
-scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() {
-  base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
-  base::SequencedWorkerPool::SequenceToken media_sequence_token =
-      pool->GetNamedSequenceToken(
-          MediaFileSystemMountPointProvider::kMediaTaskRunnerName);
-  return pool->GetSequencedTaskRunner(media_sequence_token);
-}
-
 void OnDeviceAsyncDelegateDestroyed(
     const base::FilePath::StringType& device_location) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
diff --git a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc
index fa72b2d..7a9028a 100644
--- a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc
+++ b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc
@@ -20,9 +20,8 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task_runner_util.h"
-#include "base/threading/sequenced_worker_pool.h"
 #include "base/threading/thread_restrictions.h"
-#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
 #include "chrome/browser/media_galleries/win/mtp_device_object_entry.h"
 #include "chrome/browser/media_galleries/win/mtp_device_object_enumerator.h"
 #include "chrome/browser/media_galleries/win/mtp_device_operations_util.h"
@@ -56,14 +55,6 @@
       UTF16ToUTF8(storage_device_id), pnp_device_id, storage_object_id);
 }
 
-scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() {
-  base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
-  base::SequencedWorkerPool::SequenceToken media_sequence_token =
-      pool->GetNamedSequenceToken(
-          MediaFileSystemMountPointProvider::kMediaTaskRunnerName);
-  return pool->GetSequencedTaskRunner(media_sequence_token);
-}
-
 // Returns the object id of the file object specified by the |file_path|,
 // e.g. if the |file_path| is "\\MTP:StorageSerial:SID-{1001,,192}:125\DCIM"
 // and |device_info.registered_device_path_| is
@@ -372,7 +363,7 @@
     : storage_device_info_(pnp_device_id, registered_device_path,
                            storage_object_id),
       init_state_(UNINITIALIZED),
-      media_task_runner_(GetSequencedTaskRunner()),
+      media_task_runner_(MediaFileSystemBackend::MediaTaskRunner()),
       task_in_progress_(false),
       weak_ptr_factory_(this) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc
index 8274960..ef07356 100644
--- a/chrome/browser/memory_details.cc
+++ b/chrome/browser/memory_details.cc
@@ -14,9 +14,9 @@
 #include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_process_type.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/url_constants.h"
+#include "components/nacl/common/nacl_process_type.h"
 #include "content/public/browser/browser_child_process_host_iterator.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_data.h"
@@ -385,7 +385,7 @@
     switch (browser.processes[index].process_type) {
       case content::PROCESS_TYPE_BROWSER:
         UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", sample);
-        break;
+        continue;
       case content::PROCESS_TYPE_RENDERER: {
         ProcessMemoryInformation::RendererProcessType renderer_type =
             browser.processes[index].renderer_type;
@@ -393,66 +393,65 @@
           case ProcessMemoryInformation::RENDERER_EXTENSION:
             UMA_HISTOGRAM_MEMORY_KB("Memory.Extension", sample);
             extension_count++;
-            break;
+            continue;
           case ProcessMemoryInformation::RENDERER_CHROME:
             UMA_HISTOGRAM_MEMORY_KB("Memory.Chrome", sample);
             chrome_count++;
-            break;
+            continue;
           case ProcessMemoryInformation::RENDERER_UNKNOWN:
             NOTREACHED() << "Unknown renderer process type.";
-            break;
+            continue;
           case ProcessMemoryInformation::RENDERER_NORMAL:
           default:
             // TODO(erikkay): Should we bother splitting out the other subtypes?
             UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer", sample);
             renderer_count++;
-            break;
+            continue;
         }
-        break;
       }
       case content::PROCESS_TYPE_PLUGIN:
         UMA_HISTOGRAM_MEMORY_KB("Memory.Plugin", sample);
         plugin_count++;
-        break;
+        continue;
       case content::PROCESS_TYPE_WORKER:
         UMA_HISTOGRAM_MEMORY_KB("Memory.Worker", sample);
         worker_count++;
-        break;
+        continue;
       case content::PROCESS_TYPE_UTILITY:
         UMA_HISTOGRAM_MEMORY_KB("Memory.Utility", sample);
         other_count++;
-        break;
+        continue;
       case content::PROCESS_TYPE_ZYGOTE:
         UMA_HISTOGRAM_MEMORY_KB("Memory.Zygote", sample);
         other_count++;
-        break;
+        continue;
       case content::PROCESS_TYPE_SANDBOX_HELPER:
         UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample);
         other_count++;
-        break;
+        continue;
       case content::PROCESS_TYPE_GPU:
         UMA_HISTOGRAM_MEMORY_KB("Memory.Gpu", sample);
         other_count++;
-        break;
+        continue;
       case content::PROCESS_TYPE_PPAPI_PLUGIN:
         UMA_HISTOGRAM_MEMORY_KB("Memory.PepperPlugin", sample);
         pepper_plugin_count++;
-        break;
+        continue;
       case content::PROCESS_TYPE_PPAPI_BROKER:
         UMA_HISTOGRAM_MEMORY_KB("Memory.PepperPluginBroker", sample);
         pepper_plugin_broker_count++;
-        break;
+        continue;
       case PROCESS_TYPE_NACL_LOADER:
         UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample);
         other_count++;
-        break;
+        continue;
       case PROCESS_TYPE_NACL_BROKER:
         UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClientBroker", sample);
         other_count++;
-        break;
+        continue;
       default:
         NOTREACHED();
-        break;
+        continue;
     }
   }
   UMA_HISTOGRAM_MEMORY_KB("Memory.BackingStore",
@@ -490,4 +489,80 @@
   int non_renderer_count = browser.processes.size() - all_renderer_count;
   SiteDetails::UpdateHistograms(browser.site_data, all_renderer_count,
                                 non_renderer_count);
+#if defined(OS_CHROMEOS)
+  UpdateSwapHistograms();
+#endif
+
 }
+
+#if defined(OS_CHROMEOS)
+void MemoryDetails::UpdateSwapHistograms() {
+  const ProcessData& browser = *ChromeBrowser();
+  size_t aggregate_memory = 0;
+  for (size_t index = 0; index < browser.processes.size(); index++) {
+    int sample = static_cast<int>(browser.processes[index].working_set.swapped);
+    aggregate_memory += sample;
+    switch (browser.processes[index].process_type) {
+      case content::PROCESS_TYPE_BROWSER:
+        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Browser", sample);
+        continue;
+      case content::PROCESS_TYPE_RENDERER: {
+        ProcessMemoryInformation::RendererProcessType renderer_type =
+            browser.processes[index].renderer_type;
+        switch (renderer_type) {
+          case ProcessMemoryInformation::RENDERER_EXTENSION:
+            UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Extension", sample);
+            continue;
+          case ProcessMemoryInformation::RENDERER_CHROME:
+            UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Chrome", sample);
+            continue;
+          case ProcessMemoryInformation::RENDERER_UNKNOWN:
+            NOTREACHED() << "Unknown renderer process type.";
+            continue;
+          case ProcessMemoryInformation::RENDERER_NORMAL:
+          default:
+            UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Renderer", sample);
+            continue;
+        }
+      }
+      case content::PROCESS_TYPE_PLUGIN:
+        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Plugin", sample);
+        continue;
+      case content::PROCESS_TYPE_WORKER:
+        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Worker", sample);
+        continue;
+      case content::PROCESS_TYPE_UTILITY:
+        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Utility", sample);
+        continue;
+      case content::PROCESS_TYPE_ZYGOTE:
+        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Zygote", sample);
+        continue;
+      case content::PROCESS_TYPE_SANDBOX_HELPER:
+        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.SandboxHelper", sample);
+        continue;
+      case content::PROCESS_TYPE_GPU:
+        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Gpu", sample);
+        continue;
+      case content::PROCESS_TYPE_PPAPI_PLUGIN:
+        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.PepperPlugin", sample);
+        continue;
+      case content::PROCESS_TYPE_PPAPI_BROKER:
+        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.PepperPluginBroker", sample);
+        continue;
+      case PROCESS_TYPE_NACL_LOADER:
+        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.NativeClient", sample);
+        continue;
+      case PROCESS_TYPE_NACL_BROKER:
+        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.NativeClientBroker", sample);
+        continue;
+      default:
+        NOTREACHED();
+        continue;
+    }
+  }
+
+  int total_sample = static_cast<int>(aggregate_memory / 1000);
+  UMA_HISTOGRAM_MEMORY_MB("Memory.Swap.Total", total_sample);
+}
+
+#endif
diff --git a/chrome/browser/memory_details.h b/chrome/browser/memory_details.h
index 89692e2..24abeb9 100644
--- a/chrome/browser/memory_details.h
+++ b/chrome/browser/memory_details.h
@@ -176,6 +176,10 @@
   // Updates the global histograms for tracking memory usage.
   void UpdateHistograms();
 
+#if defined(OS_CHROMEOS)
+  void UpdateSwapHistograms();
+#endif
+
   // Returns a pointer to the ProcessData structure for Chrome.
   ProcessData* ChromeBrowser();
 
diff --git a/chrome/browser/metrics/compression_utils.cc b/chrome/browser/metrics/compression_utils.cc
new file mode 100644
index 0000000..d2c2611
--- /dev/null
+++ b/chrome/browser/metrics/compression_utils.cc
@@ -0,0 +1,88 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/metrics/compression_utils.h"
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "third_party/zlib/zlib.h"
+#include "third_party/zlib/zutil.h"
+
+namespace {
+
+// The difference in bytes between a zlib header and a gzip header.
+const size_t kGzipZlibHeaderDifferenceBytes = 16;
+
+// Pass an integer greater than the following get a gzip header instead of a
+// zlib header when calling deflateInit2_.
+const int kWindowBitsToGetGzipHeader = 16;
+
+// This code is taken almost verbatim from third_party/zlib/compress.c. The only
+// difference is deflateInit2_ is called which sets the window bits to be > 16.
+// That causes a gzip header to be emitted rather than a zlib header.
+int GzipCompressHelper(Bytef* dest,
+                       uLongf* dest_length,
+                       const Bytef* source,
+                       uLong source_length) {
+    z_stream stream;
+
+    stream.next_in = bit_cast<Bytef*>(source);
+    stream.avail_in = static_cast<uInt>(source_length);
+    stream.next_out = dest;
+    stream.avail_out = static_cast<uInt>(*dest_length);
+    if (static_cast<uLong>(stream.avail_out) != *dest_length)
+      return Z_BUF_ERROR;
+
+    stream.zalloc = static_cast<alloc_func>(0);
+    stream.zfree = static_cast<free_func>(0);
+    stream.opaque = static_cast<voidpf>(0);
+
+    gz_header gzip_header;
+    memset(&gzip_header, 0, sizeof(gzip_header));
+    int err = deflateInit2_(&stream,
+                            Z_DEFAULT_COMPRESSION,
+                            Z_DEFLATED,
+                            MAX_WBITS + kWindowBitsToGetGzipHeader,
+                            DEF_MEM_LEVEL,
+                            Z_DEFAULT_STRATEGY,
+                            ZLIB_VERSION,
+                            sizeof(z_stream));
+    if (err != Z_OK)
+      return err;
+
+    err = deflateSetHeader(&stream, &gzip_header);
+    if (err != Z_OK)
+      return err;
+
+    err = deflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        deflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *dest_length = stream.total_out;
+
+    err = deflateEnd(&stream);
+    return err;
+}
+}  // namespace
+
+namespace chrome {
+
+bool GzipCompress(const std::string& input, std::string* output) {
+  std::vector<Bytef> compressed_data(kGzipZlibHeaderDifferenceBytes +
+                                     compressBound(input.size()));
+
+  uLongf compressed_size = compressed_data.size();
+  if (GzipCompressHelper(&compressed_data.front(),
+                         &compressed_size,
+                         bit_cast<const Bytef*>(input.data()),
+                         input.size()) != Z_OK)
+    return false;
+
+  compressed_data.resize(compressed_size);
+  output->assign(compressed_data.begin(), compressed_data.end());
+  return true;
+}
+}  // namespace chrome
diff --git a/chrome/browser/metrics/compression_utils.h b/chrome/browser/metrics/compression_utils.h
new file mode 100644
index 0000000..ec208ec
--- /dev/null
+++ b/chrome/browser/metrics/compression_utils.h
@@ -0,0 +1,17 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_METRICS_COMPRESSION_UTILS_H_
+#define CHROME_BROWSER_METRICS_COMPRESSION_UTILS_H_
+
+#include <string>
+
+namespace chrome {
+
+// Compresses the text in |input| using gzip storing the result in |output|.
+bool GzipCompress(const std::string& input, std::string* output);
+
+}  // namespace chrome
+
+#endif  // CHROME_BROWSER_METRICS_COMPRESSION_UTILS_H_
diff --git a/chrome/browser/metrics/compression_utils_unittest.cc b/chrome/browser/metrics/compression_utils_unittest.cc
new file mode 100644
index 0000000..ad05eef
--- /dev/null
+++ b/chrome/browser/metrics/compression_utils_unittest.cc
@@ -0,0 +1,48 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/base_paths.h"
+#include "base/basictypes.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "chrome/browser/metrics/compression_utils.h"
+#include "chrome/common/chrome_paths.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+// The data to be compressed by gzip. This is the hex representation of "hello
+// world".
+const uint8 kData[] =
+    {0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f,
+     0x72, 0x6c, 0x64};
+
+// This is the string representation of gzip compressed string above. It was
+// obtained by running echo -n "hello world" | gzip -c | hexdump -e '8 1 ",
+// 0x%x"' followed by 0'ing out the OS byte (10th byte) in the header. This is
+// so that the test passes on all platforms (that run various OS'es).
+const uint8 kCompressedData[] =
+    {0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0xcb, 0x48, 0xcd, 0xc9, 0xc9, 0x57, 0x28, 0xcf,
+     0x2f, 0xca, 0x49, 0x01, 0x00, 0x85, 0x11, 0x4a, 0x0d,
+     0x0b, 0x00, 0x00, 0x00};
+
+// Re-enable C4309.
+#if defined(OS_WIN)
+#pragma warning( default: 4309 )
+#endif
+
+TEST(CompressionUtilsTest, GzipCompression) {
+  std::string data(reinterpret_cast<const char*>(kData), arraysize(kData));
+  std::string compressed_data;
+  EXPECT_TRUE(chrome::GzipCompress(data, &compressed_data));
+  std::string golden_compressed_data(
+      reinterpret_cast<const char*>(kCompressedData),
+      arraysize(kCompressedData));
+  EXPECT_EQ(golden_compressed_data, compressed_data);
+}
+
+}  // namespace
diff --git a/chrome/browser/metrics/gzipped_protobufs_field_trial.cc b/chrome/browser/metrics/gzipped_protobufs_field_trial.cc
new file mode 100644
index 0000000..e12290d
--- /dev/null
+++ b/chrome/browser/metrics/gzipped_protobufs_field_trial.cc
@@ -0,0 +1,55 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/field_trial.h"
+
+namespace {
+
+// Name of field trial for that sends gzipped UMA protobufs.
+const char kTrialName[] = "GZippedProtobufs";
+
+// Divisor for the gzipped protobufs trial.
+const int kTrialDivisor = 100;
+
+// Quotient for the gzipped protobufs trial.
+const int kTrialQuotient = 50;
+
+// Name of the group with gzipped protobufs.
+const char kGroupName[] = "GzippedProtobufsEnabled";
+
+// Name of the group with non-gzipped protobufs.
+const char kControlGroupName[] = "GzippedProtobufsDisabled";
+
+// This is set to true if we land in the Finch group that will be sending
+// protobufs after compressing them.
+bool should_gzip_protobufs = false;
+
+}  // namespace
+
+namespace metrics {
+
+void CreateGzippedProtobufsFieldTrial() {
+  scoped_refptr<base::FieldTrial> gzipped_protobufs_trial =
+      base::FieldTrialList::FactoryGetFieldTrial(
+          kTrialName,
+          kTrialDivisor,
+          kControlGroupName,
+          2013,
+          9,
+          1,
+          NULL);
+  gzipped_protobufs_trial->UseOneTimeRandomization();
+  int gzipped_protobufs_group = gzipped_protobufs_trial->AppendGroup(
+      kGroupName,
+      kTrialQuotient);
+  should_gzip_protobufs =
+      gzipped_protobufs_trial->group() == gzipped_protobufs_group;
+}
+
+bool ShouldGzipProtobufsBeforeUploading() {
+  return should_gzip_protobufs;
+}
+
+}  // namespace metrics
diff --git a/chrome/browser/metrics/gzipped_protobufs_field_trial.h b/chrome/browser/metrics/gzipped_protobufs_field_trial.h
new file mode 100644
index 0000000..fe39f01
--- /dev/null
+++ b/chrome/browser/metrics/gzipped_protobufs_field_trial.h
@@ -0,0 +1,21 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_METRICS_GZIPPED_PROTOBUFS_FIELD_TRIAL_H_
+#define CHROME_BROWSER_METRICS_GZIPPED_PROTOBUFS_FIELD_TRIAL_H_
+
+namespace metrics {
+
+// Create a field trial for selecting whether to gzip protobufs before uploading
+// or not.
+void CreateGzippedProtobufsFieldTrial();
+
+// Returns whether we are in a field trial group that compresses protobufs
+// before uploading.
+bool ShouldGzipProtobufsBeforeUploading();
+
+}  // namespace metrics
+
+
+#endif  // CHROME_BROWSER_METRICS_GZIPPED_PROTOBUFS_FIELD_TRIAL_H_
diff --git a/chrome/browser/metrics/metrics_log.cc b/chrome/browser/metrics/metrics_log.cc
index bc8a7e7..76563f5 100644
--- a/chrome/browser/metrics/metrics_log.cc
+++ b/chrome/browser/metrics/metrics_log.cc
@@ -32,7 +32,6 @@
 #include "chrome/browser/omnibox/omnibox_log.h"
 #include "chrome/browser/plugins/plugin_prefs.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_process_type.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/logging_chrome.h"
 #include "chrome/common/metrics/proto/omnibox_event.pb.h"
@@ -41,6 +40,7 @@
 #include "chrome/common/metrics/variations/variations_util.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/installer/util/google_update_settings.h"
+#include "components/nacl/common/nacl_process_type.h"
 #include "content/public/browser/gpu_data_manager.h"
 #include "content/public/common/content_client.h"
 #include "device/bluetooth/bluetooth_adapter.h"
@@ -55,8 +55,6 @@
 #include "base/android/build_info.h"
 #endif
 
-#define OPEN_ELEMENT_FOR_SCOPE(name) ScopedElement scoped_element(this, name)
-
 #if defined(OS_WIN)
 #include "base/win/metro.h"
 #include "ui/base/win/dpi.h"
@@ -347,6 +345,13 @@
 }
 #endif  // defined(OS_CHROMEOS)
 
+// Round a timestamp measured in seconds since epoch to one with a granularity
+// of an hour. This can be used before uploaded potentially sensitive
+// timestamps.
+int64 RoundSecondsToHour(int64 time_in_seconds) {
+  return 3600 * (time_in_seconds / 3600);
+}
+
 }  // namespace
 
 GoogleUpdateMetrics::GoogleUpdateMetrics() : is_system_install(false) {}
@@ -415,15 +420,9 @@
   PrefService* pref = GetPrefService();
   DCHECK(pref);
 
-  OPEN_ELEMENT_FOR_SCOPE("profile");
-  WriteCommonEventAttributes();
-
-  {
-    OPEN_ELEMENT_FOR_SCOPE("stability");  // Minimal set of stability elements.
-    WriteRequiredStabilityAttributes(pref);
-    WriteRealtimeStabilityAttributes(pref);
-    WritePluginStabilityElements(plugin_list, pref);
-  }
+  WriteRequiredStabilityAttributes(pref);
+  WriteRealtimeStabilityAttributes(pref);
+  WritePluginStabilityElements(plugin_list, pref);
 }
 
 PrefService* MetricsLog::GetPrefService() {
@@ -458,7 +457,6 @@
   // NOTE: This could lead to some data loss if this report isn't successfully
   //       sent, but that's true for all the metrics.
 
-  OPEN_ELEMENT_FOR_SCOPE("stability");
   WriteRequiredStabilityAttributes(pref);
   WriteRealtimeStabilityAttributes(pref);
 
@@ -480,17 +478,6 @@
 
   // TODO(jar): The following are all optional, so we *could* optimize them for
   // values of zero (and not include them).
-
-  // Write the XML version.
-  WriteIntAttribute("incompleteshutdowncount", incomplete_shutdown_count);
-  WriteIntAttribute("breakpadregistrationok",
-                    breakpad_registration_success_count);
-  WriteIntAttribute("breakpadregistrationfail",
-                    breakpad_registration_failure_count);
-  WriteIntAttribute("debuggerpresent", debugger_present_count);
-  WriteIntAttribute("debuggernotpresent", debugger_not_present_count);
-
-  // Write the protobuf version.
   SystemProfileProto::Stability* stability =
       uma_proto()->mutable_system_profile()->mutable_stability();
   stability->set_incomplete_shutdown_count(incomplete_shutdown_count);
@@ -513,8 +500,6 @@
   if (!plugin_stats_list)
     return;
 
-  OPEN_ELEMENT_FOR_SCOPE("plugins");
-
 #if defined(ENABLE_PLUGINS)
   SystemProfileProto::Stability* stability =
       uma_proto()->mutable_system_profile()->mutable_stability();
@@ -527,31 +512,6 @@
     }
     DictionaryValue* plugin_dict = static_cast<DictionaryValue*>(*iter);
 
-    std::string plugin_name;
-    plugin_dict->GetString(prefs::kStabilityPluginName, &plugin_name);
-
-    std::string base64_name_hash;
-    uint64 numeric_name_hash_ignored;
-    CreateHashes(plugin_name, &base64_name_hash, &numeric_name_hash_ignored);
-
-    // Write the XML verison.
-    OPEN_ELEMENT_FOR_SCOPE("pluginstability");
-    // Use "filename" instead of "name", otherwise we need to update the
-    // UMA servers.
-    WriteAttribute("filename", base64_name_hash);
-
-    int launches = 0;
-    plugin_dict->GetInteger(prefs::kStabilityPluginLaunches, &launches);
-    WriteIntAttribute("launchcount", launches);
-
-    int instances = 0;
-    plugin_dict->GetInteger(prefs::kStabilityPluginInstances, &instances);
-    WriteIntAttribute("instancecount", instances);
-
-    int crashes = 0;
-    plugin_dict->GetInteger(prefs::kStabilityPluginCrashes, &crashes);
-    WriteIntAttribute("crashcount", crashes);
-
     // Write the protobuf version.
     // Note that this search is potentially a quadratic operation, but given the
     // low number of plugins installed on a "reasonable" setup, this should be
@@ -559,6 +519,8 @@
     // TODO(isherman): Verify that this does not show up as a hotspot in
     // profiler runs.
     const webkit::WebPluginInfo* plugin_info = NULL;
+    std::string plugin_name;
+    plugin_dict->GetString(prefs::kStabilityPluginName, &plugin_name);
     const string16 plugin_name_utf16 = UTF8ToUTF16(plugin_name);
     for (std::vector<webkit::WebPluginInfo>::const_iterator iter =
              plugin_list.begin();
@@ -573,20 +535,32 @@
       NOTREACHED();
       continue;
     }
-    int loading_errors = 0;
-    plugin_dict->GetInteger(prefs::kStabilityPluginLoadingErrors,
-                            &loading_errors);
-    WriteIntAttribute("loadingerrorcount", loading_errors);
 
-    // Write the protobuf version.
     SystemProfileProto::Stability::PluginStability* plugin_stability =
         stability->add_plugin_stability();
     SetPluginInfo(*plugin_info, plugin_prefs,
                   plugin_stability->mutable_plugin());
-    plugin_stability->set_launch_count(launches);
-    plugin_stability->set_instance_count(instances);
-    plugin_stability->set_crash_count(crashes);
-    plugin_stability->set_loading_error_count(loading_errors);
+
+    int launches = 0;
+    plugin_dict->GetInteger(prefs::kStabilityPluginLaunches, &launches);
+    if (launches > 0)
+      plugin_stability->set_launch_count(launches);
+
+    int instances = 0;
+    plugin_dict->GetInteger(prefs::kStabilityPluginInstances, &instances);
+    if (instances > 0)
+      plugin_stability->set_instance_count(instances);
+
+    int crashes = 0;
+    plugin_dict->GetInteger(prefs::kStabilityPluginCrashes, &crashes);
+    if (crashes > 0)
+      plugin_stability->set_crash_count(crashes);
+
+    int loading_errors = 0;
+    plugin_dict->GetInteger(prefs::kStabilityPluginLoadingErrors,
+                            &loading_errors);
+    if (loading_errors > 0)
+      plugin_stability->set_loading_error_count(loading_errors);
   }
 #endif  // defined(ENABLE_PLUGINS)
 
@@ -603,11 +577,6 @@
   int crash_count = pref->GetInteger(prefs::kStabilityCrashCount);
   pref->SetInteger(prefs::kStabilityCrashCount, 0);
 
-  // Write the XML version.
-  WriteIntAttribute("launchcount", launch_count);
-  WriteIntAttribute("crashcount", crash_count);
-
-  // Write the protobuf version.
   SystemProfileProto::Stability* stability =
       uma_proto()->mutable_system_profile()->mutable_stability();
   stability->set_launch_count(launch_count);
@@ -623,35 +592,30 @@
       uma_proto()->mutable_system_profile()->mutable_stability();
   int count = pref->GetInteger(prefs::kStabilityPageLoadCount);
   if (count) {
-    WriteIntAttribute("pageloadcount", count);
     stability->set_page_load_count(count);
     pref->SetInteger(prefs::kStabilityPageLoadCount, 0);
   }
 
   count = pref->GetInteger(prefs::kStabilityRendererCrashCount);
   if (count) {
-    WriteIntAttribute("renderercrashcount", count);
     stability->set_renderer_crash_count(count);
     pref->SetInteger(prefs::kStabilityRendererCrashCount, 0);
   }
 
   count = pref->GetInteger(prefs::kStabilityExtensionRendererCrashCount);
   if (count) {
-    WriteIntAttribute("extensionrenderercrashcount", count);
     stability->set_extension_renderer_crash_count(count);
     pref->SetInteger(prefs::kStabilityExtensionRendererCrashCount, 0);
   }
 
   count = pref->GetInteger(prefs::kStabilityRendererHangCount);
   if (count) {
-    WriteIntAttribute("rendererhangcount", count);
     stability->set_renderer_hang_count(count);
     pref->SetInteger(prefs::kStabilityRendererHangCount, 0);
   }
 
   count = pref->GetInteger(prefs::kStabilityChildProcessCrashCount);
   if (count) {
-    WriteIntAttribute("childprocesscrashcount", count);
     stability->set_child_process_crash_count(count);
     pref->SetInteger(prefs::kStabilityChildProcessCrashCount, 0);
   }
@@ -677,10 +641,8 @@
 #endif  // OS_CHROMEOS
 
   int64 recent_duration = GetIncrementalUptime(pref);
-  if (recent_duration) {
-    WriteInt64Attribute("uptimesec", recent_duration);
+  if (recent_duration)
     stability->set_uptime_sec(recent_duration);
-  }
 }
 
 void MetricsLog::WritePluginList(
@@ -701,88 +663,12 @@
 
 void MetricsLog::RecordEnvironment(
          const std::vector<webkit::WebPluginInfo>& plugin_list,
-         const GoogleUpdateMetrics& google_update_metrics,
-         const DictionaryValue* profile_metrics) {
+         const GoogleUpdateMetrics& google_update_metrics) {
   DCHECK(!locked());
 
   PrefService* pref = GetPrefService();
-
-  OPEN_ELEMENT_FOR_SCOPE("profile");
-  WriteCommonEventAttributes();
-
   WriteStabilityElement(plugin_list, pref);
 
-  {
-    // Write the XML version.
-    // We'll write the protobuf version in RecordEnvironmentProto().
-    OPEN_ELEMENT_FOR_SCOPE("cpu");
-    WriteAttribute("arch", base::SysInfo::OperatingSystemArchitecture());
-  }
-
-  {
-    // Write the XML version.
-    // We'll write the protobuf version in RecordEnvironmentProto().
-    OPEN_ELEMENT_FOR_SCOPE("memory");
-    WriteIntAttribute("mb", base::SysInfo::AmountOfPhysicalMemoryMB());
-#if defined(OS_WIN)
-    WriteIntAttribute("dllbase", reinterpret_cast<int>(&__ImageBase));
-#endif
-  }
-
-  {
-    // Write the XML version.
-    // We'll write the protobuf version in RecordEnvironmentProto().
-    OPEN_ELEMENT_FOR_SCOPE("os");
-    WriteAttribute("name", base::SysInfo::OperatingSystemName());
-    WriteAttribute("version", base::SysInfo::OperatingSystemVersion());
-  }
-
-  {
-    OPEN_ELEMENT_FOR_SCOPE("gpu");
-    const gpu::GPUInfo& gpu_info =
-        GpuDataManager::GetInstance()->GetGPUInfo();
-
-    // Write the XML version.
-    // We'll write the protobuf version in RecordEnvironmentProto().
-    WriteIntAttribute("vendorid", gpu_info.gpu.vendor_id);
-    WriteIntAttribute("deviceid", gpu_info.gpu.device_id);
-  }
-
-  {
-    const gfx::Size display_size = GetScreenSize();
-
-    // Write the XML version.
-    // We'll write the protobuf version in RecordEnvironmentProto().
-    OPEN_ELEMENT_FOR_SCOPE("display");
-    WriteIntAttribute("xsize", display_size.width());
-    WriteIntAttribute("ysize", display_size.height());
-    WriteIntAttribute("screens", GetScreenCount());
-  }
-
-  {
-    OPEN_ELEMENT_FOR_SCOPE("bookmarks");
-    {
-      OPEN_ELEMENT_FOR_SCOPE("bookmarklocation");
-      WriteAttribute("name", "full-tree");
-      WriteIntAttribute("foldercount", 0);
-      WriteIntAttribute("itemcount", 0);
-    }
-    {
-      OPEN_ELEMENT_FOR_SCOPE("bookmarklocation");
-      WriteAttribute("name", "toolbar");
-      WriteIntAttribute("foldercount", 0);
-      WriteIntAttribute("itemcount", 0);
-    }
-  }
-
-  {
-    OPEN_ELEMENT_FOR_SCOPE("keywords");
-    WriteIntAttribute("count", pref->GetInteger(prefs::kNumKeywords));
-  }
-
-  if (profile_metrics)
-    WriteAllProfilesMetrics(*profile_metrics);
-
   RecordEnvironmentProto(plugin_list, google_update_metrics);
 }
 
@@ -799,7 +685,14 @@
   bool success = base::StringToInt(GetMetricsEnabledDate(GetPrefService()),
                                    &enabled_date);
   DCHECK(success);
-  system_profile->set_uma_enabled_date(enabled_date);
+
+  // Reduce granularity of the enabled_date field to nearest hour.
+  system_profile->set_uma_enabled_date(RoundSecondsToHour(enabled_date));
+
+  int64 install_date = GetPrefService()->GetInt64(prefs::kInstallDate);
+
+  // Reduce granularity of the install_date field to nearest hour.
+  system_profile->set_install_date(RoundSecondsToHour(install_date));
 
   system_profile->set_application_locale(
       g_browser_process->GetApplicationLocale());
@@ -912,64 +805,6 @@
   WriteProfilerData(process_data, process_type, profile);
 }
 
-void MetricsLog::WriteAllProfilesMetrics(
-    const DictionaryValue& all_profiles_metrics) {
-  const std::string profile_prefix(prefs::kProfilePrefix);
-  for (DictionaryValue::Iterator i(all_profiles_metrics); !i.IsAtEnd();
-       i.Advance()) {
-    if (i.key().compare(0, profile_prefix.size(), profile_prefix) == 0) {
-      const DictionaryValue* profile;
-      if (i.value().GetAsDictionary(&profile))
-        WriteProfileMetrics(i.key().substr(profile_prefix.size()), *profile);
-    }
-  }
-}
-
-void MetricsLog::WriteProfileMetrics(const std::string& profileidhash,
-                                     const DictionaryValue& profile_metrics) {
-  OPEN_ELEMENT_FOR_SCOPE("userprofile");
-  WriteAttribute("profileidhash", profileidhash);
-  for (DictionaryValue::Iterator i(profile_metrics); !i.IsAtEnd();
-       i.Advance()) {
-    DCHECK_NE(i.key(), "id");
-    switch (i.value().GetType()) {
-      case Value::TYPE_STRING: {
-        std::string string_value;
-        if (i.value().GetAsString(&string_value)) {
-          OPEN_ELEMENT_FOR_SCOPE("profileparam");
-          WriteAttribute("name", i.key());
-          WriteAttribute("value", string_value);
-        }
-        break;
-      }
-
-      case Value::TYPE_BOOLEAN: {
-        bool bool_value;
-        if (i.value().GetAsBoolean(&bool_value)) {
-          OPEN_ELEMENT_FOR_SCOPE("profileparam");
-          WriteAttribute("name", i.key());
-          WriteIntAttribute("value", bool_value ? 1 : 0);
-        }
-        break;
-      }
-
-      case Value::TYPE_INTEGER: {
-        int int_value;
-        if (i.value().GetAsInteger(&int_value)) {
-          OPEN_ELEMENT_FOR_SCOPE("profileparam");
-          WriteAttribute("name", i.key());
-          WriteIntAttribute("value", int_value);
-        }
-        break;
-      }
-
-      default:
-        NOTREACHED();
-        break;
-    }
-  }
-}
-
 void MetricsLog::RecordOmniboxOpenedURL(const OmniboxLog& log) {
   DCHECK(!locked());
 
diff --git a/chrome/browser/metrics/metrics_log.h b/chrome/browser/metrics/metrics_log.h
index 86c84cc..abc0847 100644
--- a/chrome/browser/metrics/metrics_log.h
+++ b/chrome/browser/metrics/metrics_log.h
@@ -95,8 +95,7 @@
   // dictionary giving the metrics for the profile.
   void RecordEnvironment(
       const std::vector<webkit::WebPluginInfo>& plugin_list,
-      const GoogleUpdateMetrics& google_update_metrics,
-      const base::DictionaryValue* profile_metrics);
+      const GoogleUpdateMetrics& google_update_metrics);
 
   // Records the current operating environment.  Takes the list of installed
   // plugins and Google Update statistics as parameters because those can't be
@@ -173,16 +172,6 @@
   // Writes the list of installed plugins.
   void WritePluginList(const std::vector<webkit::WebPluginInfo>& plugin_list);
 
-  // Writes all profile metrics. This invokes WriteProfileMetrics for each key
-  // in all_profiles_metrics that starts with kProfilePrefix.
-  void WriteAllProfilesMetrics(
-      const base::DictionaryValue& all_profiles_metrics);
-
-  // Writes metrics for the profile identified by key. This writes all
-  // key/value pairs in profile_metrics.
-  void WriteProfileMetrics(const std::string& key,
-                           const base::DictionaryValue& profile_metrics);
-
   // Writes info about the Google Update install that is managing this client.
   // This is a no-op if called on a non-Windows platform.
   void WriteGoogleUpdateProto(const GoogleUpdateMetrics& google_update_metrics);
diff --git a/chrome/browser/metrics/metrics_log_unittest.cc b/chrome/browser/metrics/metrics_log_unittest.cc
index a319880..d88ad4a 100644
--- a/chrome/browser/metrics/metrics_log_unittest.cc
+++ b/chrome/browser/metrics/metrics_log_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/port.h"
 #include "base/prefs/pref_service.h"
 #include "base/prefs/testing_pref_service.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/sequenced_worker_pool.h"
@@ -17,13 +18,13 @@
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/metrics/metrics_log.h"
 #include "chrome/browser/prefs/browser_prefs.h"
-#include "chrome/common/chrome_process_type.h"
 #include "chrome/common/metrics/proto/profiler_event.pb.h"
 #include "chrome/common/metrics/proto/system_profile.pb.h"
 #include "chrome/common/metrics/variations/variations_util.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/installer/util/google_update_settings.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/common/process_type.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/size.h"
@@ -42,6 +43,8 @@
 namespace {
 
 const char kClientId[] = "bogus client ID";
+const int64 kInstallDate = 1373051956;
+const int64 kEnabledDate = 1373001211;
 const int kSessionId = 127;
 const int kScreenWidth = 1024;
 const int kScreenHeight = 768;
@@ -61,6 +64,9 @@
         brand_for_testing_(kBrandForTesting) {
     chrome::RegisterLocalState(prefs_.registry());
 
+    prefs_.SetInt64(prefs::kInstallDate, kInstallDate);
+    prefs_.SetString(prefs::kMetricsClientIDTimestamp,
+                     base::Int64ToString(kEnabledDate));
 #if defined(OS_CHROMEOS)
     prefs_.SetInteger(prefs::kStabilityChildProcessCrashCount, 10);
     prefs_.SetInteger(prefs::kStabilityOtherUserCrashCount, 11);
@@ -131,7 +137,13 @@
     if (proto_only)
       log.RecordEnvironmentProto(plugins, google_update_metrics);
     else
-      log.RecordEnvironment(plugins, google_update_metrics, NULL);
+      log.RecordEnvironment(plugins, google_update_metrics);
+
+    // Computed from original time of 1373051956.
+    EXPECT_EQ(1373050800, log.system_profile().install_date());
+
+    // Computed from original time of 1373001211.
+    EXPECT_EQ(1373000400, log.system_profile().uma_enabled_date());
 
     const metrics::SystemProfileProto& system_profile = log.system_profile();
     ASSERT_EQ(arraysize(kFieldTrialIds),
@@ -323,42 +335,3 @@
               tracked_object->process_type());
   }
 }
-
-#if defined(OS_CHROMEOS)
-TEST_F(MetricsLogTest, ChromeOSStabilityData) {
-  TestMetricsLog log(kClientId, kSessionId);
-
-  // Expect 3 warnings about not yet being able to send the
-  // Chrome OS stability stats.
-  std::vector<webkit::WebPluginInfo> plugins;
-  PrefService* prefs = log.GetPrefService();
-  log.WriteStabilityElement(plugins, prefs);
-  log.CloseLog();
-
-  int size = log.GetEncodedLogSizeXml();
-  ASSERT_GT(size, 0);
-
-  EXPECT_EQ(0, prefs->GetInteger(prefs::kStabilityChildProcessCrashCount));
-  EXPECT_EQ(0, prefs->GetInteger(prefs::kStabilityOtherUserCrashCount));
-  EXPECT_EQ(0, prefs->GetInteger(prefs::kStabilityKernelCrashCount));
-  EXPECT_EQ(0, prefs->GetInteger(prefs::kStabilitySystemUncleanShutdownCount));
-
-  std::string encoded;
-  // Leave room for the NUL terminator.
-  bool encoding_result = log.GetEncodedLogXml(
-      WriteInto(&encoded, size + 1), size);
-  ASSERT_TRUE(encoding_result);
-
-  // Check that we can find childprocesscrashcount, but not
-  // any of the ChromeOS ones that we are not emitting until log
-  // servers can handle them.
-  EXPECT_NE(std::string::npos,
-            encoded.find(" childprocesscrashcount=\"10\""));
-  EXPECT_EQ(std::string::npos,
-            encoded.find(" otherusercrashcount="));
-  EXPECT_EQ(std::string::npos,
-            encoded.find(" kernelcrashcount="));
-  EXPECT_EQ(std::string::npos,
-            encoded.find(" systemuncleanshutdowns="));
-}
-#endif  // OS_CHROMEOS
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc
index 1a7c769..1f7fa05 100644
--- a/chrome/browser/metrics/metrics_service.cc
+++ b/chrome/browser/metrics/metrics_service.cc
@@ -171,10 +171,13 @@
 #include "base/tracked_objects.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/process_map.h"
 #include "chrome/browser/io_thread.h"
 #include "chrome/browser/memory_details.h"
+#include "chrome/browser/metrics/compression_utils.h"
+#include "chrome/browser/metrics/gzipped_protobufs_field_trial.h"
 #include "chrome/browser/metrics/metrics_log.h"
 #include "chrome/browser/metrics/metrics_log_serializer.h"
 #include "chrome/browser/metrics/metrics_reporting_scheduler.h"
@@ -190,8 +193,6 @@
 #include "chrome/browser/ui/browser_otr_state.h"
 #include "chrome/browser/ui/search/search_tab_helper.h"
 #include "chrome/common/child_process_logging.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/chrome_process_type.h"
 #include "chrome/common/chrome_result_codes.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/metrics/entropy_provider.h"
@@ -207,6 +208,7 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/process_type.h"
 #include "net/base/load_flags.h"
 #include "net/url_request/url_fetcher.h"
 #include "webkit/plugins/webplugininfo.h"
@@ -217,7 +219,6 @@
 #endif
 
 #if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/external_metrics.h"
 #include "chrome/browser/chromeos/system/statistics_provider.h"
 #endif
@@ -425,7 +426,6 @@
   registry->RegisterIntegerPref(prefs::kStabilitySystemUncleanShutdownCount, 0);
 #endif  // OS_CHROMEOS
 
-  registry->RegisterDictionaryPref(prefs::kProfileMetrics);
   registry->RegisterIntegerPref(prefs::kNumKeywords, 0);
   registry->RegisterListPref(prefs::kMetricsInitialLogs);
   registry->RegisterListPref(prefs::kMetricsOngoingLogs);
@@ -885,22 +885,6 @@
   // Bookkeeping for the uninstall metrics.
   IncrementLongPrefsValue(prefs::kUninstallLaunchCount);
 
-  // Save profile metrics.
-  PrefService* prefs = g_browser_process->local_state();
-  if (prefs) {
-    // Remove the current dictionary and store it for use when sending data to
-    // server. By removing the value we prune potentially dead profiles
-    // (and keys). All valid values are added back once services startup.
-    const DictionaryValue* profile_dictionary =
-        prefs->GetDictionary(prefs::kProfileMetrics);
-    if (profile_dictionary) {
-      // Do a deep copy of profile_dictionary since ClearPref will delete it.
-      profile_dictionary_.reset(static_cast<DictionaryValue*>(
-          profile_dictionary->DeepCopy()));
-      prefs->ClearPref(prefs::kProfileMetrics);
-    }
-  }
-
   // Get stats on use of command line.
   const CommandLine* command_line(CommandLine::ForCurrentProcess());
   size_t common_commands = 0;
@@ -1361,8 +1345,7 @@
 
   DCHECK(initial_log_.get());
   initial_log_->set_hardware_class(hardware_class_);
-  initial_log_->RecordEnvironment(plugins_, google_update_metrics_,
-                                  profile_dictionary_.get());
+  initial_log_->RecordEnvironment(plugins_, google_update_metrics_);
 
   // Histograms only get written to the current log, so make the new log current
   // before writing them.
@@ -1417,7 +1400,36 @@
         GURL(kServerUrl), net::URLFetcher::POST, this));
     current_fetch_->SetRequestContext(
         g_browser_process->system_request_context());
-    current_fetch_->SetUploadData(kMimeType, log_manager_.staged_log_text());
+
+    // Compress the protobufs 50% of the time. This can be used to see if
+    // compressed protobufs are being mishandled by machines between the
+    // client/server or monitoring programs/firewalls on the client.
+    bool gzip_protobuf_before_uploading =
+        metrics::ShouldGzipProtobufsBeforeUploading();
+    if (gzip_protobuf_before_uploading) {
+      std::string log_text = log_manager_.staged_log_text();
+      std::string compressed_log_text;
+      bool compression_successful = chrome::GzipCompress(log_text,
+                                                         &compressed_log_text);
+      DCHECK(compression_successful);
+      if (compression_successful) {
+        current_fetch_->SetUploadData(kMimeType, compressed_log_text);
+        // Tell the server that we're uploading gzipped protobufs.
+        current_fetch_->SetExtraRequestHeaders("content-encoding: gzip");
+        UMA_HISTOGRAM_PERCENTAGE(
+            "UMA.ProtoCompressionRatio",
+            100 * compressed_log_text.size() / log_text.size());
+        UMA_HISTOGRAM_CUSTOM_COUNTS(
+            "UMA.ProtoGzippedKBSaved",
+            (log_text.size() - compressed_log_text.size()) / 1024,
+            1, 2000, 50);
+      }
+    } else {
+      current_fetch_->SetUploadData(kMimeType, log_manager_.staged_log_text());
+    }
+    UMA_HISTOGRAM_BOOLEAN("UMA.ProtoGzipped",
+                          gzip_protobuf_before_uploading);
+
     // We already drop cookies server-side, but we might as well strip them out
     // client-side as well.
     current_fetch_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
diff --git a/chrome/browser/metrics/metrics_service.h b/chrome/browser/metrics/metrics_service.h
index 52c9152..7896415 100644
--- a/chrome/browser/metrics/metrics_service.h
+++ b/chrome/browser/metrics/metrics_service.h
@@ -478,10 +478,6 @@
   // this factory are invalidated in ScheduleNextStateSave.
   base::WeakPtrFactory<MetricsService> state_saver_factory_;
 
-  // Dictionary containing all the profile specific metrics. This is set
-  // at creation time from the prefs.
-  scoped_ptr<base::DictionaryValue> profile_dictionary_;
-
   // The scheduler for determining when uploads should happen.
   scoped_ptr<MetricsReportingScheduler> scheduler_;
 
diff --git a/chrome/browser/metrics/metrics_service_unittest.cc b/chrome/browser/metrics/metrics_service_unittest.cc
index e65444e..51d4e34 100644
--- a/chrome/browser/metrics/metrics_service_unittest.cc
+++ b/chrome/browser/metrics/metrics_service_unittest.cc
@@ -8,11 +8,11 @@
 #include "base/command_line.h"
 #include "base/message_loop.h"
 #include "chrome/browser/metrics/metrics_service.h"
-#include "chrome/common/chrome_process_type.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
+#include "content/public/common/process_type.h"
 #include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/metrics/proto/study.proto b/chrome/browser/metrics/proto/study.proto
index 0879054..6a3d2b1 100644
--- a/chrome/browser/metrics/proto/study.proto
+++ b/chrome/browser/metrics/proto/study.proto
@@ -43,8 +43,19 @@
 
   // An experiment within the study.
   //
-  // Next tag: 6
+  // Next tag: 7
   message Experiment {
+    // A named parameter value for this experiment.
+    //
+    // Next tag: 3
+    message Param {
+      // The name of the parameter.
+      optional string name = 1;
+
+      // The value of the parameter.
+      optional string value = 2;
+    }
+
     // The name of the experiment within the study.
     // Ex: "bucketA"
     required string name = 1;
@@ -65,6 +76,9 @@
     // assigned to this experiment unless that flag is present in Chrome's
     // command line.
     optional string forcing_flag = 5;
+
+    // Parameter values for this experiment.
+    repeated Param param = 6; 
   }
 
   // List of experiments in this study. This list should include the default /
diff --git a/chrome/browser/metrics/tracking_synchronizer.cc b/chrome/browser/metrics/tracking_synchronizer.cc
index 383b039..aeda223 100644
--- a/chrome/browser/metrics/tracking_synchronizer.cc
+++ b/chrome/browser/metrics/tracking_synchronizer.cc
@@ -10,9 +10,9 @@
 #include "base/threading/thread.h"
 #include "base/tracked_objects.h"
 #include "chrome/browser/metrics/tracking_synchronizer_observer.h"
-#include "chrome/common/chrome_process_type.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/profiler_controller.h"
+#include "content/public/common/process_type.h"
 
 using base::TimeTicks;
 using content::BrowserThread;
diff --git a/chrome/browser/metrics/variations/variations_service.cc b/chrome/browser/metrics/variations/variations_service.cc
index 614290c..83ed215 100644
--- a/chrome/browser/metrics/variations/variations_service.cc
+++ b/chrome/browser/metrics/variations/variations_service.cc
@@ -15,6 +15,8 @@
 #include "base/metrics/sparse_histogram.h"
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
+#include "base/sha1.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/version.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/metrics/proto/trials_seed.pb.h"
@@ -157,6 +159,12 @@
   return parameter;
 }
 
+// Computes a hash of the serialized variations seed data.
+std::string HashSeed(const std::string& seed_data) {
+  const std::string sha1 = base::SHA1HashString(seed_data);
+  return base::HexEncode(sha1.data(), sha1.size());
+}
+
 enum ResourceRequestsAllowedState {
   RESOURCE_REQUESTS_ALLOWED,
   RESOURCE_REQUESTS_NOT_ALLOWED,
@@ -170,6 +178,18 @@
                             RESOURCE_REQUESTS_ALLOWED_ENUM_SIZE);
 }
 
+enum VariationSeedEmptyState {
+  VARIATIONS_SEED_NOT_EMPTY,
+  VARIATIONS_SEED_EMPTY,
+  VARIATIONS_SEED_CORRUPT,
+  VARIATIONS_SEED_EMPTY_ENUM_SIZE,
+};
+
+void RecordVariationSeedEmptyHistogram(VariationSeedEmptyState state) {
+  UMA_HISTOGRAM_ENUMERATION("Variations.SeedEmpty", state,
+                            VARIATIONS_SEED_EMPTY_ENUM_SIZE);
+}
+
 }  // namespace
 
 VariationsService::VariationsService(PrefService* local_state)
@@ -199,7 +219,7 @@
   create_trials_from_seed_called_ = true;
 
   TrialsSeed seed;
-  if (!LoadTrialsSeedFromPref(local_state_, &seed))
+  if (!LoadTrialsSeedFromPref(&seed))
     return false;
 
   const int64 date_value = local_state_->GetInt64(prefs::kVariationsSeedDate);
@@ -297,6 +317,7 @@
 // static
 void VariationsService::RegisterPrefs(PrefRegistrySimple* registry) {
   registry->RegisterStringPref(prefs::kVariationsSeed, std::string());
+  registry->RegisterStringPref(prefs::kVariationsSeedHash, std::string());
   registry->RegisterInt64Pref(prefs::kVariationsSeedDate,
                               base::Time().ToInternalValue());
   registry->RegisterInt64Pref(prefs::kVariationsLastFetchTime, 0);
@@ -419,7 +440,7 @@
   bool success = request->GetResponseAsString(&seed_data);
   DCHECK(success);
 
-  StoreSeedData(seed_data, response_date, local_state_);
+  StoreSeedData(seed_data, response_date);
 }
 
 void VariationsService::OnResourceRequestsAllowed() {
@@ -439,8 +460,7 @@
 }
 
 bool VariationsService::StoreSeedData(const std::string& seed_data,
-                                      const base::Time& seed_date,
-                                      PrefService* local_prefs) {
+                                      const base::Time& seed_date) {
   if (seed_data.empty()) {
     VLOG(1) << "Variations Seed data from server is empty, rejecting the seed.";
     return false;
@@ -461,9 +481,10 @@
     return false;
   }
 
-  local_prefs->SetString(prefs::kVariationsSeed, base64_seed_data);
-  local_prefs->SetInt64(prefs::kVariationsSeedDate,
-                        seed_date.ToInternalValue());
+  local_state_->SetString(prefs::kVariationsSeed, base64_seed_data);
+  local_state_->SetString(prefs::kVariationsSeedHash, HashSeed(seed_data));
+  local_state_->SetInt64(prefs::kVariationsSeedDate,
+                         seed_date.ToInternalValue());
   variations_serial_number_ = seed.serial_number();
 
   RecordLastFetchTime();
@@ -658,23 +679,31 @@
   return true;
 }
 
-bool VariationsService::LoadTrialsSeedFromPref(PrefService* local_prefs,
-                                               TrialsSeed* seed) {
-  std::string base64_seed_data = local_prefs->GetString(prefs::kVariationsSeed);
-  UMA_HISTOGRAM_BOOLEAN("Variations.SeedEmpty", base64_seed_data.empty());
-  if (base64_seed_data.empty())
+bool VariationsService::LoadTrialsSeedFromPref(TrialsSeed* seed) {
+  const std::string base64_seed_data =
+      local_state_->GetString(prefs::kVariationsSeed);
+  if (base64_seed_data.empty()) {
+    RecordVariationSeedEmptyHistogram(VARIATIONS_SEED_EMPTY);
     return false;
+  }
 
+  const std::string hash_from_pref =
+      local_state_->GetString(prefs::kVariationsSeedHash);
   // If the decode process fails, assume the pref value is corrupt and clear it.
   std::string seed_data;
   if (!base::Base64Decode(base64_seed_data, &seed_data) ||
+      (!hash_from_pref.empty() && HashSeed(seed_data) != hash_from_pref) ||
       !seed->ParseFromString(seed_data)) {
-    VLOG(1) << "Variations Seed data in local pref is corrupt, clearing the "
+    VLOG(1) << "Variations seed data in local pref is corrupt, clearing the "
             << "pref.";
-    local_prefs->ClearPref(prefs::kVariationsSeed);
+    local_state_->ClearPref(prefs::kVariationsSeed);
+    local_state_->ClearPref(prefs::kVariationsSeedDate);
+    local_state_->ClearPref(prefs::kVariationsSeedHash);
+    RecordVariationSeedEmptyHistogram(VARIATIONS_SEED_CORRUPT);
     return false;
   }
   variations_serial_number_ = seed->serial_number();
+  RecordVariationSeedEmptyHistogram(VARIATIONS_SEED_NOT_EMPTY);
   return true;
 }
 
@@ -716,6 +745,15 @@
 
   for (int i = 0; i < study.experiment_size(); ++i) {
     const Study_Experiment& experiment = study.experiment(i);
+
+    std::map<std::string, std::string> params;
+    for (int j = 0; j < experiment.param_size(); j++) {
+      if (experiment.param(j).has_name() && experiment.param(j).has_value())
+        params[experiment.param(j).name()] = experiment.param(j).value();
+    }
+    if (!params.empty())
+      AssociateVariationParams(study.name(), experiment.name(), params);
+
     // Groups with flags can't be selected randomly, so we don't add them to
     // the field trial.
     if (experiment.has_forcing_flag())
diff --git a/chrome/browser/metrics/variations/variations_service.h b/chrome/browser/metrics/variations/variations_service.h
index 9275786..18bf733 100644
--- a/chrome/browser/metrics/variations/variations_service.h
+++ b/chrome/browser/metrics/variations/variations_service.h
@@ -99,6 +99,7 @@
   FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, ForceGroupWithFlag2);
   FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, ForceFirstGroupWithFlag);
   FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, DontChooseGroupWithFlag);
+  FRIEND_TEST_ALL_PREFIXES(VariationsServiceTest, VariationParams);
 
   // Creates the VariationsService with the given |local_state| prefs service.
   // Use the |Create| factory method to create a VariationsService.
@@ -117,10 +118,8 @@
   // Store the given seed data to the given local prefs. Note that |seed_data|
   // is assumed to be the raw serialized protobuf data stored in a string. It
   // will be Base64Encoded for storage. If the string is invalid or the encoding
-  // fails, the |local_prefs| is left as is and the function returns false.
-  bool StoreSeedData(const std::string& seed_data,
-                     const base::Time& seed_date,
-                     PrefService* local_prefs);
+  // fails, the existing prefs are left as is and the function returns false.
+  bool StoreSeedData(const std::string& seed_data, const base::Time& seed_date);
 
   // Returns whether |study| should be disabled according to its restriction
   // parameters. Uses |version_info| for min / max version checks,
@@ -160,11 +159,10 @@
       const Study& study,
       base::FieldTrial::Probability* total_probability);
 
-  // Loads the Variations seed data from the given local prefs into |seed|. If
-  // there is a problem with loading, the pref value is cleared and false is
-  // returned. If successful, |seed| will contain the loaded data and true is
-  // returned.
-  bool LoadTrialsSeedFromPref(PrefService* local_prefs, TrialsSeed* seed);
+  // Loads the Variations seed data from local state into |seed|. If there is a
+  // problem with loading, the pref value is cleared and false is returned. If
+  // successful, |seed| will contain the loaded data and true is returned.
+  bool LoadTrialsSeedFromPref(TrialsSeed* seed);
 
   // Creates and registers a field trial from the |study| data. Disables the
   // trial if IsStudyExpired(study, reference_date) is true.
diff --git a/chrome/browser/metrics/variations/variations_service_unittest.cc b/chrome/browser/metrics/variations/variations_service_unittest.cc
index 625b616..418bcd4 100644
--- a/chrome/browser/metrics/variations/variations_service_unittest.cc
+++ b/chrome/browser/metrics/variations/variations_service_unittest.cc
@@ -7,12 +7,15 @@
 #include "base/base64.h"
 #include "base/command_line.h"
 #include "base/prefs/testing_pref_service.h"
+#include "base/sha1.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/metrics/proto/study.pb.h"
 #include "chrome/browser/metrics/variations/variations_service.h"
 #include "chrome/browser/web_resource/resource_request_allowed_notifier_test_util.h"
 #include "chrome/common/chrome_version_info.h"
+#include "chrome/common/metrics/variations/variations_util.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "content/public/test/test_browser_thread.h"
@@ -127,8 +130,12 @@
 }
 
 // Serializes |seed| to base64-encoded protobuf binary format.
-std::string SerializeSeedBase64(const TrialsSeed& seed) {
+std::string SerializeSeedBase64(const TrialsSeed& seed, std::string* hash) {
   std::string serialized_seed = SerializeSeed(seed);
+  if (hash != NULL) {
+    std::string sha1 = base::SHA1HashString(serialized_seed);
+    *hash = base::HexEncode(sha1.data(), sha1.size());
+  }
   std::string base64_serialized_seed;
   EXPECT_TRUE(base::Base64Encode(serialized_seed, &base64_serialized_seed));
   return base64_serialized_seed;
@@ -150,7 +157,7 @@
 
 }  // namespace
 
-class VariationsServiceTest : public testing::Test {
+class VariationsServiceTest : public ::testing::Test {
  protected:
   VariationsServiceTest() {}
 
@@ -522,7 +529,8 @@
 TEST_F(VariationsServiceTest, LoadSeed) {
   // Store good seed data to test if loading from prefs works.
   const TrialsSeed seed = CreateTestSeed();
-  const std::string base64_seed = SerializeSeedBase64(seed);
+  std::string seed_hash;
+  const std::string base64_seed = SerializeSeedBase64(seed, &seed_hash);
 
   TestingPrefServiceSimple prefs;
   VariationsService::RegisterPrefs(prefs.registry());
@@ -531,7 +539,8 @@
   TestVariationsService variations_service(new TestRequestAllowedNotifier,
                                            &prefs);
   TrialsSeed loaded_seed;
-  EXPECT_TRUE(variations_service.LoadTrialsSeedFromPref(&prefs, &loaded_seed));
+  // Check that loading a seed without a hash pref set works correctly.
+  EXPECT_TRUE(variations_service.LoadTrialsSeedFromPref(&loaded_seed));
 
   // Check that the loaded data is the same as the original.
   EXPECT_EQ(SerializeSeed(seed), SerializeSeed(loaded_seed));
@@ -539,16 +548,41 @@
   EXPECT_FALSE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
   EXPECT_EQ(base64_seed, prefs.GetString(prefs::kVariationsSeed));
 
+  // Check that loading a seed with the correct hash works.
+  prefs.SetString(prefs::kVariationsSeedHash, seed_hash);
+  loaded_seed.Clear();
+  EXPECT_TRUE(variations_service.LoadTrialsSeedFromPref(&loaded_seed));
+  EXPECT_EQ(SerializeSeed(seed), SerializeSeed(loaded_seed));
+
+  // Check that false is returned and the pref is cleared when hash differs.
+  TrialsSeed different_seed = seed;
+  different_seed.mutable_study(0)->set_name("octopus");
+  std::string different_hash;
+  prefs.SetString(prefs::kVariationsSeed,
+                  SerializeSeedBase64(different_seed, &different_hash));
+  ASSERT_NE(different_hash, prefs.GetString(prefs::kVariationsSeedHash));
+  EXPECT_FALSE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
+  EXPECT_FALSE(variations_service.LoadTrialsSeedFromPref(&loaded_seed));
+  EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
+  EXPECT_TRUE(
+      prefs.FindPreference(prefs::kVariationsSeedDate)->IsDefaultValue());
+  EXPECT_TRUE(
+      prefs.FindPreference(prefs::kVariationsSeedHash)->IsDefaultValue());
+
   // Check that loading a bad seed returns false and clears the pref.
   prefs.ClearPref(prefs::kVariationsSeed);
   prefs.SetString(prefs::kVariationsSeed, "this should fail");
   EXPECT_FALSE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
-  EXPECT_FALSE(variations_service.LoadTrialsSeedFromPref(&prefs, &loaded_seed));
+  EXPECT_FALSE(variations_service.LoadTrialsSeedFromPref(&loaded_seed));
   EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
+  EXPECT_TRUE(
+      prefs.FindPreference(prefs::kVariationsSeedDate)->IsDefaultValue());
+  EXPECT_TRUE(
+      prefs.FindPreference(prefs::kVariationsSeedHash)->IsDefaultValue());
 
   // Check that having no seed in prefs results in a return value of false.
   prefs.ClearPref(prefs::kVariationsSeed);
-  EXPECT_FALSE(variations_service.LoadTrialsSeedFromPref(&prefs, &loaded_seed));
+  EXPECT_FALSE(variations_service.LoadTrialsSeedFromPref(&loaded_seed));
 }
 
 TEST_F(VariationsServiceTest, StoreSeed) {
@@ -562,7 +596,7 @@
   TestVariationsService variations_service(new TestRequestAllowedNotifier,
                                            &prefs);
 
-  EXPECT_TRUE(variations_service.StoreSeedData(serialized_seed, now, &prefs));
+  EXPECT_TRUE(variations_service.StoreSeedData(serialized_seed, now));
   // Make sure the pref was actually set.
   EXPECT_FALSE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
 
@@ -575,7 +609,7 @@
 
   // Check if trying to store a bad seed leaves the pref unchanged.
   prefs.ClearPref(prefs::kVariationsSeed);
-  EXPECT_FALSE(variations_service.StoreSeedData("should fail", now, &prefs));
+  EXPECT_FALSE(variations_service.StoreSeedData("should fail", now));
   EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
 }
 
@@ -711,7 +745,8 @@
   EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
   variations_service.OnURLFetchComplete(fetcher);
   EXPECT_FALSE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
-  EXPECT_EQ(SerializeSeedBase64(seed), prefs.GetString(prefs::kVariationsSeed));
+  const std::string expected_base64 = SerializeSeedBase64(seed, NULL);
+  EXPECT_EQ(expected_base64, prefs.GetString(prefs::kVariationsSeed));
 }
 
 TEST_F(VariationsServiceTest, SeedNotStoredWhenNonOKStatus) {
@@ -747,13 +782,11 @@
 TEST_F(VariationsServiceTest, ForceGroupWithFlag1) {
   CommandLine::ForCurrentProcess()->AppendSwitch(kForcingFlag1);
 
-  base::FieldTrialList field_trial_list_(NULL);
-
-  TestVariationsService variations_service(new TestRequestAllowedNotifier,
-                                           NULL);
+  base::FieldTrialList field_trial_list(NULL);
+  TestVariationsService service(new TestRequestAllowedNotifier, NULL);
 
   Study study = CreateStudyWithFlagGroups(100, 0, 0);
-  variations_service.CreateTrialFromStudy(study, kReferenceTime);
+  service.CreateTrialFromStudy(study, kReferenceTime);
 
   EXPECT_EQ(kFlagGroup1Name,
             base::FieldTrialList::FindFullName(kFlagStudyName));
@@ -763,13 +796,11 @@
 TEST_F(VariationsServiceTest, ForceGroupWithFlag2) {
   CommandLine::ForCurrentProcess()->AppendSwitch(kForcingFlag2);
 
-  base::FieldTrialList field_trial_list_(NULL);
-
-  TestVariationsService variations_service(new TestRequestAllowedNotifier,
-                                           NULL);
+  base::FieldTrialList field_trial_list(NULL);
+  TestVariationsService service(new TestRequestAllowedNotifier, NULL);
 
   Study study = CreateStudyWithFlagGroups(100, 0, 0);
-  variations_service.CreateTrialFromStudy(study, kReferenceTime);
+  service.CreateTrialFromStudy(study, kReferenceTime);
 
   EXPECT_EQ(kFlagGroup2Name,
             base::FieldTrialList::FindFullName(kFlagStudyName));
@@ -780,31 +811,56 @@
   CommandLine::ForCurrentProcess()->AppendSwitch(kForcingFlag1);
   CommandLine::ForCurrentProcess()->AppendSwitch(kForcingFlag2);
 
-  base::FieldTrialList field_trial_list_(NULL);
-
-  TestVariationsService variations_service(new TestRequestAllowedNotifier,
-                                           NULL);
+  base::FieldTrialList field_trial_list(NULL);
+  TestVariationsService service(new TestRequestAllowedNotifier, NULL);
 
   Study study = CreateStudyWithFlagGroups(100, 0, 0);
-  variations_service.CreateTrialFromStudy(study, kReferenceTime);
+  service.CreateTrialFromStudy(study, kReferenceTime);
 
   EXPECT_EQ(kFlagGroup1Name,
             base::FieldTrialList::FindFullName(kFlagStudyName));
 }
 
 TEST_F(VariationsServiceTest, DontChooseGroupWithFlag) {
-  base::FieldTrialList field_trial_list_(NULL);
-
-  TestVariationsService variations_service(new TestRequestAllowedNotifier,
-                                           NULL);
+  base::FieldTrialList field_trial_list(NULL);
+  TestVariationsService service(new TestRequestAllowedNotifier, NULL);
 
   // The two flag groups are given high probability, which would normaly make
   // them very likely to be choosen. They won't be chosen since flag groups are
   // never chosen when their flag isn't preasent.
   Study study = CreateStudyWithFlagGroups(1, 999, 999);
-  variations_service.CreateTrialFromStudy(study, kReferenceTime);
+  service.CreateTrialFromStudy(study, kReferenceTime);
   EXPECT_EQ(kNonFlagGroupName,
             base::FieldTrialList::FindFullName(kFlagStudyName));
 }
 
+TEST_F(VariationsServiceTest, VariationParams) {
+  base::FieldTrialList field_trial_list(NULL);
+  TestVariationsService service(new TestRequestAllowedNotifier, NULL);
+
+  Study study;
+  study.set_name("Study1");
+  study.set_default_experiment_name("B");
+
+  Study_Experiment* experiment1 = study.add_experiment();
+  experiment1->set_name("A");
+  experiment1->set_probability_weight(1);
+  Study_Experiment_Param* param = experiment1->add_param();
+  param->set_name("x");
+  param->set_value("y");
+
+  Study_Experiment* experiment2 = study.add_experiment();
+  experiment2->set_name("B");
+  experiment2->set_probability_weight(0);
+
+  service.CreateTrialFromStudy(study, kReferenceTime);
+  EXPECT_EQ("y", GetVariationParamValue("Study1", "x"));
+
+  study.set_name("Study2");
+  experiment1->set_probability_weight(0);
+  experiment2->set_probability_weight(1);
+  service.CreateTrialFromStudy(study, kReferenceTime);
+  EXPECT_EQ(std::string(), GetVariationParamValue("Study2", "x"));
+}
+
 }  // namespace chrome_variations
diff --git a/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc b/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc
index 3518726..ef86c41 100644
--- a/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc
+++ b/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc
@@ -4,10 +4,12 @@
 
 #include "chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h"
 
+#include "ash/shell.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part_aurawin.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/search_engines/util.h"
 #include "chrome/browser/ui/ash/ash_init.h"
@@ -17,7 +19,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/page_navigator.h"
@@ -90,6 +91,8 @@
       AcceleratedPresenter::GetForWindow(NULL);
   any_window->SetNewTargetWindow(hwnd);
   aura::RemoteRootWindowHostWin::Instance()->Connected(this);
+  ash::Shell::GetInstance()->CreateLauncher();
+  ash::Shell::GetInstance()->ShowLauncher();
   // Tell the rest of Chrome that Ash is running.
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_ASH_SESSION_STARTED,
diff --git a/chrome/browser/nacl_host/nacl_broker_host_win.cc b/chrome/browser/nacl_host/nacl_broker_host_win.cc
index 74e4161..f0eca4d 100644
--- a/chrome/browser/nacl_host/nacl_broker_host_win.cc
+++ b/chrome/browser/nacl_host/nacl_broker_host_win.cc
@@ -4,20 +4,20 @@
 
 #include "chrome/browser/nacl_host/nacl_broker_host_win.h"
 
+#include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/path_service.h"
 #include "ipc/ipc_switches.h"
 #include "chrome/browser/nacl_host/nacl_broker_service_win.h"
 #include "chrome/browser/nacl_host/nacl_browser.h"
-#include "chrome/common/chrome_process_type.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/logging_chrome.h"
 #include "chrome/common/nacl_cmd_line.h"
 #include "chrome/common/nacl_messages.h"
+#include "components/nacl/common/nacl_process_type.h"
 #include "components/nacl/common/nacl_switches.h"
 #include "content/public/browser/browser_child_process_host.h"
 #include "content/public/browser/child_process_data.h"
 #include "content/public/common/child_process_host.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/common/sandboxed_process_launcher_delegate.h"
 
 namespace {
@@ -62,7 +62,7 @@
   cmd_line->AppendSwitchASCII(switches::kProcessType,
                               switches::kNaClBrokerProcess);
   cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
-  if (logging::DialogsAreSuppressed())
+  if (NaClBrowser::GetDelegate()->DialogsAreSuppressed())
     cmd_line->AppendSwitch(switches::kNoErrorDialogs);
 
   process_->Launch(new NaClBrokerSandboxedProcessLauncherDelegate, cmd_line);
diff --git a/chrome/browser/nacl_host/nacl_broker_service_win.cc b/chrome/browser/nacl_host/nacl_broker_service_win.cc
index b270012..0fb96f6 100644
--- a/chrome/browser/nacl_host/nacl_broker_service_win.cc
+++ b/chrome/browser/nacl_host/nacl_broker_service_win.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/nacl_host/nacl_broker_service_win.h"
 
 #include "chrome/browser/nacl_host/nacl_process_host.h"
-#include "chrome/common/chrome_process_type.h"
+#include "components/nacl/common/nacl_process_type.h"
 #include "content/public/browser/browser_child_process_host_iterator.h"
 
 using content::BrowserChildProcessHostIterator;
diff --git a/chrome/browser/nacl_host/nacl_browser.cc b/chrome/browser/nacl_host/nacl_browser.cc
index 9cf4bcd..ea9ea0f 100644
--- a/chrome/browser/nacl_host/nacl_browser.cc
+++ b/chrome/browser/nacl_host/nacl_browser.cc
@@ -14,9 +14,6 @@
 #include "base/strings/string_split.h"
 #include "base/win/windows_version.h"
 #include "build/build_config.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_paths_internal.h"
-#include "chrome/common/chrome_switches.h"
 #include "content/public/browser/browser_thread.h"
 #include "extensions/common/url_pattern.h"
 #include "url/gurl.h"
@@ -101,7 +98,7 @@
 
 void RemoveCache(const base::FilePath& filename,
                  const base::Closure& callback) {
-  base::Delete(filename, false);
+  base::DeleteFile(filename, false);
   content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
                                    callback);
 }
@@ -149,7 +146,7 @@
   }
 }
 
-}
+} // namespace nacl
 
 NaClBrowser::NaClBrowser()
     : weak_factory_(this),
@@ -166,6 +163,19 @@
       validation_cache_state_(NaClResourceUninitialized),
       path_cache_(kFilePathCacheSize),
       ok_(true) {
+}
+
+void NaClBrowser::SetDelegate(NaClBrowserDelegate* delegate) {
+  NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
+  nacl_browser->browser_delegate_.reset(delegate);
+}
+
+NaClBrowserDelegate* NaClBrowser::GetDelegate() {
+  DCHECK(GetInstance()->browser_delegate_.get() != NULL);
+  return GetInstance()->browser_delegate_.get();
+}
+
+void NaClBrowser::EarlyStartup() {
   InitIrtFilePath();
   InitValidationCacheFilePath();
 }
@@ -188,7 +198,7 @@
     irt_filepath_ = base::FilePath(path_string);
   } else {
     base::FilePath plugin_dir;
-    if (!PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &plugin_dir)) {
+    if (!browser_delegate_->GetPluginDirectory(&plugin_dir)) {
       DLOG(ERROR) << "Failed to locate the plugins directory, NaCl disabled.";
       MarkAsFailed();
       return;
@@ -340,13 +350,13 @@
   // profile.
   // Start by finding the user data directory.
   base::FilePath user_data_dir;
-  if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
+  if (!browser_delegate_->GetUserDirectory(&user_data_dir)) {
     RunWithoutValidationCache();
     return;
   }
   // The cache directory may or may not be the user data directory.
   base::FilePath cache_file_path;
-  chrome::GetUserCacheDirectory(user_data_dir, &cache_file_path);
+  browser_delegate_->GetCacheDirectory(&cache_file_path);
   // Append the base file name to the cache directory.
 
   validation_cache_file_path_ =
diff --git a/chrome/browser/nacl_host/nacl_browser.h b/chrome/browser/nacl_host/nacl_browser.h
index 77bae0f..f9c6d9c 100644
--- a/chrome/browser/nacl_host/nacl_browser.h
+++ b/chrome/browser/nacl_host/nacl_browser.h
@@ -12,6 +12,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/platform_file.h"
 #include "chrome/browser/nacl_host/nacl_validation_cache.h"
+#include "components/nacl/common/nacl_browser_delegate.h"
 
 class URLPattern;
 class GURL;
@@ -115,6 +116,9 @@
   bool GetNaCl64ExePath(base::FilePath* exe_path);
 #endif
 
+  void EarlyStartup();
+  static void SetDelegate(NaClBrowserDelegate* delegate);
+  static NaClBrowserDelegate* GetDelegate();
  private:
   friend struct DefaultSingletonTraits<NaClBrowser>;
 
@@ -172,6 +176,7 @@
   // A list of pending tasks to start NaCl processes.
   std::vector<base::Closure> waiting_;
 
+  scoped_ptr<NaClBrowserDelegate> browser_delegate_;
   DISALLOW_COPY_AND_ASSIGN(NaClBrowser);
 };
 
diff --git a/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc b/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc
new file mode 100644
index 0000000..c90aa92
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc
@@ -0,0 +1,58 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/nacl_host/nacl_browser_delegate_impl.h"
+
+#include "base/path_service.h"
+#include "chrome/browser/nacl_host/nacl_infobar_delegate.h"
+#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_paths_internal.h"
+#include "chrome/common/chrome_version_info.h"
+#include "chrome/common/logging_chrome.h"
+#include "content/public/browser/browser_thread.h"
+#include "ppapi/c/private/ppb_nacl_private.h"
+
+void NaClBrowserDelegateImpl::ShowNaClInfobar(int render_process_id,
+                                              int render_view_id,
+                                              int error_id) {
+  DCHECK_EQ(PP_NACL_MANIFEST_MISSING_ARCH, error_id);
+  content::BrowserThread::PostTask(
+      content::BrowserThread::UI, FROM_HERE,
+      base::Bind(&NaClInfoBarDelegate::Create, render_process_id,
+                 render_view_id));
+}
+
+bool NaClBrowserDelegateImpl::DialogsAreSuppressed() {
+  return logging::DialogsAreSuppressed();
+}
+
+bool NaClBrowserDelegateImpl::GetCacheDirectory(base::FilePath* cache_dir) {
+  base::FilePath user_data_dir;
+  if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
+    return false;
+  chrome::GetUserCacheDirectory(user_data_dir, cache_dir);
+  return true;
+}
+
+bool NaClBrowserDelegateImpl::GetPluginDirectory(base::FilePath* plugin_dir) {
+  return PathService::Get(chrome::DIR_INTERNAL_PLUGINS, plugin_dir);
+}
+
+bool NaClBrowserDelegateImpl::GetPnaclDirectory(base::FilePath* pnacl_dir) {
+  return PathService::Get(chrome::DIR_PNACL_COMPONENT, pnacl_dir);
+}
+
+bool NaClBrowserDelegateImpl::GetUserDirectory(base::FilePath* user_dir) {
+  return PathService::Get(chrome::DIR_USER_DATA, user_dir);
+}
+
+std::string NaClBrowserDelegateImpl::GetVersionString() const {
+  return chrome::VersionInfo().CreateVersionString();
+}
+
+ppapi::host::HostFactory* NaClBrowserDelegateImpl::CreatePpapiHostFactory(
+    content::BrowserPpapiHost* ppapi_host) {
+  return new chrome::ChromeBrowserPepperHostFactory(ppapi_host);
+}
diff --git a/chrome/browser/nacl_host/nacl_browser_delegate_impl.h b/chrome/browser/nacl_host/nacl_browser_delegate_impl.h
new file mode 100644
index 0000000..fc9c2b7
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_browser_delegate_impl.h
@@ -0,0 +1,29 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NACL_HOST_NACL_BROWSER_DELEGATE_IMPL_H_
+#define CHROME_BROWSER_NACL_HOST_NACL_BROWSER_DELEGATE_IMPL_H_
+
+#include "base/compiler_specific.h"
+#include "components/nacl/common/nacl_browser_delegate.h"
+
+class NaClBrowserDelegateImpl : public NaClBrowserDelegate {
+ public:
+  NaClBrowserDelegateImpl() {}
+  virtual ~NaClBrowserDelegateImpl() {}
+
+  virtual void ShowNaClInfobar(int render_process_id, int render_view_id,
+                               int error_id) OVERRIDE;
+  virtual bool DialogsAreSuppressed() OVERRIDE;
+  virtual bool GetCacheDirectory(base::FilePath* cache_dir) OVERRIDE;
+  virtual bool GetPluginDirectory(base::FilePath* plugin_dir) OVERRIDE;
+  virtual bool GetPnaclDirectory(base::FilePath* pnacl_dir) OVERRIDE;
+  virtual bool GetUserDirectory(base::FilePath* user_dir) OVERRIDE;
+  virtual std::string GetVersionString() const OVERRIDE;
+  virtual ppapi::host::HostFactory* CreatePpapiHostFactory(
+      content::BrowserPpapiHost* ppapi_host) OVERRIDE;
+};
+
+
+#endif  // CHROME_BROWSER_NACL_HOST_NACL_BROWSER_DELEGATE_IMPL_H_
diff --git a/chrome/browser/nacl_host/nacl_file_host.cc b/chrome/browser/nacl_host/nacl_file_host.cc
index 1acca3a..18efee9 100644
--- a/chrome/browser/nacl_host/nacl_file_host.cc
+++ b/chrome/browser/nacl_host/nacl_file_host.cc
@@ -16,9 +16,9 @@
 #include "chrome/browser/extensions/extension_info_map.h"
 #include "chrome/browser/nacl_host/nacl_browser.h"
 #include "chrome/browser/nacl_host/nacl_host_message_filter.h"
-#include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/manifest_handlers/shared_module_info.h"
 #include "chrome/common/nacl_host_messages.h"
+#include "components/nacl/common/nacl_browser_delegate.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/site_instance.h"
@@ -107,8 +107,8 @@
 
   // PNaCl must be installed.
   base::FilePath pnacl_dir;
-  if (!PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_dir) ||
-      !file_util::PathExists(pnacl_dir)) {
+  if (!NaClBrowser::GetDelegate()->GetPnaclDirectory(&pnacl_dir) ||
+      !base::PathExists(pnacl_dir)) {
     BrowserThread::PostTask(
         BrowserThread::UI, FROM_HERE,
         base::Bind(&TryInstallPnacl,
@@ -134,7 +134,7 @@
   // Do any DuplicateHandle magic that is necessary first.
   IPC::PlatformFileForTransit target_desc =
       IPC::GetFileHandleForProcess(file_to_open,
-                                   nacl_host_message_filter->peer_handle(),
+                                   nacl_host_message_filter->PeerHandle(),
                                    true /* Close source */);
   if (target_desc == IPC::InvalidPlatformFileForTransit()) {
     NotifyRendererOfError(nacl_host_message_filter.get(), reply_msg);
@@ -145,16 +145,13 @@
   nacl_host_message_filter->Send(reply_msg);
 }
 
-void DoCreateTemporaryFile(
-    scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter,
-    IPC::Message* reply_msg) {
+IPC::PlatformFileForTransit GetTemporaryFile(
+    scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter) {
   DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
 
   base::FilePath file_path;
-  if (!file_util::CreateTemporaryFile(&file_path)) {
-    NotifyRendererOfError(nacl_host_message_filter.get(), reply_msg);
-    return;
-  }
+  if (!file_util::CreateTemporaryFile(&file_path))
+    return IPC::InvalidPlatformFileForTransit();
 
   base::PlatformFileError error;
   base::PlatformFile file_handle = base::CreatePlatformFile(
@@ -164,25 +161,20 @@
       base::PLATFORM_FILE_DELETE_ON_CLOSE,
       NULL, &error);
 
-  if (error != base::PLATFORM_FILE_OK) {
-    NotifyRendererOfError(nacl_host_message_filter.get(), reply_msg);
-    return;
-  }
+  if (error != base::PLATFORM_FILE_OK)
+    return IPC::InvalidPlatformFileForTransit();
 
-  // Send the reply!
   // Do any DuplicateHandle magic that is necessary first.
-  IPC::PlatformFileForTransit target_desc =
-      IPC::GetFileHandleForProcess(file_handle,
-                                   nacl_host_message_filter->peer_handle(),
-                                   true);
-  if (target_desc == IPC::InvalidPlatformFileForTransit()) {
-    NotifyRendererOfError(nacl_host_message_filter.get(), reply_msg);
-    return;
-  }
+  return IPC::GetFileHandleForProcess(file_handle,
+                                      nacl_host_message_filter->PeerHandle(),
+                                      true);
+}
 
-  NaClHostMsg_NaClCreateTemporaryFile::WriteReplyParams(
-      reply_msg, target_desc);
-  nacl_host_message_filter->Send(reply_msg);
+void ReturnTemporaryFileOnIOThread(
+    nacl_file_host::TempFileCallback cb,
+    IPC::PlatformFileForTransit fd) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  cb.Run(fd);
 }
 
 void DoRegisterOpenedNaClExecutableFile(
@@ -200,7 +192,7 @@
 
   IPC::PlatformFileForTransit file_desc = IPC::GetFileHandleForProcess(
       file,
-      nacl_host_message_filter->peer_handle(),
+      nacl_host_message_filter->PeerHandle(),
       true /* close_source */);
 
   NaClHostMsg_OpenNaClExecutable::WriteReplyParams(
@@ -331,7 +323,7 @@
 
   // PNaCl must be installed.
   base::FilePath pnacl_dir;
-  if (!PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_dir) ||
+  if (!NaClBrowser::GetDelegate()->GetPnaclDirectory(&pnacl_dir) ||
       pnacl_dir.empty())
     return false;
 
@@ -344,13 +336,14 @@
 
 void CreateTemporaryFile(
     scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter,
-    IPC::Message* reply_msg) {
-  if (!BrowserThread::PostBlockingPoolTask(
-      FROM_HERE,
-      base::Bind(&DoCreateTemporaryFile,
-                 nacl_host_message_filter,
-                 reply_msg))) {
-    NotifyRendererOfError(nacl_host_message_filter.get(), reply_msg);
+    TempFileCallback cb) {
+    if (!base::PostTaskAndReplyWithResult(
+            BrowserThread::GetBlockingPool(),
+            FROM_HERE,
+            base::Bind(&GetTemporaryFile, nacl_host_message_filter),
+            base::Bind(&ReturnTemporaryFileOnIOThread, cb))) {
+    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+    cb.Run(IPC::InvalidPlatformFileForTransit());
   }
 }
 
diff --git a/chrome/browser/nacl_host/nacl_file_host.h b/chrome/browser/nacl_host/nacl_file_host.h
index 3491688..b27a87e 100644
--- a/chrome/browser/nacl_host/nacl_file_host.h
+++ b/chrome/browser/nacl_host/nacl_file_host.h
@@ -7,7 +7,9 @@
 
 #include <string>
 
+#include "base/callback.h"
 #include "base/memory/ref_counted.h"
+#include "ipc/ipc_platform_file.h"
 
 class ExtensionInfoMap;
 class GURL;
@@ -24,6 +26,7 @@
 // Opens NaCl Files in the Browser process, on behalf of the NaCl plugin.
 
 namespace nacl_file_host {
+typedef base::Callback<void(IPC::PlatformFileForTransit)> TempFileCallback;
 
 // Open a Pnacl file (readonly) on behalf of the NaCl plugin.
 void GetReadonlyPnaclFd(
@@ -40,7 +43,7 @@
 // is closed, or earlier.
 void CreateTemporaryFile(
     scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter,
-    IPC::Message* reply_msg);
+    TempFileCallback cb);
 
 // Opens a NaCl executable file for reading and executing.
 void OpenNaClExecutable(
diff --git a/chrome/browser/nacl_host/nacl_file_host_unittest.cc b/chrome/browser/nacl_host/nacl_file_host_unittest.cc
index 73c26df..7b27bed 100644
--- a/chrome/browser/nacl_host/nacl_file_host_unittest.cc
+++ b/chrome/browser/nacl_host/nacl_file_host_unittest.cc
@@ -9,22 +9,69 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
 #include "base/test/scoped_path_override.h"
-#include "chrome/common/chrome_paths.h"
-
+#include "chrome/browser/nacl_host/nacl_browser.h"
+#include "components/nacl/common/nacl_browser_delegate.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using nacl_file_host::PnaclCanOpenFile;
 
+class DummyNaClBrowserDelegate : public NaClBrowserDelegate {
+ public:
+  virtual void ShowNaClInfobar(int render_process_id,
+                               int render_view_id,
+                               int error_id) OVERRIDE {
+  }
+
+  virtual bool DialogsAreSuppressed() OVERRIDE {
+    return false;
+  }
+
+  virtual bool GetCacheDirectory(base::FilePath* cache_dir) OVERRIDE {
+    return false;
+  }
+
+  virtual bool GetPluginDirectory(base::FilePath* plugin_dir) OVERRIDE {
+    return false;
+  }
+
+  virtual bool GetPnaclDirectory(base::FilePath* pnacl_dir) OVERRIDE {
+    *pnacl_dir = pnacl_path_;
+    return true;
+  }
+
+  virtual bool GetUserDirectory(base::FilePath* user_dir) OVERRIDE {
+    return false;
+  }
+
+  virtual std::string GetVersionString() const OVERRIDE {
+    return std::string();
+  }
+
+  virtual ppapi::host::HostFactory* CreatePpapiHostFactory(
+      content::BrowserPpapiHost* ppapi_host) OVERRIDE {
+    return NULL;
+  }
+
+  void SetPnaclDirectory(const base::FilePath& pnacl_dir) {
+    pnacl_path_ = pnacl_dir;
+  }
+
+ private:
+  base::FilePath pnacl_path_;
+};
+
 // Try to pass a few funny filenames with a dummy pnacl directory set.
 TEST(PnaclFileHostTest, TestFilenamesWithPnaclPath) {
   base::ScopedTempDir scoped_tmp_dir;
   ASSERT_TRUE(scoped_tmp_dir.CreateUniqueTempDir());
 
   base::FilePath kDummyPnaclPath = scoped_tmp_dir.path();
-  base::ScopedPathOverride pnach_dir_override(chrome::DIR_PNACL_COMPONENT,
-                                              kDummyPnaclPath);
-  ASSERT_TRUE(PathService::Get(chrome::DIR_PNACL_COMPONENT,
-                               &kDummyPnaclPath));
+
+  DummyNaClBrowserDelegate* nacl_browser_delegate =
+      new DummyNaClBrowserDelegate;
+  nacl_browser_delegate->SetPnaclDirectory(kDummyPnaclPath);
+  NaClBrowser::SetDelegate(nacl_browser_delegate);
+  ASSERT_TRUE(NaClBrowser::GetDelegate()->GetPnaclDirectory(&kDummyPnaclPath));
 
   // Check allowed strings, and check that the expected prefix is added.
   base::FilePath out_path;
@@ -70,4 +117,5 @@
   EXPECT_FALSE(PnaclCanOpenFile("$HOME", &out_path));
   EXPECT_FALSE(PnaclCanOpenFile("$HOME/.bashrc", &out_path));
 #endif
+  NaClBrowser::SetDelegate(NULL);
 }
diff --git a/chrome/browser/nacl_host/nacl_host_message_filter.cc b/chrome/browser/nacl_host/nacl_host_message_filter.cc
index 1cb2167..01cc5f8 100644
--- a/chrome/browser/nacl_host/nacl_host_message_filter.cc
+++ b/chrome/browser/nacl_host/nacl_host_message_filter.cc
@@ -4,21 +4,14 @@
 
 #include "chrome/browser/nacl_host/nacl_host_message_filter.h"
 
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/file_util.h"
-#include "base/metrics/histogram.h"
 #include "chrome/browser/extensions/extension_info_map.h"
-#include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/nacl_host/nacl_browser.h"
 #include "chrome/browser/nacl_host/nacl_file_host.h"
-#include "chrome/browser/nacl_host/nacl_infobar.h"
 #include "chrome/browser/nacl_host/nacl_process_host.h"
-#include "chrome/common/extensions/extension.h"
 #include "chrome/common/nacl_host_messages.h"
 #include "extensions/common/constants.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_getter.h"
-#include "url/gurl.h"
 
 static base::FilePath GetManifestPath(
     ExtensionInfoMap* extension_info_map, const std::string& manifest) {
@@ -61,6 +54,10 @@
                                     OnGetReadonlyPnaclFd)
     IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClHostMsg_NaClCreateTemporaryFile,
                                     OnNaClCreateTemporaryFile)
+    IPC_MESSAGE_HANDLER(NaClHostMsg_NexeTempFileRequest,
+                        OnGetNexeFd)
+    IPC_MESSAGE_HANDLER(NaClHostMsg_ReportTranslationFinished,
+                        OnTranslationFinished)
     IPC_MESSAGE_HANDLER(NaClHostMsg_NaClErrorStatus, OnNaClErrorStatus)
     IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClHostMsg_OpenNaClExecutable,
                                     OnOpenNaClExecutable)
@@ -88,9 +85,8 @@
       launch_params.enable_exception_handling,
       off_the_record_,
       profile_directory_);
-  base::FilePath manifest_url = GetManifestPath(
-        extension_info_map_,
-        launch_params.manifest_url);
+  base::FilePath manifest_url =
+      GetManifestPath(extension_info_map_.get(), launch_params.manifest_url);
   host->Launch(this, reply_msg, manifest_url);
 }
 
@@ -101,16 +97,59 @@
   nacl_file_host::GetReadonlyPnaclFd(this, filename, reply_msg);
 }
 
+// Return the temporary file via a reply to the
+// NaClHostMsg_NaClCreateTemporaryFile sync message.
+void NaClHostMessageFilter::SyncReturnTemporaryFile(
+    IPC::Message* reply_msg,
+    IPC::PlatformFileForTransit fd) {
+  if (fd == IPC::InvalidPlatformFileForTransit()) {
+    reply_msg->set_reply_error();
+  } else {
+    NaClHostMsg_NaClCreateTemporaryFile::WriteReplyParams(
+        reply_msg, fd);
+  }
+  Send(reply_msg);
+}
+
 void NaClHostMessageFilter::OnNaClCreateTemporaryFile(
     IPC::Message* reply_msg) {
-  nacl_file_host::CreateTemporaryFile(this, reply_msg);
+  nacl_file_host::CreateTemporaryFile(
+      this,
+      base::Bind(&NaClHostMessageFilter::SyncReturnTemporaryFile,
+                 this,
+                 reply_msg));
+}
+
+// For now, GetNexeFd cache requests always set is_hit to false and returns
+// a new temporary file via a NaClViewMsg_NexeTempFileReply message.
+// A future CL will implement the cache lookup logic.
+// See also https://code.google.com/p/nativeclient/issues/detail?id=3372
+void NaClHostMessageFilter::AsyncReturnTemporaryFile(
+    int render_view_id,
+    IPC::PlatformFileForTransit fd) {
+  Send(new NaClViewMsg_NexeTempFileReply(render_view_id, false, fd));
+}
+
+void NaClHostMessageFilter::OnGetNexeFd(
+    int render_view_id,
+    const nacl::PnaclCacheInfo& cache_info) {
+  nacl_file_host::CreateTemporaryFile(
+      this,
+      base::Bind(&NaClHostMessageFilter::AsyncReturnTemporaryFile,
+                 this,
+                 render_view_id));
+}
+
+// For now, ignore translation finished messages. A future CL will implement
+// the logic of reading the nexe from the temp file and storing it in the cache.
+// See also https://code.google.com/p/nativeclient/issues/detail?id=3372
+void NaClHostMessageFilter::OnTranslationFinished(int render_view_id) {
 }
 
 void NaClHostMessageFilter::OnNaClErrorStatus(int render_view_id,
                                               int error_id) {
-  // Currently there is only one kind of error status, for which
-  // we want to show the user an infobar.
-  ShowNaClInfobar(render_process_id_, render_view_id, error_id);
+  NaClBrowser::GetDelegate()->ShowNaClInfobar(render_process_id_,
+                                              render_view_id, error_id);
 }
 
 void NaClHostMessageFilter::OnOpenNaClExecutable(int render_view_id,
diff --git a/chrome/browser/nacl_host/nacl_host_message_filter.h b/chrome/browser/nacl_host/nacl_host_message_filter.h
index 4d9cdb0..8c99c55 100644
--- a/chrome/browser/nacl_host/nacl_host_message_filter.h
+++ b/chrome/browser/nacl_host/nacl_host_message_filter.h
@@ -8,12 +8,14 @@
 #include "base/files/file_path.h"
 #include "base/memory/weak_ptr.h"
 #include "content/public/browser/browser_message_filter.h"
+#include "ipc/ipc_platform_file.h"
 
 class ExtensionInfoMap;
 class GURL;
 
 namespace nacl {
 struct NaClLaunchParams;
+struct PnaclCacheInfo;
 }
 
 namespace net {
@@ -51,10 +53,17 @@
   void OnGetReadonlyPnaclFd(const std::string& filename,
                             IPC::Message* reply_msg);
   void OnNaClCreateTemporaryFile(IPC::Message* reply_msg);
+  void OnGetNexeFd(int render_view_id, const nacl::PnaclCacheInfo& cache_info);
+  void OnTranslationFinished(int render_view_id);
   void OnNaClErrorStatus(int render_view_id, int error_id);
   void OnOpenNaClExecutable(int render_view_id,
                             const GURL& file_url,
                             IPC::Message* reply_msg);
+
+  void SyncReturnTemporaryFile(IPC::Message* reply_msg,
+                               IPC::PlatformFileForTransit fd);
+  void AsyncReturnTemporaryFile(int render_view_id,
+                                IPC::PlatformFileForTransit fd);
 #endif
   int render_process_id_;
 
diff --git a/chrome/browser/nacl_host/nacl_infobar.cc b/chrome/browser/nacl_host/nacl_infobar.cc
deleted file mode 100644
index e9c33d4..0000000
--- a/chrome/browser/nacl_host/nacl_infobar.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/nacl_host/nacl_infobar.h"
-
-#include "base/bind.h"
-#include "base/strings/string16.h"
-#include "chrome/browser/infobars/confirm_infobar_delegate.h"
-#include "chrome/browser/infobars/infobar_service.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/web_contents.h"
-#include "grit/generated_resources.h"
-#include "ppapi/c/private/ppb_nacl_private.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "url/gurl.h"
-
-using content::BrowserThread;
-using content::RenderViewHost;
-using content::WebContents;
-
-namespace {
-// The URL for the "learn more" article.
-const char kNaClLearnMoreUrl[] =
-    "https://support.google.com/chrome/?p=ib_nacl";
-
-// A simple LinkInfoBarDelegate doesn't support making the link right-aligned
-// so use a ConfirmInfoBarDelegate without any buttons instead.
-class NaClInfoBarDelegate : public ConfirmInfoBarDelegate {
- public:
-  static void Create(InfoBarService* ibs, WebContents* wc);
-
- private:
-  NaClInfoBarDelegate(WebContents* wc, InfoBarService* ibs) :
-      ConfirmInfoBarDelegate(ibs), wc_(wc) {}
-
-  virtual string16 GetMessageText() const OVERRIDE;
-  virtual int GetButtons() const OVERRIDE;
-  virtual string16 GetLinkText() const OVERRIDE;
-  virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE;
-
-  WebContents* wc_;
-
-  DISALLOW_COPY_AND_ASSIGN(NaClInfoBarDelegate);
-};
-
-// static
-void NaClInfoBarDelegate::Create(InfoBarService* ibs, WebContents *wc) {
-  ibs->AddInfoBar(scoped_ptr<InfoBarDelegate>(
-      new NaClInfoBarDelegate(wc, ibs)));
-}
-
-string16 NaClInfoBarDelegate::GetMessageText() const {
-  return l10n_util::GetStringUTF16(IDS_NACL_APP_MISSING_ARCH_MESSAGE);
-}
-
-int NaClInfoBarDelegate::GetButtons() const { return BUTTON_NONE; }
-
-string16 NaClInfoBarDelegate::GetLinkText() const {
-  return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
-}
-
-bool NaClInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition) {
-  content::OpenURLParams params(
-      GURL(kNaClLearnMoreUrl), content::Referrer(),
-      (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
-      content::PAGE_TRANSITION_LINK,
-      false);
-  wc_->OpenURL(params);
-  return false;
-}
-
-void ShowInfobar(int render_process_id, int render_view_id,
-                 int error_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(static_cast<PP_NaClError>(error_id) ==
-        PP_NACL_MANIFEST_MISSING_ARCH);
-  RenderViewHost* rvh = RenderViewHost::FromID(render_process_id,
-                                               render_view_id);
-  if (!rvh)
-    return;
-
-  WebContents* wc = WebContents::FromRenderViewHost(rvh);
-  if (!wc)
-    return;
-
-  InfoBarService* infobar_service = InfoBarService::FromWebContents(wc);
-  if (infobar_service)
-    NaClInfoBarDelegate::Create(infobar_service, wc);
-}
-
-}  // namespace
-
-void ShowNaClInfobar(int render_process_id, int render_view_id,
-                     int error_id) {
-  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-      base::Bind(&ShowInfobar, render_process_id, render_view_id,
-                 error_id));
-}
diff --git a/chrome/browser/nacl_host/nacl_infobar.h b/chrome/browser/nacl_host/nacl_infobar.h
deleted file mode 100644
index 89e2f26..0000000
--- a/chrome/browser/nacl_host/nacl_infobar.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_NACL_HOST_NACL_INFOBAR_H_
-#define CHROME_BROWSER_NACL_HOST_NACL_INFOBAR_H_
-
-// Display an infobar to the user. The message_id corresponds to
-// a PP_NaClError enum in ppb_nacl_private_impl.idl
-void ShowNaClInfobar(int render_process_id, int render_view_id,
-                     int error_id);
-
-#endif  // CHROME_BROWSER_NACL_HOST_NACL_INFOBAR_H_
diff --git a/chrome/browser/nacl_host/nacl_infobar_delegate.cc b/chrome/browser/nacl_host/nacl_infobar_delegate.cc
new file mode 100644
index 0000000..b9e08b8
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_infobar_delegate.cc
@@ -0,0 +1,57 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/nacl_host/nacl_infobar_delegate.h"
+
+#include "chrome/browser/infobars/infobar_service.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/web_contents.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
+
+
+// static
+void NaClInfoBarDelegate::Create(int render_process_id, int render_view_id) {
+  content::RenderViewHost* rvh =
+      content::RenderViewHost::FromID(render_process_id, render_view_id);
+  if (!rvh)
+    return;
+  content::WebContents* web_contents =
+      content::WebContents::FromRenderViewHost(rvh);
+  if (!web_contents)
+    return;
+  InfoBarService* infobar_service =
+      InfoBarService::FromWebContents(web_contents);
+  if (infobar_service)
+    infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
+        new NaClInfoBarDelegate(infobar_service)));
+}
+
+NaClInfoBarDelegate::NaClInfoBarDelegate(InfoBarService* infobar_service)
+    : ConfirmInfoBarDelegate(infobar_service) {
+}
+
+NaClInfoBarDelegate::~NaClInfoBarDelegate() {
+}
+
+string16 NaClInfoBarDelegate::GetMessageText() const {
+  return l10n_util::GetStringUTF16(IDS_NACL_APP_MISSING_ARCH_MESSAGE);
+}
+
+int NaClInfoBarDelegate::GetButtons() const {
+  return BUTTON_NONE;
+}
+
+string16 NaClInfoBarDelegate::GetLinkText() const {
+  return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
+}
+
+bool NaClInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition) {
+  web_contents()->OpenURL(content::OpenURLParams(
+      GURL("https://support.google.com/chrome/?p=ib_nacl"), content::Referrer(),
+      (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
+      content::PAGE_TRANSITION_LINK, false));
+  return false;
+}
diff --git a/chrome/browser/nacl_host/nacl_infobar_delegate.h b/chrome/browser/nacl_host/nacl_infobar_delegate.h
new file mode 100644
index 0000000..c3da4d4
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_infobar_delegate.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NACL_HOST_NACL_INFOBAR_DELEGATE_H_
+#define CHROME_BROWSER_NACL_HOST_NACL_INFOBAR_DELEGATE_H_
+
+#include "chrome/browser/infobars/confirm_infobar_delegate.h"
+
+class NaClInfoBarDelegate : public ConfirmInfoBarDelegate {
+ public:
+  // Creates a NaCl delegate and adds it to the infobar service corresponding to
+  // the given render process and view IDs.
+  static void Create(int render_process_id, int render_view_id);
+
+ private:
+  explicit NaClInfoBarDelegate(InfoBarService* infobar_service);
+  virtual ~NaClInfoBarDelegate();
+
+  virtual string16 GetMessageText() const OVERRIDE;
+  virtual int GetButtons() const OVERRIDE;
+  virtual string16 GetLinkText() const OVERRIDE;
+  virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE;
+
+  DISALLOW_COPY_AND_ASSIGN(NaClInfoBarDelegate);
+};
+
+#endif  // CHROME_BROWSER_NACL_HOST_NACL_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc
index f713448..df54445 100644
--- a/chrome/browser/nacl_host/nacl_process_host.cc
+++ b/chrome/browser/nacl_host/nacl_process_host.cc
@@ -25,27 +25,24 @@
 #include "build/build_config.h"
 #include "chrome/browser/nacl_host/nacl_browser.h"
 #include "chrome/browser/nacl_host/nacl_host_message_filter.h"
-#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_process_type.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/chrome_version_info.h"
-#include "chrome/common/logging_chrome.h"
 #include "chrome/common/nacl_cmd_line.h"
 #include "chrome/common/nacl_host_messages.h"
 #include "chrome/common/nacl_messages.h"
-#include "chrome/common/render_messages.h"
+#include "components/nacl/common/nacl_browser_delegate.h"
+#include "components/nacl/common/nacl_process_type.h"
 #include "components/nacl/common/nacl_switches.h"
 #include "content/public/browser/browser_child_process_host.h"
 #include "content/public/browser/browser_ppapi_host.h"
 #include "content/public/browser/child_process_data.h"
 #include "content/public/common/child_process_host.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/common/process_type.h"
 #include "ipc/ipc_channel.h"
 #include "ipc/ipc_switches.h"
 #include "native_client/src/shared/imc/nacl_imc_c.h"
 #include "net/base/net_util.h"
 #include "net/socket/tcp_listen_socket.h"
+#include "ppapi/host/host_factory.h"
 #include "ppapi/host/ppapi_host.h"
 #include "ppapi/proxy/ppapi_messages.h"
 #include "ppapi/shared_impl/ppapi_nacl_channel_args.h"
@@ -257,7 +254,9 @@
 
 // This is called at browser startup.
 // static
-void NaClProcessHost::EarlyStartup() {
+void NaClProcessHost::EarlyStartup(NaClBrowserDelegate* delegate) {
+  NaClBrowser::SetDelegate(delegate);
+  NaClBrowser::GetInstance()->EarlyStartup();
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
   // Open the IRT file early to make sure that it isn't replaced out from
   // under us by autoupdate.
@@ -440,7 +439,7 @@
   cmd_line->AppendSwitchASCII(switches::kProcessType,
                               switches::kNaClLoaderProcess);
   cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
-  if (logging::DialogsAreSuppressed())
+  if (NaClBrowser::GetDelegate()->DialogsAreSuppressed())
     cmd_line->AppendSwitch(switches::kNoErrorDialogs);
 
   if (!nacl_loader_prefix.empty())
@@ -507,6 +506,20 @@
 
 bool NaClProcessHost::ReplyToRenderer(
     const IPC::ChannelHandle& channel_handle) {
+#if defined(OS_WIN)
+  // If we are on 64-bit Windows, the NaCl process's sandbox is
+  // managed by a different process from the renderer's sandbox.  We
+  // need to inform the renderer's sandbox about the NaCl process so
+  // that the renderer can send handles to the NaCl process using
+  // BrokerDuplicateHandle().
+  if (RunningOnWOW64()) {
+    if (!content::BrokerAddTargetPeer(process_->GetData().handle)) {
+      LOG(ERROR) << "Failed to add NaCl process PID";
+      return false;
+    }
+  }
+#endif
+
   nacl::FileDescriptor handle_for_renderer;
 #if defined(OS_WIN)
   // Copy the handle into the renderer process.
@@ -514,7 +527,7 @@
   if (!DuplicateHandle(base::GetCurrentProcessHandle(),
                        reinterpret_cast<HANDLE>(
                            internal_->socket_for_renderer),
-                       nacl_host_message_filter_->peer_handle(),
+                       nacl_host_message_filter_->PeerHandle(),
                        &handle_in_renderer,
                        0,  // Unused given DUPLICATE_SAME_ACCESS.
                        FALSE,
@@ -533,20 +546,6 @@
   handle_for_renderer = imc_handle;
 #endif
 
-#if defined(OS_WIN)
-  // If we are on 64-bit Windows, the NaCl process's sandbox is
-  // managed by a different process from the renderer's sandbox.  We
-  // need to inform the renderer's sandbox about the NaCl process so
-  // that the renderer can send handles to the NaCl process using
-  // BrokerDuplicateHandle().
-  if (RunningOnWOW64()) {
-    if (!content::BrokerAddTargetPeer(process_->GetData().handle)) {
-      LOG(ERROR) << "Failed to add NaCl process PID";
-      return false;
-    }
-  }
-#endif
-
   const ChildProcessData& data = process_->GetData();
   NaClHostMsg_LaunchNaCl::WriteReplyParams(
       reply_msg_, handle_for_renderer,
@@ -596,7 +595,7 @@
   nacl::NaClStartParams params;
   params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled();
   params.validation_cache_key = nacl_browser->GetValidationCacheKey();
-  params.version = chrome::VersionInfo().CreateVersionString();
+  params.version = NaClBrowser::GetDelegate()->GetVersionString();
   params.enable_exception_handling = enable_exception_handling_;
   params.enable_debug_stub = enable_debug_stub_ &&
       NaClBrowser::GetInstance()->URLMatchesDebugPatterns(manifest_url_);
@@ -712,7 +711,8 @@
 
     ppapi_host_->GetPpapiHost()->AddHostFactoryFilter(
         scoped_ptr<ppapi::host::HostFactory>(
-            new chrome::ChromeBrowserPepperHostFactory(ppapi_host_.get())));
+            NaClBrowser::GetDelegate()->CreatePpapiHostFactory(
+                ppapi_host_.get())));
 
     // Send a message to create the NaCl-Renderer channel. The handle is just
     // a place holder.
diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h
index 4496f92..d68693d 100644
--- a/chrome/browser/nacl_host/nacl_process_host.h
+++ b/chrome/browser/nacl_host/nacl_process_host.h
@@ -21,8 +21,10 @@
 #include "ppapi/shared_impl/ppapi_permissions.h"
 #include "url/gurl.h"
 
-class NaClHostMessageFilter;
 class CommandLine;
+class ExtensionInfoMap;
+class NaClBrowserDelegate;
+class NaClHostMessageFilter;
 
 namespace content {
 class BrowserChildProcessHost;
@@ -58,7 +60,7 @@
   virtual ~NaClProcessHost();
 
   // Do any minimal work that must be done at browser startup.
-  static void EarlyStartup();
+  static void EarlyStartup(NaClBrowserDelegate* delegate);
 
   // Initialize the new NaCl process. Result is returned by sending ipc
   // message reply_msg.
diff --git a/chrome/browser/nacl_host/pnacl_translation_cache.cc b/chrome/browser/nacl_host/pnacl_translation_cache.cc
index f9a2c1a..155258b 100644
--- a/chrome/browser/nacl_host/pnacl_translation_cache.cc
+++ b/chrome/browser/nacl_host/pnacl_translation_cache.cc
@@ -9,7 +9,6 @@
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/threading/thread_checker.h"
-#include "chrome/common/chrome_paths.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
@@ -18,7 +17,7 @@
 using content::BrowserThread;
 
 static const base::FilePath::CharType kDiskCacheDirectoryName[] =
-    FILE_PATH_LITERAL("PNaClTranslationCache");
+    FILE_PATH_LITERAL("PnaclTranslationCache");
 
 namespace {
 
@@ -35,14 +34,14 @@
 //////////////////////////////////////////////////////////////////////
 // Handle Reading/Writing to Cache.
 
-// PNaClTranslationCacheEntry is a shim that provides storage for the
+// PnaclTranslationCacheEntry is a shim that provides storage for the
 // 'key' and 'data' strings as the disk_cache is performing various async
 // operations. It also tracks the open disk_cache::Entry
 // and ensures that the entry is closed.
-class PNaClTranslationCacheEntry
-    : public base::RefCounted<PNaClTranslationCacheEntry> {
+class PnaclTranslationCacheEntry
+    : public base::RefCounted<PnaclTranslationCacheEntry> {
  public:
-  PNaClTranslationCacheEntry(base::WeakPtr<PNaClTranslationCache> cache,
+  PnaclTranslationCacheEntry(base::WeakPtr<PnaclTranslationCache> cache,
                              const std::string& key,
                              std::string* read_nexe,
                              const std::string& write_nexe,
@@ -69,8 +68,8 @@
   };
 
  private:
-  friend class base::RefCounted<PNaClTranslationCacheEntry>;
-  ~PNaClTranslationCacheEntry();
+  friend class base::RefCounted<PnaclTranslationCacheEntry>;
+  ~PnaclTranslationCacheEntry();
 
   // Try to open an existing entry in the backend
   void OpenEntry();
@@ -92,7 +91,7 @@
   // entry has been opened.
   int GetTransferSize();
 
-  base::WeakPtr<PNaClTranslationCache> cache_;
+  base::WeakPtr<PnaclTranslationCache> cache_;
 
   std::string key_;
   std::string* read_nexe_;
@@ -105,11 +104,11 @@
   scoped_refptr<net::IOBufferWithSize> read_buf_;
   CompletionCallback finish_callback_;
   base::ThreadChecker thread_checker_;
-  DISALLOW_COPY_AND_ASSIGN(PNaClTranslationCacheEntry);
+  DISALLOW_COPY_AND_ASSIGN(PnaclTranslationCacheEntry);
 };
 
-PNaClTranslationCacheEntry::PNaClTranslationCacheEntry(
-    base::WeakPtr<PNaClTranslationCache> cache,
+PnaclTranslationCacheEntry::PnaclTranslationCacheEntry(
+    base::WeakPtr<PnaclTranslationCache> cache,
     const std::string& key,
     std::string* read_nexe,
     const std::string& write_nexe,
@@ -126,12 +125,12 @@
       bytes_to_transfer_(-1),
       finish_callback_(callback) {}
 
-PNaClTranslationCacheEntry::~PNaClTranslationCacheEntry() {
+PnaclTranslationCacheEntry::~PnaclTranslationCacheEntry() {
   // Ensure we have called the user's callback
   DCHECK(finish_callback_.is_null());
 }
 
-void PNaClTranslationCacheEntry::Start() {
+void PnaclTranslationCacheEntry::Start() {
   DCHECK(thread_checker_.CalledOnValidThread());
   step_ = OPEN_ENTRY;
   OpenEntry();
@@ -139,25 +138,25 @@
 
 // OpenEntry, CreateEntry, WriteEntry, ReadEntry and CloseEntry are only called
 // from DispatchNext, so they know that cache_ is still valid.
-void PNaClTranslationCacheEntry::OpenEntry() {
+void PnaclTranslationCacheEntry::OpenEntry() {
   int rv = cache_->backend()
       ->OpenEntry(key_,
                   &entry_,
-                  base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this));
+                  base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this));
   if (rv != net::ERR_IO_PENDING)
     DispatchNext(rv);
 }
 
-void PNaClTranslationCacheEntry::CreateEntry() {
+void PnaclTranslationCacheEntry::CreateEntry() {
   int rv = cache_->backend()->CreateEntry(
       key_,
       &entry_,
-      base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this));
+      base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this));
   if (rv != net::ERR_IO_PENDING)
     DispatchNext(rv);
 }
 
-void PNaClTranslationCacheEntry::WriteEntry(int offset, int len) {
+void PnaclTranslationCacheEntry::WriteEntry(int offset, int len) {
   scoped_refptr<net::StringIOBuffer> io_buf =
       new net::StringIOBuffer(write_nexe_.substr(offset, len));
   int rv = entry_->WriteData(
@@ -165,25 +164,25 @@
       offset,
       io_buf.get(),
       len,
-      base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this),
+      base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this),
       false);
   if (rv != net::ERR_IO_PENDING)
     DispatchNext(rv);
 }
 
-void PNaClTranslationCacheEntry::ReadEntry(int offset, int len) {
+void PnaclTranslationCacheEntry::ReadEntry(int offset, int len) {
   read_buf_ = new net::IOBufferWithSize(len);
   int rv = entry_->ReadData(
       1,
       offset,
       read_buf_.get(),
       len,
-      base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this));
+      base::Bind(&PnaclTranslationCacheEntry::DispatchNext, this));
   if (rv != net::ERR_IO_PENDING)
     DispatchNext(rv);
 }
 
-int PNaClTranslationCacheEntry::GetTransferSize() {
+int PnaclTranslationCacheEntry::GetTransferSize() {
   if (is_read_) {
     DCHECK(entry_);
     return entry_->GetDataSize(1);
@@ -191,7 +190,7 @@
   return write_nexe_.size();
 }
 
-void PNaClTranslationCacheEntry::CloseEntry(int rv) {
+void PnaclTranslationCacheEntry::CloseEntry(int rv) {
   DCHECK(entry_);
   if (rv < 0)
     entry_->Doom();
@@ -200,7 +199,7 @@
   Finish(rv);
 }
 
-void PNaClTranslationCacheEntry::Finish(int rv) {
+void PnaclTranslationCacheEntry::Finish(int rv) {
   if (!finish_callback_.is_null()) {
     finish_callback_.Run(rv);
     finish_callback_.Reset();
@@ -208,7 +207,7 @@
   cache_->OpComplete(this);
 }
 
-void PNaClTranslationCacheEntry::DispatchNext(int rv) {
+void PnaclTranslationCacheEntry::DispatchNext(int rv) {
   DCHECK(thread_checker_.CalledOnValidThread());
   if (!cache_)
     return;
@@ -281,31 +280,31 @@
 }
 
 //////////////////////////////////////////////////////////////////////
-void PNaClTranslationCache::OpComplete(PNaClTranslationCacheEntry* entry) {
+void PnaclTranslationCache::OpComplete(PnaclTranslationCacheEntry* entry) {
   open_entries_.erase(entry);
 }
 
 //////////////////////////////////////////////////////////////////////
 // Construction and cache backend initialization
-PNaClTranslationCache::PNaClTranslationCache()
+PnaclTranslationCache::PnaclTranslationCache()
     : disk_cache_(NULL), in_memory_(false) {}
 
-PNaClTranslationCache::~PNaClTranslationCache() { delete disk_cache_; }
+PnaclTranslationCache::~PnaclTranslationCache() { delete disk_cache_; }
 
-int PNaClTranslationCache::InitWithDiskBackend(
+int PnaclTranslationCache::InitWithDiskBackend(
     const base::FilePath& cache_dir,
     int cache_size,
     const CompletionCallback& callback) {
   return Init(net::DISK_CACHE, cache_dir, cache_size, callback);
 }
 
-int PNaClTranslationCache::InitWithMemBackend(
+int PnaclTranslationCache::InitWithMemBackend(
     int cache_size,
     const CompletionCallback& callback) {
   return Init(net::MEMORY_CACHE, base::FilePath(), cache_size, callback);
 }
 
-int PNaClTranslationCache::Init(net::CacheType cache_type,
+int PnaclTranslationCache::Init(net::CacheType cache_type,
                                 const base::FilePath& cache_dir,
                                 int cache_size,
                                 const CompletionCallback& callback) {
@@ -318,7 +317,7 @@
       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(),
       NULL, /* dummy net log */
       &disk_cache_,
-      base::Bind(&PNaClTranslationCache::OnCreateBackendComplete, AsWeakPtr()));
+      base::Bind(&PnaclTranslationCache::OnCreateBackendComplete, AsWeakPtr()));
   init_callback_ = callback;
   if (rv != net::ERR_IO_PENDING) {
     OnCreateBackendComplete(rv);
@@ -326,7 +325,7 @@
   return rv;
 }
 
-void PNaClTranslationCache::OnCreateBackendComplete(int rv) {
+void PnaclTranslationCache::OnCreateBackendComplete(int rv) {
   // Invoke our client's callback function.
   if (!init_callback_.is_null()) {
     init_callback_.Run(rv);
@@ -337,30 +336,30 @@
 //////////////////////////////////////////////////////////////////////
 // High-level API
 
-void PNaClTranslationCache::StoreNexe(const std::string& key,
+void PnaclTranslationCache::StoreNexe(const std::string& key,
                                       const std::string& nexe) {
   StoreNexe(key, nexe, CompletionCallback());
 }
 
-void PNaClTranslationCache::StoreNexe(const std::string& key,
+void PnaclTranslationCache::StoreNexe(const std::string& key,
                                       const std::string& nexe,
                                       const CompletionCallback& callback) {
-  PNaClTranslationCacheEntry* entry = new PNaClTranslationCacheEntry(
+  PnaclTranslationCacheEntry* entry = new PnaclTranslationCacheEntry(
       AsWeakPtr(), key, NULL, nexe, callback, false);
   open_entries_[entry] = entry;
   entry->Start();
 }
 
-void PNaClTranslationCache::GetNexe(const std::string& key,
+void PnaclTranslationCache::GetNexe(const std::string& key,
                                     std::string* nexe,
                                     const CompletionCallback& callback) {
-  PNaClTranslationCacheEntry* entry = new PNaClTranslationCacheEntry(
+  PnaclTranslationCacheEntry* entry = new PnaclTranslationCacheEntry(
       AsWeakPtr(), key, nexe, std::string(), callback, true);
   open_entries_[entry] = entry;
   entry->Start();
 }
 
-int PNaClTranslationCache::InitCache(const base::FilePath& cache_directory,
+int PnaclTranslationCache::InitCache(const base::FilePath& cache_directory,
                                      bool in_memory,
                                      const CompletionCallback& callback) {
   int rv;
@@ -376,7 +375,7 @@
   return rv;
 }
 
-int PNaClTranslationCache::Size() {
+int PnaclTranslationCache::Size() {
   if (!disk_cache_)
     return -1;
   return disk_cache_->GetEntryCount();
diff --git a/chrome/browser/nacl_host/pnacl_translation_cache.h b/chrome/browser/nacl_host/pnacl_translation_cache.h
index 14b1816..6af0ddc 100644
--- a/chrome/browser/nacl_host/pnacl_translation_cache.h
+++ b/chrome/browser/nacl_host/pnacl_translation_cache.h
@@ -22,14 +22,14 @@
 
 namespace pnacl_cache {
 typedef base::Callback<void(int)> CompletionCallback;
-class PNaClTranslationCacheEntry;
+class PnaclTranslationCacheEntry;
 extern const int kMaxMemCacheSize;
 
-class PNaClTranslationCache
-    : public base::SupportsWeakPtr<PNaClTranslationCache> {
+class PnaclTranslationCache
+    : public base::SupportsWeakPtr<PnaclTranslationCache> {
  public:
-  PNaClTranslationCache();
-  virtual ~PNaClTranslationCache();
+  PnaclTranslationCache();
+  virtual ~PnaclTranslationCache();
 
   // Initialize the translation cache in |cache_dir| (or in memory if
   // |in_memory| is true). Call |callback| with a 0 argument on sucess and
@@ -58,10 +58,10 @@
   int Size();
 
  private:
-  friend class PNaClTranslationCacheEntry;
-  // PNaClTranslationCacheEntry should only use the
-  // OpComplete and backend methods on PNaClTranslationCache.
-  void OpComplete(PNaClTranslationCacheEntry* entry);
+  friend class PnaclTranslationCacheEntry;
+  // PnaclTranslationCacheEntry should only use the
+  // OpComplete and backend methods on PnaclTranslationCache.
+  void OpComplete(PnaclTranslationCacheEntry* entry);
   disk_cache::Backend* backend() { return disk_cache_; }
 
   int InitWithDiskBackend(const base::FilePath& disk_cache_dir,
@@ -80,9 +80,9 @@
   disk_cache::Backend* disk_cache_;
   CompletionCallback init_callback_;
   bool in_memory_;
-  std::map<void*, scoped_refptr<PNaClTranslationCacheEntry> > open_entries_;
+  std::map<void*, scoped_refptr<PnaclTranslationCacheEntry> > open_entries_;
 
-  DISALLOW_COPY_AND_ASSIGN(PNaClTranslationCache);
+  DISALLOW_COPY_AND_ASSIGN(PnaclTranslationCache);
 };
 
 }  // namespace pnacl_cache
diff --git a/chrome/browser/nacl_host/pnacl_translation_cache_unittest.cc b/chrome/browser/nacl_host/pnacl_translation_cache_unittest.cc
index 6e23500..a22db45 100644
--- a/chrome/browser/nacl_host/pnacl_translation_cache_unittest.cc
+++ b/chrome/browser/nacl_host/pnacl_translation_cache_unittest.cc
@@ -18,14 +18,14 @@
 
 namespace pnacl_cache {
 
-class PNaClTranslationCacheTest : public testing::Test {
+class PnaclTranslationCacheTest : public testing::Test {
  protected:
-  PNaClTranslationCacheTest()
+  PnaclTranslationCacheTest()
       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
-  virtual ~PNaClTranslationCacheTest() {}
-  virtual void SetUp() { cache_ = new PNaClTranslationCache(); }
+  virtual ~PnaclTranslationCacheTest() {}
+  virtual void SetUp() { cache_ = new PnaclTranslationCache(); }
   virtual void TearDown() {
-    // The destructor of PNaClTranslationCacheWriteEntry posts a task to the IO
+    // The destructor of PnaclTranslationCacheWriteEntry posts a task to the IO
     // thread to close the backend cache entry. We want to make sure the entries
     // are closed before we delete the backend (and in particular the destructor
     // for the memory backend has a DCHECK to verify this), so we run the loop
@@ -39,12 +39,12 @@
   std::string GetNexe(const std::string& key);
 
  protected:
-  PNaClTranslationCache* cache_;
+  PnaclTranslationCache* cache_;
   content::TestBrowserThreadBundle thread_bundle_;
   base::ScopedTempDir temp_dir_;
 };
 
-void PNaClTranslationCacheTest::InitBackend(bool in_mem) {
+void PnaclTranslationCacheTest::InitBackend(bool in_mem) {
   net::TestCompletionCallback init_cb;
   if (!in_mem) {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
@@ -56,7 +56,7 @@
   ASSERT_EQ(0, cache_->Size());
 }
 
-void PNaClTranslationCacheTest::StoreNexe(const std::string& key,
+void PnaclTranslationCacheTest::StoreNexe(const std::string& key,
                                           const std::string& nexe) {
   net::TestCompletionCallback store_cb;
   cache_->StoreNexe(key, nexe, store_cb.callback());
@@ -66,7 +66,7 @@
   EXPECT_EQ(net::OK, store_cb.GetResult(net::ERR_IO_PENDING));
 }
 
-std::string PNaClTranslationCacheTest::GetNexe(const std::string& key) {
+std::string PnaclTranslationCacheTest::GetNexe(const std::string& key) {
   net::TestCompletionCallback load_cb;
   std::string nexe;
   cache_->GetNexe(key, &nexe, load_cb.callback());
@@ -78,21 +78,21 @@
 static const std::string test_store_val("testnexe");
 static const int kLargeNexeSize = 16 * 1024 *1024;
 
-TEST_F(PNaClTranslationCacheTest, StoreSmallInMem) {
+TEST_F(PnaclTranslationCacheTest, StoreSmallInMem) {
   // Test that a single store puts something in the mem backend
   InitBackend(true);
   StoreNexe(test_key, test_store_val);
   EXPECT_EQ(1, cache_->Size());
 }
 
-TEST_F(PNaClTranslationCacheTest, StoreSmallOnDisk) {
+TEST_F(PnaclTranslationCacheTest, StoreSmallOnDisk) {
   // Test that a single store puts something in the disk backend
   InitBackend(false);
   StoreNexe(test_key, test_store_val);
   EXPECT_EQ(1, cache_->Size());
 }
 
-TEST_F(PNaClTranslationCacheTest, StoreLargeOnDisk) {
+TEST_F(PnaclTranslationCacheTest, StoreLargeOnDisk) {
   // Test a value too large(?) for a single I/O operation
   // TODO(dschuff): we only seem to ever have one operation go through into the
   // backend. Find out what the 'offset' field means, and if it can ever require
@@ -103,7 +103,7 @@
   EXPECT_EQ(1, cache_->Size());
 }
 
-TEST_F(PNaClTranslationCacheTest, InMemSizeLimit) {
+TEST_F(PnaclTranslationCacheTest, InMemSizeLimit) {
   InitBackend(true);
   const std::string large_buffer(kMaxMemCacheSize + 1, 'a');
   net::TestCompletionCallback store_cb;
@@ -113,14 +113,14 @@
   EXPECT_EQ(0, cache_->Size());
 }
 
-TEST_F(PNaClTranslationCacheTest, GetOneInMem) {
+TEST_F(PnaclTranslationCacheTest, GetOneInMem) {
   InitBackend(true);
   StoreNexe(test_key, test_store_val);
   EXPECT_EQ(1, cache_->Size());
   EXPECT_EQ(0, GetNexe(test_key).compare(test_store_val));
 }
 
-TEST_F(PNaClTranslationCacheTest, GetLargeOnDisk) {
+TEST_F(PnaclTranslationCacheTest, GetLargeOnDisk) {
   InitBackend(false);
   const std::string large_buffer(kLargeNexeSize, 'a');
   StoreNexe(test_key, large_buffer);
@@ -128,7 +128,7 @@
   EXPECT_EQ(0, GetNexe(test_key).compare(large_buffer));
 }
 
-TEST_F(PNaClTranslationCacheTest, StoreTwice) {
+TEST_F(PnaclTranslationCacheTest, StoreTwice) {
   // Test that storing twice with the same key overwrites
   InitBackend(true);
   StoreNexe(test_key, test_store_val);
@@ -137,7 +137,7 @@
   EXPECT_EQ(0, GetNexe(test_key).compare(test_store_val + "aaa"));
 }
 
-TEST_F(PNaClTranslationCacheTest, StoreTwo) {
+TEST_F(PnaclTranslationCacheTest, StoreTwo) {
   InitBackend(true);
   StoreNexe(test_key, test_store_val);
   StoreNexe(test_key + "a", test_store_val + "aaa");
@@ -146,7 +146,7 @@
   EXPECT_EQ(0, GetNexe(test_key + "a").compare(test_store_val + "aaa"));
 }
 
-TEST_F(PNaClTranslationCacheTest, GetMiss) {
+TEST_F(PnaclTranslationCacheTest, GetMiss) {
   InitBackend(true);
   StoreNexe(test_key, test_store_val);
   net::TestCompletionCallback load_cb;
diff --git a/chrome/browser/nacl_host/test/gdb_debug_stub_browsertest.cc b/chrome/browser/nacl_host/test/gdb_debug_stub_browsertest.cc
index c173df7..a522dce 100644
--- a/chrome/browser/nacl_host/test/gdb_debug_stub_browsertest.cc
+++ b/chrome/browser/nacl_host/test/gdb_debug_stub_browsertest.cc
@@ -8,8 +8,8 @@
 #include "base/process_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/nacl_host/nacl_browser.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/test/ppapi/ppapi_test.h"
+#include "components/nacl/common/nacl_switches.h"
 #include "content/public/test/test_utils.h"
 
 class NaClGdbDebugStubTest : public PPAPINaClNewlibTest {
diff --git a/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc b/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc
index 6e1c074..02b4a8c 100644
--- a/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc
+++ b/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc
@@ -57,12 +57,12 @@
 
     EXPECT_TRUE(file_util::ReadFileToString(mock_nacl_gdb_file, &content));
     EXPECT_STREQ("PASS", content.c_str());
-    EXPECT_TRUE(base::Delete(mock_nacl_gdb_file, false));
+    EXPECT_TRUE(base::DeleteFile(mock_nacl_gdb_file, false));
 
     content.clear();
     EXPECT_TRUE(file_util::ReadFileToString(script_, &content));
     EXPECT_STREQ("PASS", content.c_str());
-    EXPECT_TRUE(base::Delete(script_, false));
+    EXPECT_TRUE(base::DeleteFile(script_, false));
   }
 
  private:
diff --git a/chrome/browser/net/dns_probe_browsertest.cc b/chrome/browser/net/dns_probe_browsertest.cc
new file mode 100644
index 0000000..76d494a
--- /dev/null
+++ b/chrome/browser/net/dns_probe_browsertest.cc
@@ -0,0 +1,535 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop.h"
+#include "base/path_service.h"
+#include "base/threading/thread_restrictions.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/google/google_util.h"
+#include "chrome/browser/io_thread.h"
+#include "chrome/browser/net/dns_probe_test_util.h"
+#include "chrome/browser/net/net_error_tab_helper.h"
+#include "chrome/browser/net/url_request_mock_util.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/net/net_error_info.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/test/net/url_request_failed_job.h"
+#include "content/test/net/url_request_mock_http_job.h"
+#include "net/base/net_errors.h"
+#include "net/dns/dns_test_util.h"
+#include "net/url_request/url_request_filter.h"
+#include "net/url_request/url_request_job.h"
+#include "net/url_request/url_request_job_factory.h"
+
+using base::Bind;
+using base::Callback;
+using base::Closure;
+using base::ConstRef;
+using base::FilePath;
+using base::MessageLoop;
+using base::Unretained;
+using chrome_common_net::DnsProbeStatus;
+using content::BrowserThread;
+using content::URLRequestFailedJob;
+using content::URLRequestMockHTTPJob;
+using content::WebContents;
+using google_util::LinkDoctorBaseURL;
+using net::MockDnsClientRule;
+using net::NetworkDelegate;
+using net::URLRequest;
+using net::URLRequestFilter;
+using net::URLRequestJob;
+using net::URLRequestJobFactory;
+using ui_test_utils::NavigateToURL;
+using ui_test_utils::NavigateToURLBlockUntilNavigationsComplete;
+
+namespace chrome_browser_net {
+
+namespace {
+
+// Wraps DnsProbeService and delays callbacks until someone calls
+// CallDelayedCallbacks.  This allows the DnsProbeBrowserTest to enforce a
+// stricter ordering of events.
+class DelayingDnsProbeService : public DnsProbeService {
+ public:
+  DelayingDnsProbeService() {}
+
+  virtual ~DelayingDnsProbeService() {
+    EXPECT_TRUE(delayed_probes_.empty());
+  }
+
+  virtual void ProbeDns(const ProbeCallback& callback) OVERRIDE {
+    delayed_probes_.push_back(callback);
+  }
+
+  void StartDelayedProbes() {
+    CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+    std::vector<ProbeCallback> probes;
+    probes.swap(delayed_probes_);
+
+    for (std::vector<ProbeCallback>::const_iterator i = probes.begin();
+         i != probes.end(); ++i) {
+      DnsProbeService::ProbeDns(*i);
+    }
+  }
+
+  int delayed_probe_count() const {
+    CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+    return delayed_probes_.size();
+  }
+
+ private:
+  std::vector<ProbeCallback> delayed_probes_;
+};
+
+FilePath GetMockLinkDoctorFilePath() {
+  FilePath root_http;
+  PathService::Get(chrome::DIR_TEST_DATA, &root_http);
+  return root_http.AppendASCII("mock-link-doctor.html");
+}
+
+class BreakableLinkDoctorProtocolHandler
+    : public URLRequestJobFactory::ProtocolHandler {
+ public:
+  explicit BreakableLinkDoctorProtocolHandler(
+      const FilePath& mock_link_doctor_file_path)
+      : mock_link_doctor_file_path_(mock_link_doctor_file_path),
+        net_error_(net::OK) {}
+
+  virtual ~BreakableLinkDoctorProtocolHandler() {}
+
+  virtual URLRequestJob* MaybeCreateJob(
+      URLRequest* request, NetworkDelegate* network_delegate) const OVERRIDE {
+    if (net_error_ != net::OK) {
+      return new URLRequestFailedJob(request, network_delegate, net_error_);
+    } else {
+      return new URLRequestMockHTTPJob(
+          request, network_delegate, mock_link_doctor_file_path_);
+    }
+  }
+
+  void set_net_error(int net_error) { net_error_ = net_error; }
+
+ private:
+  const FilePath mock_link_doctor_file_path_;
+  int net_error_;
+};
+
+class DnsProbeBrowserTestIOThreadHelper {
+ public:
+  DnsProbeBrowserTestIOThreadHelper();
+
+  void SetUpOnIOThread(IOThread* io_thread);
+  void CleanUpOnIOThreadAndDeleteHelper();
+
+  void SetMockDnsClientRules(MockDnsClientRule::Result system_good_result,
+                             MockDnsClientRule::Result public_good_result);
+  void SetLinkDoctorNetError(int link_doctor_net_error);
+  void StartDelayedProbes(int expected_delayed_probe_count);
+
+ private:
+  IOThread* io_thread_;
+  DnsProbeService* original_dns_probe_service_;
+  DelayingDnsProbeService* delaying_dns_probe_service_;
+  BreakableLinkDoctorProtocolHandler* protocol_handler_;
+  FilePath mock_link_doctor_file_path_;
+};
+
+DnsProbeBrowserTestIOThreadHelper::DnsProbeBrowserTestIOThreadHelper()
+    : io_thread_(NULL),
+      original_dns_probe_service_(NULL),
+      delaying_dns_probe_service_(NULL),
+      protocol_handler_(NULL),
+      mock_link_doctor_file_path_(GetMockLinkDoctorFilePath()) {}
+
+void DnsProbeBrowserTestIOThreadHelper::SetUpOnIOThread(IOThread* io_thread) {
+  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  CHECK(io_thread);
+  CHECK(!io_thread_);
+  CHECK(!original_dns_probe_service_);
+  CHECK(!delaying_dns_probe_service_);
+  CHECK(!protocol_handler_);
+
+  io_thread_ = io_thread;
+
+  delaying_dns_probe_service_ = new DelayingDnsProbeService();
+
+  IOThread::Globals* globals = io_thread_->globals();
+  original_dns_probe_service_ = globals->dns_probe_service.release();
+  globals->dns_probe_service.reset(delaying_dns_probe_service_);
+
+  URLRequestFailedJob::AddUrlHandler();
+
+  scoped_ptr<URLRequestJobFactory::ProtocolHandler> protocol_handler(
+      new BreakableLinkDoctorProtocolHandler(mock_link_doctor_file_path_));
+  protocol_handler_ =
+      static_cast<BreakableLinkDoctorProtocolHandler*>(protocol_handler.get());
+  const GURL link_doctor_base_url = LinkDoctorBaseURL();
+  const std::string link_doctor_host = link_doctor_base_url.host();
+  URLRequestFilter::GetInstance()->AddHostnameProtocolHandler(
+      "http", link_doctor_host, protocol_handler.Pass());
+}
+
+void DnsProbeBrowserTestIOThreadHelper::CleanUpOnIOThreadAndDeleteHelper() {
+  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  URLRequestFilter::GetInstance()->ClearHandlers();
+
+  IOThread::Globals* globals = io_thread_->globals();
+  scoped_ptr<DnsProbeService> delaying_dns_probe_service(
+      globals->dns_probe_service.release());
+  globals->dns_probe_service.reset(original_dns_probe_service_);
+
+  CHECK_EQ(delaying_dns_probe_service_, delaying_dns_probe_service.get());
+
+  delete this;
+}
+
+void DnsProbeBrowserTestIOThreadHelper::SetMockDnsClientRules(
+    MockDnsClientRule::Result system_result,
+    MockDnsClientRule::Result public_result) {
+  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  DnsProbeService* service = io_thread_->globals()->dns_probe_service.get();
+  service->SetSystemClientForTesting(
+      CreateMockDnsClientForProbes(system_result));
+  service->SetPublicClientForTesting(
+      CreateMockDnsClientForProbes(public_result));
+}
+
+void DnsProbeBrowserTestIOThreadHelper::SetLinkDoctorNetError(
+    int link_doctor_net_error) {
+  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  protocol_handler_->set_net_error(link_doctor_net_error);
+}
+
+void DnsProbeBrowserTestIOThreadHelper::StartDelayedProbes(
+    int expected_delayed_probe_count) {
+  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  CHECK(delaying_dns_probe_service_);
+
+  int actual_delayed_probe_count =
+      delaying_dns_probe_service_->delayed_probe_count();
+  EXPECT_EQ(expected_delayed_probe_count, actual_delayed_probe_count);
+
+  delaying_dns_probe_service_->StartDelayedProbes();
+}
+
+class DnsProbeBrowserTest : public InProcessBrowserTest {
+ public:
+  DnsProbeBrowserTest();
+
+  virtual void SetUpOnMainThread() OVERRIDE;
+  virtual void CleanUpOnMainThread() OVERRIDE;
+
+ protected:
+  void SetLinkDoctorBroken(bool broken);
+  void SetMockDnsClientRules(MockDnsClientRule::Result system_result,
+                             MockDnsClientRule::Result public_result);
+  void NavigateToDnsError();
+  void NavigateToOtherError();
+
+  void StartDelayedProbes(int expected_delayed_probe_count);
+  DnsProbeStatus WaitForSentStatus();
+  int pending_status_count() const { return dns_probe_status_queue_.size(); }
+
+  std::string Title();
+  bool PageContains(const std::string& expected);
+
+ private:
+  void OnDnsProbeStatusSent(DnsProbeStatus dns_probe_status);
+
+  DnsProbeBrowserTestIOThreadHelper* helper_;
+
+  bool awaiting_dns_probe_status_;
+  // Queue of statuses received but not yet consumed by WaitForSentStatus().
+  std::list<DnsProbeStatus> dns_probe_status_queue_;
+};
+
+DnsProbeBrowserTest::DnsProbeBrowserTest()
+    : helper_(new DnsProbeBrowserTestIOThreadHelper()),
+      awaiting_dns_probe_status_(false) {
+}
+
+void DnsProbeBrowserTest::SetUpOnMainThread() {
+  NetErrorTabHelper::set_state_for_testing(
+      NetErrorTabHelper::TESTING_FORCE_ENABLED);
+
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      Bind(&DnsProbeBrowserTestIOThreadHelper::SetUpOnIOThread,
+           Unretained(helper_),
+           g_browser_process->io_thread()));
+
+  NetErrorTabHelper* tab_helper = NetErrorTabHelper::FromWebContents(
+      browser()->tab_strip_model()->GetActiveWebContents());
+  tab_helper->set_dns_probe_status_snoop_callback_for_testing(Bind(
+      &DnsProbeBrowserTest::OnDnsProbeStatusSent,
+      Unretained(this)));
+}
+
+void DnsProbeBrowserTest::CleanUpOnMainThread() {
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      Bind(&DnsProbeBrowserTestIOThreadHelper::CleanUpOnIOThreadAndDeleteHelper,
+           Unretained(helper_)));
+
+  NetErrorTabHelper::set_state_for_testing(
+      NetErrorTabHelper::TESTING_DEFAULT);
+}
+
+void DnsProbeBrowserTest::SetLinkDoctorBroken(bool broken) {
+  int net_error = broken ? net::ERR_NAME_NOT_RESOLVED : net::OK;
+
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      Bind(&DnsProbeBrowserTestIOThreadHelper::SetLinkDoctorNetError,
+           Unretained(helper_),
+           net_error));
+}
+
+// These two functions wait for two navigations because Link Doctor loads two
+// pages: a blank page, so the user stops seeing the previous page, and then
+// either the Link Doctor page or a regular error page.  We want to wait for
+// the error page, so we wait for both loads to finish.
+
+void DnsProbeBrowserTest::NavigateToDnsError() {
+  NavigateToURLBlockUntilNavigationsComplete(
+      browser(),
+      URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED),
+      2);
+}
+
+void DnsProbeBrowserTest::NavigateToOtherError() {
+  NavigateToURLBlockUntilNavigationsComplete(
+      browser(),
+      URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_REFUSED),
+      2);
+}
+
+void DnsProbeBrowserTest::SetMockDnsClientRules(
+    MockDnsClientRule::Result system_result,
+    MockDnsClientRule::Result public_result) {
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      Bind(&DnsProbeBrowserTestIOThreadHelper::SetMockDnsClientRules,
+           Unretained(helper_),
+           system_result,
+           public_result));
+}
+
+void DnsProbeBrowserTest::StartDelayedProbes(
+    int expected_delayed_probe_count) {
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      Bind(&DnsProbeBrowserTestIOThreadHelper::StartDelayedProbes,
+           Unretained(helper_),
+           expected_delayed_probe_count));
+}
+
+DnsProbeStatus DnsProbeBrowserTest::WaitForSentStatus() {
+  CHECK(!awaiting_dns_probe_status_);
+  while (dns_probe_status_queue_.empty()) {
+    awaiting_dns_probe_status_ = true;
+    MessageLoop::current()->Run();
+    awaiting_dns_probe_status_ = false;
+  }
+
+  CHECK(!dns_probe_status_queue_.empty());
+  DnsProbeStatus status = dns_probe_status_queue_.front();
+  dns_probe_status_queue_.pop_front();
+  return status;
+}
+
+// Check title by roundtripping to renderer, to make sure any probe results
+// sent before this have been applied.
+std::string DnsProbeBrowserTest::Title() {
+  std::string title;
+
+  WebContents* contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  bool rv = content::ExecuteScriptAndExtractString(
+      contents,
+      "domAutomationController.send(document.title);",
+      &title);
+  if (!rv)
+    return "";
+
+  return title;
+}
+
+// Check text by roundtripping to renderer, to make sure any probe results
+// sent before this have been applied.
+bool DnsProbeBrowserTest::PageContains(const std::string& expected) {
+  std::string text_content;
+
+  bool rv = content::ExecuteScriptAndExtractString(
+      browser()->tab_strip_model()->GetActiveWebContents(),
+      "domAutomationController.send(document.body.textContent);",
+      &text_content);
+  if (!rv)
+    return false;
+
+  return text_content.find(expected) != std::string::npos;
+}
+
+void DnsProbeBrowserTest::OnDnsProbeStatusSent(
+    DnsProbeStatus dns_probe_status) {
+  dns_probe_status_queue_.push_back(dns_probe_status);
+  if (awaiting_dns_probe_status_)
+    MessageLoop::current()->Quit();
+}
+
+// Make sure probes don't break non-DNS error pages when Link Doctor loads.
+IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, OtherErrorWithWorkingLinkDoctor) {
+  SetLinkDoctorBroken(false);
+
+  NavigateToOtherError();
+  EXPECT_EQ("Mock Link Doctor", Title());
+
+  EXPECT_EQ(0, pending_status_count());
+}
+
+// Make sure probes don't break non-DNS error pages when Link Doctor doesn't
+// load.
+IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, OtherErrorWithBrokenLinkDoctor) {
+  SetLinkDoctorBroken(true);
+
+  NavigateToOtherError();
+  EXPECT_TRUE(PageContains("CONNECTION_REFUSED"));
+
+  EXPECT_EQ(0, pending_status_count());
+}
+
+// Make sure probes don't break DNS error pages when Link doctor loads.
+IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest,
+    NxdomainProbeResultWithWorkingLinkDoctor) {
+  SetLinkDoctorBroken(false);
+  SetMockDnsClientRules(MockDnsClientRule::OK, MockDnsClientRule::OK);
+
+  NavigateToDnsError();
+  EXPECT_EQ("Mock Link Doctor", Title());
+
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
+  EXPECT_EQ(0, pending_status_count());
+  EXPECT_EQ("Mock Link Doctor", Title());
+
+  StartDelayedProbes(1);
+
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN,
+            WaitForSentStatus());
+  EXPECT_EQ(0, pending_status_count());
+  EXPECT_EQ("Mock Link Doctor", Title());
+}
+
+// Make sure probes update DNS error page properly when they're supposed to.
+IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest,
+    NoInternetProbeResultWithBrokenLinkDoctor) {
+  SetLinkDoctorBroken(true);
+  SetMockDnsClientRules(MockDnsClientRule::TIMEOUT,
+                        MockDnsClientRule::TIMEOUT);
+
+  NavigateToDnsError();
+
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
+
+  // PageContains runs the RunLoop, so make sure nothing hairy happens.
+  EXPECT_EQ(0, pending_status_count());
+  EXPECT_TRUE(PageContains("DNS_PROBE_STARTED"));
+  EXPECT_EQ(0, pending_status_count());
+
+  StartDelayedProbes(1);
+
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
+            WaitForSentStatus());
+
+  // PageContains runs the RunLoop, so make sure nothing hairy happens.
+  EXPECT_EQ(0, pending_status_count());
+  EXPECT_TRUE(PageContains("DNS_PROBE_FINISHED_NO_INTERNET"));
+  EXPECT_EQ(0, pending_status_count());
+}
+
+// Double-check to make sure sync failures don't explode.
+IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, SyncFailureWithBrokenLinkDoctor) {
+  SetLinkDoctorBroken(true);
+  SetMockDnsClientRules(MockDnsClientRule::FAIL_SYNC,
+                        MockDnsClientRule::FAIL_SYNC);
+
+  NavigateToDnsError();
+
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
+
+  // PageContains runs the RunLoop, so make sure nothing hairy happens.
+  EXPECT_EQ(0, pending_status_count());
+  EXPECT_TRUE(PageContains("DNS_PROBE_STARTED"));
+  EXPECT_EQ(0, pending_status_count());
+
+  StartDelayedProbes(1);
+
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE,
+            WaitForSentStatus());
+
+  // PageContains runs the RunLoop, so make sure nothing hairy happens.
+  EXPECT_EQ(0, pending_status_count());
+  EXPECT_TRUE(PageContains("NAME_NOT_RESOLVED"));
+  EXPECT_EQ(0, pending_status_count());
+}
+
+// Make sure probes don't run for subframe DNS errors.
+IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, NoProbeInSubframe) {
+  SetLinkDoctorBroken(false);
+
+  const FilePath::CharType kIframeDnsErrorHtmlName[] =
+      FILE_PATH_LITERAL("iframe_dns_error.html");
+
+  NavigateToURL(
+      browser(),
+      URLRequestMockHTTPJob::GetMockUrl(FilePath(kIframeDnsErrorHtmlName)));
+
+  // By the time NavigateToURL returns, the browser will have seen the failed
+  // provisional load.  If a probe was started (or considered but not run),
+  // then the NetErrorTabHelper would have sent a NetErrorInfo message.  Thus,
+  // if one hasn't been sent by now, the NetErrorTabHelper has not (and won't)
+  // start a probe for this DNS error.
+  EXPECT_EQ(0, pending_status_count());
+}
+
+// Make sure browser sends NOT_RUN properly when probes are disabled.
+IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, ProbesDisabled) {
+  NetErrorTabHelper::set_state_for_testing(
+      NetErrorTabHelper::TESTING_FORCE_DISABLED);
+
+  SetLinkDoctorBroken(true);
+  SetMockDnsClientRules(MockDnsClientRule::TIMEOUT,
+                        MockDnsClientRule::TIMEOUT);
+
+  NavigateToDnsError();
+
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_NOT_RUN, WaitForSentStatus());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_NOT_RUN, WaitForSentStatus());
+
+  // PageContains runs the RunLoop, so make sure nothing hairy happens.
+  EXPECT_EQ(0, pending_status_count());
+  EXPECT_TRUE(PageContains("NAME_NOT_RESOLVED"));
+  EXPECT_EQ(0, pending_status_count());
+}
+
+}  // namespace
+
+}  // namespace chrome_browser_net
diff --git a/chrome/browser/net/dns_probe_job.cc b/chrome/browser/net/dns_probe_job.cc
deleted file mode 100644
index f51f450..0000000
--- a/chrome/browser/net/dns_probe_job.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/net/dns_probe_job.h"
-
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
-#include "base/time/time.h"
-#include "net/base/address_list.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_log.h"
-#include "net/dns/dns_client.h"
-#include "net/dns/dns_protocol.h"
-#include "net/dns/dns_response.h"
-#include "net/dns/dns_transaction.h"
-
-using base::TimeDelta;
-using net::AddressList;
-using net::BoundNetLog;
-using net::DnsClient;
-using net::DnsResponse;
-using net::DnsTransaction;
-using net::NetLog;
-
-namespace chrome_browser_net {
-
-namespace {
-
-// Returns true if the given net_error indicates that we received a response
-// from the DNS server containing an error, or false if the given net_error
-// indicates that we never received a response.
-bool DidReceiveDnsResponse(int net_error) {
-  switch (net_error) {
-  case net::ERR_NAME_NOT_RESOLVED:  // NXDOMAIN maps to this.
-  case net::ERR_DNS_MALFORMED_RESPONSE:
-  case net::ERR_DNS_SERVER_REQUIRES_TCP:
-  case net::ERR_DNS_SERVER_FAILED:
-  case net::ERR_DNS_SORT_ERROR:  // Can only happen if the server responds.
-    return true;
-  default:
-    return false;
-  }
-}
-
-class DnsProbeJobImpl : public DnsProbeJob {
- public:
-  DnsProbeJobImpl(scoped_ptr<DnsClient> dns_client,
-                  const DnsProbeJob::CallbackType& callback,
-                  NetLog* net_log);
-  virtual ~DnsProbeJobImpl();
-
- private:
-  enum QueryResult {
-    QUERY_UNKNOWN,
-    QUERY_CORRECT,
-    QUERY_INCORRECT,
-    QUERY_DNS_ERROR,
-    QUERY_NET_ERROR,
-  };
-
-  void Start();
-
-  scoped_ptr<DnsTransaction> CreateTransaction(
-      const std::string& hostname);
-  void StartTransaction(DnsTransaction* transaction);
-  // Checks that |net_error| is OK, |response| parses, and has at least one
-  // address.
-  QueryResult EvaluateGoodResponse(int net_error, const DnsResponse* response);
-  // Checks that |net_error| is OK, |response| parses but has no addresses.
-  QueryResult EvaluateBadResponse(int net_error, const DnsResponse* response);
-  DnsProbeJob::Result EvaluateQueryResults();
-  void OnTransactionComplete(DnsTransaction* transaction,
-                             int net_error,
-                             const DnsResponse* response);
-
-  BoundNetLog bound_net_log_;
-  scoped_ptr<DnsClient> dns_client_;
-  const DnsProbeJob::CallbackType callback_;
-  scoped_ptr<DnsTransaction> good_transaction_;
-  scoped_ptr<DnsTransaction> bad_transaction_;
-  bool good_running_;
-  bool bad_running_;
-  QueryResult good_result_;
-  QueryResult bad_result_;
-  base::WeakPtrFactory<DnsProbeJobImpl> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(DnsProbeJobImpl);
-};
-
-DnsProbeJobImpl::DnsProbeJobImpl(scoped_ptr<DnsClient> dns_client,
-                                 const DnsProbeJob::CallbackType& callback,
-                                 NetLog* net_log)
-    : bound_net_log_(
-          BoundNetLog::Make(net_log, NetLog::SOURCE_DNS_PROBER)),
-      dns_client_(dns_client.Pass()),
-      callback_(callback),
-      good_running_(false),
-      bad_running_(false),
-      good_result_(QUERY_UNKNOWN),
-      bad_result_(QUERY_UNKNOWN),
-      weak_factory_(this) {
-  DCHECK(dns_client_.get());
-  DCHECK(dns_client_->GetConfig());
-
-  base::MessageLoop::current()->PostTask(
-      FROM_HERE,
-      base::Bind(&DnsProbeJobImpl::Start,
-                 weak_factory_.GetWeakPtr()));
-}
-
-DnsProbeJobImpl::~DnsProbeJobImpl() {
-}
-
-void DnsProbeJobImpl::Start() {
-  // TODO(ttuttle): Pick a good random hostname for the bad case.
-  //                Consider running transactions in series?
-  good_transaction_ = CreateTransaction("google.com");
-  bad_transaction_ = CreateTransaction("thishostname.doesnotresolve");
-
-  // StartTransaction may call the callback synchrononously, so set these
-  // before we call it.
-  good_running_ = true;
-  bad_running_ = true;
-
-  // TODO(ttuttle): Log probe started.
-
-  StartTransaction(good_transaction_.get());
-  StartTransaction(bad_transaction_.get());
-}
-
-scoped_ptr<DnsTransaction> DnsProbeJobImpl::CreateTransaction(
-    const std::string& hostname) {
-  return dns_client_->GetTransactionFactory()->CreateTransaction(
-      hostname,
-      net::dns_protocol::kTypeA,
-      base::Bind(&DnsProbeJobImpl::OnTransactionComplete,
-                 base::Unretained(this)),
-      bound_net_log_);
-}
-
-void DnsProbeJobImpl::StartTransaction(DnsTransaction* transaction) {
-  int rv = transaction->Start();
-  if (rv != net::ERR_IO_PENDING) {
-    // TODO(ttuttle): Make sure this counts as unreachable, not error.
-    OnTransactionComplete(transaction, rv, NULL);
-  }
-
-  // TODO(ttuttle): Log transaction started.
-}
-
-DnsProbeJobImpl::QueryResult DnsProbeJobImpl::EvaluateGoodResponse(
-    int net_error,
-    const DnsResponse* response) {
-  if (net_error != net::OK)
-    return DidReceiveDnsResponse(net_error) ? QUERY_DNS_ERROR : QUERY_NET_ERROR;
-
-  AddressList addr_list;
-  TimeDelta ttl;
-  DnsResponse::Result result = response->ParseToAddressList(&addr_list, &ttl);
-
-  if (result != DnsResponse::DNS_PARSE_OK)
-    return QUERY_DNS_ERROR;
-
-  if (addr_list.empty())
-    return QUERY_INCORRECT;
-
-  return QUERY_CORRECT;
-}
-
-DnsProbeJobImpl::QueryResult DnsProbeJobImpl::EvaluateBadResponse(
-    int net_error,
-    const DnsResponse* response) {
-  if (net_error == net::ERR_NAME_NOT_RESOLVED)  // NXDOMAIN maps to this
-    return QUERY_CORRECT;
-
-  if (net_error != net::OK)
-    return DidReceiveDnsResponse(net_error) ? QUERY_DNS_ERROR : QUERY_NET_ERROR;
-
-  return QUERY_INCORRECT;
-}
-
-DnsProbeJob::Result DnsProbeJobImpl::EvaluateQueryResults() {
-  if (good_result_ == QUERY_NET_ERROR || bad_result_ == QUERY_NET_ERROR)
-    return SERVERS_UNREACHABLE;
-
-  if (good_result_ == QUERY_DNS_ERROR || bad_result_ == QUERY_DNS_ERROR)
-    return SERVERS_FAILING;
-
-  // Ignore incorrect responses to known-bad query to avoid flagging domain
-  // helpers.
-  if (good_result_ == QUERY_INCORRECT)
-    return SERVERS_INCORRECT;
-
-  return SERVERS_CORRECT;
-}
-
-void DnsProbeJobImpl::OnTransactionComplete(DnsTransaction* transaction,
-                                            int net_error,
-                                            const DnsResponse* response) {
-  if (transaction == good_transaction_.get()) {
-    DCHECK(good_running_);
-    DCHECK_EQ(QUERY_UNKNOWN, good_result_);
-    good_result_ = EvaluateGoodResponse(net_error, response);
-    good_running_ = false;
-  } else if (transaction == bad_transaction_.get()) {
-    DCHECK(bad_running_);
-    DCHECK_EQ(QUERY_UNKNOWN, bad_result_);
-    bad_result_ = EvaluateBadResponse(net_error, response);
-    bad_running_ = false;
-  } else {
-    NOTREACHED();
-    return;
-  }
-
-  if (good_running_ || bad_running_)
-    return;
-
-  callback_.Run(this, EvaluateQueryResults());
-
-  // TODO(ttuttle): Log probe finished.
-}
-
-}  // namespace
-
-scoped_ptr<DnsProbeJob> DnsProbeJob::CreateJob(
-    scoped_ptr<DnsClient> dns_client,
-    const CallbackType& callback,
-    NetLog* net_log) {
-  return scoped_ptr<DnsProbeJob>(
-      new DnsProbeJobImpl(dns_client.Pass(), callback, net_log));
-}
-
-}  // namespace chrome_browser_net
diff --git a/chrome/browser/net/dns_probe_job.h b/chrome/browser/net/dns_probe_job.h
deleted file mode 100644
index 6572de1..0000000
--- a/chrome/browser/net/dns_probe_job.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_NET_DNS_PROBE_JOB_H_
-#define CHROME_BROWSER_NET_DNS_PROBE_JOB_H_
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace net {
-class DnsClient;
-class NetLog;
-}
-
-namespace chrome_browser_net {
-
-// A job to probe the health of a DNS configuration.
-class DnsProbeJob {
- public:
-  enum Result {
-    SERVERS_UNKNOWN,
-    SERVERS_CORRECT,  // Server responds with correct answers.
-    SERVERS_INCORRECT,  // Server responds with success but incorrect answer.
-    // TODO(ttuttle): Do we want an "unreliable" result, for e.g. servers that
-    // lie about NXDOMAIN?
-    SERVERS_FAILING,  // Server responds with errors.
-    SERVERS_UNREACHABLE,  // Server doesn't respond (or never got our packets)
-    MAX_RESULT
-  };
-  typedef base::Callback<void(DnsProbeJob* job, Result result)> CallbackType;
-
-  virtual ~DnsProbeJob() { }
-
-  // Creates and starts a probe job.
-  //
-  // |dns_client| should be a DnsClient with the DnsConfig already set.
-  // |callback| will be called when the probe finishes, which may happen
-  // before the constructor returns (for example, if we can't create the DNS
-  // transactions).
-  static scoped_ptr<DnsProbeJob> CreateJob(
-      scoped_ptr<net::DnsClient> dns_client,
-      const CallbackType& callback,
-      net::NetLog* net_log);
-
- protected:
-  DnsProbeJob() { }
-
-  DISALLOW_COPY_AND_ASSIGN(DnsProbeJob);
-};
-
-}  // namespace chrome_browser_net
-
-#endif  // CHROME_BROWSER_NET_DNS_PROBE_JOB_H_
diff --git a/chrome/browser/net/dns_probe_job_unittest.cc b/chrome/browser/net/dns_probe_job_unittest.cc
deleted file mode 100644
index d1779b1..0000000
--- a/chrome/browser/net/dns_probe_job_unittest.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/net/dns_probe_job.h"
-
-#include "base/basictypes.h"
-#include "base/message_loop.h"
-#include "base/run_loop.h"
-#include "net/base/net_log.h"
-#include "net/dns/dns_client.h"
-#include "net/dns/dns_config_service.h"
-#include "net/dns/dns_protocol.h"
-#include "net/dns/dns_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using net::DnsClient;
-using net::DnsConfig;
-using net::IPAddressNumber;
-using net::IPEndPoint;
-using net::ParseIPLiteralToNumber;
-using net::MockDnsClientRule;
-using net::MockDnsClientRuleList;
-using net::NetLog;
-
-namespace chrome_browser_net {
-
-namespace {
-
-class DnsProbeJobTest : public testing::Test {
- public:
-  void RunProbe(MockDnsClientRule::Result expected_good_result,
-                MockDnsClientRule::Result expected_bad_result);
-
- protected:
-  void OnProbeFinished(DnsProbeJob* job, DnsProbeJob::Result result);
-
-  bool callback_called_;
-  DnsProbeJob::Result callback_result_;
-};
-
-// Runs a probe and waits for the callback.  |good_result| and |bad_result|
-// are the result of the good and bad transactions that the DnsProbeJob will
-// receive.
-void DnsProbeJobTest::RunProbe(MockDnsClientRule::Result good_result,
-                               MockDnsClientRule::Result bad_result) {
-  DnsConfig config;
-  config.nameservers.clear();
-  IPAddressNumber dns_ip;
-  ParseIPLiteralToNumber("192.168.1.1", &dns_ip);
-  const uint16 kDnsPort = net::dns_protocol::kDefaultPort;
-  config.nameservers.push_back(IPEndPoint(dns_ip, kDnsPort));
-
-  const uint16 kTypeA = net::dns_protocol::kTypeA;
-  MockDnsClientRuleList rules;
-  rules.push_back(MockDnsClientRule("google.com", kTypeA, good_result));
-  rules.push_back(MockDnsClientRule(std::string(), kTypeA, bad_result));
-
-  scoped_ptr<DnsClient> dns_client = CreateMockDnsClient(config, rules);
-  dns_client->SetConfig(config);
-
-  NetLog* net_log = NULL;
-  DnsProbeJob::CallbackType callback = base::Bind(
-      &DnsProbeJobTest::OnProbeFinished,
-      base::Unretained(this));
-
-  // Need to set these before creating job, because it can call the callback
-  // synchronously in the constructor if both transactions fail to start.
-  callback_called_ = false;
-  callback_result_ = DnsProbeJob::SERVERS_UNKNOWN;
-
-  // DnsProbeJob needs somewhere to post the callback.
-  scoped_ptr<base::MessageLoop> message_loop_(new base::MessageLoopForIO());
-
-  scoped_ptr<DnsProbeJob> job(
-      DnsProbeJob::CreateJob(dns_client.Pass(), callback, net_log));
-
-  // Force callback to run.
-  base::RunLoop run_loop;
-  run_loop.RunUntilIdle();
-}
-
-void DnsProbeJobTest::OnProbeFinished(DnsProbeJob* job,
-                                      DnsProbeJob::Result result) {
-  EXPECT_FALSE(callback_called_);
-
-  callback_called_ = true;
-  callback_result_ = result;
-}
-
-struct TestCase {
-  MockDnsClientRule::Result good_result;
-  MockDnsClientRule::Result bad_result;
-  DnsProbeJob::Result expected_probe_result;
-};
-
-TEST_F(DnsProbeJobTest, Test) {
-  static const TestCase kTestCases[] = {
-    { MockDnsClientRule::OK,
-      MockDnsClientRule::EMPTY,
-      DnsProbeJob::SERVERS_CORRECT },
-    { MockDnsClientRule::EMPTY,
-      MockDnsClientRule::EMPTY,
-      DnsProbeJob::SERVERS_INCORRECT },
-    // TODO(ttuttle): Test that triggers QUERY_DNS_ERROR.
-    //                (Need to add another mock behavior to MockDnsClient.)
-    { MockDnsClientRule::FAIL_ASYNC,
-      MockDnsClientRule::FAIL_ASYNC,
-      DnsProbeJob::SERVERS_FAILING },
-    { MockDnsClientRule::FAIL_SYNC,
-      MockDnsClientRule::FAIL_SYNC,
-      DnsProbeJob::SERVERS_FAILING },
-    { MockDnsClientRule::TIMEOUT,
-      MockDnsClientRule::TIMEOUT,
-      DnsProbeJob::SERVERS_UNREACHABLE },
-  };
-  for (size_t i = 0; i < arraysize(kTestCases); i++) {
-    const TestCase* test_case = &kTestCases[i];
-    RunProbe(test_case->good_result, test_case->bad_result);
-    EXPECT_TRUE(callback_called_);
-    EXPECT_EQ(test_case->expected_probe_result, callback_result_);
-  }
-}
-
-}  // namespace
-
-}  // namespace chrome_browser_net
diff --git a/chrome/browser/net/dns_probe_runner.cc b/chrome/browser/net/dns_probe_runner.cc
new file mode 100644
index 0000000..d2b3a5d
--- /dev/null
+++ b/chrome/browser/net/dns_probe_runner.cc
@@ -0,0 +1,143 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/net/dns_probe_runner.h"
+
+#include "base/bind.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/base/address_list.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/base/net_util.h"
+#include "net/base/network_change_notifier.h"
+#include "net/dns/dns_client.h"
+#include "net/dns/dns_protocol.h"
+#include "net/dns/dns_response.h"
+#include "net/dns/dns_transaction.h"
+
+using base::TimeDelta;
+using content::BrowserThread;
+using net::AddressList;
+using net::BoundNetLog;
+using net::DnsClient;
+using net::DnsResponse;
+using net::DnsTransaction;
+using net::IPAddressNumber;
+using net::IPEndPoint;
+using net::NetLog;
+using net::NetworkChangeNotifier;
+using net::ParseIPLiteralToNumber;
+
+namespace chrome_browser_net {
+
+const char* DnsProbeRunner::kKnownGoodHostname = "google.com";
+
+namespace {
+
+DnsProbeRunner::Result EvaluateResponse(
+    int net_error,
+    const DnsResponse* response) {
+  switch (net_error) {
+    case net::OK:
+      break;
+
+    // ERR_NAME_NOT_RESOLVED maps to NXDOMAIN, which means the server is working
+    // but gave us a wrong answer.
+    case net::ERR_NAME_NOT_RESOLVED:
+      return DnsProbeRunner::INCORRECT;
+
+    // These results mean we heard *something* from the DNS server, but it was
+    // unsuccessful (SERVFAIL) or malformed.
+    case net::ERR_DNS_MALFORMED_RESPONSE:
+    case net::ERR_DNS_SERVER_REQUIRES_TCP:  // Shouldn't happen; DnsTransaction
+                                            // will retry with TCP.
+    case net::ERR_DNS_SERVER_FAILED:
+    case net::ERR_DNS_SORT_ERROR:  // Can only happen if the server responds.
+      return DnsProbeRunner::FAILING;
+
+    // Any other error means we never reached the DNS server in the first place.
+    case net::ERR_DNS_TIMED_OUT:
+    default:
+      // Something else happened, probably at a network level.
+      return DnsProbeRunner::UNREACHABLE;
+  }
+
+  AddressList addr_list;
+  TimeDelta ttl;
+  DnsResponse::Result result = response->ParseToAddressList(&addr_list, &ttl);
+
+  if (result != DnsResponse::DNS_PARSE_OK) {
+    return DnsProbeRunner::FAILING;
+  }
+
+  if (addr_list.empty()) {
+    return DnsProbeRunner::INCORRECT;
+  }
+
+  return DnsProbeRunner::CORRECT;
+}
+
+}  // namespace
+
+DnsProbeRunner::DnsProbeRunner() : weak_factory_(this), result_(UNKNOWN) {}
+
+DnsProbeRunner::~DnsProbeRunner() {}
+
+void DnsProbeRunner::SetClient(scoped_ptr<net::DnsClient> client) {
+  client_ = client.Pass();
+}
+
+void DnsProbeRunner::RunProbe(const base::Closure& callback) {
+  DCHECK(!callback.is_null());
+  DCHECK(client_.get());
+  DCHECK(callback_.is_null());
+  DCHECK(!transaction_.get());
+
+  callback_ = callback;
+  transaction_ = client_->GetTransactionFactory()->CreateTransaction(
+      kKnownGoodHostname,
+      net::dns_protocol::kTypeA,
+      base::Bind(&DnsProbeRunner::OnTransactionComplete,
+                 weak_factory_.GetWeakPtr()),
+      BoundNetLog());
+
+  int rv = transaction_->Start();
+  if (rv != net::ERR_IO_PENDING)
+    OnTransactionComplete(transaction_.get(), rv, NULL);
+}
+
+bool DnsProbeRunner::IsRunning() const {
+  return !callback_.is_null();
+}
+
+void DnsProbeRunner::OnTransactionComplete(
+    DnsTransaction* transaction,
+    int net_error,
+    const DnsResponse* response) {
+  DCHECK(!callback_.is_null());
+  DCHECK(transaction_.get());
+  DCHECK_EQ(transaction_.get(), transaction);
+
+  result_ = EvaluateResponse(net_error, response);
+  transaction_.reset();
+
+  BrowserThread::PostTask(
+      BrowserThread::IO,
+      FROM_HERE,
+      base::Bind(&DnsProbeRunner::CallCallback,
+                 weak_factory_.GetWeakPtr()));
+}
+
+void DnsProbeRunner::CallCallback() {
+  DCHECK(!callback_.is_null());
+  DCHECK(!transaction_.get());
+
+  // Clear callback in case it starts a new probe immediately.
+  const base::Closure callback = callback_;
+  callback_.Reset();
+  callback.Run();
+}
+
+}  // namespace chrome_browser_net
diff --git a/chrome/browser/net/dns_probe_runner.h b/chrome/browser/net/dns_probe_runner.h
new file mode 100644
index 0000000..3f294c2
--- /dev/null
+++ b/chrome/browser/net/dns_probe_runner.h
@@ -0,0 +1,85 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NET_DNS_PROBE_RUNNER_H_
+#define CHROME_BROWSER_NET_DNS_PROBE_RUNNER_H_
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+
+namespace net {
+class DnsClient;
+class DnsResponse;
+class DnsTransaction;
+}
+
+namespace chrome_browser_net {
+
+// Runs DNS probes using a single DnsClient and evaluates the responses.
+// (Currently requests A records for google.com and expects at least one IP
+// address in the response.)
+// Used by DnsProbeService to probe the system and public DNS configurations.
+class DnsProbeRunner {
+ public:
+  static const char* kKnownGoodHostname;
+
+  // Used in histograms; add new entries at the bottom, and don't remove any.
+  enum Result {
+    UNKNOWN,
+    CORRECT,     // Response contains at least one A record.
+    INCORRECT,   // Response claimed success but included no A records.
+    FAILING,     // Response included an error or was malformed.
+    UNREACHABLE  // No response received (timeout, network unreachable, etc.).
+  };
+
+  DnsProbeRunner();
+  ~DnsProbeRunner();
+
+  // Sets the DnsClient that will be used for DNS probes sent by this runner.
+  // Must be called before RunProbe; can be called repeatedly, including during
+  // a probe.  It will not affect an in-flight probe, if one is running.
+  void SetClient(scoped_ptr<net::DnsClient> client);
+
+  // Starts a probe using the client specified with SetClient, which must have
+  // been called before RunProbe.  |callback| will be called asynchronously
+  // when the result is ready, even if it is ready synchronously.  Must not
+  // be called again until the callback is called, but may be called during the
+  // callback.
+  void RunProbe(const base::Closure& callback);
+
+  // Returns true if a probe is running.  Guaranteed to return true after
+  // RunProbe returns, and false during and after the callback.
+  bool IsRunning() const;
+
+  // Returns the result of the last probe.
+  Result result() const { return result_; }
+
+ private:
+  void OnTransactionComplete(net::DnsTransaction* transaction,
+                             int net_error,
+                             const net::DnsResponse* response);
+  void CallCallback();
+
+  base::WeakPtrFactory<DnsProbeRunner> weak_factory_;
+
+  scoped_ptr<net::DnsClient> client_;
+
+  // The callback passed to |RunProbe|.  Cleared right before calling the
+  // callback.
+  base::Closure callback_;
+
+  // The transaction started in |RunProbe| for the DNS probe.  Reset once the
+  // results have been examined.
+  scoped_ptr<net::DnsTransaction> transaction_;
+
+  Result result_;
+
+  DISALLOW_COPY_AND_ASSIGN(DnsProbeRunner);
+};
+
+}  // namespace chrome_browser_net
+
+#endif  // CHROME_BROWSER_NET_DNS_PROBE_RUNNER_H_
diff --git a/chrome/browser/net/dns_probe_runner_unittest.cc b/chrome/browser/net/dns_probe_runner_unittest.cc
new file mode 100644
index 0000000..5519da2
--- /dev/null
+++ b/chrome/browser/net/dns_probe_runner_unittest.cc
@@ -0,0 +1,95 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop.h"
+#include "base/run_loop.h"
+#include "chrome/browser/net/dns_probe_runner.h"
+#include "chrome/browser/net/dns_probe_test_util.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/dns/dns_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::MessageLoopForIO;
+using base::RunLoop;
+using content::TestBrowserThreadBundle;
+using net::MockDnsClientRule;
+
+namespace chrome_browser_net {
+
+namespace {
+
+class TestDnsProbeRunnerCallback {
+ public:
+  TestDnsProbeRunnerCallback()
+      : callback_(base::Bind(&TestDnsProbeRunnerCallback::OnCalled,
+                             base::Unretained(this))),
+        called_(false) {}
+
+  const base::Closure& callback() const { return callback_; }
+  bool called() const { return called_; }
+
+ private:
+  void OnCalled() {
+    EXPECT_FALSE(called_);
+    called_ = true;
+  }
+
+  base::Closure callback_;
+  bool called_;
+};
+
+class DnsProbeRunnerTest : public testing::Test {
+ protected:
+  void RunTest(MockDnsClientRule::Result query_result,
+               DnsProbeRunner::Result expected_probe_result);
+
+  TestBrowserThreadBundle bundle_;
+  DnsProbeRunner runner_;
+};
+
+void DnsProbeRunnerTest::RunTest(
+    MockDnsClientRule::Result query_result,
+    DnsProbeRunner::Result expected_probe_result) {
+  TestDnsProbeRunnerCallback callback;
+
+  runner_.SetClient(CreateMockDnsClientForProbes(query_result));
+  runner_.RunProbe(callback.callback());
+  EXPECT_TRUE(runner_.IsRunning());
+
+  RunLoop().RunUntilIdle();
+  EXPECT_FALSE(runner_.IsRunning());
+  EXPECT_TRUE(callback.called());
+  EXPECT_EQ(expected_probe_result, runner_.result());
+}
+
+TEST_F(DnsProbeRunnerTest, Probe_OK) {
+  RunTest(MockDnsClientRule::OK, DnsProbeRunner::CORRECT);
+}
+
+TEST_F(DnsProbeRunnerTest, Probe_EMPTY) {
+  RunTest(MockDnsClientRule::EMPTY, DnsProbeRunner::INCORRECT);
+}
+
+TEST_F(DnsProbeRunnerTest, Probe_TIMEOUT) {
+  RunTest(MockDnsClientRule::TIMEOUT, DnsProbeRunner::UNREACHABLE);
+}
+
+TEST_F(DnsProbeRunnerTest, Probe_FAIL_ASYNC) {
+  RunTest(MockDnsClientRule::FAIL_ASYNC, DnsProbeRunner::INCORRECT);
+}
+
+TEST_F(DnsProbeRunnerTest, Probe_FAIL_SYNC) {
+  RunTest(MockDnsClientRule::FAIL_SYNC, DnsProbeRunner::INCORRECT);
+}
+
+TEST_F(DnsProbeRunnerTest, TwoProbes) {
+  RunTest(MockDnsClientRule::OK, DnsProbeRunner::CORRECT);
+  RunTest(MockDnsClientRule::EMPTY, DnsProbeRunner::INCORRECT);
+}
+
+}  // namespace
+
+}  // namespace chrome_browser_net
diff --git a/chrome/browser/net/dns_probe_service.cc b/chrome/browser/net/dns_probe_service.cc
index 156313f..36e28af 100644
--- a/chrome/browser/net/dns_probe_service.cc
+++ b/chrome/browser/net/dns_probe_service.cc
@@ -7,8 +7,6 @@
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram.h"
 #include "base/strings/string_number_conversions.h"
-#include "chrome/browser/net/dns_probe_job.h"
-#include "chrome/common/net/net_error_info.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_util.h"
 #include "net/dns/dns_client.h"
@@ -17,7 +15,7 @@
 
 using base::FieldTrialList;
 using base::StringToInt;
-using chrome_common_net::DnsProbeResult;
+using chrome_common_net::DnsProbeStatus;
 using net::DnsClient;
 using net::DnsConfig;
 using net::IPAddressNumber;
@@ -36,8 +34,8 @@
 
 // The public DNS servers used by the DnsProbeService to verify internet
 // connectivity.
-const char kPublicDnsPrimary[]   = "8.8.8.8";
-const char kPublicDnsSecondary[] = "8.8.4.4";
+const char kGooglePublicDns1[] = "8.8.8.8";
+const char kGooglePublicDns2[] = "8.8.4.4";
 
 IPEndPoint MakeDnsEndPoint(const std::string& dns_ip_literal) {
   IPAddressNumber dns_ip_number;
@@ -46,299 +44,217 @@
   return IPEndPoint(dns_ip_number, net::dns_protocol::kDefaultPort);
 }
 
-const int kAttemptsUseDefault = -1;
-
-const char kAttemptsFieldTrialName[] = "DnsProbe-Attempts";
-
-int GetAttemptsFromFieldTrial() {
-  std::string group = FieldTrialList::FindFullName(kAttemptsFieldTrialName);
-  if (group == "" || group == "default")
-    return kAttemptsUseDefault;
-
-  int attempts;
-  if (!StringToInt(group, &attempts))
-   return kAttemptsUseDefault;
-
-  return attempts;
-}
-
-bool IsLocalhost(const IPAddressNumber& ip) {
-  return (ip.size() == net::kIPv4AddressSize)
-         && (ip[0] == 127) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 1);
-}
-
-// The maximum number of nameservers counted in histograms.
-const int kNameserverCountMax = 10;
-
-}  // namespace
-
-DnsProbeService::DnsProbeService()
-    : system_result_(DnsProbeJob::SERVERS_UNKNOWN),
-      public_result_(DnsProbeJob::SERVERS_UNKNOWN),
-      state_(STATE_NO_RESULTS),
-      result_(chrome_common_net::DNS_PROBE_UNKNOWN),
-      dns_attempts_(GetAttemptsFromFieldTrial()) {
-  NetworkChangeNotifier::AddIPAddressObserver(this);
-}
-
-DnsProbeService::~DnsProbeService() {
-  NetworkChangeNotifier::RemoveIPAddressObserver(this);
-}
-
-void DnsProbeService::ProbeDns(const DnsProbeService::CallbackType& callback) {
-  callbacks_.push_back(callback);
-
-  if (state_ == STATE_RESULTS_CACHED && ResultsExpired())
-    ExpireResults();
-
-  switch (state_) {
-  case STATE_NO_RESULTS:
-    StartProbes();
-    break;
-  case STATE_RESULTS_CACHED:
-    CallCallbacks();
-    break;
-  case STATE_PROBE_RUNNING:
-    // do nothing; probe is already running, and will call the callback
-    break;
-  }
-}
-
-scoped_ptr<DnsProbeJob> DnsProbeService::CreateSystemProbeJob(
-    const DnsProbeJob::CallbackType& job_callback) {
-  DnsConfig system_config;
-  GetSystemDnsConfig(&system_config);
-  return CreateProbeJob(system_config, job_callback);
-}
-
-scoped_ptr<DnsProbeJob> DnsProbeService::CreatePublicProbeJob(
-    const DnsProbeJob::CallbackType& job_callback) {
-  DnsConfig public_config;
-  GetPublicDnsConfig(&public_config);
-  return CreateProbeJob(public_config, job_callback);
-}
-
-void DnsProbeService::OnIPAddressChanged() {
-  if (state_ == STATE_RESULTS_CACHED)
-    ExpireResults();
-}
-
-void DnsProbeService::ExpireResults() {
-  DCHECK_EQ(STATE_RESULTS_CACHED, state_);
-
-  state_ = STATE_NO_RESULTS;
-  result_ = chrome_common_net::DNS_PROBE_UNKNOWN;
-}
-
-void DnsProbeService::StartProbes() {
-  DCHECK_NE(STATE_PROBE_RUNNING, state_);
-  DCHECK(!system_job_.get());
-  DCHECK(!public_job_.get());
-
-  DnsProbeJob::CallbackType job_callback =
-      base::Bind(&DnsProbeService::OnProbeJobComplete,
-                 base::Unretained(this));
-
-  // TODO(ttuttle): Do we want to keep explicit flags for "job done"?
-  //                Or maybe DnsProbeJob should have a "finished" flag?
-  system_result_ = DnsProbeJob::SERVERS_UNKNOWN;
-  public_result_ = DnsProbeJob::SERVERS_UNKNOWN;
-
-  system_job_ = CreateSystemProbeJob(job_callback);
-  public_job_ = CreatePublicProbeJob(job_callback);
-
-  // If we can't create one or both jobs, fail the probe immediately.
-  if (!system_job_.get() || !public_job_.get()) {
-    system_job_.reset();
-    public_job_.reset();
-    state_ = STATE_RESULTS_CACHED;
-    // TODO(ttuttle): Should this be BAD_CONFIG?  Currently I think it only
-    // happens when the system DnsConfig has no servers.
-    result_ = chrome_common_net::DNS_PROBE_UNKNOWN;
-    CallCallbacks();
-    return;
-  }
-
-  state_ = STATE_PROBE_RUNNING;
-  probe_start_time_ = base::Time::Now();
-}
-
-void DnsProbeService::OnProbesComplete() {
-  DCHECK_EQ(STATE_PROBE_RUNNING, state_);
-
-  state_ = STATE_RESULTS_CACHED;
-  result_ = EvaluateResults();
-
-  HistogramProbes();
-
-  CallCallbacks();
-}
-
-void DnsProbeService::HistogramProbes() const {
-  const DnsProbeResult kMaxResult = chrome_common_net::DNS_PROBE_MAX;
-
-  DCHECK_EQ(STATE_RESULTS_CACHED, state_);
-  DCHECK_NE(kMaxResult, result_);
-
-  base::TimeDelta elapsed = base::Time::Now() - probe_start_time_;
-
-  UMA_HISTOGRAM_ENUMERATION("DnsProbe.Probe.Result", result_, kMaxResult);
-  UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.Elapsed", elapsed);
-
-  if (NetworkChangeNotifier::IsOffline()) {
-    UMA_HISTOGRAM_ENUMERATION("DnsProbe.Probe.NcnOffline.Result",
-                              result_, kMaxResult);
-    UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.NcnOffline.Elapsed", elapsed);
-  } else {
-    UMA_HISTOGRAM_ENUMERATION("DnsProbe.Probe.NcnOnline.Result",
-                              result_, kMaxResult);
-    UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.NcnOnline.Elapsed", elapsed);
-  }
-
-  switch (result_) {
-  case chrome_common_net::DNS_PROBE_UNKNOWN:
-    UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.ResultUnknown.Elapsed",
-                               elapsed);
-    break;
-  case chrome_common_net::DNS_PROBE_NO_INTERNET:
-    UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.ResultNoInternet.Elapsed",
-                               elapsed);
-    break;
-  case chrome_common_net::DNS_PROBE_BAD_CONFIG:
-    UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.ResultBadConfig.Elapsed",
-                               elapsed);
-
-    // Histogram some extra data to see why BAD_CONFIG is happening.
-    UMA_HISTOGRAM_ENUMERATION(
-        "DnsProbe.Probe.ResultBadConfig.SystemJobResult",
-        system_result_,
-        DnsProbeJob::MAX_RESULT);
-    UMA_HISTOGRAM_CUSTOM_COUNTS(
-        "DnsProbe.Probe.ResultBadConfig.SystemNameserverCount",
-        system_nameserver_count_,
-        0, kNameserverCountMax, kNameserverCountMax + 1);
-    UMA_HISTOGRAM_BOOLEAN(
-        "DnsProbe.Probe.ResultBadConfig.SystemIsLocalhost",
-        system_is_localhost_);
-    break;
-  case chrome_common_net::DNS_PROBE_NXDOMAIN:
-    UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.ResultNxdomain.Elapsed",
-                               elapsed);
-    break;
-  case chrome_common_net::DNS_PROBE_MAX:
-    NOTREACHED();
-    break;
-  }
-}
-
-DnsProbeResult DnsProbeService::EvaluateResults() const {
-  DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, system_result_);
-  DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, public_result_);
-
+DnsProbeStatus EvaluateResults(DnsProbeRunner::Result system_result,
+                               DnsProbeRunner::Result public_result) {
   // If the system DNS is working, assume the domain doesn't exist.
-  if (system_result_ == DnsProbeJob::SERVERS_CORRECT)
-    return chrome_common_net::DNS_PROBE_NXDOMAIN;
+  if (system_result == DnsProbeRunner::CORRECT)
+    return chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN;
 
   // If the system DNS is not working but another public server is, assume the
   // DNS config is bad (or perhaps the DNS servers are down or broken).
-  if (public_result_ == DnsProbeJob::SERVERS_CORRECT)
-    return chrome_common_net::DNS_PROBE_BAD_CONFIG;
+  if (public_result == DnsProbeRunner::CORRECT)
+    return chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG;
 
   // If the system DNS is not working and another public server is unreachable,
   // assume the internet connection is down (note that system DNS may be a
   // router on the LAN, so it may be reachable but returning errors.)
-  if (public_result_ == DnsProbeJob::SERVERS_UNREACHABLE)
-    return chrome_common_net::DNS_PROBE_NO_INTERNET;
+  if (public_result == DnsProbeRunner::UNREACHABLE)
+    return chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET;
 
   // Otherwise: the system DNS is not working and another public server is
   // responding but with errors or incorrect results.  This is an awkward case;
   // an invasive captive portal or a restrictive firewall may be intercepting
   // or rewriting DNS traffic, or the public server may itself be failing or
   // down.
-  return chrome_common_net::DNS_PROBE_UNKNOWN;
+  return chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE;
+}
+
+void HistogramProbe(DnsProbeStatus status, base::TimeDelta elapsed) {
+  DCHECK(chrome_common_net::DnsProbeStatusIsFinished(status));
+
+  int result = status - chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE;
+
+  const int kMaxResult = chrome_common_net::DNS_PROBE_MAX -
+                         chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE;
+
+  UMA_HISTOGRAM_ENUMERATION("DnsProbe.Status", result, kMaxResult);
+  UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed", elapsed);
+
+  if (NetworkChangeNotifier::IsOffline()) {
+    UMA_HISTOGRAM_ENUMERATION("DnsProbe.Status_NcnOffline",
+                              result, kMaxResult);
+    UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_NcnOffline", elapsed);
+  } else {
+    UMA_HISTOGRAM_ENUMERATION("DnsProbe.Status_NcnOnline",
+                              result, kMaxResult);
+    UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_NcnOnline", elapsed);
+  }
+
+  switch (status) {
+    case chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE:
+      UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_Unknown",
+                                 elapsed);
+      break;
+    case chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET:
+      UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_NoInternet",
+                                 elapsed);
+      break;
+    case chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG:
+      UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_BadConfig",
+                                 elapsed);
+      break;
+    case chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN:
+      UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_Nxdomain",
+                                 elapsed);
+      break;
+
+    // These aren't actually results.
+    case chrome_common_net::DNS_PROBE_POSSIBLE:
+    case chrome_common_net::DNS_PROBE_NOT_RUN:
+    case chrome_common_net::DNS_PROBE_STARTED:
+    case chrome_common_net::DNS_PROBE_MAX:
+      NOTREACHED();
+      break;
+  }
+}
+
+}  // namespace
+
+DnsProbeService::DnsProbeService()
+    : state_(STATE_NO_RESULT) {
+  NetworkChangeNotifier::AddDNSObserver(this);
+  SetSystemClientToCurrentConfig();
+  SetPublicClientToGooglePublicDns();
+}
+
+DnsProbeService::~DnsProbeService() {
+  NetworkChangeNotifier::RemoveDNSObserver(this);
+}
+
+void DnsProbeService::ProbeDns(const DnsProbeService::ProbeCallback& callback) {
+  pending_callbacks_.push_back(callback);
+
+  if (CachedResultIsExpired())
+    ClearCachedResult();
+
+  switch (state_) {
+    case STATE_NO_RESULT:
+      StartProbes();
+      break;
+    case STATE_RESULT_CACHED:
+      CallCallbacks();
+      break;
+    case STATE_PROBE_RUNNING:
+      // Do nothing; probe is already running, and will call the callback.
+      break;
+  }
+}
+
+void DnsProbeService::OnDNSChanged() {
+  ClearCachedResult();
+  SetSystemClientToCurrentConfig();
+}
+
+void DnsProbeService::SetSystemClientForTesting(
+    scoped_ptr<DnsClient> system_client) {
+  system_runner_.SetClient(system_client.Pass());
+}
+
+void DnsProbeService::SetPublicClientForTesting(
+    scoped_ptr<DnsClient> public_client) {
+  public_runner_.SetClient(public_client.Pass());
+}
+
+void DnsProbeService::ClearCachedResultForTesting() {
+  ClearCachedResult();
+}
+
+void DnsProbeService::SetSystemClientToCurrentConfig() {
+  DnsConfig system_config;
+  NetworkChangeNotifier::GetDnsConfig(&system_config);
+  system_config.search.clear();
+  system_config.attempts = 1;
+  system_config.randomize_ports = false;
+
+  scoped_ptr<DnsClient> system_client(DnsClient::CreateClient(NULL));
+  system_client->SetConfig(system_config);
+
+  system_runner_.SetClient(system_client.Pass());
+}
+
+void DnsProbeService::SetPublicClientToGooglePublicDns() {
+  DnsConfig public_config;
+  public_config.nameservers.push_back(MakeDnsEndPoint(kGooglePublicDns1));
+  public_config.nameservers.push_back(MakeDnsEndPoint(kGooglePublicDns2));
+  public_config.attempts = 1;
+  public_config.randomize_ports = false;
+
+  scoped_ptr<DnsClient> public_client(DnsClient::CreateClient(NULL));
+  public_client->SetConfig(public_config);
+
+  public_runner_.SetClient(public_client.Pass());
+}
+
+void DnsProbeService::StartProbes() {
+  DCHECK_EQ(STATE_NO_RESULT, state_);
+
+  DCHECK(!system_runner_.IsRunning());
+  DCHECK(!public_runner_.IsRunning());
+
+  const base::Closure callback = base::Bind(&DnsProbeService::OnProbeComplete,
+                                            base::Unretained(this));
+  system_runner_.RunProbe(callback);
+  public_runner_.RunProbe(callback);
+  probe_start_time_ = base::Time::Now();
+  state_ = STATE_PROBE_RUNNING;
+
+  DCHECK(system_runner_.IsRunning());
+  DCHECK(public_runner_.IsRunning());
+}
+
+void DnsProbeService::OnProbeComplete() {
+  DCHECK_EQ(STATE_PROBE_RUNNING, state_);
+
+  if (system_runner_.IsRunning() || public_runner_.IsRunning())
+    return;
+
+  cached_result_ = EvaluateResults(system_runner_.result(),
+                                   public_runner_.result());
+  state_ = STATE_RESULT_CACHED;
+
+  HistogramProbe(cached_result_, base::Time::Now() - probe_start_time_);
+
+  CallCallbacks();
 }
 
 void DnsProbeService::CallCallbacks() {
-  DCHECK_EQ(STATE_RESULTS_CACHED, state_);
-  DCHECK(!callbacks_.empty());
+  DCHECK_EQ(STATE_RESULT_CACHED, state_);
+  DCHECK(chrome_common_net::DnsProbeStatusIsFinished(cached_result_));
+  DCHECK(!pending_callbacks_.empty());
 
-  std::vector<CallbackType> callbacks = callbacks_;
-  callbacks_.clear();
+  std::vector<ProbeCallback> callbacks;
+  callbacks.swap(pending_callbacks_);
 
-  for (std::vector<CallbackType>::const_iterator i = callbacks.begin();
+  for (std::vector<ProbeCallback>::const_iterator i = callbacks.begin();
        i != callbacks.end(); ++i) {
-    i->Run(result_);
+    i->Run(cached_result_);
   }
 }
 
-scoped_ptr<DnsProbeJob> DnsProbeService::CreateProbeJob(
-    const DnsConfig& dns_config,
-    const DnsProbeJob::CallbackType& job_callback) {
-  if (!dns_config.IsValid())
-    return scoped_ptr<DnsProbeJob>();
-
-  scoped_ptr<DnsClient> dns_client(DnsClient::CreateClient(NULL));
-  dns_client->SetConfig(dns_config);
-  return DnsProbeJob::CreateJob(dns_client.Pass(), job_callback, NULL);
-}
-
-void DnsProbeService::OnProbeJobComplete(DnsProbeJob* job,
-                                         DnsProbeJob::Result result) {
-  DCHECK_EQ(STATE_PROBE_RUNNING, state_);
-
-  if (job == system_job_.get()) {
-    system_result_ = result;
-    system_job_.reset();
-  } else if (job == public_job_.get()) {
-    public_result_ = result;
-    public_job_.reset();
-  } else {
-    NOTREACHED();
-    return;
-  }
-
-  if (system_result_ != DnsProbeJob::SERVERS_UNKNOWN &&
-      public_result_ != DnsProbeJob::SERVERS_UNKNOWN) {
-    OnProbesComplete();
+void DnsProbeService::ClearCachedResult() {
+  if (state_ == STATE_RESULT_CACHED) {
+    state_ = STATE_NO_RESULT;
+    cached_result_ = chrome_common_net::DNS_PROBE_MAX;
   }
 }
 
-void DnsProbeService::GetSystemDnsConfig(DnsConfig* config) {
-  NetworkChangeNotifier::GetDnsConfig(config);
+bool DnsProbeService::CachedResultIsExpired() const {
+  if (state_ != STATE_RESULT_CACHED)
+    return false;
 
-  // DNS probes don't need or want the suffix search list populated
-  config->search.clear();
-
-  if (dns_attempts_ != kAttemptsUseDefault)
-    config->attempts = dns_attempts_;
-
-  // Take notes in case the config turns out to be bad, so we can histogram
-  // some useful data.
-  system_nameserver_count_ = config->nameservers.size();
-  system_is_localhost_ = (system_nameserver_count_ == 1)
-                         && IsLocalhost(config->nameservers[0].address());
-
-  // Disable port randomization.
-  config->randomize_ports = false;
-}
-
-void DnsProbeService::GetPublicDnsConfig(DnsConfig* config) {
-  *config = DnsConfig();
-
-  config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsPrimary));
-  config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsSecondary));
-
-  if (dns_attempts_ != kAttemptsUseDefault)
-    config->attempts = dns_attempts_;
-
-  // Disable port randomization.
-  config->randomize_ports = false;
-}
-
-bool DnsProbeService::ResultsExpired() {
   const base::TimeDelta kMaxResultAge =
       base::TimeDelta::FromMilliseconds(kMaxResultAgeMs);
   return base::Time::Now() - probe_start_time_ > kMaxResultAge;
 }
 
-} // namespace chrome_browser_net
+}  // namespace chrome_browser_net
diff --git a/chrome/browser/net/dns_probe_service.h b/chrome/browser/net/dns_probe_service.h
index a906d75..d1df98e 100644
--- a/chrome/browser/net/dns_probe_service.h
+++ b/chrome/browser/net/dns_probe_service.h
@@ -8,78 +8,70 @@
 #include <vector>
 
 #include "base/basictypes.h"
+#include "base/bind.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
-#include "chrome/browser/net/dns_probe_job.h"
+#include "chrome/browser/net/dns_probe_runner.h"
 #include "chrome/common/net/net_error_info.h"
 #include "net/base/network_change_notifier.h"
 
 namespace net {
+class DnsClient;
 struct DnsConfig;
 }
 
 namespace chrome_browser_net {
 
-class DnsProbeService : public net::NetworkChangeNotifier::IPAddressObserver {
+// Probes the system and public DNS servers to determine the (probable) cause
+// of a recent DNS-related page load error.  Coalesces multiple probe requests
+// (perhaps from multiple tabs) and caches the results.
+//
+// Uses a single DNS attempt per config, and doesn't randomize source ports.
+class DnsProbeService : public net::NetworkChangeNotifier::DNSObserver {
  public:
-  typedef base::Callback<void(chrome_common_net::DnsProbeResult result)>
-      CallbackType;
+  typedef base::Callback<void(chrome_common_net::DnsProbeStatus result)>
+      ProbeCallback;
 
   DnsProbeService();
   virtual ~DnsProbeService();
 
-  void ProbeDns(const CallbackType& callback);
+  virtual void ProbeDns(const ProbeCallback& callback);
 
-  // NetworkChangeNotifier::IPAddressObserver implementation:
-  virtual void OnIPAddressChanged() OVERRIDE;
+  // NetworkChangeNotifier::DNSObserver implementation:
+  virtual void OnDNSChanged() OVERRIDE;
 
- protected:
-  // This can be called by tests to pretend the cached reuslt has expired.
-  void ExpireResults();
+  void SetSystemClientForTesting(scoped_ptr<net::DnsClient> system_client);
+  void SetPublicClientForTesting(scoped_ptr<net::DnsClient> public_client);
+  void ClearCachedResultForTesting();
 
  private:
   enum State {
-    STATE_NO_RESULTS,
+    STATE_NO_RESULT,
     STATE_PROBE_RUNNING,
-    STATE_RESULTS_CACHED,
+    STATE_RESULT_CACHED,
   };
 
+  void SetSystemClientToCurrentConfig();
+  void SetPublicClientToGooglePublicDns();
+
+  // Starts a probe (runs system and public probes).
   void StartProbes();
-  void OnProbesComplete();
+  void OnProbeComplete();
+  // Calls all |pending_callbacks_| with the |cached_result_|.
   void CallCallbacks();
+  // Clears a cached probe result.
+  void ClearCachedResult();
 
-  void OnProbeJobComplete(DnsProbeJob* job, DnsProbeJob::Result result);
-  chrome_common_net::DnsProbeResult EvaluateResults() const;
-  void HistogramProbes() const;
+  bool CachedResultIsExpired() const;
 
-  // These are expected to be overridden by tests to return mock jobs.
-  virtual scoped_ptr<DnsProbeJob> CreateSystemProbeJob(
-      const DnsProbeJob::CallbackType& job_callback);
-  virtual scoped_ptr<DnsProbeJob> CreatePublicProbeJob(
-      const DnsProbeJob::CallbackType& job_callback);
-
-  scoped_ptr<DnsProbeJob> CreateProbeJob(
-      const net::DnsConfig& dns_config,
-      const DnsProbeJob::CallbackType& job_callback);
-  void GetSystemDnsConfig(net::DnsConfig* config);
-  void GetPublicDnsConfig(net::DnsConfig* config);
-  bool ResultsExpired();
-
-  scoped_ptr<DnsProbeJob> system_job_;
-  scoped_ptr<DnsProbeJob> public_job_;
-  DnsProbeJob::Result system_result_;
-  DnsProbeJob::Result public_result_;
-  std::vector<CallbackType> callbacks_;
   State state_;
-  chrome_common_net::DnsProbeResult result_;
+  std::vector<ProbeCallback> pending_callbacks_;
   base::Time probe_start_time_;
-  // How many DNS request attempts the probe jobs will make before giving up
-  // (Overrides the attempts field in the system DnsConfig.)
-  const int dns_attempts_;
-  // How many nameservers the system config has.
-  int system_nameserver_count_;
-  // Whether the only system nameserver is 127.0.0.1.
-  bool system_is_localhost_;
+  chrome_common_net::DnsProbeStatus cached_result_;
+
+  // DnsProbeRunners for the system DNS configuration and a public DNS server.
+  DnsProbeRunner system_runner_;
+  DnsProbeRunner public_runner_;
 
   DISALLOW_COPY_AND_ASSIGN(DnsProbeService);
 };
diff --git a/chrome/browser/net/dns_probe_service_unittest.cc b/chrome/browser/net/dns_probe_service_unittest.cc
index 15cbb44..d8b55eb 100644
--- a/chrome/browser/net/dns_probe_service_unittest.cc
+++ b/chrome/browser/net/dns_probe_service_unittest.cc
@@ -9,111 +9,28 @@
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop.h"
 #include "base/run_loop.h"
-#include "chrome/browser/net/dns_probe_job.h"
+#include "chrome/browser/net/dns_probe_runner.h"
+#include "chrome/browser/net/dns_probe_test_util.h"
 #include "chrome/common/net/net_error_info.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/dns/dns_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using chrome_common_net::DnsProbeResult;
+using base::MessageLoopForIO;
+using base::RunLoop;
+using chrome_common_net::DnsProbeStatus;
+using content::TestBrowserThreadBundle;
+using net::MockDnsClientRule;
 
 namespace chrome_browser_net {
 
 namespace {
 
-class MockDnsProbeJob : public DnsProbeJob {
- public:
-  MockDnsProbeJob(const CallbackType& callback,
-                  DnsProbeJob::Result result)
-      : weak_factory_(this) {
-    base::MessageLoop::current()->PostTask(
-        FROM_HERE,
-        base::Bind(&MockDnsProbeJob::CallCallback,
-                   weak_factory_.GetWeakPtr(),
-                   callback,
-                   result));
-  }
-
-  virtual ~MockDnsProbeJob() { }
-
- private:
-  void CallCallback(const CallbackType& callback, Result result) {
-    callback.Run(this, result);
-  }
-
-  base::WeakPtrFactory<MockDnsProbeJob> weak_factory_;
-};
-
-class TestDnsProbeService : public DnsProbeService {
- public:
-  TestDnsProbeService()
-      : DnsProbeService(),
-        system_job_created_(false),
-        public_job_created_(false),
-        mock_system_result_(DnsProbeJob::SERVERS_UNKNOWN),
-        mock_public_result_(DnsProbeJob::SERVERS_UNKNOWN),
-        mock_system_fail_(false) {
-  }
-
-  virtual ~TestDnsProbeService() { }
-
-  void set_mock_results(
-      DnsProbeJob::Result mock_system_result,
-      DnsProbeJob::Result mock_public_result) {
-    mock_system_result_ = mock_system_result;
-    mock_public_result_ = mock_public_result;
-  }
-
-  void set_mock_system_fail(bool mock_system_fail) {
-    mock_system_fail_ = mock_system_fail;
-  }
-
-  bool jobs_created(void) {
-    return system_job_created_ && public_job_created_;
-  }
-
-  void ResetJobsCreated() {
-    system_job_created_ = false;
-    public_job_created_ = false;
-  }
-
-  void MockExpireResults() {
-    ExpireResults();
-  }
-
-  bool system_job_created_;
-  bool public_job_created_;
-
- private:
-  // Override methods in DnsProbeService to return mock jobs:
-
-  virtual scoped_ptr<DnsProbeJob> CreateSystemProbeJob(
-      const DnsProbeJob::CallbackType& job_callback) OVERRIDE {
-    if (mock_system_fail_)
-      return scoped_ptr<DnsProbeJob>();
-
-    system_job_created_ = true;
-    return scoped_ptr<DnsProbeJob>(
-        new MockDnsProbeJob(job_callback,
-                            mock_system_result_));
-  }
-
-  virtual scoped_ptr<DnsProbeJob> CreatePublicProbeJob(
-      const DnsProbeJob::CallbackType& job_callback) OVERRIDE {
-    public_job_created_ = true;
-    return scoped_ptr<DnsProbeJob>(
-        new MockDnsProbeJob(job_callback,
-                            mock_public_result_));
-  }
-
-  DnsProbeJob::Result mock_system_result_;
-  DnsProbeJob::Result mock_public_result_;
-  bool mock_system_fail_;
-};
-
 class DnsProbeServiceTest : public testing::Test {
  public:
   DnsProbeServiceTest()
       : callback_called_(false),
-        callback_result_(chrome_common_net::DNS_PROBE_UNKNOWN) {
+        callback_result_(chrome_common_net::DNS_PROBE_MAX) {
   }
 
   void Probe() {
@@ -121,98 +38,94 @@
                                  base::Unretained(this)));
   }
 
-  void RunUntilIdle() {
-    base::RunLoop run_loop;
-    run_loop.RunUntilIdle();
-  }
-
   void Reset() {
-    service_.ResetJobsCreated();
     callback_called_ = false;
   }
 
-  base::MessageLoopForIO message_loop_;
-  TestDnsProbeService service_;
-  bool callback_called_;
-  DnsProbeResult callback_result_;
+ protected:
+  void SetRules(MockDnsClientRule::Result system_query_result,
+                MockDnsClientRule::Result public_query_result) {
+    service_.SetSystemClientForTesting(
+        CreateMockDnsClientForProbes(system_query_result));
+    service_.SetPublicClientForTesting(
+        CreateMockDnsClientForProbes(public_query_result));
+  }
+
+  void RunTest(MockDnsClientRule::Result system_query_result,
+               MockDnsClientRule::Result public_query_result,
+               DnsProbeStatus expected_result) {
+    Reset();
+    SetRules(system_query_result, public_query_result);
+
+    Probe();
+    RunLoop().RunUntilIdle();
+    EXPECT_TRUE(callback_called_);
+    EXPECT_EQ(expected_result, callback_result_);
+  }
+
+  void ClearCachedResult() {
+    service_.ClearCachedResultForTesting();
+  }
 
  private:
-  void ProbeCallback(DnsProbeResult result) {
+  void ProbeCallback(DnsProbeStatus result) {
+    EXPECT_FALSE(callback_called_);
     callback_called_ = true;
     callback_result_ = result;
   }
+
+  DnsProbeService service_;
+  bool callback_called_;
+  DnsProbeStatus callback_result_;
+  TestBrowserThreadBundle bundle_;
 };
 
-TEST_F(DnsProbeServiceTest, Null) {
+TEST_F(DnsProbeServiceTest, Probe_OK_OK) {
+  RunTest(MockDnsClientRule::OK, MockDnsClientRule::OK,
+          chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
 }
 
-TEST_F(DnsProbeServiceTest, Probe) {
-  service_.set_mock_results(DnsProbeJob::SERVERS_CORRECT,
-                            DnsProbeJob::SERVERS_CORRECT);
+TEST_F(DnsProbeServiceTest, Probe_TIMEOUT_OK) {
+  RunTest(MockDnsClientRule::TIMEOUT, MockDnsClientRule::OK,
+          chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG);
+}
 
-  Probe();
-  EXPECT_TRUE(service_.jobs_created());
-  EXPECT_FALSE(callback_called_);
+TEST_F(DnsProbeServiceTest, Probe_TIMEOUT_TIMEOUT) {
+  RunTest(MockDnsClientRule::TIMEOUT, MockDnsClientRule::TIMEOUT,
+          chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET);
+}
 
-  RunUntilIdle();
-  EXPECT_TRUE(callback_called_);
-  EXPECT_EQ(chrome_common_net::DNS_PROBE_NXDOMAIN, callback_result_);
+TEST_F(DnsProbeServiceTest, Probe_OK_FAIL_SYNC) {
+  RunTest(MockDnsClientRule::OK, MockDnsClientRule::FAIL_SYNC,
+          chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+}
+
+TEST_F(DnsProbeServiceTest, Probe_FAIL_SYNC_OK) {
+  RunTest(MockDnsClientRule::FAIL_SYNC, MockDnsClientRule::OK,
+          chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG);
+}
+
+TEST_F(DnsProbeServiceTest, Probe_FAIL_SYNC_FAIL_SYNC) {
+  RunTest(MockDnsClientRule::FAIL_SYNC, MockDnsClientRule::FAIL_SYNC,
+          chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE);
 }
 
 TEST_F(DnsProbeServiceTest, Cache) {
-  service_.set_mock_results(DnsProbeJob::SERVERS_CORRECT,
-                            DnsProbeJob::SERVERS_CORRECT);
-
-  Probe();
-  RunUntilIdle();
-  Reset();
-
-  // Cached NXDOMAIN result should persist.
-
-  Probe();
-  EXPECT_FALSE(service_.jobs_created());
-
-  RunUntilIdle();
-  EXPECT_TRUE(callback_called_);
-  EXPECT_EQ(chrome_common_net::DNS_PROBE_NXDOMAIN, callback_result_);
+  RunTest(MockDnsClientRule::OK, MockDnsClientRule::OK,
+          chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+  // Cached NXDOMAIN result should persist, not the result from the new rules.
+  RunTest(MockDnsClientRule::TIMEOUT, MockDnsClientRule::TIMEOUT,
+          chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
 }
 
-TEST_F(DnsProbeServiceTest, Expired) {
-  service_.set_mock_results(DnsProbeJob::SERVERS_CORRECT,
-                            DnsProbeJob::SERVERS_CORRECT);
-
-  Probe();
-  EXPECT_TRUE(service_.jobs_created());
-
-  RunUntilIdle();
-  EXPECT_TRUE(callback_called_);
-  EXPECT_EQ(chrome_common_net::DNS_PROBE_NXDOMAIN, callback_result_);
-
-  Reset();
-
-  service_.MockExpireResults();
-
-  Probe();
-  EXPECT_TRUE(service_.jobs_created());
-
-  RunUntilIdle();
-  EXPECT_TRUE(callback_called_);
-  EXPECT_EQ(chrome_common_net::DNS_PROBE_NXDOMAIN, callback_result_);
-}
-
-TEST_F(DnsProbeServiceTest, SystemFail) {
-  service_.set_mock_results(DnsProbeJob::SERVERS_CORRECT,
-                            DnsProbeJob::SERVERS_CORRECT);
-  service_.set_mock_system_fail(true);
-
-  Probe();
-  EXPECT_TRUE(callback_called_);
-  EXPECT_EQ(chrome_common_net::DNS_PROBE_UNKNOWN, callback_result_);
-
-  Reset();
-
-  RunUntilIdle();
-  EXPECT_FALSE(callback_called_);
+TEST_F(DnsProbeServiceTest, Expire) {
+  RunTest(MockDnsClientRule::OK, MockDnsClientRule::OK,
+          chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+  // Pretend cache expires.
+  ClearCachedResult();
+  // New rules should apply, since a new probe should be run.
+  RunTest(MockDnsClientRule::TIMEOUT, MockDnsClientRule::TIMEOUT,
+          chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET);
 }
 
 }  // namespace
diff --git a/chrome/browser/net/dns_probe_test_util.cc b/chrome/browser/net/dns_probe_test_util.cc
new file mode 100644
index 0000000..88d481d
--- /dev/null
+++ b/chrome/browser/net/dns_probe_test_util.cc
@@ -0,0 +1,37 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/net/dns_probe_test_util.h"
+
+#include "chrome/browser/net/dns_probe_runner.h"
+#include "net/dns/dns_config_service.h"
+#include "net/dns/dns_protocol.h"
+
+using net::DnsClient;
+using net::DnsConfig;
+using net::IPAddressNumber;
+using net::IPEndPoint;
+using net::MockDnsClientRule;
+using net::MockDnsClientRuleList;
+using net::ParseIPLiteralToNumber;
+
+namespace chrome_browser_net {
+
+scoped_ptr<DnsClient> CreateMockDnsClientForProbes(
+    MockDnsClientRule::Result result) {
+  DnsConfig config;
+  IPAddressNumber dns_ip;
+  ParseIPLiteralToNumber("192.168.1.1", &dns_ip);
+  const uint16 kDnsPort = net::dns_protocol::kDefaultPort;
+  config.nameservers.push_back(IPEndPoint(dns_ip, kDnsPort));
+
+  const uint16 kTypeA = net::dns_protocol::kTypeA;
+  MockDnsClientRuleList rules;
+  rules.push_back(
+      MockDnsClientRule(DnsProbeRunner::kKnownGoodHostname, kTypeA, result));
+
+  return CreateMockDnsClient(config, rules).Pass();
+}
+
+}  // namespace chrome_browser_net
diff --git a/chrome/browser/net/dns_probe_test_util.h b/chrome/browser/net/dns_probe_test_util.h
new file mode 100644
index 0000000..0f36174
--- /dev/null
+++ b/chrome/browser/net/dns_probe_test_util.h
@@ -0,0 +1,21 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NET_DNS_PROBE_TEST_UTIL_H_
+#define CHROME_BROWSER_NET_DNS_PROBE_TEST_UTIL_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "net/dns/dns_client.h"
+#include "net/dns/dns_test_util.h"
+
+namespace chrome_browser_net {
+
+// Creates a mock DNS client with a single rule for the known-good query
+// (currently google.com) that returns |result|.
+scoped_ptr<net::DnsClient> CreateMockDnsClientForProbes(
+    net::MockDnsClientRule::Result result);
+
+}  // namespace chrome_browser_net
+
+#endif  // CHROME_BROWSER_NET_DNS_PROBE_TEST_UTIL_H_
diff --git a/chrome/browser/net/http_server_properties_manager.cc b/chrome/browser/net/http_server_properties_manager.cc
index 6dc629a..7da72f4 100644
--- a/chrome/browser/net/http_server_properties_manager.cc
+++ b/chrome/browser/net/http_server_properties_manager.cc
@@ -11,7 +11,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/browser_thread.h"
@@ -39,7 +39,7 @@
 const int kMissingVersion = 0;
 
 // The version number of persisted http_server_properties.
-const int kVersionNumber = 1;
+const int kVersionNumber = 2;
 
 typedef std::vector<std::string> StringVector;
 
@@ -92,13 +92,24 @@
 }
 
 // static
-void HttpServerPropertiesManager::RegisterUserPrefs(
+void HttpServerPropertiesManager::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* prefs) {
   prefs->RegisterDictionaryPref(
       prefs::kHttpServerProperties,
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 }
 
+// static
+void HttpServerPropertiesManager::SetVersion(
+    base::DictionaryValue* http_server_properties_dict,
+    int version_number) {
+  if (version_number < 0)
+    version_number =  kVersionNumber;
+  DCHECK_LE(version_number, kVersionNumber);
+  if (version_number <= kVersionNumber)
+    http_server_properties_dict->SetInteger("version", version_number);
+}
+
 // This is required for conformance with the HttpServerProperties interface.
 void HttpServerPropertiesManager::Clear() {
   Clear(base::Closure());
@@ -258,28 +269,27 @@
   const base::DictionaryValue& http_server_properties_dict =
       *pref_service_->GetDictionary(prefs::kHttpServerProperties);
 
-  // Initialize version to kMissingVersion because there might not be a
-  // "version" key in the properties.
   int version = kMissingVersion;
-  http_server_properties_dict.GetIntegerWithoutPathExpansion(
-      "version", &version);
+  if (!http_server_properties_dict.GetIntegerWithoutPathExpansion(
+      "version", &version)) {
+    DVLOG(1) << "Missing version. Clearing all properties.";
+    return;
+  }
 
-  const base::DictionaryValue* servers_dict;
-  if (version == kMissingVersion) {
-    // If http_server_properties_dict has no "version" key and no "servers" key,
-    // then the properties for a given server are in
-    // http_server_properties_dict[server].
-    servers_dict = &http_server_properties_dict;
-  } else {
-    // The "new" format has "version" and "servers" keys. The properties for a
-    // given server is in http_server_properties_dict["servers"][server].
-    const base::DictionaryValue* servers_dict_temp = NULL;
-    if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
-        "servers", &servers_dict_temp)) {
-      DVLOG(1) << "Malformed http_server_properties for servers";
-      return;
-    }
-    servers_dict = servers_dict_temp;
+  // The properties for a given server is in
+  // http_server_properties_dict["servers"][server].
+  const base::DictionaryValue* servers_dict = NULL;
+  if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
+      "servers", &servers_dict)) {
+    DVLOG(1) << "Malformed http_server_properties for servers.";
+    return;
+  }
+
+  // TODO(rtenneti): Mark entries with an LRU sequence number (date of access?),
+  // and then truncate down deleting old stuff.
+  if (version != kVersionNumber && servers_dict->size() > 300) {
+    DVLOG(1) << "Size is too large. Clearing all properties.";
+    return;
   }
 
   // String is host/port pair of spdy server.
@@ -317,34 +327,32 @@
 
     // Get SpdySettings.
     DCHECK(!ContainsKey(*spdy_settings_map, server));
-    if (version == kVersionNumber) {
-      const base::DictionaryValue* spdy_settings_dict = NULL;
-      if (server_pref_dict->GetDictionaryWithoutPathExpansion(
-          "settings", &spdy_settings_dict)) {
-        net::SettingsMap settings_map;
-        for (base::DictionaryValue::Iterator dict_it(*spdy_settings_dict);
-             !dict_it.IsAtEnd(); dict_it.Advance()) {
-          const std::string& id_str = dict_it.key();
-          int id = 0;
-          if (!base::StringToInt(id_str, &id)) {
-            DVLOG(1) << "Malformed id in SpdySettings for server: " <<
-                server_str;
-            NOTREACHED();
-            continue;
-          }
-          int value = 0;
-          if (!dict_it.value().GetAsInteger(&value)) {
-            DVLOG(1) << "Malformed value in SpdySettings for server: " <<
-                server_str;
-            NOTREACHED();
-            continue;
-          }
-          net::SettingsFlagsAndValue flags_and_value(
-              net::SETTINGS_FLAG_PERSISTED, value);
-          settings_map[static_cast<net::SpdySettingsIds>(id)] = flags_and_value;
+    const base::DictionaryValue* spdy_settings_dict = NULL;
+    if (server_pref_dict->GetDictionaryWithoutPathExpansion(
+        "settings", &spdy_settings_dict)) {
+      net::SettingsMap settings_map;
+      for (base::DictionaryValue::Iterator dict_it(*spdy_settings_dict);
+           !dict_it.IsAtEnd(); dict_it.Advance()) {
+        const std::string& id_str = dict_it.key();
+        int id = 0;
+        if (!base::StringToInt(id_str, &id)) {
+          DVLOG(1) << "Malformed id in SpdySettings for server: " <<
+              server_str;
+          NOTREACHED();
+          continue;
         }
-        (*spdy_settings_map)[server] = settings_map;
+        int value = 0;
+        if (!dict_it.value().GetAsInteger(&value)) {
+          DVLOG(1) << "Malformed value in SpdySettings for server: " <<
+              server_str;
+          NOTREACHED();
+          continue;
+        }
+        net::SettingsFlagsAndValue flags_and_value(
+            net::SETTINGS_FLAG_PERSISTED, value);
+        settings_map[static_cast<net::SpdySettingsIds>(id)] = flags_and_value;
       }
+      (*spdy_settings_map)[server] = settings_map;
     }
 
     int pipeline_capability = net::PIPELINE_UNKNOWN;
@@ -659,7 +667,7 @@
   }
 
   http_server_properties_dict.SetWithoutPathExpansion("servers", servers_dict);
-  http_server_properties_dict.SetInteger("version", kVersionNumber);
+  SetVersion(&http_server_properties_dict, kVersionNumber);
   setting_prefs_ = true;
   pref_service_->Set(prefs::kHttpServerProperties,
                      http_server_properties_dict);
diff --git a/chrome/browser/net/http_server_properties_manager.h b/chrome/browser/net/http_server_properties_manager.h
index a63859a..756b119 100644
--- a/chrome/browser/net/http_server_properties_manager.h
+++ b/chrome/browser/net/http_server_properties_manager.h
@@ -67,7 +67,11 @@
   void ShutdownOnUIThread();
 
   // Register |prefs| for properties managed here.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
+  // Helper function for unit tests to set the version in the dictionary.
+  static void SetVersion(base::DictionaryValue* http_server_properties_dict,
+                         int version_number);
 
   // Deletes all data. Works asynchronously, but if a |completion| callback is
   // provided, it will be fired on the UI thread when everything is done.
diff --git a/chrome/browser/net/http_server_properties_manager_unittest.cc b/chrome/browser/net/http_server_properties_manager_unittest.cc
index 5be9d96..16b28ce 100644
--- a/chrome/browser/net/http_server_properties_manager_unittest.cc
+++ b/chrome/browser/net/http_server_properties_manager_unittest.cc
@@ -160,9 +160,8 @@
   server_pref_dict->SetInteger("pipeline_capability", net::PIPELINE_CAPABLE);
 
   // Set the server preference for www.google.com:80.
-  base::DictionaryValue* http_server_properties_dict =
-      new base::DictionaryValue;
-  http_server_properties_dict->SetWithoutPathExpansion(
+  base::DictionaryValue* servers_dict = new base::DictionaryValue;
+  servers_dict->SetWithoutPathExpansion(
       "www.google.com:80", server_pref_dict);
 
   // Set the preference for mail.google.com server.
@@ -183,9 +182,14 @@
   server_pref_dict1->SetInteger("pipeline_capability", net::PIPELINE_INCAPABLE);
 
   // Set the server preference for mail.google.com:80.
-  http_server_properties_dict->SetWithoutPathExpansion(
+  servers_dict->SetWithoutPathExpansion(
       "mail.google.com:80", server_pref_dict1);
 
+  base::DictionaryValue* http_server_properties_dict =
+      new base::DictionaryValue;
+  HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
+  http_server_properties_dict->SetWithoutPathExpansion("servers", servers_dict);
+
   // Set the same value for kHttpServerProperties multiple times.
   pref_service_.SetManagedPref(prefs::kHttpServerProperties,
                                http_server_properties_dict);
diff --git a/chrome/browser/net/net_error_tab_helper.cc b/chrome/browser/net/net_error_tab_helper.cc
index c7189a9..6f20a8a 100644
--- a/chrome/browser/net/net_error_tab_helper.cc
+++ b/chrome/browser/net/net_error_tab_helper.cc
@@ -18,7 +18,8 @@
 #include "net/base/net_errors.h"
 
 using base::FieldTrialList;
-using chrome_common_net::DnsProbeResult;
+using chrome_common_net::DnsProbeStatus;
+using chrome_common_net::DnsProbeStatusToString;
 using content::BrowserContext;
 using content::BrowserThread;
 using content::PageTransition;
@@ -32,9 +33,6 @@
 
 namespace {
 
-const char kDnsProbeFieldTrialName[] = "DnsProbe-Enable";
-const char kDnsProbeFieldTrialEnableGroupName[] = "enable";
-
 static NetErrorTabHelper::TestingState testing_state_ =
     NetErrorTabHelper::TESTING_DEFAULT;
 
@@ -45,48 +43,24 @@
          net_error == net::ERR_NAME_RESOLUTION_FAILED;
 }
 
-bool GetEnabledByTrial() {
-  return (FieldTrialList::FindFullName(kDnsProbeFieldTrialName)
-          == kDnsProbeFieldTrialEnableGroupName);
-}
-
-NetErrorTracker::FrameType GetFrameType(bool is_main_frame) {
-  return is_main_frame ? NetErrorTracker::FRAME_MAIN
-                       : NetErrorTracker::FRAME_SUB;
-}
-
-NetErrorTracker::PageType GetPageType(bool is_error_page) {
-  return is_error_page ? NetErrorTracker::PAGE_ERROR
-                       : NetErrorTracker::PAGE_NORMAL;
-}
-
-NetErrorTracker::ErrorType GetErrorType(int net_error) {
-  return IsDnsError(net_error) ? NetErrorTracker::ERROR_DNS
-                               : NetErrorTracker::ERROR_OTHER;
-}
-
 void OnDnsProbeFinishedOnIOThread(
-    const base::Callback<void(DnsProbeResult)>& callback,
-    DnsProbeResult result) {
+    const base::Callback<void(DnsProbeStatus)>& callback,
+    DnsProbeStatus result) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
-  DVLOG(1) << "DNS probe finished with result " << result;
-
   BrowserThread::PostTask(
       BrowserThread::UI,
       FROM_HERE,
       base::Bind(callback, result));
 }
 
-// We can only access g_browser_process->io_thread() from the browser thread,
-// so we have to pass it in to the callback instead of dereferencing it here.
+// Can only access g_browser_process->io_thread() from the browser thread,
+// so have to pass it in to the callback instead of dereferencing it here.
 void StartDnsProbeOnIOThread(
-    const base::Callback<void(DnsProbeResult)>& callback,
+    const base::Callback<void(DnsProbeStatus)>& callback,
     IOThread* io_thread) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
-  DVLOG(1) << "Starting DNS probe";
-
   DnsProbeService* probe_service =
       io_thread->globals()->dns_probe_service.get();
 
@@ -113,8 +87,10 @@
     RenderViewHost* render_view_host) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  tracker_.OnStartProvisionalLoad(GetFrameType(is_main_frame),
-                                  GetPageType(is_error_page));
+  if (!is_main_frame)
+    return;
+
+  is_error_page_ = is_error_page;
 }
 
 void NetErrorTabHelper::DidCommitProvisionalLoadForFrame(
@@ -125,7 +101,21 @@
     RenderViewHost* render_view_host) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  tracker_.OnCommitProvisionalLoad(GetFrameType(is_main_frame));
+  if (!is_main_frame)
+    return;
+
+  // Resend status every time an error page commits; this is somewhat spammy,
+  // but ensures that the status will make it to the real error page, even if
+  // the link doctor loads a blank intermediate page or the tab switches
+  // renderer processes.
+  if (is_error_page_ && dns_error_active_) {
+    dns_error_page_committed_ = true;
+    DVLOG(1) << "Committed error page; resending status.";
+    SendInfo();
+  } else {
+    dns_error_active_ = false;
+    dns_error_page_committed_ = false;
+  }
 }
 
 void NetErrorTabHelper::DidFailProvisionalLoad(
@@ -137,75 +127,70 @@
     RenderViewHost* render_view_host) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  tracker_.OnFailProvisionalLoad(GetFrameType(is_main_frame),
-                                 GetErrorType(error_code));
-}
+  if (!is_main_frame)
+    return;
 
-void NetErrorTabHelper::DidFinishLoad(
-    int64 frame_id,
-    const GURL& validated_url,
-    bool is_main_frame,
-    RenderViewHost* render_view_host) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  tracker_.OnFinishLoad(GetFrameType(is_main_frame));
+  if (IsDnsError(error_code)) {
+    dns_error_active_ = true;
+    OnMainFrameDnsError();
+  }
 }
 
 NetErrorTabHelper::NetErrorTabHelper(WebContents* contents)
     : WebContentsObserver(contents),
       weak_factory_(this),
-      tracker_(base::Bind(&NetErrorTabHelper::TrackerCallback,
-                          weak_factory_.GetWeakPtr())),
-      dns_error_page_state_(NetErrorTracker::DNS_ERROR_PAGE_NONE),
-      dns_probe_state_(DNS_PROBE_NONE),
-      enabled_by_trial_(GetEnabledByTrial()) {
+      is_error_page_(false),
+      dns_error_active_(false),
+      dns_error_page_committed_(false),
+      dns_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE),
+      enabled_by_trial_(chrome_common_net::DnsProbesEnabledByFieldTrial()) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  InitializePref(contents);
+  // If this helper is under test, it won't have a WebContents.
+  if (contents)
+    InitializePref(contents);
 }
 
-void NetErrorTabHelper::TrackerCallback(
-    NetErrorTracker::DnsErrorPageState state) {
-  dns_error_page_state_ = state;
-
-  MaybePostStartDnsProbeTask();
-  MaybeSendInfo();
-}
-
-void NetErrorTabHelper::MaybePostStartDnsProbeTask() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  if (dns_error_page_state_ != NetErrorTracker::DNS_ERROR_PAGE_NONE &&
-      dns_probe_state_ != DNS_PROBE_STARTED &&
-      ProbesAllowed()) {
-    BrowserThread::PostTask(
-        BrowserThread::IO,
-        FROM_HERE,
-        base::Bind(&StartDnsProbeOnIOThread,
-                   base::Bind(&NetErrorTabHelper::OnDnsProbeFinished,
-                              weak_factory_.GetWeakPtr()),
-                   g_browser_process->io_thread()));
-    dns_probe_state_ = DNS_PROBE_STARTED;
+void NetErrorTabHelper::OnMainFrameDnsError() {
+  if (ProbesAllowed()) {
+    // Don't start more than one probe at a time.
+    if (dns_probe_status_ != chrome_common_net::DNS_PROBE_STARTED) {
+      StartDnsProbe();
+      dns_probe_status_ = chrome_common_net::DNS_PROBE_STARTED;
+    }
+  } else {
+    dns_probe_status_ = chrome_common_net::DNS_PROBE_NOT_RUN;
   }
 }
 
-void NetErrorTabHelper::OnDnsProbeFinished(DnsProbeResult result) {
+void NetErrorTabHelper::StartDnsProbe() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK_EQ(DNS_PROBE_STARTED, dns_probe_state_);
+  DCHECK(dns_error_active_);
+  DCHECK_NE(chrome_common_net::DNS_PROBE_STARTED, dns_probe_status_);
 
-  dns_probe_result_ = result;
-  dns_probe_state_ = DNS_PROBE_FINISHED;
+  DVLOG(1) << "Starting DNS probe.";
 
-  MaybeSendInfo();
+  BrowserThread::PostTask(
+      BrowserThread::IO,
+      FROM_HERE,
+      base::Bind(&StartDnsProbeOnIOThread,
+                 base::Bind(&NetErrorTabHelper::OnDnsProbeFinished,
+                            weak_factory_.GetWeakPtr()),
+                 g_browser_process->io_thread()));
 }
 
-void NetErrorTabHelper::MaybeSendInfo() {
-  if (dns_error_page_state_ == NetErrorTracker::DNS_ERROR_PAGE_LOADED &&
-      dns_probe_state_ == DNS_PROBE_FINISHED) {
-    DVLOG(1) << "Sending result " << dns_probe_result_ << " to renderer";
-    Send(new ChromeViewMsg_NetErrorInfo(routing_id(), dns_probe_result_));
-    dns_probe_state_ = DNS_PROBE_NONE;
-  }
+void NetErrorTabHelper::OnDnsProbeFinished(DnsProbeStatus result) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_EQ(chrome_common_net::DNS_PROBE_STARTED, dns_probe_status_);
+  DCHECK(chrome_common_net::DnsProbeStatusIsFinished(result));
+
+  DVLOG(1) << "Finished DNS probe with result "
+           << DnsProbeStatusToString(result) << ".";
+
+  dns_probe_status_ = result;
+
+  if (dns_error_page_committed_)
+    SendInfo();
 }
 
 void NetErrorTabHelper::InitializePref(WebContents* contents) {
@@ -226,4 +211,15 @@
   return enabled_by_trial_ && *resolve_errors_with_web_service_;
 }
 
+void NetErrorTabHelper::SendInfo() {
+  DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, dns_probe_status_);
+  DCHECK(dns_error_page_committed_);
+
+  DVLOG(1) << "Sending status " << DnsProbeStatusToString(dns_probe_status_);
+  Send(new ChromeViewMsg_NetErrorInfo(routing_id(), dns_probe_status_));
+
+  if (!dns_probe_status_snoop_callback_.is_null())
+    dns_probe_status_snoop_callback_.Run(dns_probe_status_);
+}
+
 }  // namespace chrome_browser_net
diff --git a/chrome/browser/net/net_error_tab_helper.h b/chrome/browser/net/net_error_tab_helper.h
index e48fa9f..fd0553e 100644
--- a/chrome/browser/net/net_error_tab_helper.h
+++ b/chrome/browser/net/net_error_tab_helper.h
@@ -6,12 +6,12 @@
 #define CHROME_BROWSER_NET_NET_ERROR_TAB_HELPER_H_
 
 #include "base/basictypes.h"
+#include "base/bind.h"
 #include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "base/prefs/pref_member.h"
 #include "chrome/browser/net/dns_probe_service.h"
 #include "chrome/common/net/net_error_info.h"
-#include "chrome/common/net/net_error_tracker.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 
@@ -30,10 +30,21 @@
     TESTING_FORCE_ENABLED
   };
 
+  typedef base::Callback<void(chrome_common_net::DnsProbeStatus)>
+      DnsProbeStatusSnoopCallback;
+
   virtual ~NetErrorTabHelper();
 
   static void set_state_for_testing(TestingState testing_state);
 
+  // Sets a callback that will be called immediately after the helper sends
+  // a NetErrorHelper IPC.  (Used by the DNS probe browser test to know when to
+  // check the error page for updates, instead of polling.)
+  void set_dns_probe_status_snoop_callback_for_testing(
+      const DnsProbeStatusSnoopCallback& dns_probe_status_snoop_callback) {
+    dns_probe_status_snoop_callback_ = dns_probe_status_snoop_callback;
+  }
+
   // content::WebContentsObserver implementation.
   virtual void DidStartProvisionalLoadForFrame(
       int64 frame_id,
@@ -59,43 +70,50 @@
       const string16& error_description,
       content::RenderViewHost* render_view_host) OVERRIDE;
 
-  virtual void DidFinishLoad(
-      int64 frame_id,
-      const GURL& validated_url,
-      bool is_main_frame,
-      content::RenderViewHost* render_view_host) OVERRIDE;
+ protected:
+  // |contents| is the WebContents of the tab this NetErrorTabHelper is
+  // attached to.
+  explicit NetErrorTabHelper(content::WebContents* contents);
+  virtual void StartDnsProbe();
+  virtual void SendInfo();
+  void OnDnsProbeFinished(chrome_common_net::DnsProbeStatus result);
+
+  chrome_common_net::DnsProbeStatus dns_probe_status() const {
+    return dns_probe_status_;
+  }
 
  private:
   friend class content::WebContentsUserData<NetErrorTabHelper>;
 
-  enum DnsProbeState {
-    DNS_PROBE_NONE,
-    DNS_PROBE_STARTED,
-    DNS_PROBE_FINISHED
-  };
-
-  // |contents| is the WebContents of the tab this NetErrorTabHelper is
-  // attached to.
-  explicit NetErrorTabHelper(content::WebContents* contents);
-
-  void TrackerCallback(NetErrorTracker::DnsErrorPageState state);
-  void MaybePostStartDnsProbeTask();
-  void OnDnsProbeFinished(chrome_common_net::DnsProbeResult result);
-  void MaybeSendInfo();
+  void OnMainFrameDnsError();
 
   void InitializePref(content::WebContents* contents);
   bool ProbesAllowed() const;
 
   base::WeakPtrFactory<NetErrorTabHelper> weak_factory_;
 
-  NetErrorTracker tracker_;
-  NetErrorTracker::DnsErrorPageState dns_error_page_state_;
+  // True if the last provisional load that started was for an error page.
+  bool is_error_page_;
 
-  DnsProbeState dns_probe_state_;
-  chrome_common_net::DnsProbeResult dns_probe_result_;
+  // True if the helper has seen a main frame page load fail with a DNS error,
+  // but has not yet seen a new page commit successfully afterwards.
+  bool dns_error_active_;
+
+  // True if the helper has seen an error page commit while |dns_error_active_|
+  // is true.  (This should never be true if |dns_error_active_| is false.)
+  bool dns_error_page_committed_;
+
+  // The status of a DNS probe that may or may not have started or finished.
+  // Since the renderer can change out from under the helper (in cross-process
+  // navigations), it re-sends the status whenever an error page commits.
+  chrome_common_net::DnsProbeStatus dns_probe_status_;
 
   // Whether we are enabled to run by the DnsProbe-Enable field trial.
   const bool enabled_by_trial_;
+
+  // Optional callback for browser test to snoop on outgoing NetErrorInfo IPCs.
+  DnsProbeStatusSnoopCallback dns_probe_status_snoop_callback_;
+
   // "Use a web service to resolve navigation errors" preference is required
   // to allow probes.
   BooleanPrefMember resolve_errors_with_web_service_;
diff --git a/chrome/browser/net/net_error_tab_helper_unittest.cc b/chrome/browser/net/net_error_tab_helper_unittest.cc
new file mode 100644
index 0000000..3a029bb
--- /dev/null
+++ b/chrome/browser/net/net_error_tab_helper_unittest.cc
@@ -0,0 +1,392 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/net/net_error_tab_helper.h"
+
+#include "base/message_loop.h"
+#include "chrome/common/net/net_error_info.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/page_transition_types.h"
+#include "content/public/test/test_browser_thread.h"
+#include "net/base/net_errors.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::MessageLoop;
+using chrome_browser_net::NetErrorTabHelper;
+using chrome_common_net::DnsProbeStatus;
+using content::BrowserThread;
+using content::TestBrowserThread;
+
+class TestNetErrorTabHelper : public NetErrorTabHelper {
+ public:
+  TestNetErrorTabHelper()
+      : NetErrorTabHelper(NULL),
+        mock_probe_running_(false),
+        last_status_sent_(chrome_common_net::DNS_PROBE_MAX),
+        mock_sent_count_(0) {}
+
+  void FinishProbe(DnsProbeStatus status) {
+    EXPECT_TRUE(mock_probe_running_);
+    OnDnsProbeFinished(status);
+    mock_probe_running_ = false;
+  }
+
+  bool mock_probe_running() const { return mock_probe_running_; }
+  DnsProbeStatus last_status_sent() const { return last_status_sent_; }
+  int mock_sent_count() const { return mock_sent_count_; }
+
+ private:
+  virtual void StartDnsProbe() OVERRIDE {
+    EXPECT_FALSE(mock_probe_running_);
+    mock_probe_running_ = true;
+  }
+
+  virtual void SendInfo() OVERRIDE {
+    last_status_sent_ = dns_probe_status();
+    mock_sent_count_++;
+  }
+
+  bool mock_probe_running_;
+  DnsProbeStatus last_status_sent_;
+  int mock_sent_count_;
+};
+
+class NetErrorTabHelperTest : public testing::Test {
+ protected:
+  enum MainFrame { SUB_FRAME, MAIN_FRAME };
+  enum ErrorPage { NORMAL_PAGE, ERROR_PAGE };
+  enum ErrorType { DNS_ERROR, OTHER_ERROR };
+
+  NetErrorTabHelperTest()
+      : fake_ui_thread_(BrowserThread::UI, &message_loop_) {
+    NetErrorTabHelper::set_state_for_testing(
+        NetErrorTabHelper::TESTING_FORCE_ENABLED);
+  }
+
+  void StartProvisionalLoad(MainFrame main_frame, ErrorPage error_page) {
+    tab_helper_.DidStartProvisionalLoadForFrame(
+        1,  // frame_id
+        0,  // parent_frame_id
+        (main_frame == MAIN_FRAME),
+        bogus_url_,  // validated_url
+        (error_page == ERROR_PAGE),
+        false,  // is_iframe_srcdoc
+        NULL);  // render_view_host
+  }
+
+  void CommitProvisionalLoad(MainFrame main_frame) {
+    tab_helper_.DidCommitProvisionalLoadForFrame(
+        1,  // frame id
+        (main_frame == MAIN_FRAME),
+        bogus_url_,  // url
+        content::PAGE_TRANSITION_TYPED,
+        NULL);  // render_view_host
+  }
+
+  void FailProvisionalLoad(MainFrame main_frame, ErrorType error_type) {
+    int net_error;
+
+    if (error_type == DNS_ERROR)
+      net_error = net::ERR_NAME_NOT_RESOLVED;
+    else
+      net_error = net::ERR_TIMED_OUT;
+
+    tab_helper_.DidFailProvisionalLoad(
+        1,  // frame id
+        (main_frame == MAIN_FRAME),
+        bogus_url_,  // validated_url
+        net_error,
+        string16(),
+        NULL);  // render_view_host
+  }
+
+  void FinishProbe(DnsProbeStatus status) {
+    tab_helper_.FinishProbe(status);
+  }
+
+  bool probe_running() { return tab_helper_.mock_probe_running(); }
+  DnsProbeStatus last_status_sent() { return tab_helper_.last_status_sent(); }
+  int sent_count() { return tab_helper_.mock_sent_count(); }
+
+ private:
+  MessageLoop message_loop_;
+  TestBrowserThread fake_ui_thread_;
+  TestNetErrorTabHelper tab_helper_;
+  GURL bogus_url_;
+};
+
+TEST_F(NetErrorTabHelperTest, Null) {
+  EXPECT_FALSE(probe_running());
+}
+
+TEST_F(NetErrorTabHelperTest, MainFrameNonDnsError) {
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, OTHER_ERROR);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(0, sent_count());
+}
+
+TEST_F(NetErrorTabHelperTest, NonMainFrameDnsError) {
+  StartProvisionalLoad(SUB_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(SUB_FRAME, DNS_ERROR);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(0, sent_count());
+}
+
+// Test complete DNS error page loads.  Note that the helper can see two error
+// page loads: Link Doctor loads an empty HTML page so the user knows something
+// is going on, then fails over to the normal error page if and when Link
+// Doctor fails to load or declines to provide a page.
+
+TEST_F(NetErrorTabHelperTest, ProbeResponseBeforeFirstCommit) {
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(1, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(1, sent_count());
+
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(2, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent());
+}
+
+TEST_F(NetErrorTabHelperTest, ProbeResponseBetweenFirstAndSecondCommit) {
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(1, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(2, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(2, sent_count());
+
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(3, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent());
+}
+
+TEST_F(NetErrorTabHelperTest, ProbeResponseAfterSecondCommit) {
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(1, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(1, sent_count());
+
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(2, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(3, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent());
+}
+
+// Send result even if a new page load has started; the error page is still
+// visible, and the user might cancel the load.
+TEST_F(NetErrorTabHelperTest, ProbeResponseAfterNewStart) {
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(1, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(1, sent_count());
+
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(2, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(2, sent_count());
+
+  FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(3, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent());
+}
+
+// Don't send result if a new page has committed; the result would go to the
+// wrong page, and the error page is gone anyway.
+TEST_F(NetErrorTabHelperTest, ProbeResponseAfterNewCommit) {
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(1, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(1, sent_count());
+
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(2, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(2, sent_count());
+
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(2, sent_count());
+
+  FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(2, sent_count());
+}
+
+TEST_F(NetErrorTabHelperTest, MultipleDnsErrorsWithProbesWithoutErrorPages) {
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(0, sent_count());
+}
+
+TEST_F(NetErrorTabHelperTest, MultipleDnsErrorsWithProbesAndErrorPages) {
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(0, sent_count());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(1, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(2, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent());
+
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(2, sent_count());
+
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(3, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(4, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
+            last_status_sent());
+}
+
+// If multiple DNS errors occur in a row before a probe result, don't start
+// multiple probes.
+TEST_F(NetErrorTabHelperTest, CoalesceFailures) {
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(1, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(2, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE);
+  FailProvisionalLoad(MAIN_FRAME, DNS_ERROR);
+  StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE);
+  CommitProvisionalLoad(MAIN_FRAME);
+  EXPECT_TRUE(probe_running());
+  EXPECT_EQ(3, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent());
+
+  FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
+  EXPECT_FALSE(probe_running());
+  EXPECT_EQ(4, sent_count());
+  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent());
+}
diff --git a/chrome/browser/net/net_log_temp_file.cc b/chrome/browser/net/net_log_temp_file.cc
index c764d1f..00c1dc6 100644
--- a/chrome/browser/net/net_log_temp_file.cc
+++ b/chrome/browser/net/net_log_temp_file.cc
@@ -153,5 +153,5 @@
 bool NetLogTempFile::NetExportLogExists() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
   DCHECK(!log_path_.empty());
-  return file_util::PathExists(log_path_);
+  return base::PathExists(log_path_);
 }
diff --git a/chrome/browser/net/net_log_temp_file_unittest.cc b/chrome/browser/net/net_log_temp_file_unittest.cc
index e77ecc5..8370f9f 100644
--- a/chrome/browser/net/net_log_temp_file_unittest.cc
+++ b/chrome/browser/net/net_log_temp_file_unittest.cc
@@ -79,7 +79,7 @@
 
   virtual void TearDown() OVERRIDE {
     // Delete the temporary file we have created.
-    ASSERT_TRUE(base::Delete(net_export_log_, false));
+    ASSERT_TRUE(base::DeleteFile(net_export_log_, false));
   }
 
   std::string GetStateString() const {
@@ -93,7 +93,7 @@
   // constants will always be written to it on creation.
   void VerifyNetExportLog() {
     EXPECT_EQ(net_export_log_, net_log_temp_file_->log_path_);
-    EXPECT_TRUE(file_util::PathExists(net_export_log_));
+    EXPECT_TRUE(base::PathExists(net_export_log_));
 
     int64 file_size;
     // file_util::GetFileSize returns proper file size on open handles.
@@ -142,7 +142,7 @@
 
     base::FilePath net_export_file_path;
     EXPECT_TRUE(net_log_temp_file_->GetFilePath(&net_export_file_path));
-    EXPECT_TRUE(file_util::PathExists(net_export_file_path));
+    EXPECT_TRUE(base::PathExists(net_export_file_path));
     EXPECT_EQ(net_export_log_, net_export_file_path);
 
     VerifyNetExportLog();
@@ -187,11 +187,11 @@
   EXPECT_EQ(NetLogTempFile::STATE_ALLOW_START_SEND,
             net_log_temp_file_->state());
   EXPECT_EQ(net_export_log_, net_log_temp_file_->log_path_);
-  EXPECT_TRUE(file_util::PathExists(net_export_log_));
+  EXPECT_TRUE(base::PathExists(net_export_log_));
 
   base::FilePath net_export_file_path;
   EXPECT_TRUE(net_log_temp_file_->GetFilePath(&net_export_file_path));
-  EXPECT_TRUE(file_util::PathExists(net_export_file_path));
+  EXPECT_TRUE(base::PathExists(net_export_file_path));
   EXPECT_EQ(net_export_log_, net_export_file_path);
 
   // GetFilePath should return false if NetExportLogExists() fails.
diff --git a/chrome/browser/net/net_pref_observer.cc b/chrome/browser/net/net_pref_observer.cc
index 74a1e05..d731020 100644
--- a/chrome/browser/net/net_pref_observer.cc
+++ b/chrome/browser/net/net_pref_observer.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/net/net_pref_observer.h"
 
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/net/predictor.h"
 #include "chrome/browser/prerender/prerender_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/browser_thread.h"
@@ -48,7 +48,7 @@
 }
 
 // static
-void NetPrefObserver::RegisterUserPrefs(
+void NetPrefObserver::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kNetworkPredictionEnabled,
diff --git a/chrome/browser/net/net_pref_observer.h b/chrome/browser/net/net_pref_observer.h
index d8c9597..ba938b0 100644
--- a/chrome/browser/net/net_pref_observer.h
+++ b/chrome/browser/net/net_pref_observer.h
@@ -35,7 +35,7 @@
                   chrome_browser_net::Predictor* predictor);
   virtual ~NetPrefObserver();
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  private:
   void ApplySettings();
diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc
index 67273cb..6bedafb 100644
--- a/chrome/browser/net/predictor.cc
+++ b/chrome/browser/net/predictor.cc
@@ -157,7 +157,8 @@
   return new Predictor(preconnect_enabled);
 }
 
-void Predictor::RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+void Predictor::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(prefs::kDnsPrefetchingStartupList,
                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
   registry->RegisterListPref(prefs::kDnsPrefetchingHostReferralList,
diff --git a/chrome/browser/net/predictor.h b/chrome/browser/net/predictor.h
index b56a62b..3e6a2e3 100644
--- a/chrome/browser/net/predictor.h
+++ b/chrome/browser/net/predictor.h
@@ -110,7 +110,7 @@
   static Predictor* CreatePredictor(bool preconnect_enabled,
                                     bool simple_shutdown);
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // ------------- Start UI thread methods.
 
diff --git a/chrome/browser/net/pref_proxy_config_tracker_impl.cc b/chrome/browser/net/pref_proxy_config_tracker_impl.cc
index a4215ce..2c6318c 100644
--- a/chrome/browser/net/pref_proxy_config_tracker_impl.cc
+++ b/chrome/browser/net/pref_proxy_config_tracker_impl.cc
@@ -8,8 +8,8 @@
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prefs/proxy_config_dictionary.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/browser_thread.h"
@@ -203,7 +203,7 @@
 }
 
 // static
-void PrefProxyConfigTrackerImpl::RegisterUserPrefs(
+void PrefProxyConfigTrackerImpl::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* pref_service) {
   DictionaryValue* default_settings = ProxyConfigDictionary::CreateSystem();
   pref_service->RegisterDictionaryPref(
diff --git a/chrome/browser/net/pref_proxy_config_tracker_impl.h b/chrome/browser/net/pref_proxy_config_tracker_impl.h
index 1bf7183..0abbc99 100644
--- a/chrome/browser/net/pref_proxy_config_tracker_impl.h
+++ b/chrome/browser/net/pref_proxy_config_tracker_impl.h
@@ -123,7 +123,7 @@
   // Registers the proxy preferences. These are actually registered
   // the same way in local state and in user prefs.
   static void RegisterPrefs(PrefRegistrySimple* registry);
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Creates a proxy configuration from proxy-related preferences of
   // |pref_service|. Configuration is stored in |config|, return value indicates
diff --git a/chrome/browser/net/proxy_browsertest.cc b/chrome/browser/net/proxy_browsertest.cc
index ca4a737..1d84336 100644
--- a/chrome/browser/net/proxy_browsertest.cc
+++ b/chrome/browser/net/proxy_browsertest.cc
@@ -7,10 +7,10 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/login/login_prompt.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/net/proxy_service_factory.cc b/chrome/browser/net/proxy_service_factory.cc
index 9d30b1e..0c83d0e 100644
--- a/chrome/browser/net/proxy_service_factory.cc
+++ b/chrome/browser/net/proxy_service_factory.cc
@@ -54,20 +54,28 @@
   return new ChromeProxyConfigService(base_service);
 }
 
+// static
+PrefProxyConfigTracker*
+ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
+    PrefService* profile_prefs,
+    PrefService* local_state_prefs) {
 #if defined(OS_CHROMEOS)
-// static
-chromeos::ProxyConfigServiceImpl*
-    ProxyServiceFactory::CreatePrefProxyConfigTracker(
-        PrefService* pref_service) {
-  return new chromeos::ProxyConfigServiceImpl(pref_service);
-}
+  return new chromeos::ProxyConfigServiceImpl(profile_prefs, local_state_prefs);
 #else
-// static
-PrefProxyConfigTrackerImpl* ProxyServiceFactory::CreatePrefProxyConfigTracker(
-    PrefService* pref_service) {
-  return new PrefProxyConfigTrackerImpl(pref_service);
-}
+  return new PrefProxyConfigTrackerImpl(profile_prefs);
 #endif  // defined(OS_CHROMEOS)
+}
+
+// static
+PrefProxyConfigTracker*
+ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
+    PrefService* local_state_prefs) {
+#if defined(OS_CHROMEOS)
+  return new chromeos::ProxyConfigServiceImpl(NULL, local_state_prefs);
+#else
+  return new PrefProxyConfigTrackerImpl(local_state_prefs);
+#endif  // defined(OS_CHROMEOS)
+}
 
 // static
 net::ProxyService* ProxyServiceFactory::CreateProxyService(
diff --git a/chrome/browser/net/proxy_service_factory.h b/chrome/browser/net/proxy_service_factory.h
index c0c26fd..154f5e9 100644
--- a/chrome/browser/net/proxy_service_factory.h
+++ b/chrome/browser/net/proxy_service_factory.h
@@ -18,6 +18,12 @@
 }
 #endif  // defined(OS_CHROMEOS)
 
+#if defined(OS_CHROMEOS)
+typedef chromeos::ProxyConfigServiceImpl PrefProxyConfigTracker;
+#else
+typedef PrefProxyConfigTrackerImpl PrefProxyConfigTracker;
+#endif  // defined(OS_CHROMEOS)
+
 namespace net {
 class NetLog;
 class NetworkDelegate;
@@ -34,13 +40,19 @@
   // about the proxy configuration by calling its UpdateProxyConfig method.
   static ChromeProxyConfigService* CreateProxyConfigService();
 
-#if defined(OS_CHROMEOS)
-  static chromeos::ProxyConfigServiceImpl* CreatePrefProxyConfigTracker(
-      PrefService* pref_service);
-#else
-  static PrefProxyConfigTrackerImpl* CreatePrefProxyConfigTracker(
-      PrefService* pref_service);
-#endif  // defined(OS_CHROMEOS)
+  // Creates a PrefProxyConfigTracker that tracks preferences of a
+  // profile. On ChromeOS it additionaly tracks local state for shared proxy
+  // settings. This tracker should be used if the profile's preferences should
+  // be respected. On ChromeOS's signin screen this is for example not the case.
+  static PrefProxyConfigTracker* CreatePrefProxyConfigTrackerOfProfile(
+      PrefService* profile_prefs,
+      PrefService* local_state_prefs);
+
+  // Creates a PrefProxyConfigTracker that tracks local state only. This tracker
+  // should be used for the system request context and the signin screen
+  // (ChromeOS only).
+  static PrefProxyConfigTracker* CreatePrefProxyConfigTrackerOfLocalState(
+      PrefService* local_state_prefs);
 
   // Create a proxy service according to the options on command line.
   static net::ProxyService* CreateProxyService(
diff --git a/chrome/browser/net/sqlite_server_bound_cert_store.cc b/chrome/browser/net/sqlite_server_bound_cert_store.cc
index fe28561..8432267 100644
--- a/chrome/browser/net/sqlite_server_bound_cert_store.cc
+++ b/chrome/browser/net/sqlite_server_bound_cert_store.cc
@@ -17,7 +17,6 @@
 #include "base/strings/string_util.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
-#include "chrome/browser/diagnostics/sqlite_diagnostics.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/cert/x509_certificate.h"
 #include "net/cookies/cookie_util.h"
@@ -201,7 +200,7 @@
   // Ensure the parent directory for storing certs is created before reading
   // from it.
   const base::FilePath dir = path_.DirName();
-  if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir))
+  if (!base::PathExists(dir) && !file_util::CreateDirectory(dir))
     return;
 
   int64 db_size = 0;
diff --git a/chrome/browser/net/ssl_config_service_manager_pref.cc b/chrome/browser/net/ssl_config_service_manager_pref.cc
index 2f7e48a..44efff4 100644
--- a/chrome/browser/net/ssl_config_service_manager_pref.cc
+++ b/chrome/browser/net/ssl_config_service_manager_pref.cc
@@ -13,8 +13,8 @@
 #include "base/prefs/pref_member.h"
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_utils.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/net/url_fixer_upper.cc b/chrome/browser/net/url_fixer_upper.cc
index 6c82ba4..49671ac 100644
--- a/chrome/browser/net/url_fixer_upper.cc
+++ b/chrome/browser/net/url_fixer_upper.cc
@@ -107,7 +107,7 @@
   if (file_path.empty())
     return false;
 
-  if (!file_util::PathExists(file_path))
+  if (!base::PathExists(file_path))
     return false;
 
   *full_path = file_path;
diff --git a/chrome/browser/net/url_fixer_upper_unittest.cc b/chrome/browser/net/url_fixer_upper_unittest.cc
index 5dc335c..19e796b 100644
--- a/chrome/browser/net/url_fixer_upper_unittest.cc
+++ b/chrome/browser/net/url_fixer_upper_unittest.cc
@@ -459,7 +459,7 @@
         file_cases[i].desired_tld).possibly_invalid_spec());
   }
 
-  EXPECT_TRUE(base::Delete(original, false));
+  EXPECT_TRUE(base::DeleteFile(original, false));
 }
 
 TEST(URLFixerUpperTest, FixupRelativeFile) {
@@ -483,7 +483,7 @@
   // are no backslashes
   EXPECT_TRUE(IsMatchingFileURL(URLFixerUpper::FixupRelativeFile(dir,
       file_part).possibly_invalid_spec(), full_path));
-  EXPECT_TRUE(base::Delete(full_path, false));
+  EXPECT_TRUE(base::DeleteFile(full_path, false));
 
   // create a filename we know doesn't exist and make sure it doesn't get
   // fixed up to a file URL
@@ -527,8 +527,8 @@
       base::FilePath(relative_file_str)).possibly_invalid_spec(), full_path));
 
   // done with the subdir
-  EXPECT_TRUE(base::Delete(full_path, false));
-  EXPECT_TRUE(base::Delete(new_dir, true));
+  EXPECT_TRUE(base::DeleteFile(full_path, false));
+  EXPECT_TRUE(base::DeleteFile(new_dir, true));
 
   // Test that an obvious HTTP URL isn't accidentally treated as an absolute
   // file path (on account of system-specific craziness).
diff --git a/chrome/browser/notifications/balloon_collection_impl.cc b/chrome/browser/notifications/balloon_collection_impl.cc
index 1d032d2..c7d0861 100644
--- a/chrome/browser/notifications/balloon_collection_impl.cc
+++ b/chrome/browser/notifications/balloon_collection_impl.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/notifications/balloon.h"
 #include "chrome/browser/notifications/balloon_host.h"
 #include "chrome/browser/notifications/notification.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/ui/panels/docked_panel_collection.h"
 #include "chrome/browser/ui/panels/panel.h"
 #include "chrome/browser/ui/panels/panel_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
 #include "ui/gfx/rect.h"
diff --git a/chrome/browser/notifications/balloon_host.cc b/chrome/browser/notifications/balloon_host.cc
index 24c39f2..362804f 100644
--- a/chrome/browser/notifications/balloon_host.cc
+++ b/chrome/browser/notifications/balloon_host.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/notifications/balloon_host.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/notifications/balloon.h"
 #include "chrome/browser/notifications/balloon_collection_impl.h"
 #include "chrome/browser/notifications/notification.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_messages.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/common/url_constants.h"
@@ -116,7 +116,7 @@
       content::NotificationService::NoDetails());
 }
 
-void BalloonHost::RenderViewGone(base::TerminationStatus status) {
+void BalloonHost::RenderProcessGone(base::TerminationStatus status) {
   CloseContents(web_contents_.get());
 }
 
diff --git a/chrome/browser/notifications/balloon_host.h b/chrome/browser/notifications/balloon_host.h
index 83dc9cc..693b21b 100644
--- a/chrome/browser/notifications/balloon_host.h
+++ b/chrome/browser/notifications/balloon_host.h
@@ -74,7 +74,7 @@
   virtual void RenderViewCreated(
       content::RenderViewHost* render_view_host) OVERRIDE;
   virtual void RenderViewReady() OVERRIDE;
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
 
   // Message handlers
diff --git a/chrome/browser/notifications/balloon_notification_ui_manager.cc b/chrome/browser/notifications/balloon_notification_ui_manager.cc
index edbebd4..d6ea75e 100644
--- a/chrome/browser/notifications/balloon_notification_ui_manager.cc
+++ b/chrome/browser/notifications/balloon_notification_ui_manager.cc
@@ -9,12 +9,12 @@
 #include "base/prefs/pref_service.h"
 #include "base/stl_util.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/fullscreen.h"
 #include "chrome/browser/idle.h"
 #include "chrome/browser/notifications/balloon_collection.h"
 #include "chrome/browser/notifications/notification.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/notifications/desktop_notification_service.cc b/chrome/browser/notifications/desktop_notification_service.cc
index 1fc2985..e81a2b1 100644
--- a/chrome/browser/notifications/desktop_notification_service.cc
+++ b/chrome/browser/notifications/desktop_notification_service.cc
@@ -8,6 +8,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_details.h"
 #include "chrome/browser/content_settings/content_settings_provider.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/content_settings_pattern.h"
 #include "chrome/common/pref_names.h"
@@ -57,7 +57,6 @@
 using WebKit::WebTextDirection;
 using WebKit::WebSecurityOrigin;
 
-const ContentSetting kDefaultSetting = CONTENT_SETTING_ASK;
 
 // NotificationPermissionInfoBarDelegate --------------------------------------
 
@@ -197,7 +196,7 @@
 // DesktopNotificationService -------------------------------------------------
 
 // static
-void DesktopNotificationService::RegisterUserPrefs(
+void DesktopNotificationService::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(prefs::kMessageCenterDisabledExtensionIds,
                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
@@ -294,7 +293,6 @@
     const string16& replace_id,
     NotificationDelegate* delegate,
     Profile* profile) {
-
   if (message_center::IsRichNotificationEnabled()) {
     // For message center create a non-HTML notification with |icon|.
     Notification notification(origin_url, icon, title, message,
@@ -465,11 +463,8 @@
           infobar_service,
           DesktopNotificationServiceFactory::GetForProfile(
               Profile::FromBrowserContext(contents->GetBrowserContext())),
-          origin,
-          DisplayNameForOriginInProcessId(origin, process_id),
-          process_id,
-          route_id,
-          callback_context);
+          origin, DisplayNameForOriginInProcessId(origin, process_id),
+          process_id, route_id, callback_context);
       return;
     }
   }
@@ -613,16 +608,14 @@
   }
   DCHECK(pref_name != NULL);
 
-  {
-    ListPrefUpdate update(profile_->GetPrefs(), pref_name);
-    base::ListValue* const list = update.Get();
-    if (add_new_item) {
-      // AppendIfNotPresent will delete |adding_value| when the same value
-      // already exists.
-      list->AppendIfNotPresent(id.release());
-    } else {
-      list->Remove(*id, NULL);
-    }
+  ListPrefUpdate update(profile_->GetPrefs(), pref_name);
+  base::ListValue* const list = update.Get();
+  if (add_new_item) {
+    // AppendIfNotPresent will delete |adding_value| when the same value
+    // already exists.
+    list->AppendIfNotPresent(id.release());
+  } else {
+    list->Remove(*id, NULL);
   }
 }
 
diff --git a/chrome/browser/notifications/desktop_notification_service.h b/chrome/browser/notifications/desktop_notification_service.h
index 3783950..042e2e1 100644
--- a/chrome/browser/notifications/desktop_notification_service.h
+++ b/chrome/browser/notifications/desktop_notification_service.h
@@ -53,7 +53,7 @@
   };
 
   // Register profile-specific prefs of notifications.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* prefs);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* prefs);
 
   DesktopNotificationService(Profile* profile,
                              NotificationUIManager* ui_manager);
@@ -74,7 +74,9 @@
   // other parameters supplied by the worker or page.
   bool ShowDesktopNotification(
       const content::ShowDesktopNotificationHostMsgParams& params,
-      int process_id, int route_id, DesktopNotificationSource source);
+      int process_id,
+      int route_id,
+      DesktopNotificationSource source);
 
   // Cancels a notification.  If it has already been shown, it will be
   // removed from the screen.  If it hasn't been shown yet, it won't be
@@ -191,7 +193,7 @@
   // Called when the enabled_sync_notifier_id pref has been changed.
   void OnEnabledSyncNotifierIdsChanged();
 
-  // content::NotificationObserver override.
+  // content::NotificationObserver:
   virtual void Observe(int type,
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
diff --git a/chrome/browser/notifications/message_center_notifications_unittest_win.cc b/chrome/browser/notifications/message_center_notifications_unittest_win.cc
index 8846ecc..130fd9f 100644
--- a/chrome/browser/notifications/message_center_notifications_unittest_win.cc
+++ b/chrome/browser/notifications/message_center_notifications_unittest_win.cc
@@ -38,7 +38,6 @@
   virtual void OnMessageCenterTrayChanged() OVERRIDE {}
   virtual bool ShowPopups() OVERRIDE { return true; }
   virtual void HidePopups() OVERRIDE {}
-  virtual void UpdatePopups() OVERRIDE {}
   virtual bool ShowMessageCenter() OVERRIDE { return true; }
   virtual bool ShowNotifierSettings() OVERRIDE { return true; }
   virtual void HideMessageCenter() OVERRIDE {}
diff --git a/chrome/browser/notifications/notification_audio_controller.cc b/chrome/browser/notifications/notification_audio_controller.cc
deleted file mode 100644
index ec7f090..0000000
--- a/chrome/browser/notifications/notification_audio_controller.cc
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/notifications/notification_audio_controller.h"
-
-#include <cstring>
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/cancelable_callback.h"
-#include "base/location.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "base/sys_byteorder.h"
-#include "base/task_runner_util.h"
-#include "media/audio/audio_io.h"
-#include "media/audio/audio_manager.h"
-#include "media/audio/audio_parameters.h"
-#include "media/base/audio_bus.h"
-#include "media/base/channel_layout.h"
-
-namespace {
-
-// The size of the header of a wav file. The header consists of 'RIFF', 4 bytes
-// of total data length, and 'WAVE'.
-const size_t kWavFileHeaderSize = 12;
-
-// The size of a chunk header in wav file format. A chunk header consists of a
-// tag ('fmt ' or 'data') and 4 bytes of chunk length.
-const size_t kChunkHeaderSize = 8;
-
-// The minimum size of 'fmt' chunk.
-const size_t kFmtChunkMinimumSize = 16;
-
-// The offsets of 'fmt' fields.
-const size_t kAudioFormatOffset = 0;
-const size_t kChunnelOffset = 2;
-const size_t kSampleRateOffset = 4;
-const size_t kBitsPerSampleOffset = 14;
-
-// Some constants for audio format.
-const int kAudioFormatPCM = 1;
-
-// The frame-per-buffer parameter for wav data format reader. Since wav format
-// doesn't have this parameter in its header, just choose some value.
-const int kFramesPerBuffer = 4096;
-
-///////////////////////////////////////////////////////////////////////////
-// WavAudioHandler
-//
-// This class provides the input from wav file format.
-// See https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
-class WavAudioHandler {
- public:
-  explicit WavAudioHandler(const base::StringPiece& data);
-  virtual ~WavAudioHandler();
-
-  // Returns true when it plays to the end of the track.
-  bool AtEnd();
-
-  // Copies the audio data to |dest|.
-  void CopyTo(media::AudioBus* dest);
-
-  uint16 num_channels() const { return num_channels_; }
-  uint32 sample_rate() const { return sample_rate_; }
-  uint16 bits_per_sample() const { return bits_per_sample_; }
-
- private:
-  // Parses a chunk of wav format data. Returns the length of the chunk.
-  int ParseSubChunk(const base::StringPiece& data);
-
-  // Parses the 'fmt' section chunk and stores |params_|.
-  void ParseFmtChunk(const base::StringPiece& data);
-
-  // Parses the 'data' section chunk and stores |data_|.
-  void ParseDataChunk(const base::StringPiece& data);
-
-  // Reads an integer from |data| with |offset|.
-  template<typename T> T ReadInt(const base::StringPiece& data, size_t offset);
-
-  base::StringPiece data_;
-  size_t cursor_;
-  uint16 num_channels_;
-  uint32 sample_rate_;
-  uint16 bits_per_sample_;
-
-  DISALLOW_COPY_AND_ASSIGN(WavAudioHandler);
-};
-
-WavAudioHandler::WavAudioHandler(const base::StringPiece& data)
-    : cursor_(0),
-      num_channels_(0),
-      sample_rate_(0),
-      bits_per_sample_(0) {
-  if (data.size() < kWavFileHeaderSize)
-    return;
-
-  if (!data.starts_with("RIFF") || ::memcmp(data.data() + 8, "WAVE", 4) != 0)
-    return;
-
-  uint32 total_length =
-      std::min(ReadInt<uint32>(data, 4), static_cast<uint32>(data.size()));
-
-  uint32 offset = kWavFileHeaderSize;
-  while (offset < total_length)
-    offset += ParseSubChunk(data.substr(offset));
-}
-
-WavAudioHandler::~WavAudioHandler() {
-}
-
-bool WavAudioHandler::AtEnd() {
-  return data_.size() <= cursor_;
-}
-
-void WavAudioHandler::CopyTo(media::AudioBus* dest) {
-  DCHECK_EQ(dest->channels(), num_channels_);
-  if (cursor_ >= data_.size()) {
-    dest->Zero();
-    return;
-  }
-
-  const int bytes_per_sample = bits_per_sample_ / 8;
-  const int bytes_per_frame = num_channels_ * bytes_per_sample;
-  const int remaining_frames = (data_.size() - cursor_) / bytes_per_frame;
-  const int frames = std::min(dest->frames(), remaining_frames);
-  dest->FromInterleaved(data_.data() + cursor_, frames, bytes_per_sample);
-  cursor_ += frames * bytes_per_frame;
-  dest->ZeroFramesPartial(frames, dest->frames() - frames);
-}
-
-int WavAudioHandler::ParseSubChunk(const base::StringPiece& data) {
-  if (data.size() < kChunkHeaderSize)
-    return data.size();
-  uint32 chunk_length = ReadInt<uint32>(data, 4);
-
-  if (data.starts_with("fmt "))
-    ParseFmtChunk(data.substr(kChunkHeaderSize, chunk_length));
-  else if (data.starts_with("data"))
-    ParseDataChunk(data.substr(kChunkHeaderSize, chunk_length));
-  else
-    DLOG(WARNING) << "Unknown data chunk: " << data.substr(0, 4);
-  return chunk_length + kChunkHeaderSize;
-}
-
-void WavAudioHandler::ParseFmtChunk(const base::StringPiece& data) {
-  if (data.size() < kFmtChunkMinimumSize) {
-    DLOG(ERROR) << "data size " << data.size() << " is too short.";
-    return;
-  }
-
-  DCHECK_EQ(ReadInt<uint16>(data, kAudioFormatOffset), kAudioFormatPCM);
-
-  num_channels_ = ReadInt<uint16>(data, kChunnelOffset);
-  sample_rate_ = ReadInt<uint32>(data, kSampleRateOffset);
-  bits_per_sample_ = ReadInt<uint16>(data, kBitsPerSampleOffset);
-}
-
-void WavAudioHandler::ParseDataChunk(const base::StringPiece& data) {
-  data_ = data;
-}
-
-template<typename T> T WavAudioHandler::ReadInt(const base::StringPiece& data,
-                                                size_t offset) {
-  DCHECK_LE(offset + sizeof(T), data.size());
-  T result;
-  ::memcpy(&result, data.data() + offset, sizeof(T));
-#if !defined(ARCH_CPU_LITTLE_ENDIAN)
-  result = base::ByteSwap(result);
-#endif
-
-  return result;
-}
-
-}  // namespace
-
-///////////////////////////////////////////////////////////////////////////
-// NotificationAudioController::AudioHandler
-//
-// This class connects a sound for a notification to the audio manager. It
-// will be released by its owner when the sound ends.
-class NotificationAudioController::AudioHandler
-    : public media::AudioOutputStream::AudioSourceCallback {
- public:
-  typedef base::Callback<void(AudioHandler*)> OnFinishedCB;
-
-  AudioHandler(const OnFinishedCB& on_finished_callback,
-               const std::string& notification_id,
-               const Profile* profile,
-               const base::StringPiece& data);
-  virtual ~AudioHandler();
-
-  const std::string& notification_id() const { return notification_id_; }
-  const Profile* profile() const { return profile_; }
-
-  // Start playing the sound with the specified format. Returns true when it's
-  // successfully scheduled.
-  bool StartPlayingSound(media::AudioParameters::Format format);
-
-  // Stops the playing sound request.
-  void StopPlayingSound();
-
- private:
-  // media::AudioOutputStream::AudioSourceCallback overrides:
-  virtual int OnMoreData(media::AudioBus* dest,
-                         media::AudioBuffersState state) OVERRIDE;
-  virtual int OnMoreIOData(media::AudioBus* source,
-                           media::AudioBus* dest,
-                           media::AudioBuffersState state) OVERRIDE;
-  virtual void OnError(media::AudioOutputStream* stream) OVERRIDE;
-
-  OnFinishedCB on_finished_callback_;
-  base::CancelableClosure stop_playing_sound_;
-  std::string notification_id_;
-  const Profile* profile_;
-
-  media::AudioManager* audio_manager_;
-  WavAudioHandler wav_audio_;
-  media::AudioOutputStream* stream_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioHandler);
-};
-
-NotificationAudioController::AudioHandler::AudioHandler(
-    const OnFinishedCB& on_finished_callback,
-    const std::string& notification_id,
-    const Profile* profile,
-    const base::StringPiece& data)
-    : on_finished_callback_(on_finished_callback),
-      notification_id_(notification_id),
-      profile_(profile),
-      audio_manager_(media::AudioManager::Get()),
-      wav_audio_(data) {
-}
-
-NotificationAudioController::AudioHandler::~AudioHandler() {
-}
-
-bool NotificationAudioController::AudioHandler::StartPlayingSound(
-    media::AudioParameters::Format format) {
-  DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
-
-  media::AudioParameters params = media::AudioParameters(
-      format,
-      media::GuessChannelLayout(wav_audio_.num_channels()),
-      wav_audio_.num_channels(),
-      wav_audio_.sample_rate(),
-      wav_audio_.bits_per_sample(),
-      kFramesPerBuffer);
-
-  if (!params.IsValid())
-    return false;
-
-  stream_ = audio_manager_->MakeAudioOutputStreamProxy(params, std::string());
-  if (!stream_->Open()) {
-    DLOG(ERROR) << "Failed to open the output stream";
-    stream_->Close();
-    return false;
-  }
-
-  stop_playing_sound_.Reset(base::Bind(
-      &AudioHandler::StopPlayingSound, base::Unretained(this)));
-  stream_->Start(this);
-  return true;
-}
-
-// Stops actually the audio output stream.
-void NotificationAudioController::AudioHandler::StopPlayingSound() {
-  DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
-  stop_playing_sound_.Cancel();
-
-  // Close deletes |stream| too.
-  stream_->Stop();
-  stream_->Close();
-  on_finished_callback_.Run(this);
-}
-
-int NotificationAudioController::AudioHandler::OnMoreData(
-    media::AudioBus* dest,
-    media::AudioBuffersState state) {
-  wav_audio_.CopyTo(dest);
-  if (wav_audio_.AtEnd()) {
-    audio_manager_->GetMessageLoop()->PostTask(
-        FROM_HERE, stop_playing_sound_.callback());
-  }
-  return dest->frames();
-}
-
-int NotificationAudioController::AudioHandler::OnMoreIOData(
-    media::AudioBus* source,
-    media::AudioBus* dest,
-    media::AudioBuffersState state) {
-  return OnMoreData(dest, state);
-}
-
-void NotificationAudioController::AudioHandler::OnError(
-    media::AudioOutputStream* stream) {
-}
-
-///////////////////////////////////////////////////////////////////////////
-// NotificationAudioController
-//
-
-NotificationAudioController::NotificationAudioController()
-    : message_loop_(media::AudioManager::Get()->GetMessageLoop()),
-      output_format_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY) {
-}
-
-NotificationAudioController::~NotificationAudioController() {
-  DCHECK(message_loop_->BelongsToCurrentThread());
-}
-
-void NotificationAudioController::RequestPlayNotificationSound(
-    const std::string& notification_id,
-    const Profile* profile,
-    const base::StringPiece& data) {
-  message_loop_->PostTask(
-      FROM_HERE,
-      base::Bind(
-          &NotificationAudioController::PlayNotificationSound,
-          base::Unretained(this),
-          notification_id,
-          base::Unretained(profile),
-          data));
-}
-
-void NotificationAudioController::RequestShutdown() {
-  message_loop_->PostTask(
-      FROM_HERE,
-      base::Bind(
-          &NotificationAudioController::Shutdown, base::Unretained(this)));
-}
-
-void NotificationAudioController::OnNotificationSoundFinished(
-    AudioHandler* audio_handler) {
-  DCHECK(message_loop_->BelongsToCurrentThread());
-  std::vector<AudioHandler*>::iterator it =
-      std::find(audio_handlers_.begin(), audio_handlers_.end(), audio_handler);
-  DCHECK(it != audio_handlers_.end());
-  audio_handlers_.erase(it);
-}
-
-void NotificationAudioController::UseFakeAudioOutputForTest() {
-  output_format_ = media::AudioParameters::AUDIO_FAKE;
-}
-
-void NotificationAudioController::GetAudioHandlersSizeForTest(
-    const base::Callback<void(size_t)>& on_get) {
-  base::PostTaskAndReplyWithResult(
-      message_loop_.get(),
-      FROM_HERE,
-      base::Bind(&NotificationAudioController::GetAudioHandlersSizeCallback,
-                 base::Unretained(this)),
-      on_get);
-}
-
-void NotificationAudioController::PlayNotificationSound(
-    const std::string& notification_id,
-    const Profile* profile,
-    const base::StringPiece& data) {
-  DCHECK(message_loop_->BelongsToCurrentThread());
-
-  for (size_t i = 0; i < audio_handlers_.size(); ++i) {
-    if (audio_handlers_[i]->notification_id() == notification_id &&
-        audio_handlers_[i]->profile() == profile) {
-      audio_handlers_[i]->StopPlayingSound();
-      break;
-    }
-  }
-
-  scoped_ptr<AudioHandler> new_handler(new AudioHandler(
-      base::Bind(&NotificationAudioController::OnNotificationSoundFinished,
-                 base::Unretained(this)),
-      notification_id,
-      profile,
-      data));
-  if (new_handler->StartPlayingSound(output_format_))
-    audio_handlers_.push_back(new_handler.release());
-}
-
-void NotificationAudioController::Shutdown() {
-  DCHECK(message_loop_->BelongsToCurrentThread());
-
-  while (!audio_handlers_.empty())
-    audio_handlers_[0]->StopPlayingSound();
-
-  delete this;
-}
-
-size_t NotificationAudioController::GetAudioHandlersSizeCallback() {
-  DCHECK(message_loop_->BelongsToCurrentThread());
-  return audio_handlers_.size();
-}
diff --git a/chrome/browser/notifications/notification_audio_controller.h b/chrome/browser/notifications/notification_audio_controller.h
deleted file mode 100644
index c8a27a7..0000000
--- a/chrome/browser/notifications/notification_audio_controller.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_AUDIO_CONTROLLER_H_
-#define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_AUDIO_CONTROLLER_H_
-
-#include <string>
-
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_vector.h"
-#include "base/strings/string_piece.h"
-#include "media/audio/audio_parameters.h"
-
-namespace base {
-class MessageLoopProxy;
-}
-
-class Profile;
-
-// This class controls the sound playing for notifications. Note that this class
-// belongs to the audio thread and self-owned.
-class NotificationAudioController {
- public:
-  NotificationAudioController();
-
-  // Requests the audio thread to play a sound for a notification. |data|
-  // specifies the raw audio data in wav file format. |notification_id|
-  // and |profile| represents the id of the notification for the sound.
-  // When this method is called during playing sound for the specified
-  // |notification_id|, it will stop playing the sound and start the sound for
-  // the newly specified |data|.
-  void RequestPlayNotificationSound(
-      const std::string& notification_id,
-      const Profile* profile,
-      const base::StringPiece& data);
-
-  // Request shutdown process in the audio thread. Delete itself when all
-  // processes have finished.
-  void RequestShutdown();
-
- private:
-  class AudioHandler;
-  friend class NotificationAudioControllerTest;
-
-  ~NotificationAudioController();
-
-  void UseFakeAudioOutputForTest();
-
-  // Request the current number of audio handlers to the audio thread. |on_get|
-  // will be called with the result when finished.
-  void GetAudioHandlersSizeForTest(const base::Callback<void(size_t)>& on_get);
-
-  // Actually start playing the notification sound in the audio thread.
-  void PlayNotificationSound(
-      const std::string& notification_id,
-      const Profile* profile,
-      const base::StringPiece& data);
-
-  // Removes all instances in |audio_handlers_|.
-  void Shutdown();
-
-  // Gets the current size of |audio_handlers_| in the audio thread.
-  size_t GetAudioHandlersSizeCallback();
-
-  // Called when the sound for |audio_handler| has finished.
-  void OnNotificationSoundFinished(AudioHandler* audio_handler);
-
-  scoped_refptr<base::MessageLoopProxy> message_loop_;
-  ScopedVector<AudioHandler> audio_handlers_;
-
-  media::AudioParameters::Format output_format_;
-
-  DISALLOW_COPY_AND_ASSIGN(NotificationAudioController);
-};
-
-#endif  // CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_AUDIO_CONTROLLER_H_
diff --git a/chrome/browser/notifications/notification_audio_controller_unittest.cc b/chrome/browser/notifications/notification_audio_controller_unittest.cc
deleted file mode 100644
index 7ab0cff..0000000
--- a/chrome/browser/notifications/notification_audio_controller_unittest.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/notifications/notification_audio_controller.h"
-
-#include "base/bind.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
-#include "base/run_loop.h"
-#include "chrome/test/base/testing_profile.h"
-#include "media/audio/audio_manager.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-// Sample audio data
-const char kTestAudioData[] = "RIFF\x26\x00\x00\x00WAVEfmt \x10\x00\x00\x00"
-    "\x01\x00\x02\x00\x80\xbb\x00\x00\x00\x77\x01\x00\x02\x00\x10\x00"
-    "data\x04\x00\x00\x00\x01\x00\x01\x00";
-const char kInvalidAudioData[] = "invalid audio data";
-const char kDummyNotificationId[] = "dummy_id";
-const char kDummyNotificationId2[] = "dummy_id2";
-
-void CopyResultAndQuit(
-    base::RunLoop* run_loop, size_t *result_ptr, size_t result) {
-  *result_ptr = result;
-  run_loop->Quit();
-}
-
-} // namespace
-
-class NotificationAudioControllerTest : public testing::Test {
- public:
-  NotificationAudioControllerTest() {
-    audio_manager_.reset(media::AudioManager::Create());
-    notification_audio_controller_ = new NotificationAudioController();
-    notification_audio_controller_->UseFakeAudioOutputForTest();
-  }
-
-  virtual ~NotificationAudioControllerTest() {
-    notification_audio_controller_->RequestShutdown();
-    base::RunLoop().RunUntilIdle();
-    audio_manager_.reset();
-  }
-
- protected:
-  NotificationAudioController* notification_audio_controller() {
-    return notification_audio_controller_;
-  }
-  Profile* profile() { return &profile_; }
-
-  size_t GetHandlersSize() {
-    base::RunLoop run_loop;
-    size_t result = 0;
-    notification_audio_controller_->GetAudioHandlersSizeForTest(
-        base::Bind(&CopyResultAndQuit, &run_loop, &result));
-    run_loop.Run();
-    return result;
-  }
-
- private:
-  base::MessageLoopForUI message_loop_;
-  TestingProfile profile_;
-  NotificationAudioController* notification_audio_controller_;
-  scoped_ptr<media::AudioManager> audio_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(NotificationAudioControllerTest);
-};
-
-TEST_F(NotificationAudioControllerTest, PlaySound) {
-  notification_audio_controller()->RequestPlayNotificationSound(
-      kDummyNotificationId,
-      profile(),
-      base::StringPiece(kTestAudioData, arraysize(kTestAudioData)));
-  // Still playing the sound, not empty yet.
-  EXPECT_EQ(1u, GetHandlersSize());
-}
-
-// TODO(mukai): http://crbug.com/246061
-#if !defined(OS_WIN) && !defined(ARCH_CPU_X86_64)
-TEST_F(NotificationAudioControllerTest, PlayInvalidSound) {
-  notification_audio_controller()->RequestPlayNotificationSound(
-      kDummyNotificationId,
-      profile(),
-      base::StringPiece(kInvalidAudioData, arraysize(kInvalidAudioData)));
-  EXPECT_EQ(0u, GetHandlersSize());
-}
-#endif
-
-TEST_F(NotificationAudioControllerTest, PlayTwoSounds) {
-  notification_audio_controller()->RequestPlayNotificationSound(
-      kDummyNotificationId,
-      profile(),
-      base::StringPiece(kTestAudioData, arraysize(kTestAudioData)));
-  notification_audio_controller()->RequestPlayNotificationSound(
-      kDummyNotificationId2,
-      profile(),
-      base::StringPiece(kTestAudioData, arraysize(kTestAudioData)));
-  EXPECT_EQ(2u, GetHandlersSize());
-}
-
-TEST_F(NotificationAudioControllerTest, PlaySoundTwice) {
-  notification_audio_controller()->RequestPlayNotificationSound(
-      kDummyNotificationId,
-      profile(),
-      base::StringPiece(kTestAudioData, arraysize(kTestAudioData)));
-  notification_audio_controller()->RequestPlayNotificationSound(
-      kDummyNotificationId,
-      profile(),
-      base::StringPiece(kTestAudioData, arraysize(kTestAudioData)));
-  EXPECT_EQ(1u, GetHandlersSize());
-}
-
-#if defined(THREAD_SANITIZER)
-// This test fails under ThreadSanitizer v2, see http://crbug.com/247440.
-#define MAYBE_MultiProfiles DISABLED_MultiProfiles
-#else
-#define MAYBE_MultiProfiles MultiProfiles
-#endif
-TEST_F(NotificationAudioControllerTest, MAYBE_MultiProfiles) {
-  TestingProfile profile2;
-
-  notification_audio_controller()->RequestPlayNotificationSound(
-      kDummyNotificationId,
-      profile(),
-      base::StringPiece(kTestAudioData, arraysize(kTestAudioData)));
-  notification_audio_controller()->RequestPlayNotificationSound(
-      kDummyNotificationId,
-      &profile2,
-      base::StringPiece(kTestAudioData, arraysize(kTestAudioData)));
-  EXPECT_EQ(2u, GetHandlersSize());
-}
diff --git a/chrome/browser/notifications/notification_browsertest.cc b/chrome/browser/notifications/notification_browsertest.cc
index fe5982a..496147c 100644
--- a/chrome/browser/notifications/notification_browsertest.cc
+++ b/chrome/browser/notifications/notification_browsertest.cc
@@ -14,6 +14,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/notifications/balloon.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/content_settings_pattern.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/notifications/notification_ui_manager_impl.cc b/chrome/browser/notifications/notification_ui_manager_impl.cc
index e7fc422..6e15592 100644
--- a/chrome/browser/notifications/notification_ui_manager_impl.cc
+++ b/chrome/browser/notifications/notification_ui_manager_impl.cc
@@ -9,12 +9,12 @@
 #include "base/memory/linked_ptr.h"
 #include "base/stl_util.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/fullscreen.h"
 #include "chrome/browser/idle.h"
 #include "chrome/browser/notifications/balloon_collection.h"
 #include "chrome/browser/notifications/notification.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.cc b/chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.cc
index f61714e..794cb5f 100644
--- a/chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.cc
+++ b/chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.cc
@@ -5,25 +5,67 @@
 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.h"
 
 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h"
+#include "chrome/browser/notifications/sync_notifier/synced_notification.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "content/public/browser/page_navigator.h"
 
 namespace notifier {
-ChromeNotifierDelegate::ChromeNotifierDelegate(const std::string& id,
-                                               ChromeNotifierService* notifier)
-    : id_(id), chrome_notifier_(notifier) {}
+ChromeNotifierDelegate::ChromeNotifierDelegate(
+    const std::string& notification_id,
+    ChromeNotifierService* notifier)
+    : notification_id_(notification_id), chrome_notifier_(notifier) {}
 
 ChromeNotifierDelegate::~ChromeNotifierDelegate() {}
 
 std::string ChromeNotifierDelegate::id() const {
-  return id_;
+   return notification_id_;
 }
 
 content::RenderViewHost* ChromeNotifierDelegate::GetRenderViewHost() const {
     return NULL;
 }
 
+// TODO(petewil) Add the ability to do URL actions also.
+void ChromeNotifierDelegate::Click() {
+  SyncedNotification* notification =
+      chrome_notifier_->FindNotificationById(notification_id_);
+  if (notification == NULL)
+    return;
+
+  GURL destination = notification->GetDefaultDestinationUrl();
+  NavigateToUrl(destination);
+}
+
+// TODO(petewil) Add the ability to do URL actions also.
+void ChromeNotifierDelegate::ButtonClick(int button_index) {
+  SyncedNotification* notification =
+      chrome_notifier_->FindNotificationById(notification_id_);
+  if (notification) {
+    GURL destination = notification->GetButtonUrl(button_index);
+    NavigateToUrl(destination);
+  }
+}
+
+void ChromeNotifierDelegate::NavigateToUrl(const GURL& destination) const {
+  if (!destination.is_valid())
+    return;
+
+  content::OpenURLParams openParams(destination, content::Referrer(),
+                                    NEW_FOREGROUND_TAB,
+                                    content::PAGE_TRANSITION_LINK, false);
+  Browser* browser = chrome::FindLastActiveWithProfile(
+      chrome_notifier_->profile(),
+      chrome::GetActiveDesktop());
+  // Navigate to the URL in a new tab.
+  if (browser != NULL)
+    browser->OpenURL(openParams);
+
+}
+
 void ChromeNotifierDelegate::Close(bool by_user) {
   if (by_user)
-    chrome_notifier_->MarkNotificationAsDismissed(id_);
+    chrome_notifier_->MarkNotificationAsDismissed(notification_id_);
 }
 
 }  // namespace notifier
diff --git a/chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.h b/chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.h
index ad462b8..f0ea79b 100644
--- a/chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.h
+++ b/chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "chrome/browser/notifications/notification_delegate.h"
+#include "url/gurl.h"
 
 namespace notifier {
 
@@ -19,21 +20,26 @@
 
 class ChromeNotifierDelegate : public NotificationDelegate {
  public:
-  explicit ChromeNotifierDelegate(const std::string& id,
+  // We use an id instead of a notification so we can check to see if the
+  // notification still exists before acting on it instead of using a ref count.
+  explicit ChromeNotifierDelegate(const std::string& notification_id,
                                   ChromeNotifierService* notifier);
 
   // NotificationDelegate interface.
   virtual void Display() OVERRIDE {}
   virtual void Error() OVERRIDE {}
   virtual void Close(bool by_user) OVERRIDE;
-  virtual void Click() OVERRIDE {}
+  virtual void Click() OVERRIDE;
+  virtual void ButtonClick(int button_index) OVERRIDE;
   virtual std::string id() const OVERRIDE;
+
   virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE;
 
  private:
   virtual ~ChromeNotifierDelegate();
+  void NavigateToUrl(const GURL& destination) const;
 
-  const std::string id_;
+  const std::string notification_id_;
   ChromeNotifierService* const chrome_notifier_;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeNotifierDelegate);
diff --git a/chrome/browser/notifications/sync_notifier/chrome_notifier_delegate_browsertest.cc b/chrome/browser/notifications/sync_notifier/chrome_notifier_delegate_browsertest.cc
new file mode 100644
index 0000000..d35e532
--- /dev/null
+++ b/chrome/browser/notifications/sync_notifier/chrome_notifier_delegate_browsertest.cc
@@ -0,0 +1,160 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.h"
+#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h"
+#include "chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.h"
+#include "chrome/browser/notifications/sync_notifier/synced_notification.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/test/test_utils.h"
+#include "sync/api/sync_change.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/message_center/notification_types.h"
+
+namespace {
+const char kTestNotificationId[] = "SomeRandomNotificationId";
+const int kNotificationPriority = static_cast<int>(
+    message_center::LOW_PRIORITY);
+}  // namespace
+
+class StubChromeNotifierService : public notifier::ChromeNotifierService {
+ public:
+  StubChromeNotifierService()
+      : ChromeNotifierService(ProfileManager::GetDefaultProfile(), NULL) {}
+
+  virtual ~StubChromeNotifierService() {}
+
+  virtual void MarkNotificationAsDismissed(const std::string& id) OVERRIDE {
+    dismissed_id_ = id;
+  }
+
+  notifier::SyncedNotification* CreateNotification(
+      const std::string& title,
+      const std::string& text,
+      const std::string& app_icon_url,
+      const std::string& image_url,
+      const std::string& app_id,
+      const std::string& key,
+      sync_pb::CoalescedSyncedNotification_ReadState read_state) {
+    syncer::SyncData sync_data = CreateSyncData(title, text, app_icon_url,
+                                                image_url,app_id, key,
+                                                read_state);
+    // Set enough fields in sync_data, including specifics, for our tests
+    // to pass.
+    return new notifier::SyncedNotification(sync_data);
+  }
+
+  // For testing, just return our test notification no matter what key the
+  // caller sends.
+  virtual notifier::SyncedNotification* FindNotificationById(
+      const std::string& id) OVERRIDE {
+    return CreateNotification(
+        kTitle1, kText1, kIconUrl1, kImageUrl1, kAppId1, kKey1, kUnread);
+  }
+
+  const std::string& dismissed_id() { return dismissed_id_; }
+
+ private:
+  std::string dismissed_id_;
+};
+
+class ChromeNotifierDelegateBrowserTest : public InProcessBrowserTest {};
+
+// Test will not have access to the browser profile on linux aura
+#if defined(OS_LINUX) && defined(USE_AURA)
+#define MAYBE_ClickTest \
+    DISABLED_ClickTest
+#else
+#define MAYBE_ClickTest \
+    ClickTest
+#endif
+
+IN_PROC_BROWSER_TEST_F(ChromeNotifierDelegateBrowserTest, MAYBE_ClickTest) {
+  std::string id(kTestNotificationId);
+  StubChromeNotifierService notifier;
+  notifier::ChromeNotifierDelegate* delegate =
+      new notifier::ChromeNotifierDelegate(id, &notifier);
+
+  // Set up an observer to wait for the navigation
+  content::WindowedNotificationObserver observer(
+        chrome::NOTIFICATION_TAB_ADDED,
+        content::NotificationService::AllSources());
+
+  delegate->Click();
+
+  // Wait for navigation to finish.
+  observer.Wait();
+
+  // Verify the navigation happened as expected - we should be on chrome://flags
+  GURL url(kDefaultDestinationUrl);
+  content::WebContents* tab =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_EQ(url, tab->GetController().GetActiveEntry()->GetVirtualURL());
+}
+
+// Test will not have access to the browser profile on linux aura.
+#if defined(OS_LINUX) && defined(USE_AURA)
+#define MAYBE_ButtonClickTest \
+    DISABLED_ButtonClickTest
+#else
+#define MAYBE_ButtonClickTest \
+    ButtonClickTest
+#endif
+
+IN_PROC_BROWSER_TEST_F(ChromeNotifierDelegateBrowserTest,
+                       MAYBE_ButtonClickTest) {
+  std::string id(kTestNotificationId);
+  StubChromeNotifierService notifier;
+  notifier::ChromeNotifierDelegate* delegate =
+      new notifier::ChromeNotifierDelegate(id, &notifier);
+
+  // Set up an observer to wait for the navigation
+  content::WindowedNotificationObserver observer(
+        chrome::NOTIFICATION_TAB_ADDED,
+        content::NotificationService::AllSources());
+
+  delegate->ButtonClick(0);
+
+  // Wait for navigation to finish.
+  observer.Wait();
+
+  // Verify the navigation happened as expected - we should be on chrome://sync
+  content::WebContents* tab;
+  GURL url1(kButtonOneUrl);
+  tab = browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_EQ(url1, tab->GetController().GetActiveEntry()->GetVirtualURL());
+
+
+  delegate->ButtonClick(1);
+
+  // Wait for navigation to finish.
+  observer.Wait();
+
+  // Verify the navigation happened as expected - we should be on chrome://sync
+  GURL url2(kButtonTwoUrl);
+  tab = browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_EQ(url2, tab->GetController().GetActiveEntry()->GetVirtualURL());
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeNotifierDelegateBrowserTest, CloseTest) {
+  std::string id(kTestNotificationId);
+  StubChromeNotifierService notifier;
+  notifier::ChromeNotifierDelegate* delegate =
+      new notifier::ChromeNotifierDelegate(id, &notifier);
+
+  delegate->Close(false);
+  ASSERT_EQ("", notifier.dismissed_id());
+
+  delegate->Close(true);
+  ASSERT_EQ(kTestNotificationId, notifier.dismissed_id());
+}
diff --git a/chrome/browser/notifications/sync_notifier/chrome_notifier_service.cc b/chrome/browser/notifications/sync_notifier/chrome_notifier_service.cc
index 8cb839f..84643d3 100644
--- a/chrome/browser/notifications/sync_notifier/chrome_notifier_service.cc
+++ b/chrome/browser/notifications/sync_notifier/chrome_notifier_service.cc
@@ -76,7 +76,7 @@
     // Process each incoming remote notification.
     const std::string& key = incoming->GetKey();
     DCHECK_GT(key.length(), 0U);
-    SyncedNotification* found = FindNotificationByKey(key);
+    SyncedNotification* found = FindNotificationById(key);
 
     if (NULL == found) {
       // If there are no conflicts, copy in the data from remote.
@@ -94,7 +94,8 @@
           if (incoming->GetReadState() == SyncedNotification::kDismissed) {
             // If it is marked as read on the server, but not the client.
             found->NotificationHasBeenDismissed();
-            // TODO(petewil): Tell the Notification UI Manager to mark it read.
+            // Tell the Notification UI Manager to mark it read.
+            notification_manager_->CancelById(found->GetKey());
           } else {
             // If it is marked as read on the client, but not the server.
             syncer::SyncData sync_data = CreateSyncDataFromNotification(*found);
@@ -111,6 +112,9 @@
         // TODO(petewil): Someday we may allow changes from the client to
         // flow upwards, when we do, we will need better merge resolution.
         found->Update(sync_data);
+
+        // Tell the notification manager to update the notification.
+        Display(found);
       }
     }
   }
@@ -149,7 +153,7 @@
 syncer::SyncError ChromeNotifierService::ProcessSyncChanges(
       const tracked_objects::Location& from_here,
       const syncer::SyncChangeList& change_list) {
-  // TODO(petewil): add a check that we are called on the thread we expect.
+  // TODO(petewil): Add a check that we are called on the thread we expect.
   syncer::SyncError error;
 
   for (syncer::SyncChangeList::const_iterator it = change_list.begin();
@@ -224,7 +228,7 @@
           specifics.coalesced_notification().read_state()) ==
        SyncedNotification::kDismissed);
 
-  // if the notification is poorly formed, return a null pointer
+  // If the notification is poorly formed, return a null pointer.
   if (!is_well_formed_unread_notification &&
       !is_well_formed_dismissed_notification) {
     DVLOG(1) << "Synced Notification is not well formed."
@@ -244,8 +248,8 @@
 
 // This returns a pointer into a vector that we own.  Caller must not free it.
 // Returns NULL if no match is found.
-SyncedNotification* ChromeNotifierService::FindNotificationByKey(
-    const std::string& key) {
+SyncedNotification* ChromeNotifierService::FindNotificationById(
+    const std::string& notification_id) {
   // TODO(petewil): We can make a performance trade off here.
   // While the vector has good locality of reference, a map has faster lookup.
   // Based on how big we expect this to get, maybe change this to a map.
@@ -254,7 +258,7 @@
       it != notification_data_.end();
       ++it) {
     SyncedNotification* notification = *it;
-    if (key == notification->GetKey())
+    if (notification_id == notification->GetKey())
       return *it;
   }
 
@@ -263,8 +267,8 @@
 
 void ChromeNotifierService::GetSyncedNotificationServices(
     std::vector<message_center::Notifier*>* notifiers) {
-  // TODO(mukai|petewil): should check the profile's eligibility before adding
-  // the sample app.
+  // TODO(mukai|petewil): Check the profile's eligibility before adding the
+  // sample app.
 
   // Currently we just use kSampleSyncedNotificationServiceId as a place holder.
   // TODO(petewil): Really obtain the list of apps from the server and create
@@ -279,12 +283,12 @@
       l10n_util::GetStringUTF16(
           IDS_MESSAGE_CENTER_SAMPLE_SYNCED_NOTIFICATION_SERVICE_NAME),
       desktop_notification_service->IsNotifierEnabled(notifier_id)));
-  // TODO(mukai): should add icon for the sample app.
+  // TODO(mukai): Add icon for the sample app.
 }
 
 void ChromeNotifierService::MarkNotificationAsDismissed(
     const std::string& key) {
-  SyncedNotification* notification = FindNotificationByKey(key);
+  SyncedNotification* notification = FindNotificationById(key);
   CHECK(notification != NULL);
 
   notification->NotificationHasBeenDismissed();
@@ -307,8 +311,17 @@
   // Take ownership of the object and put it into our local storage.
   notification_data_.push_back(notification.release());
 
+  Display(notification_copy);
+}
+
+void ChromeNotifierService::AddForTest(
+    scoped_ptr<notifier::SyncedNotification> notification) {
+    notification_data_.push_back(notification.release());
+  }
+
+void ChromeNotifierService::Display(SyncedNotification* notification) {
   // Set up to fetch the bitmaps.
-  notification_copy->QueueBitmapFetchJobs(notification_manager_,
+  notification->QueueBitmapFetchJobs(notification_manager_,
                                           this,
                                           profile_);
 
@@ -319,7 +332,7 @@
 
   // Start the bitmap fetching, Show() will be called when the last bitmap
   // either arrives or times out.
-  notification_copy->StartBitmapFetch();
+  notification->StartBitmapFetch();
 }
 
 void ChromeNotifierService::OnSyncedNotificationServiceEnabled(
diff --git a/chrome/browser/notifications/sync_notifier/chrome_notifier_service.h b/chrome/browser/notifications/sync_notifier/chrome_notifier_service.h
index ba3666d..b423703 100644
--- a/chrome/browser/notifications/sync_notifier/chrome_notifier_service.h
+++ b/chrome/browser/notifications/sync_notifier/chrome_notifier_service.h
@@ -57,26 +57,27 @@
       const syncer::SyncData& sync_data);
 
   // Get a pointer to a notification.  ChromeNotifierService owns this pointer.
-  // The caller must not free it.
-  notifier::SyncedNotification* FindNotificationByKey(const std::string& key);
+  virtual notifier::SyncedNotification* FindNotificationById(
+      const std::string& notification_id);
 
   // Get the list of synced notification services and fill their meta data to
   // |notifiers|.
   void GetSyncedNotificationServices(
       std::vector<message_center::Notifier*>* notifiers);
 
-  // Called when we dismiss a notification.
-  void MarkNotificationAsDismissed(const std::string& id);
+  // Called when we dismiss a notification.  This is virtual so that test
+  // subclasses can override it.
+  virtual void MarkNotificationAsDismissed(const std::string& id);
 
   // Called when a notier is enabled or disabled.
   void OnSyncedNotificationServiceEnabled(
       const std::string& notifier_id,
       bool enabled);
 
-  // functions for test
-  void AddForTest(scoped_ptr<notifier::SyncedNotification> notification) {
-    Add(notification.Pass());
-  }
+  Profile* profile() const { return profile_; }
+
+  // Functions for test.
+  void AddForTest(scoped_ptr<notifier::SyncedNotification> notification);
 
   // If we allow the tests to do bitmap fetching, they will attempt to fetch
   // a URL from the web, which will fail.  We can already test the majority
@@ -90,8 +91,8 @@
   // Add a notification to our list.  This takes ownership of the pointer.
   void Add(scoped_ptr<notifier::SyncedNotification> notification);
 
-  // Display a notification in the notification center.
-  void Show(notifier::SyncedNotification* notification);
+  // Display a notification in the notification center (eventually).
+  void Display(notifier::SyncedNotification* notification);
 
   // Back pointer to the owning profile.
   Profile* const profile_;
@@ -99,7 +100,7 @@
   scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
   static bool avoid_bitmap_fetching_for_test_;
 
-  // TODO(petewil): consider whether a map would better suit our data.
+  // TODO(petewil): Consider whether a map would better suit our data.
   // If there are many entries, lookup time may trump locality of reference.
   ScopedVector<notifier::SyncedNotification> notification_data_;
 
diff --git a/chrome/browser/notifications/sync_notifier/chrome_notifier_service_unittest.cc b/chrome/browser/notifications/sync_notifier/chrome_notifier_service_unittest.cc
index 5ad3b95..caedb24 100644
--- a/chrome/browser/notifications/sync_notifier/chrome_notifier_service_unittest.cc
+++ b/chrome/browser/notifications/sync_notifier/chrome_notifier_service_unittest.cc
@@ -11,14 +11,13 @@
 #include "chrome/browser/notifications/notification_test_util.h"
 #include "chrome/browser/notifications/notification_ui_manager.h"
 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h"
+#include "chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.h"
 #include "chrome/browser/notifications/sync_notifier/synced_notification.h"
 #include "chrome/browser/profiles/profile.h"
 #include "sync/api/sync_change.h"
 #include "sync/api/sync_change_processor.h"
 #include "sync/api/sync_error_factory.h"
 #include "sync/api/sync_error_factory_mock.h"
-#include "sync/protocol/sync.pb.h"
-#include "sync/protocol/synced_notification_specifics.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/message_center/message_center_util.h"
 
@@ -34,75 +33,8 @@
 
 namespace {
 
-const char kAppId1[] = "fboilmbenheemaomgaeehigklolhkhnf";
-const char kAppId2[] = "fbcmoldooppoahjhfflnmljoanccekpf";
-const char kAppId3[] = "fbcmoldooppoahjhfflnmljoanccek33";
-const char kAppId4[] = "fbcmoldooppoahjhfflnmljoanccek44";
-const char kAppId5[] = "fbcmoldooppoahjhfflnmljoanccek55";
-const char kAppId6[] = "fbcmoldooppoahjhfflnmljoanccek66";
-const char kAppId7[] = "fbcmoldooppoahjhfflnmljoanccek77";
-const char kKey1[] = "foo";
-const char kKey2[] = "bar";
-const char kKey3[] = "bat";
-const char kKey4[] = "baz";
-const char kKey5[] = "foobar";
-const char kKey6[] = "fu";
-const char kKey7[] = "meta";
-const char kIconUrl[] = "http://www.google.com/icon1.jpg";
-const char kTitle1[] = "New appointment at 2:15";
-const char kTitle2[] = "Email from Mark: Upcoming Ski trip";
-const char kTitle3[] = "Weather alert - light rain tonight.";
-const char kTitle4[] = "Zombie Alert on I-405";
-const char kTitle5[] = "5-dimensional plutonian steam hockey scores";
-const char kTitle6[] = "Conterfactuals Inc Stock report";
-const char kTitle7[] = "Push Messaging app updated";
-const char kText1[] = "Space Needle, 12:00 pm";
-const char kText2[] = "Stevens Pass is our first choice.";
-const char kText3[] = "More rain expected in the Seattle area tonight.";
-const char kText4[] = "Traffic slowdown as motorists are hitting zombies";
-const char kText5[] = "Neptune wins, pi to e";
-const char kText6[] = "Beef flavored base for soups";
-const char kText7[] = "You now have the latest version of Push Messaging App.";
-const char kIconUrl1[] = "http://www.google.com/icon1.jpg";
-const char kIconUrl2[] = "http://www.google.com/icon2.jpg";
-const char kIconUrl3[] = "http://www.google.com/icon3.jpg";
-const char kIconUrl4[] = "http://www.google.com/icon4.jpg";
-const char kIconUrl5[] = "http://www.google.com/icon5.jpg";
-const char kIconUrl6[] = "http://www.google.com/icon6.jpg";
-const char kIconUrl7[] = "http://www.google.com/icon7.jpg";
-const char kImageUrl1[] = "http://www.google.com/image1.jpg";
-const char kImageUrl2[] = "http://www.google.com/image2.jpg";
-const char kImageUrl3[] = "http://www.google.com/image3.jpg";
-const char kImageUrl4[] = "http://www.google.com/image4.jpg";
-const char kImageUrl5[] = "http://www.google.com/image5.jpg";
-const char kImageUrl6[] = "http://www.google.com/image6.jpg";
-const char kImageUrl7[] = "http://www.google.com/image7.jpg";
-const char kExpectedOriginUrl[] =
-    "chrome-extension://fboilmbenheemaomgaeehigklolhkhnf/";
-const char kDefaultDestinationTitle[] = "Open web page";
-const char kDefaultDestinationIconUrl[] = "http://www.google.com/image4.jpg";
-const char kDefaultDestinationUrl[] = "http://www.google.com";
-const char kButtonOneTitle[] = "Read";
-const char kButtonOneIconUrl[] = "http://www.google.com/image8.jpg";
-const char kButtonOneUrl[] = "http://www.google.com/do-something1";
-const char kButtonTwoTitle[] = "Reply";
-const char kButtonTwoIconUrl[] = "http://www.google.com/image9.jpg";
-const char kButtonTwoUrl[] = "http://www.google.com/do-something2";
-const char kContainedTitle1[] = "Today's Picnic moved";
-const char kContainedTitle2[] = "Group Run Today";
-const char kContainedTitle3[] = "Starcraft Tonight";
-const char kContainedMessage1[] = "Due to rain, we will be inside the cafe.";
-const char kContainedMessage2[] = "Meet at noon in the Gym.";
-const char kContainedMessage3[] = "Let's play starcraft tonight on the LAN.";
-const int64 kFakeCreationTime = 42;
-const int kProtobufPriority = static_cast<int>(
-    sync_pb::CoalescedSyncedNotification_Priority_LOW);
 const int kNotificationPriority = static_cast<int>(
     message_center::LOW_PRIORITY);
-const sync_pb::CoalescedSyncedNotification_ReadState kDismissed =
-    sync_pb::CoalescedSyncedNotification_ReadState_DISMISSED;
-const sync_pb::CoalescedSyncedNotification_ReadState kUnread =
-    sync_pb::CoalescedSyncedNotification_ReadState_UNREAD;
 
 // Extract notification id from syncer::SyncData.
 std::string GetNotificationId(const SyncData& sync_data) {
@@ -140,7 +72,8 @@
   // Removes any notifications matching the supplied ID, either currently
   // displayed or in the queue.  Returns true if anything was removed.
   virtual bool CancelById(const std::string& notification_id) OVERRIDE {
-    return false;
+    dismissed_id_ = notification_id;
+    return true;
   }
 
   // Adds the notification_id for each outstanding notification to the set
@@ -173,10 +106,14 @@
   // Test hook to get the notification so we can check it
   const Notification& notification() const { return notification_; }
 
+  // Test hook to check the ID of the last notification cancelled.
+  std::string& dismissed_id() { return dismissed_id_; }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(StubNotificationUIManager);
   Notification notification_;
   Profile* profile_;
+  std::string dismissed_id_;
 };
 
 // Dummy SyncChangeProcessor used to help review what SyncChanges are pushed
@@ -292,243 +229,6 @@
         ChromeNotifierService::CreateSyncDataFromNotification(*notification));
   }
 
-  // Helper to create syncer::SyncData.
-  static SyncData CreateSyncData(
-      const std::string& title,
-      const std::string& text,
-      const std::string& app_icon_url,
-      const std::string& image_url,
-      const std::string& app_id,
-      const std::string& key,
-      const sync_pb::CoalescedSyncedNotification_ReadState read_state) {
-    // CreateLocalData makes a copy of this, so this can safely live
-    // on the stack.
-    EntitySpecifics entity_specifics;
-
-    // Get a writeable pointer to the sync notifications specifics inside the
-    // entity specifics.
-    SyncedNotificationSpecifics* specifics =
-        entity_specifics.mutable_synced_notification();
-
-    specifics->mutable_coalesced_notification()->
-        set_app_id(app_id);
-
-    specifics->mutable_coalesced_notification()->
-        set_key(key);
-
-    specifics->mutable_coalesced_notification()->
-        set_priority(static_cast<sync_pb::CoalescedSyncedNotification_Priority>(
-            kProtobufPriority));
-
-    // Set the title.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_simple_expanded_layout()->
-        set_title(title);
-
-    // Set the text.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_simple_expanded_layout()->
-        set_text(text);
-
-    // Set the heading.
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_simple_collapsed_layout()->
-        set_heading(title);
-
-    // Add the collapsed info and set the app_icon_url on it.
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        add_collapsed_info();
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(0)->
-        mutable_simple_collapsed_layout()->
-        mutable_app_icon()->
-        set_url(app_icon_url);
-
-    // Add the media object and set the image url on it.
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_simple_expanded_layout()->
-        add_media();
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_simple_expanded_layout()->
-        mutable_media(0)->
-        mutable_image()->
-        set_url(image_url);
-
-    specifics->mutable_coalesced_notification()->
-        set_creation_time_msec(kFakeCreationTime);
-
-    specifics->mutable_coalesced_notification()->
-        set_read_state(read_state);
-
-    // Contained notification one.
-    // We re-use the collapsed info we added for the app_icon_url,
-    // so no need to create another one here.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(0)->
-        mutable_simple_collapsed_layout()->
-        set_heading(kContainedTitle1);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(0)->
-        mutable_simple_collapsed_layout()->
-        set_description(kContainedMessage1);
-
-    // Contained notification two.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        add_collapsed_info();
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(1)->
-        mutable_simple_collapsed_layout()->
-        set_heading(kContainedTitle2);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(1)->
-        mutable_simple_collapsed_layout()->
-        set_description(kContainedMessage2);
-
-    // Contained notification three.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        add_collapsed_info();
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(2)->
-        mutable_simple_collapsed_layout()->
-        set_heading(kContainedTitle3);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(2)->
-        mutable_simple_collapsed_layout()->
-        set_description(kContainedMessage3);
-
-    // Default Destination.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_default_destination()->
-        set_text(kDefaultDestinationTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_default_destination()->
-        mutable_icon()->
-        set_url(kDefaultDestinationIconUrl);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_default_destination()->
-        mutable_icon()->
-        set_alt_text(kDefaultDestinationTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_default_destination()->
-        set_url(kDefaultDestinationUrl);
-
-    // Buttons are represented as targets.
-
-    // Button One.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        add_target();
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(0)->
-        mutable_action()->
-        set_text(kButtonOneTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(0)->
-        mutable_action()->
-        mutable_icon()->
-        set_url(kButtonOneIconUrl);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(0)->
-        mutable_action()->
-        mutable_icon()->
-        set_alt_text(kButtonOneTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(0)->
-        mutable_action()->
-        set_url(kButtonOneUrl);
-
-    // Button Two.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        add_target();
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(1)->
-        mutable_action()->
-        set_text(kButtonTwoTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(1)->
-        mutable_action()->
-        mutable_icon()->
-        set_url(kButtonTwoIconUrl);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(1)->
-        mutable_action()->
-        mutable_icon()->
-        set_alt_text(kButtonTwoTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(1)->
-        mutable_action()->
-        set_url(kButtonTwoUrl);
-
-    SyncData sync_data = SyncData::CreateLocalData(
-        "syncer::SYNCED_NOTIFICATIONS",
-        "ChromeNotifierServiceUnitTest",
-        entity_specifics);
-
-    return sync_data;
-  }
-
  private:
   scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
   scoped_ptr<syncer::SyncChangeProcessor> sync_processor_delegate_;
@@ -638,13 +338,13 @@
 
   // Ensure the local store now has all local and remote notifications.
   EXPECT_EQ(7U, notifier.GetAllSyncData(SYNCED_NOTIFICATIONS).size());
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey1));
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey2));
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey3));
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey4));
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey5));
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey6));
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey7));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey1));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey2));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey3));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey4));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey5));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey6));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey7));
 
   // Test the type conversion and construction functions.
   for (SyncDataList::const_iterator iter = initial_data.begin();
@@ -654,14 +354,14 @@
     // TODO(petewil): Revisit this when we add version info to notifications.
     const std::string& key = notification1->GetKey();
     const SyncedNotification* notification2 =
-        notifier.FindNotificationByKey(key);
+        notifier.FindNotificationById(key);
     EXPECT_TRUE(NULL != notification2);
     EXPECT_TRUE(notification1->EqualsIgnoringReadState(*notification2));
     EXPECT_EQ(notification1->GetReadState(), notification2->GetReadState());
   }
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey1));
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey2));
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey3));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey1));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey2));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey3));
 }
 
 // Test the local store having the read bit unset, the remote store having
@@ -694,11 +394,15 @@
   // state of the first is now read.
   EXPECT_EQ(2U, notifier.GetAllSyncData(syncer::SYNCED_NOTIFICATIONS).size());
   SyncedNotification* notification1 =
-      notifier.FindNotificationByKey(kKey1);
+      notifier.FindNotificationById(kKey1);
   EXPECT_FALSE(NULL == notification1);
   EXPECT_EQ(SyncedNotification::kDismissed, notification1->GetReadState());
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey2));
-  EXPECT_FALSE(notifier.FindNotificationByKey(kKey3));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey2));
+  EXPECT_FALSE(notifier.FindNotificationById(kKey3));
+
+  // Make sure that the notification manager was told to dismiss the
+  // notification.
+  EXPECT_EQ(std::string(kKey1), notification_manager.dismissed_id());
 
   // Ensure no new data will be sent to the remote store for notification1.
   EXPECT_EQ(0U, processor()->change_list_size());
@@ -735,11 +439,11 @@
   // state of the first is now read.
   EXPECT_EQ(2U, notifier.GetAllSyncData(syncer::SYNCED_NOTIFICATIONS).size());
   SyncedNotification* notification1 =
-      notifier.FindNotificationByKey(kKey1);
+      notifier.FindNotificationById(kKey1);
   EXPECT_FALSE(NULL == notification1);
   EXPECT_EQ(SyncedNotification::kDismissed, notification1->GetReadState());
-  EXPECT_TRUE(notifier.FindNotificationByKey(kKey2));
-  EXPECT_FALSE(notifier.FindNotificationByKey(kKey3));
+  EXPECT_TRUE(notifier.FindNotificationById(kKey2));
+  EXPECT_FALSE(notifier.FindNotificationById(kKey3));
 
   // Ensure the new data will be sent to the remote store for notification1.
   EXPECT_EQ(1U, processor()->change_list_size());
@@ -773,11 +477,11 @@
   // Ensure the local store still has only one notification
   EXPECT_EQ(1U, notifier.GetAllSyncData(syncer::SYNCED_NOTIFICATIONS).size());
   SyncedNotification* notification1 =
-      notifier.FindNotificationByKey(kKey1);
+      notifier.FindNotificationById(kKey1);
 
   EXPECT_FALSE(NULL == notification1);
   EXPECT_EQ(SyncedNotification::kUnread, notification1->GetReadState());
-  EXPECT_EQ(kTitle2, notification1->GetTitle());
+  EXPECT_EQ(std::string(kTitle2), notification1->GetTitle());
 
   // Ensure no new data will be sent to the remote store for notification1.
   EXPECT_EQ(0U, processor()->change_list_size());
diff --git a/chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.cc b/chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.cc
new file mode 100644
index 0000000..e560baf
--- /dev/null
+++ b/chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.cc
@@ -0,0 +1,198 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.h"
+
+// Fake data for creating a SyncData object to use in creating a
+// SyncedNotification.
+const char kAppId1[] = "fboilmbenheemaomgaeehigklolhkhnf";
+const char kAppId2[] = "fbcmoldooppoahjhfflnmljoanccekpf";
+const char kAppId3[] = "fbcmoldooppoahjhfflnmljoanccek33";
+const char kAppId4[] = "fbcmoldooppoahjhfflnmljoanccek44";
+const char kAppId5[] = "fbcmoldooppoahjhfflnmljoanccek55";
+const char kAppId6[] = "fbcmoldooppoahjhfflnmljoanccek66";
+const char kAppId7[] = "fbcmoldooppoahjhfflnmljoanccek77";
+const char kKey1[] = "foo";
+const char kKey2[] = "bar";
+const char kKey3[] = "bat";
+const char kKey4[] = "baz";
+const char kKey5[] = "foobar";
+const char kKey6[] = "fu";
+const char kKey7[] = "meta";
+const char kIconUrl1[] = "http://www.google.com/icon1.jpg";
+const char kIconUrl2[] = "http://www.google.com/icon2.jpg";
+const char kIconUrl3[] = "http://www.google.com/icon3.jpg";
+const char kIconUrl4[] = "http://www.google.com/icon4.jpg";
+const char kIconUrl5[] = "http://www.google.com/icon5.jpg";
+const char kIconUrl6[] = "http://www.google.com/icon6.jpg";
+const char kIconUrl7[] = "http://www.google.com/icon7.jpg";
+const char kTitle1[] = "New appointment at 2:15";
+const char kTitle2[] = "Email from Mark: Upcoming Ski trip";
+const char kTitle3[] = "Weather alert - light rain tonight.";
+const char kTitle4[] = "Zombie Alert on I-405";
+const char kTitle5[] = "5-dimensional plutonian steam hockey scores";
+const char kTitle6[] = "Conterfactuals Inc Stock report";
+const char kTitle7[] = "Push Messaging app updated";
+const char kText1[] = "Space Needle, 12:00 pm";
+const char kText2[] = "Stevens Pass is our first choice.";
+const char kText3[] = "More rain expected in the Seattle area tonight.";
+const char kText4[] = "Traffic slowdown as motorists are hitting zombies";
+const char kText5[] = "Neptune wins, pi to e";
+const char kText6[] = "Beef flavored base for soups";
+const char kText7[] = "You now have the latest version of Push Messaging App.";
+const char kImageUrl1[] = "http://www.google.com/image1.jpg";
+const char kImageUrl2[] = "http://www.google.com/image2.jpg";
+const char kImageUrl3[] = "http://www.google.com/image3.jpg";
+const char kImageUrl4[] = "http://www.google.com/image4.jpg";
+const char kImageUrl5[] = "http://www.google.com/image5.jpg";
+const char kImageUrl6[] = "http://www.google.com/image6.jpg";
+const char kImageUrl7[] = "http://www.google.com/image7.jpg";
+const char kExpectedOriginUrl[] =
+    "chrome-extension://fboilmbenheemaomgaeehigklolhkhnf/";
+const char kDefaultDestinationTitle[] = "Open web page";
+const char kDefaultDestinationIconUrl[] = "http://www.google.com/image4.jpg";
+const char kDefaultDestinationUrl[] = "chrome://flags";
+const char kButtonOneTitle[] = "Read";
+const char kButtonOneIconUrl[] = "http://www.google.com/image8.jpg";
+const char kButtonOneUrl[] = "chrome://sync";
+const char kButtonTwoTitle[] = "Reply";
+const char kButtonTwoIconUrl[] = "http://www.google.com/image9.jpg";
+const char kButtonTwoUrl[] = "chrome://about";
+const char kContainedTitle1[] = "Today's Picnic moved";
+const char kContainedTitle2[] = "Group Run Today";
+const char kContainedTitle3[] = "Starcraft Tonight";
+const char kContainedMessage1[] = "Due to rain, we will be inside the cafe.";
+const char kContainedMessage2[] = "Meet at noon in the Gym.";
+const char kContainedMessage3[] = "Let's play starcraft tonight on the LAN.";
+
+syncer::SyncData CreateSyncData(
+    const std::string& title,
+    const std::string& text,
+    const std::string& app_icon_url,
+    const std::string& image_url,
+    const std::string& app_id,
+    const std::string& key,
+    const sync_pb::CoalescedSyncedNotification_ReadState read_state) {
+  // CreateLocalData makes a copy of this, so this can safely live
+  // on the stack.
+  sync_pb::EntitySpecifics entity_specifics;
+
+  // Get a writeable pointer to the sync notifications specifics inside the
+  // entity specifics.
+  sync_pb::SyncedNotificationSpecifics* specifics =
+      entity_specifics.mutable_synced_notification();
+
+  // Get pointers to sub structures.
+  sync_pb::CoalescedSyncedNotification* coalesced_notification =
+      specifics->mutable_coalesced_notification();
+  sync_pb::SyncedNotificationRenderInfo* render_info =
+      coalesced_notification->mutable_render_info();
+  sync_pb::ExpandedInfo* expanded_info =
+      render_info->mutable_expanded_info();
+  sync_pb::SimpleExpandedLayout* simple_expanded_layout =
+      expanded_info->mutable_simple_expanded_layout();
+  sync_pb::CollapsedInfo* collapsed_info =
+      render_info->mutable_collapsed_info();
+  sync_pb::SimpleCollapsedLayout* simple_collapsed_layout =
+      collapsed_info->mutable_simple_collapsed_layout();
+  sync_pb::SyncedNotificationDestination* default_destination =
+      collapsed_info->mutable_default_destination();
+
+  coalesced_notification->set_app_id(app_id);
+
+  coalesced_notification->set_key(key);
+
+  coalesced_notification->
+      set_priority(static_cast<sync_pb::CoalescedSyncedNotification_Priority>(
+          kProtobufPriority));
+
+  // Set the title.
+  simple_expanded_layout->set_title(title);
+
+  // Set the text.
+  simple_expanded_layout->set_text(text);
+
+  // Set the heading.
+  simple_collapsed_layout->set_heading(title);
+
+  // Add the collapsed info and set the app_icon_url on it.
+  expanded_info->add_collapsed_info();
+  expanded_info->
+      mutable_collapsed_info(0)->
+      mutable_simple_collapsed_layout()->
+      mutable_app_icon()->
+      set_url(app_icon_url);
+
+  // Add the media object and set the image url on it.
+  simple_expanded_layout->add_media();
+  simple_expanded_layout->
+      mutable_media(0)->
+      mutable_image()->
+      set_url(image_url);
+
+  coalesced_notification->set_creation_time_msec(kFakeCreationTime);
+
+  coalesced_notification->set_read_state(read_state);
+
+  // Contained notification one.
+  // We re-use the collapsed info we added for the app_icon_url,
+  // so no need to create another one here.
+  sync_pb::SimpleCollapsedLayout* notification_layout1 =
+      expanded_info->
+      mutable_collapsed_info(0)->
+      mutable_simple_collapsed_layout();
+  notification_layout1->set_heading(kContainedTitle1);
+  notification_layout1->set_description(kContainedMessage1);
+
+  // Contained notification two.
+  expanded_info->add_collapsed_info();
+  sync_pb::SimpleCollapsedLayout* notification_layout2 =
+      expanded_info->
+      mutable_collapsed_info(1)->
+      mutable_simple_collapsed_layout();
+  notification_layout2->set_heading(kContainedTitle2);
+  notification_layout2->set_description(kContainedMessage2);
+
+  // Contained notification three.
+  expanded_info->add_collapsed_info();
+  sync_pb::SimpleCollapsedLayout* notification_layout3 =
+      expanded_info->
+      mutable_collapsed_info(2)->
+      mutable_simple_collapsed_layout();
+  notification_layout3->set_heading(kContainedTitle3);
+  notification_layout3->set_description(kContainedMessage3);
+
+  // Default Destination.
+  default_destination->set_text(kDefaultDestinationTitle);
+  default_destination->mutable_icon()->set_url(kDefaultDestinationIconUrl);
+  default_destination->mutable_icon()->set_alt_text(kDefaultDestinationTitle);
+  default_destination->set_url(kDefaultDestinationUrl);
+
+  // Buttons are represented as targets.
+
+  // Button One.
+  collapsed_info->add_target();
+  sync_pb::SyncedNotificationAction* action1 =
+      collapsed_info->mutable_target(0)->mutable_action();
+  action1->set_text(kButtonOneTitle);
+  action1->mutable_icon()->set_url(kButtonOneIconUrl);
+  action1->mutable_icon()->set_alt_text(kButtonOneTitle);
+  action1->set_url(kButtonOneUrl);
+
+  // Button Two.
+  collapsed_info->add_target();
+  sync_pb::SyncedNotificationAction* action2 =
+      collapsed_info->mutable_target(1)->mutable_action();
+  action2->set_text(kButtonOneTitle);
+  action2->mutable_icon()->set_url(kButtonTwoIconUrl);
+  action2->mutable_icon()->set_alt_text(kButtonTwoTitle);
+  action2->set_url(kButtonTwoUrl);
+
+  syncer::SyncData sync_data = syncer::SyncData::CreateLocalData(
+      "syncer::SYNCED_NOTIFICATIONS",
+      "ChromeNotifierServiceUnitTest",
+      entity_specifics);
+
+  return sync_data;
+}
diff --git a/chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.h b/chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.h
new file mode 100644
index 0000000..be33257
--- /dev/null
+++ b/chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.h
@@ -0,0 +1,97 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NOTIFICATIONS_SYNC_NOTIFIER_SYNC_NOTIFIER_TEST_UTILS_H_
+#define CHROME_BROWSER_NOTIFICATIONS_SYNC_NOTIFIER_SYNC_NOTIFIER_TEST_UTILS_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "sync/api/sync_data.h"
+#include "sync/protocol/sync.pb.h"
+#include "sync/protocol/synced_notification_specifics.pb.h"
+
+
+// Fake data for creating a SyncedNotification.
+extern const char kAppId1[];
+extern const char kAppId2[];
+extern const char kAppId3[];
+extern const char kAppId4[];
+extern const char kAppId5[];
+extern const char kAppId6[];
+extern const char kAppId7[];
+extern const char kKey1[];
+extern const char kKey2[];
+extern const char kKey3[];
+extern const char kKey4[];
+extern const char kKey5[];
+extern const char kKey6[];
+extern const char kKey7[];
+extern const char kIconUrl1[];
+extern const char kIconUrl2[];
+extern const char kIconUrl3[];
+extern const char kIconUrl4[];
+extern const char kIconUrl5[];
+extern const char kIconUrl6[];
+extern const char kIconUrl7[];
+extern const char kTitle1[];
+extern const char kTitle2[];
+extern const char kTitle3[];
+extern const char kTitle4[];
+extern const char kTitle5[];
+extern const char kTitle6[];
+extern const char kTitle7[];
+extern const char kText1[];
+extern const char kText2[];
+extern const char kText3[];
+extern const char kText4[];
+extern const char kText5[];
+extern const char kText6[];
+extern const char kText7[];
+extern const char kImageUrl1[];
+extern const char kImageUrl2[];
+extern const char kImageUrl3[];
+extern const char kImageUrl4[];
+extern const char kImageUrl5[];
+extern const char kImageUrl6[];
+extern const char kImageUrl7[];
+extern const char kExpectedOriginUrl[];
+extern const char kDefaultDestinationTitle[];
+extern const char kDefaultDestinationIconUrl[];
+extern const char kDefaultDestinationUrl[];
+extern const char kButtonOneTitle[];
+extern const char kButtonOneIconUrl[];
+extern const char kButtonOneUrl[];
+extern const char kButtonTwoTitle[];
+extern const char kButtonTwoIconUrl[];
+extern const char kButtonTwoUrl[];
+extern const char kContainedTitle1[];
+extern const char kContainedTitle2[];
+extern const char kContainedTitle3[];
+extern const char kContainedMessage1[];
+extern const char kContainedMessage2[];
+extern const char kContainedMessage3[];
+const uint64 kFakeCreationTime = 42;
+const int kProtobufPriority = static_cast<int>(
+    sync_pb::CoalescedSyncedNotification_Priority_LOW);
+
+const sync_pb::CoalescedSyncedNotification_ReadState kRead =
+    sync_pb::CoalescedSyncedNotification_ReadState_READ;
+const sync_pb::CoalescedSyncedNotification_ReadState kDismissed =
+    sync_pb::CoalescedSyncedNotification_ReadState_DISMISSED;
+const sync_pb::CoalescedSyncedNotification_ReadState kUnread =
+    sync_pb::CoalescedSyncedNotification_ReadState_UNREAD;
+
+// This function builds the sync data object we use to create a testing
+// notification.
+syncer::SyncData CreateSyncData(
+    const std::string& title,
+    const std::string& text,
+    const std::string& app_icon_url,
+    const std::string& image_url,
+    const std::string& app_id,
+    const std::string& key,
+      const sync_pb::CoalescedSyncedNotification_ReadState read_state);
+
+#endif  // CHROME_BROWSER_NOTIFICATIONS_SYNC_NOTIFIER_SYNC_NOTIFIER_TEST_UTILS_H_
diff --git a/chrome/browser/notifications/sync_notifier/synced_notification.cc b/chrome/browser/notifications/sync_notifier/synced_notification.cc
index 69c19d6..851c5d6 100644
--- a/chrome/browser/notifications/sync_notifier/synced_notification.cc
+++ b/chrome/browser/notifications/sync_notifier/synced_notification.cc
@@ -22,6 +22,10 @@
 namespace {
 const char kExtensionScheme[] = "chrome-extension://";
 
+// Today rich notifications only supports two buttons, make sure we don't
+// try to supply them with more than this number of buttons.
+const unsigned int kMaxNotificationButtonIndex = 2;
+
 bool UseRichNotifications() {
   return message_center::IsRichNotificationEnabled();
 }
@@ -54,7 +58,7 @@
 SyncedNotification::~SyncedNotification() {}
 
 void SyncedNotification::Update(const syncer::SyncData& sync_data) {
-  // TODO(petewil): Let's add checking that the notification looks valid.
+  // TODO(petewil): Add checking that the notification looks valid.
   specifics_.CopyFrom(sync_data.GetSpecifics().synced_notification());
 }
 
@@ -72,18 +76,18 @@
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 
   // Match the incoming bitmaps to URLs.  In case this is a dup, make sure to
-  // try all potentially matching urls.
+  // Try all potentially matching urls.
   if (GetAppIconUrl() == url && bitmap != NULL) {
     app_icon_bitmap_ = gfx::Image::CreateFrom1xBitmap(*bitmap);
   }
   if (GetImageUrl() == url && bitmap != NULL) {
     image_bitmap_ = gfx::Image::CreateFrom1xBitmap(*bitmap);
   }
-  if (GetButtonOneIconUrl() == url.spec() && bitmap != NULL) {
-    button_one_bitmap_ = gfx::Image::CreateFrom1xBitmap(*bitmap);
-  }
-  if (GetButtonTwoIconUrl() == url.spec() && bitmap != NULL) {
-    button_two_bitmap_ = gfx::Image::CreateFrom1xBitmap(*bitmap);
+
+  // If this URL matches one or more button bitmaps, save them off.
+  for (unsigned int i = 0; i < GetButtonCount(); ++i) {
+    if (GetButtonIconUrl(i) == url && bitmap != NULL)
+      button_bitmaps_[i] = gfx::Image::CreateFrom1xBitmap(*bitmap);
   }
 
   // Count off the bitmaps as they arrive.
@@ -99,7 +103,6 @@
     NotificationUIManager* notification_manager,
     ChromeNotifierService* notifier_service,
     Profile* profile) {
-
   // If we are not using the MessageCenter, call show now, and the existing
   // code will handle the bitmap fetch for us.
   if (!UseRichNotifications()) {
@@ -113,17 +116,16 @@
   profile_ = profile;
   DCHECK_EQ(active_fetcher_count_, 0);
 
-  // Get the URLs that we might need to fetch from Synced Notification.
-  // TODO(petewil): clean up the fact that icon and image return a GURL, and
-  // button urls return a string.
-  // TODO(petewil): Eventually refactor this to accept an arbitrary number of
-  // button URLs.
+  // Ensure our bitmap vector has as many entries as there are buttons,
+  // so that when the bitmaps arrive the vector has a slot for them.
+  for (unsigned int i = 0; i < GetButtonCount(); ++i) {
+    button_bitmaps_.push_back(gfx::Image());
+    AddBitmapToFetchQueue(GetButtonIconUrl(i));
+  }
 
   // If the URL is non-empty, add it to our queue of URLs to fetch.
   AddBitmapToFetchQueue(GetAppIconUrl());
   AddBitmapToFetchQueue(GetImageUrl());
-  AddBitmapToFetchQueue(GURL(GetButtonOneIconUrl()));
-  AddBitmapToFetchQueue(GURL(GetButtonTwoIconUrl()));
 
   // If there are no bitmaps, call show now.
   if (active_fetcher_count_ == 0) {
@@ -156,6 +158,15 @@
 void SyncedNotification::Show(NotificationUIManager* notification_manager,
                               ChromeNotifierService* notifier_service,
                               Profile* profile) {
+  // Let NotificationUIManager know that the notification has been dismissed.
+  if (SyncedNotification::kRead == GetReadState() ||
+      SyncedNotification::kDismissed == GetReadState() ) {
+    notification_manager->CancelById(GetKey());
+    DVLOG(2) << "Dismissed notification arrived"
+             << GetHeading() << " " << GetText();
+    return;
+  }
+
   // Set up the fields we need to send and create a Notification object.
   GURL image_url = GetImageUrl();
   string16 text = UTF8ToUTF16(GetText());
@@ -169,25 +180,13 @@
   scoped_refptr<NotificationDelegate> delegate =
       new ChromeNotifierDelegate(GetKey(), notifier_service);
 
-  // TODO(petewil): For now, just punt on dismissed notifications until
-  // I change the interface to let NotificationUIManager know the right way.
-  if (SyncedNotification::kRead == GetReadState() ||
-      SyncedNotification::kDismissed == GetReadState() ) {
-    DVLOG(2) << "Dismissed notification arrived"
-             << GetHeading() << " " << GetText();
-    return;
-  }
-
   // Some inputs and fields are only used if there is a notification center.
   if (UseRichNotifications()) {
     base::Time creation_time =
         base::Time::FromDoubleT(static_cast<double>(GetCreationTime()));
     int priority = GetPriority();
     int notification_count = GetNotificationCount();
-    int button_count = GetButtonCount();
-    // TODO(petewil): Refactor this for an arbitrary number of buttons.
-    std::string button_one_title = GetButtonOneTitle();
-    std::string button_two_title = GetButtonTwoTitle();
+    unsigned int button_count = GetButtonCount();
 
     // Deduce which notification template to use from the data.
     message_center::NotificationType notification_type =
@@ -206,16 +205,23 @@
     rich_notification_data.timestamp = creation_time;
     if (priority != SyncedNotification::kUndefinedPriority)
       rich_notification_data.priority = priority;
-    if (!button_one_title.empty()) {
-      message_center::ButtonInfo button_info(UTF8ToUTF16(button_one_title));
-      if (!button_one_bitmap_.IsEmpty())
-        button_info.icon = button_one_bitmap_;
-      rich_notification_data.buttons.push_back(button_info);
-    }
-    if (!button_two_title.empty()) {
-      message_center::ButtonInfo button_info(UTF8ToUTF16(button_two_title));
-      if (!button_two_bitmap_.IsEmpty())
-        button_info.icon = button_two_bitmap_;
+
+    // Fill in the button data.
+    // TODO(petewil): Today Rich notifiations are limited to two buttons.
+    // When rich notifications supports more, remove the
+    // "&& i < kMaxNotificationButtonIndex" below.
+    for (unsigned int i = 0;
+         i < button_count
+         && i < button_bitmaps_.size()
+         && i < kMaxNotificationButtonIndex;
+         ++i) {
+      // Stop at the first button with no title
+      std::string title = GetButtonTitle(i);
+      if (title.empty())
+        break;
+      message_center::ButtonInfo button_info(UTF8ToUTF16(title));
+      if (!button_bitmaps_[i].IsEmpty())
+        button_info.icon = button_bitmaps_[i];
       rich_notification_data.buttons.push_back(button_info);
     }
 
@@ -265,23 +271,60 @@
   return;
 }
 
-// TODO(petewil): Decide what we need for equals - is this enough, or should
-// we exhaustively compare every field in case the server refreshed the notif?
+// This should detect even small changes in case the server updated the
+// notification.
+// TODO(petewil): Should I also ignore the timestamp if other fields match?
 bool SyncedNotification::EqualsIgnoringReadState(
     const SyncedNotification& other) const {
-  return (GetTitle() == other.GetTitle() &&
-          GetAppId() == other.GetAppId() &&
-          GetKey() == other.GetKey() &&
-          GetText() == other.GetText() &&
-          GetOriginUrl() == other.GetOriginUrl() &&
-          GetAppIconUrl() == other.GetAppIconUrl() &&
-          GetImageUrl() == other.GetImageUrl() );
+  if (GetTitle() == other.GetTitle() &&
+      GetHeading() == other.GetHeading() &&
+      GetDescription() == other.GetDescription() &&
+      GetAppId() == other.GetAppId() &&
+      GetKey() == other.GetKey() &&
+      GetOriginUrl() == other.GetOriginUrl() &&
+      GetAppIconUrl() == other.GetAppIconUrl() &&
+      GetImageUrl() == other.GetImageUrl() &&
+      GetText() == other.GetText() &&
+      // We intentionally skip read state
+      GetCreationTime() == other.GetCreationTime() &&
+      GetPriority() == other.GetPriority() &&
+      GetDefaultDestinationTitle() == other.GetDefaultDestinationTitle() &&
+      GetDefaultDestinationIconUrl() == other.GetDefaultDestinationIconUrl() &&
+      GetNotificationCount() == other.GetNotificationCount() &&
+      GetButtonCount() == other.GetButtonCount()) {
+
+    // If all the surface data matched, check, to see if contained data also
+    // matches, titles and messages.
+    size_t count = GetNotificationCount();
+    for (size_t ii = 0; ii < count; ++ii) {
+      if (GetContainedNotificationTitle(ii) !=
+          other.GetContainedNotificationTitle(ii))
+        return false;
+      if (GetContainedNotificationMessage(ii) !=
+          other.GetContainedNotificationMessage(ii))
+        return false;
+    }
+
+    // Make sure buttons match.
+    count = GetButtonCount();
+    for (size_t jj = 0; jj < count; ++jj) {
+      if (GetButtonTitle(jj) != other.GetButtonTitle(jj))
+        return false;
+      if (GetButtonIconUrl(jj) != other.GetButtonIconUrl(jj))
+        return false;
+    }
+
+    // If buttons and notifications matched, they are equivalent.
+    return true;
+  }
+
+  return false;
 }
 
 // Set the read state on the notification, returns true for success.
 void SyncedNotification::SetReadState(const ReadState& read_state) {
 
-  // convert the read state to the protobuf type for read state
+  // Convert the read state to the protobuf type for read state.
   if (kDismissed == read_state)
     specifics_.mutable_coalesced_notification()->set_read_state(
         sync_pb::CoalescedSyncedNotification_ReadState_DISMISSED);
@@ -344,8 +387,8 @@
   return GURL(origin_url);
 }
 
-// TODO(petewil): This only returns the first icon. We should make all the
-// icons available.
+// TODO(petewil): This only returns the first icon. Make all the icons
+// available.
 GURL SyncedNotification::GetAppIconUrl() const {
   if (specifics_.coalesced_notification().render_info().expanded_info().
       collapsed_info_size() == 0)
@@ -438,12 +481,12 @@
   }
 }
 
-int SyncedNotification::GetNotificationCount() const {
+size_t SyncedNotification::GetNotificationCount() const {
   return specifics_.coalesced_notification().render_info().
       expanded_info().collapsed_info_size();
 }
 
-int SyncedNotification::GetButtonCount() const {
+size_t SyncedNotification::GetButtonCount() const {
   return specifics_.coalesced_notification().render_info().collapsed_info().
       target_size();
 }
@@ -457,94 +500,59 @@
       default_destination().icon().alt_text();
 }
 
-std::string SyncedNotification::GetDefaultDestinationIconUrl() const {
+GURL SyncedNotification::GetDefaultDestinationIconUrl() const {
   if (!specifics_.coalesced_notification().render_info().collapsed_info().
       default_destination().icon().has_url()) {
-    return std::string();
+    return GURL();
   }
-  return specifics_.coalesced_notification().render_info().collapsed_info().
-      default_destination().icon().url();
+  return GURL(specifics_.coalesced_notification().render_info().
+              collapsed_info().default_destination().icon().url());
 }
 
-std::string SyncedNotification::GetDefaultDestinationUrl() const {
+GURL SyncedNotification::GetDefaultDestinationUrl() const {
   if (!specifics_.coalesced_notification().render_info().collapsed_info().
       default_destination().has_url()) {
-    return std::string();
+    return GURL();
   }
-  return specifics_.coalesced_notification().render_info().collapsed_info().
-      default_destination().url();
+  return GURL(specifics_.coalesced_notification().render_info().
+              collapsed_info().default_destination().url());
 }
 
-std::string SyncedNotification::GetButtonOneTitle() const {
+std::string SyncedNotification::GetButtonTitle(
+    unsigned int which_button) const {
   // Must ensure that we have a target before trying to access it.
-  if (GetButtonCount() < 1)
+  if (GetButtonCount() <= which_button)
     return std::string();
   if (!specifics_.coalesced_notification().render_info().collapsed_info().
-      target(0).action().icon().has_alt_text()) {
+      target(which_button).action().icon().has_alt_text()) {
     return std::string();
   }
   return specifics_.coalesced_notification().render_info().collapsed_info().
-      target(0).action().icon().alt_text();
+      target(which_button).action().icon().alt_text();
 }
 
-std::string SyncedNotification::GetButtonOneIconUrl() const {
+GURL SyncedNotification::GetButtonIconUrl(unsigned int which_button) const {
   // Must ensure that we have a target before trying to access it.
-  if (GetButtonCount() < 1)
-    return std::string();
+  if (GetButtonCount() <= which_button)
+    return GURL();
   if (!specifics_.coalesced_notification().render_info().collapsed_info().
-      target(0).action().icon().has_url()) {
-    return std::string();
+      target(which_button).action().icon().has_url()) {
+    return GURL();
   }
-  return specifics_.coalesced_notification().render_info().collapsed_info().
-      target(0).action().icon().url();
+  return GURL(specifics_.coalesced_notification().render_info().
+              collapsed_info().target(which_button).action().icon().url());
 }
 
-std::string SyncedNotification::GetButtonOneUrl() const {
+GURL SyncedNotification::GetButtonUrl(unsigned int which_button) const {
   // Must ensure that we have a target before trying to access it.
-  if (GetButtonCount() < 1)
-    return std::string();
+  if (GetButtonCount() <= which_button)
+    return GURL();
   if (!specifics_.coalesced_notification().render_info().collapsed_info().
-      target(0).action().has_url()) {
-    return std::string();
+      target(which_button).action().has_url()) {
+    return GURL();
   }
-  return specifics_.coalesced_notification().render_info().collapsed_info().
-      target(0).action().url();
-}
-
-std::string SyncedNotification::GetButtonTwoTitle() const {
-  // Must ensure that we have a target before trying to access it.
-  if (GetButtonCount() < 2)
-    return std::string();
-  if (!specifics_.coalesced_notification().render_info().collapsed_info().
-      target(1).action().icon().has_alt_text()) {
-    return std::string();
-  }
-  return specifics_.coalesced_notification().render_info().collapsed_info().
-      target(1).action().icon().alt_text();
-}
-
-std::string SyncedNotification::GetButtonTwoIconUrl() const {
-  // Must ensure that we have a target before trying to access it.
-  if (GetButtonCount() < 2)
-    return std::string();
-  if (!specifics_.coalesced_notification().render_info().collapsed_info().
-      target(1).action().icon().has_url()) {
-    return std::string();
-  }
-  return specifics_.coalesced_notification().render_info().collapsed_info().
-      target(1).action().icon().url();
-}
-
-std::string SyncedNotification::GetButtonTwoUrl() const {
-  // Must ensure that we have a target before trying to access it.
-  if (GetButtonCount() < 2)
-    return std::string();
-  if (!specifics_.coalesced_notification().render_info().collapsed_info().
-      target(1).action().has_url()) {
-    return std::string();
-  }
-  return specifics_.coalesced_notification().render_info().collapsed_info().
-      target(1).action().url();
+  return GURL(specifics_.coalesced_notification().render_info().
+              collapsed_info().target(which_button).action().url());
 }
 
 std::string SyncedNotification::GetContainedNotificationTitle(
diff --git a/chrome/browser/notifications/sync_notifier/synced_notification.h b/chrome/browser/notifications/sync_notifier/synced_notification.h
index 52f37ee..fd3ee55 100644
--- a/chrome/browser/notifications/sync_notifier/synced_notification.h
+++ b/chrome/browser/notifications/sync_notifier/synced_notification.h
@@ -62,16 +62,13 @@
   uint64 GetCreationTime() const;
   int GetPriority() const;
   std::string GetDefaultDestinationTitle() const;
-  std::string GetDefaultDestinationIconUrl() const;
-  std::string GetDefaultDestinationUrl() const;
-  std::string GetButtonOneTitle() const;
-  std::string GetButtonOneIconUrl() const;
-  std::string GetButtonOneUrl() const;
-  std::string GetButtonTwoTitle() const;
-  std::string GetButtonTwoIconUrl() const;
-  std::string GetButtonTwoUrl() const;
-  int GetNotificationCount() const;
-  int GetButtonCount() const;
+  GURL GetDefaultDestinationIconUrl() const;
+  GURL GetDefaultDestinationUrl() const;
+  std::string GetButtonTitle(unsigned int which_button) const;
+  GURL GetButtonIconUrl(unsigned int which_button) const;
+  GURL GetButtonUrl(unsigned int which_button) const;
+  size_t GetNotificationCount() const;
+  size_t GetButtonCount() const;
   std::string GetContainedNotificationTitle(int index) const;
   std::string GetContainedNotificationMessage(int index) const;
 
@@ -116,8 +113,7 @@
   int active_fetcher_count_;
   gfx::Image app_icon_bitmap_;
   gfx::Image image_bitmap_;
-  gfx::Image button_one_bitmap_;
-  gfx::Image button_two_bitmap_;
+  std::vector<gfx::Image> button_bitmaps_;
 
   FRIEND_TEST_ALL_PREFIXES(SyncedNotificationTest, AddBitmapToFetchQueueTest);
   FRIEND_TEST_ALL_PREFIXES(SyncedNotificationTest, OnFetchCompleteTest);
diff --git a/chrome/browser/notifications/sync_notifier/synced_notification_unittest.cc b/chrome/browser/notifications/sync_notifier/synced_notification_unittest.cc
index f1f9483..abb60a2 100644
--- a/chrome/browser/notifications/sync_notifier/synced_notification_unittest.cc
+++ b/chrome/browser/notifications/sync_notifier/synced_notification_unittest.cc
@@ -10,13 +10,11 @@
 #include "chrome/browser/notifications/notification.h"
 #include "chrome/browser/notifications/notification_test_util.h"
 #include "chrome/browser/notifications/notification_ui_manager.h"
+#include "chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.h"
 #include "chrome/browser/notifications/sync_notifier/synced_notification.h"
 #include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread.h"
-#include "sync/api/sync_data.h"
-#include "sync/protocol/sync.pb.h"
-#include "sync/protocol/synced_notification_specifics.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/message_center/message_center_util.h"
@@ -28,9 +26,6 @@
 using sync_pb::SyncedNotificationSpecifics;
 
 namespace {
-const uint64 kFakeCreationTime = 42;
-const int kProtobufPriority = static_cast<int>(
-    sync_pb::CoalescedSyncedNotification_Priority_LOW);
 const int kNotificationPriority = static_cast<int>(
     message_center::LOW_PRIORITY);
 
@@ -38,46 +33,6 @@
   return message_center::IsRichNotificationEnabled();
 }
 
-const char kTitle1[] = "New appointment at 2:15";
-const char kTitle2[] = "Email from Mark: Upcoming Ski trip";
-const char kTitle3[] = "Weather alert - light rain tonight.";
-const char kAppId1[] = "fboilmbenheemaomgaeehigklolhkhnf";
-const char kAppId2[] = "fbcmoldooppoahjhfflnmljoanccekpf";
-const char kKey1[] = "foo";
-const char kKey2[] = "bar";
-const char kText1[] = "Space Needle, 12:00 pm";
-const char kText2[] = "Stevens Pass is our first choice.";
-const char kText3[] = "More rain expected in the Seattle area tonight.";
-const char kIconUrl1[] = "http://www.google.com/icon1.jpg";
-const char kIconUrl2[] = "http://www.google.com/icon2.jpg";
-const char kIconUrl3[] = "http://www.google.com/icon3.jpg";
-const char kImageUrl1[] = "http://www.google.com/image1.jpg";
-const char kImageUrl2[] = "http://www.google.com/image2.jpg";
-const char kImageUrl3[] = "http://www.google.com/image3.jpg";
-const char kDefaultDestinationTitle[] = "Open web page";
-const char kDefaultDestinationIconUrl[] = "http://www.google.com/image4.jpg";
-const char kDefaultDestinationUrl[] = "http://www.google.com";
-const char kButtonOneTitle[] = "Read";
-const char kButtonOneIconUrl[] = "http://www.google.com/image5.jpg";
-const char kButtonOneUrl[] = "http://www.google.com/do-something1";
-const char kButtonTwoTitle[] = "Reply";
-const char kButtonTwoIconUrl[] = "http://www.google.com/image6.jpg";
-const char kButtonTwoUrl[] = "http://www.google.com/do-something2";
-const char kContainedTitle1[] = "Today's Picnic moved";
-const char kContainedTitle2[] = "Group Run Today";
-const char kContainedTitle3[] = "Starcraft Tonight";
-const char kContainedMessage1[] = "Due to rain, we will be inside the cafe.";
-const char kContainedMessage2[] = "Meet at noon in the Gym.";
-const char kContainedMessage3[] = "Let's play starcraft tonight on the LAN.";
-const char kExpectedOriginUrl[] =
-    "chrome-extension://fboilmbenheemaomgaeehigklolhkhnf/";
-
-const sync_pb::CoalescedSyncedNotification_ReadState kRead =
-    sync_pb::CoalescedSyncedNotification_ReadState_READ;
-const sync_pb::CoalescedSyncedNotification_ReadState kUnread =
-    sync_pb::CoalescedSyncedNotification_ReadState_UNREAD;
-const sync_pb::CoalescedSyncedNotification_ReadState kDismissed =
-    sync_pb::CoalescedSyncedNotification_ReadState_DISMISSED;
 }  // namespace
 
 namespace notifier {
@@ -110,7 +65,8 @@
   // Removes any notifications matching the supplied ID, either currently
   // displayed or in the queue.  Returns true if anything was removed.
   virtual bool CancelById(const std::string& notification_id) OVERRIDE {
-    return false;
+    dismissed_id_ = notification_id;
+    return true;
   }
 
   virtual std::set<std::string> GetAllIdsByProfileAndSourceOrigin(
@@ -141,10 +97,14 @@
   // Test hook to get the notification so we can check it
   const Notification& notification() const { return notification_; }
 
+  // Test hook to check the ID of the last notification cancelled.
+  std::string& dismissed_id() { return dismissed_id_; }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(StubNotificationUIManager);
   Notification notification_;
   Profile* profile_;
+  std::string dismissed_id_;
 };
 
 class SyncedNotificationTest : public testing::Test {
@@ -187,246 +147,6 @@
   syncer::SyncData sync_data4_;
 
  private:
-  // Helper to create syncer::SyncData.
-  static SyncData CreateSyncData(
-      const std::string& title,
-      const std::string& text,
-      const std::string& app_icon_url,
-      const std::string& image_url,
-      const std::string& app_id,
-      const std::string& key,
-      const sync_pb::CoalescedSyncedNotification_ReadState read_state) {
-    // CreateLocalData makes a copy of this, so this can safely live
-    // on the stack.
-    EntitySpecifics entity_specifics;
-
-    // Get a writeable pointer to the sync notifications specifics inside the
-    // entity specifics.
-    SyncedNotificationSpecifics* specifics =
-        entity_specifics.mutable_synced_notification();
-
-    specifics->mutable_coalesced_notification()->
-        set_app_id(app_id);
-
-    specifics->mutable_coalesced_notification()->
-        set_key(key);
-
-    specifics->mutable_coalesced_notification()->
-        set_priority(static_cast<sync_pb::CoalescedSyncedNotification_Priority>(
-            kProtobufPriority));
-
-    // Set the title.
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_simple_expanded_layout()->
-        set_title(title);
-
-    // Set the text.
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_simple_expanded_layout()->
-        set_text(text);
-
-    // Set the heading.
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_simple_collapsed_layout()->
-        set_heading(title);
-
-    // Add the collapsed info and set the app_icon_url on it.
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        add_collapsed_info();
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(0)->
-        mutable_simple_collapsed_layout()->
-        mutable_app_icon()->
-        set_url(app_icon_url);
-
-    // Add the media object and set the image url on it.
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_simple_expanded_layout()->
-        add_media();
-    specifics->
-        mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_simple_expanded_layout()->
-        mutable_media(0)->
-        mutable_image()->
-        set_url(image_url);
-
-    specifics->mutable_coalesced_notification()->
-        set_creation_time_msec(kFakeCreationTime);
-
-    specifics->mutable_coalesced_notification()->
-        set_read_state(read_state);
-
-    // Contained notification one.
-    // We re-use the collapsed info we added for the app_icon_url,
-    // so no need to create another one here.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(0)->
-        mutable_simple_collapsed_layout()->
-        set_heading(kContainedTitle1);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(0)->
-        mutable_simple_collapsed_layout()->
-        set_description(kContainedMessage1);
-
-    // Contained notification two.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        add_collapsed_info();
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(1)->
-        mutable_simple_collapsed_layout()->
-        set_heading(kContainedTitle2);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(1)->
-        mutable_simple_collapsed_layout()->
-        set_description(kContainedMessage2);
-
-    // Contained notification three.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        add_collapsed_info();
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(2)->
-        mutable_simple_collapsed_layout()->
-        set_heading(kContainedTitle3);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_expanded_info()->
-        mutable_collapsed_info(2)->
-        mutable_simple_collapsed_layout()->
-        set_description(kContainedMessage3);
-
-    // Default Destination.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_default_destination()->
-        set_text(kDefaultDestinationTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_default_destination()->
-        mutable_icon()->
-        set_url(kDefaultDestinationIconUrl);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_default_destination()->
-        mutable_icon()->
-        set_alt_text(kDefaultDestinationTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_default_destination()->
-        set_url(kDefaultDestinationUrl);
-
-    // Buttons are represented as targets.
-
-    // Button One.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        add_target();
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(0)->
-        mutable_action()->
-        set_text(kButtonOneTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(0)->
-        mutable_action()->
-        mutable_icon()->
-        set_url(kButtonOneIconUrl);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(0)->
-        mutable_action()->
-        mutable_icon()->
-        set_alt_text(kButtonOneTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(0)->
-        mutable_action()->
-        set_url(kButtonOneUrl);
-
-    // Button Two.
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        add_target();
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(1)->
-        mutable_action()->
-        set_text(kButtonTwoTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(1)->
-        mutable_action()->
-        mutable_icon()->
-        set_url(kButtonTwoIconUrl);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(1)->
-        mutable_action()->
-        mutable_icon()->
-        set_alt_text(kButtonTwoTitle);
-    specifics->mutable_coalesced_notification()->
-        mutable_render_info()->
-        mutable_collapsed_info()->
-        mutable_target(1)->
-        mutable_action()->
-        set_url(kButtonTwoUrl);
-
-    SyncData sync_data = SyncData::CreateLocalData(
-        "syncer::SYNCED_NOTIFICATIONS",
-        "SyncedNotificationTest",
-        entity_specifics);
-
-    return sync_data;
-  }
-
- private:
   base::MessageLoopForIO message_loop_;
   content::TestBrowserThread ui_thread_;
 
@@ -480,8 +200,8 @@
 // TODO(petewil): Improve ctor to pass in an image and type so this test can
 // pass on actual data.
 TEST_F(SyncedNotificationTest, GetImageURLTest) {
-  std::string found_image_url = notification1_->GetImageUrl().spec();
-  std::string expected_image_url = kImageUrl1;
+  GURL found_image_url = notification1_->GetImageUrl();
+  GURL expected_image_url = GURL(kImageUrl1);
 
   EXPECT_EQ(expected_image_url, found_image_url);
 }
@@ -517,29 +237,29 @@
 TEST_F(SyncedNotificationTest, GetDefaultDestinationDataTest) {
     std::string default_destination_title =
         notification1_->GetDefaultDestinationTitle();
-    std::string default_destination_icon_url =
+    GURL default_destination_icon_url =
         notification1_->GetDefaultDestinationIconUrl();
-    std::string default_destination_url =
+    GURL default_destination_url =
         notification1_->GetDefaultDestinationUrl();
     EXPECT_EQ(std::string(kDefaultDestinationTitle), default_destination_title);
-    EXPECT_EQ(std::string(kDefaultDestinationIconUrl),
+    EXPECT_EQ(GURL(kDefaultDestinationIconUrl),
               default_destination_icon_url);
-    EXPECT_EQ(std::string(kDefaultDestinationUrl), default_destination_url);
+    EXPECT_EQ(GURL(kDefaultDestinationUrl), default_destination_url);
 }
 
 TEST_F(SyncedNotificationTest, GetButtonDataTest) {
-    std::string button_one_title = notification1_->GetButtonOneTitle();
-    std::string button_one_icon_url = notification1_->GetButtonOneIconUrl();
-    std::string button_one_url = notification1_->GetButtonOneUrl();
-    std::string button_two_title = notification1_->GetButtonTwoTitle();
-    std::string button_two_icon_url = notification1_->GetButtonTwoIconUrl();
-    std::string button_two_url = notification1_->GetButtonTwoUrl();
+    std::string button_one_title = notification1_->GetButtonTitle(0);
+    GURL button_one_icon_url = notification1_->GetButtonIconUrl(0);
+    GURL button_one_url = notification1_->GetButtonUrl(0);
+    std::string button_two_title = notification1_->GetButtonTitle(1);
+    GURL button_two_icon_url = notification1_->GetButtonIconUrl(1);
+    GURL button_two_url = notification1_->GetButtonUrl(1);
     EXPECT_EQ(std::string(kButtonOneTitle), button_one_title);
-    EXPECT_EQ(std::string(kButtonOneIconUrl), button_one_icon_url);
-    EXPECT_EQ(std::string(kButtonOneUrl), button_one_url);
+    EXPECT_EQ(GURL(kButtonOneIconUrl), button_one_icon_url);
+    EXPECT_EQ(GURL(kButtonOneUrl), button_one_url);
     EXPECT_EQ(std::string(kButtonTwoTitle), button_two_title);
-    EXPECT_EQ(std::string(kButtonTwoIconUrl), button_two_icon_url);
-    EXPECT_EQ(std::string(kButtonTwoUrl), button_two_url);
+    EXPECT_EQ(GURL(kButtonTwoIconUrl), button_two_icon_url);
+    EXPECT_EQ(GURL(kButtonTwoUrl), button_two_url);
 }
 
 TEST_F(SyncedNotificationTest, ContainedNotificationTest) {
@@ -598,17 +318,14 @@
 
   // Check the base fields of the notification.
   EXPECT_EQ(message_center::NOTIFICATION_TYPE_IMAGE, notification.type());
-  EXPECT_EQ(kTitle1, UTF16ToUTF8(notification.title()));
-  EXPECT_EQ(kText1, UTF16ToUTF8(notification.message()));
-  EXPECT_EQ(kExpectedOriginUrl, notification.origin_url().spec());
-  EXPECT_EQ(kKey1, UTF16ToUTF8(notification.replace_id()));
+  EXPECT_EQ(std::string(kTitle1), UTF16ToUTF8(notification.title()));
+  EXPECT_EQ(std::string(kText1), UTF16ToUTF8(notification.message()));
+  EXPECT_EQ(std::string(kExpectedOriginUrl), notification.origin_url().spec());
+  EXPECT_EQ(std::string(kKey1), UTF16ToUTF8(notification.replace_id()));
 
   EXPECT_EQ(kFakeCreationTime, notification.timestamp().ToDoubleT());
   EXPECT_EQ(kNotificationPriority, notification.priority());
 
-  EXPECT_EQ(UTF8ToUTF16(kButtonOneTitle), notification.buttons()[0].title);
-  EXPECT_EQ(UTF8ToUTF16(kButtonTwoTitle), notification.buttons()[1].title);
-
   EXPECT_EQ(UTF8ToUTF16(kContainedTitle1), notification.items()[0].title);
   EXPECT_EQ(UTF8ToUTF16(kContainedTitle2), notification.items()[1].title);
   EXPECT_EQ(UTF8ToUTF16(kContainedTitle3), notification.items()[2].title);
@@ -618,6 +335,19 @@
   EXPECT_EQ(UTF8ToUTF16(kContainedMessage3), notification.items()[2].message);
 }
 
+TEST_F(SyncedNotificationTest, DismissTest) {
+
+  if (!UseRichNotifications())
+    return;
+
+  StubNotificationUIManager notification_manager;
+
+  // Call the method under test using a dismissed notification.
+  notification4_->Show(&notification_manager, NULL, NULL);
+
+  EXPECT_EQ(std::string(kKey1), notification_manager.dismissed_id());
+}
+
 TEST_F(SyncedNotificationTest, AddBitmapToFetchQueueTest) {
   scoped_ptr<SyncedNotification> notification6;
   notification6.reset(new SyncedNotification(sync_data1_));
@@ -666,9 +396,9 @@
   // Since we check Show() thoroughly in its own test, we only check cursorily.
   EXPECT_EQ(message_center::NOTIFICATION_TYPE_IMAGE,
             notification_manager.notification().type());
-  EXPECT_EQ(kTitle1,
+  EXPECT_EQ(std::string(kTitle1),
             UTF16ToUTF8(notification_manager.notification().title()));
-  EXPECT_EQ(kText1,
+  EXPECT_EQ(std::string(kText1),
             UTF16ToUTF8(notification_manager.notification().message()));
 
   // TODO(petewil): Check that the bitmap in the notification is what we expect.
diff --git a/chrome/browser/omnibox/omnibox_field_trial.cc b/chrome/browser/omnibox/omnibox_field_trial.cc
index da16943..0fbf10d 100644
--- a/chrome/browser/omnibox/omnibox_field_trial.cc
+++ b/chrome/browser/omnibox/omnibox_field_trial.cc
@@ -17,12 +17,12 @@
 namespace {
 
 // Field trial names.
-const char kDisallowInlineHQPFieldTrialName[] = "OmniboxDisallowInlineHQP";
 const char kHUPCullRedirectsFieldTrialName[] = "OmniboxHUPCullRedirects";
 const char kHUPCreateShorterMatchFieldTrialName[] =
     "OmniboxHUPCreateShorterMatch";
 const char kStopTimerFieldTrialName[] = "OmniboxStopTimer";
 const char kShortcutsScoringFieldTrialName[] = "OmniboxShortcutsScoring";
+const char kSearchHistoryFieldTrialName[] = "OmniboxSearchHistory";
 
 // The autocomplete dynamic field trial name prefix.  Each field trial is
 // configured dynamically and is retrieved automatically by Chrome during
@@ -33,12 +33,6 @@
 
 // Field trial experiment probabilities.
 
-// For inline History Quick Provider field trial, put 0% ( = 0/100 )
-// of the users in the disallow-inline experiment group.
-const base::FieldTrial::Probability kDisallowInlineHQPFieldTrialDivisor = 100;
-const base::FieldTrial::Probability
-    kDisallowInlineHQPFieldTrialExperimentFraction = 0;
-
 // For HistoryURL provider cull redirects field trial, put 0% ( = 0/100 )
 // of the users in the don't-cull-redirects experiment group.
 // TODO(mpearson): Remove this field trial and the code it uses once I'm
@@ -69,10 +63,6 @@
 // ActivateStaticTrials() method.
 bool static_field_trials_initialized = false;
 
-// Field trial ID for the disallow-inline History Quick Provider
-// experiment group.
-int disallow_inline_hqp_experiment_group = 0;
-
 // Field trial ID for the HistoryURL provider cull redirects experiment group.
 int hup_dont_cull_redirects_experiment_group = 0;
 
@@ -93,28 +83,12 @@
 void OmniboxFieldTrial::ActivateStaticTrials() {
   DCHECK(!static_field_trials_initialized);
 
-  // Create inline History Quick Provider field trial.
-  // Make it expire on November 8, 2012.
-  scoped_refptr<base::FieldTrial> trial(
-      base::FieldTrialList::FactoryGetFieldTrial(
-      kDisallowInlineHQPFieldTrialName, kDisallowInlineHQPFieldTrialDivisor,
-      "Standard", 2012, 11, 8, NULL));
-  // Because users tend to use omnibox without attention to it--habits
-  // get ingrained, users tend to learn that a particular suggestion is
-  // at a particular spot in the drop-down--we're going to make these
-  // field trials sticky.  We want users to stay in them once assigned
-  // so they have a better experience and also so we don't get weird
-  // effects as omnibox ranking keeps changing and users learn they can't
-  // trust the omnibox.
-  trial->UseOneTimeRandomization();
-  disallow_inline_hqp_experiment_group = trial->AppendGroup("DisallowInline",
-      kDisallowInlineHQPFieldTrialExperimentFraction);
-
   // Create the HistoryURL provider cull redirects field trial.
   // Make it expire on March 1, 2013.
-  trial = base::FieldTrialList::FactoryGetFieldTrial(
+  scoped_refptr<base::FieldTrial> trial(
+      base::FieldTrialList::FactoryGetFieldTrial(
       kHUPCullRedirectsFieldTrialName, kHUPCullRedirectsFieldTrialDivisor,
-      "Standard", 2013, 3, 1, NULL);
+      "Standard", 2013, 3, 1, NULL));
   trial->UseOneTimeRandomization();
   hup_dont_cull_redirects_experiment_group =
       trial->AppendGroup("DontCullRedirects",
@@ -168,20 +142,6 @@
   return provider_types;
 }
 
-bool OmniboxFieldTrial::InDisallowInlineHQPFieldTrial() {
-  return base::FieldTrialList::TrialExists(kDisallowInlineHQPFieldTrialName);
-}
-
-bool OmniboxFieldTrial::InDisallowInlineHQPFieldTrialExperimentGroup() {
-  if (!base::FieldTrialList::TrialExists(kDisallowInlineHQPFieldTrialName))
-    return false;
-
-  // Return true if we're in the experiment group.
-  const int group = base::FieldTrialList::FindValue(
-      kDisallowInlineHQPFieldTrialName);
-  return group == disallow_inline_hqp_experiment_group;
-}
-
 void OmniboxFieldTrial::GetActiveSuggestFieldTrialHashes(
     std::vector<uint32>* field_trial_hashes) {
   field_trial_hashes->clear();
@@ -258,3 +218,13 @@
   }
   return true;
 }
+
+bool OmniboxFieldTrial::SearchHistoryPreventInlining() {
+  return (base::FieldTrialList::FindFullName(kSearchHistoryFieldTrialName) ==
+          "PreventInlining");
+}
+
+bool OmniboxFieldTrial::SearchHistoryDisable() {
+  return (base::FieldTrialList::FindFullName(kSearchHistoryFieldTrialName) ==
+          "Disable");
+}
diff --git a/chrome/browser/omnibox/omnibox_field_trial.h b/chrome/browser/omnibox/omnibox_field_trial.h
index ab5babc..d555a9f 100644
--- a/chrome/browser/omnibox/omnibox_field_trial.h
+++ b/chrome/browser/omnibox/omnibox_field_trial.h
@@ -34,19 +34,6 @@
   static int GetDisabledProviderTypes();
 
   // ---------------------------------------------------------
-  // For the inline History Quick Provider field trial.
-
-  // Returns whether the user is in any field trial group for this
-  // field trial.  False indicates that the field trial wasn't
-  // successfully created for some reason.
-  static bool InDisallowInlineHQPFieldTrial();
-
-  // Returns whether the user should get the experiment setup or
-  // the default setup for this field trial.  The experiment
-  // group prohibits inlining suggestions.
-  static bool InDisallowInlineHQPFieldTrialExperimentGroup();
-
-  // ---------------------------------------------------------
   // For the suggest field trial.
 
   // Populates |field_trial_hash| with hashes of the active suggest field trial
@@ -113,6 +100,18 @@
   // inlined.)
   static bool ShortcutsScoringMaxRelevance(int* max_relevance);
 
+  // ---------------------------------------------------------
+  // For the SearchHistory field trial.
+
+  // Returns true if the user is in the experiment group that scores
+  // search history query suggestions less aggressively so that they don't
+  // inline.
+  static bool SearchHistoryPreventInlining();
+
+  // Returns true if the user is in the experiment group that disables
+  // all query suggestions from search history.
+  static bool SearchHistoryDisable();
+
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(OmniboxFieldTrial);
 };
diff --git a/chrome/browser/page_cycler/page_cycler.cc b/chrome/browser/page_cycler/page_cycler.cc
index 0d10e08..1f1c47e 100644
--- a/chrome/browser/page_cycler/page_cycler.cc
+++ b/chrome/browser/page_cycler/page_cycler.cc
@@ -13,11 +13,11 @@
 #include "base/strings/string_split.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/chrome_process_util.h"
 #include "chrome/test/perf/perf_test.h"
 #include "content/public/browser/browser_thread.h"
@@ -92,7 +92,7 @@
   std::string file_contents;
   std::vector<std::string> url_strings;
 
-  CHECK(file_util::PathExists(urls_file_)) << urls_file_.value();
+  CHECK(base::PathExists(urls_file_)) << urls_file_.value();
   file_util::ReadFileToString(urls_file_, &file_contents);
   base::SplitStringAlongWhitespace(file_contents, &url_strings);
 
@@ -209,7 +209,7 @@
 
   if (!output.empty()) {
     CHECK(!stats_file_.empty());
-    if (file_util::PathExists(stats_file_)) {
+    if (base::PathExists(stats_file_)) {
       VLOG(1) << "PageCycler: Previous stats file found; appending.";
       file_util::AppendToFile(stats_file_, output.c_str(), output.size());
     } else {
@@ -220,9 +220,9 @@
     if (!error_.empty()) {
       file_util::WriteFile(errors_file_, UTF16ToUTF8(error_).c_str(),
                            error_.size());
-    } else if (file_util::PathExists(errors_file_)) {
+    } else if (base::PathExists(errors_file_)) {
       // If there is an old error file, delete it to avoid confusion.
-      base::Delete(errors_file_, false);
+      base::DeleteFile(errors_file_, false);
     }
   }
   if (aborted_) {
diff --git a/chrome/browser/page_cycler/page_cycler_browsertest.cc b/chrome/browser/page_cycler/page_cycler_browsertest.cc
index c4d8650..b2cbe0e 100644
--- a/chrome/browser/page_cycler/page_cycler_browsertest.cc
+++ b/chrome/browser/page_cycler/page_cycler_browsertest.cc
@@ -9,12 +9,12 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/threading/sequenced_worker_pool.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/page_cycler/page_cycler.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser_list.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -51,9 +51,9 @@
     errors_file_ = temp_path.AppendASCII("errors");
     stats_file_ = temp_path.AppendASCII("stats");
 
-    ASSERT_FALSE(file_util::PathExists(urls_file_));
-    ASSERT_FALSE(file_util::PathExists(errors_file_));
-    ASSERT_FALSE(file_util::PathExists(stats_file_));
+    ASSERT_FALSE(base::PathExists(urls_file_));
+    ASSERT_FALSE(base::PathExists(errors_file_));
+    ASSERT_FALSE(base::PathExists(stats_file_));
   }
 
   // Initialize a PageCycler using either the base fields, or using provided
@@ -152,18 +152,17 @@
     test_dir = test_dir.AppendASCII("page_cycler");
 
     base::FilePath source_data_dir = test_dir.AppendASCII("cached_data_dir");
-    CHECK(file_util::PathExists(source_data_dir));
+    CHECK(base::PathExists(source_data_dir));
 
     CHECK(user_data_dir_.CreateUniqueTempDir());
 
     base::FilePath dest_data_dir =
         user_data_dir_.path().AppendASCII("cached_data_dir");
-    CHECK(!file_util::PathExists(dest_data_dir));
+    CHECK(!base::PathExists(dest_data_dir));
 
-    CHECK(file_util::CopyDirectory(source_data_dir,
-                                   user_data_dir_.path(),
-                                   true));  // recursive.
-    CHECK(file_util::PathExists(dest_data_dir));
+    CHECK(base::CopyDirectory(source_data_dir, user_data_dir_.path(),
+                              true));  // recursive.
+    CHECK(base::PathExists(dest_data_dir));
 
     command_line->AppendSwitchPath(switches::kUserDataDir,
                                    dest_data_dir);
@@ -178,9 +177,9 @@
     errors_file_ = temp_path.AppendASCII("errors");
     stats_file_ = temp_path.AppendASCII("stats");
 
-    ASSERT_TRUE(file_util::PathExists(urls_file_));
-    ASSERT_FALSE(file_util::PathExists(errors_file_));
-    ASSERT_FALSE(file_util::PathExists(stats_file_));
+    ASSERT_TRUE(base::PathExists(urls_file_));
+    ASSERT_FALSE(base::PathExists(errors_file_));
+    ASSERT_FALSE(base::PathExists(stats_file_));
   }
 
  private:
@@ -208,8 +207,8 @@
   page_cycler()->Run();
 
   content::RunMessageLoop();
-  ASSERT_FALSE(file_util::PathExists(errors_file()));
-  ASSERT_TRUE(file_util::PathExists(stats_file()));
+  ASSERT_FALSE(base::PathExists(errors_file()));
+  ASSERT_TRUE(base::PathExists(stats_file()));
 }
 
 // Test to make sure that PageCycler will recognize unvisitable URLs, and will
@@ -237,8 +236,8 @@
   page_cycler()->Run();
 
   content::RunMessageLoop();
-  ASSERT_TRUE(file_util::PathExists(errors_file()));
-  ASSERT_TRUE(file_util::PathExists(stats_file()));
+  ASSERT_TRUE(base::PathExists(errors_file()));
+  ASSERT_TRUE(base::PathExists(stats_file()));
 
   std::vector<std::string> errors = GetErrorsFromFile();
 
@@ -271,8 +270,8 @@
   page_cycler()->Run();
 
   content::RunMessageLoop();
-  ASSERT_TRUE(file_util::PathExists(errors_file()));
-  ASSERT_TRUE(file_util::PathExists(stats_file()));
+  ASSERT_TRUE(base::PathExists(errors_file()));
+  ASSERT_TRUE(base::PathExists(stats_file()));
 
   std::vector<std::string> errors = GetErrorsFromFile();
   ASSERT_EQ(1u, errors.size());
@@ -304,8 +303,8 @@
   page_cycler()->Run();
 
   content::RunMessageLoop();
-  ASSERT_TRUE(file_util::PathExists(errors_file()));
-  ASSERT_TRUE(file_util::PathExists(stats_file()));
+  ASSERT_TRUE(base::PathExists(errors_file()));
+  ASSERT_TRUE(base::PathExists(stats_file()));
 
   std::vector<std::string> errors = GetErrorsFromFile();
   ASSERT_EQ(1u, errors.size());
@@ -344,8 +343,8 @@
   page_cycler()->Run();
 
   content::RunMessageLoop();
-  ASSERT_TRUE(file_util::PathExists(stats_file()));
-  ASSERT_FALSE(file_util::PathExists(errors_file()));
+  ASSERT_TRUE(base::PathExists(stats_file()));
+  ASSERT_FALSE(base::PathExists(errors_file()));
 }
 #endif  // !defined(OS_CHROMEOS)
 
@@ -375,7 +374,7 @@
   // other URLs.
 
   base::FilePath new_urls_file = temp.path().AppendASCII("urls");
-  ASSERT_FALSE(file_util::PathExists(new_urls_file));
+  ASSERT_FALSE(base::PathExists(new_urls_file));
 
   ASSERT_TRUE(file_util::WriteFile(new_urls_file, kCacheMissURL,
                                    sizeof(kCacheMissURL)));
@@ -384,8 +383,8 @@
   page_cycler()->Run();
 
   content::RunMessageLoop();
-  ASSERT_TRUE(file_util::PathExists(errors_file()));
-  ASSERT_TRUE(file_util::PathExists(stats_file()));
+  ASSERT_TRUE(base::PathExists(errors_file()));
+  ASSERT_TRUE(base::PathExists(stats_file()));
 
   std::vector<std::string> errors = GetErrorsFromFile();
   ASSERT_EQ(1u, errors.size());
diff --git a/chrome/browser/page_cycler/page_cycler_unittest.cc b/chrome/browser/page_cycler/page_cycler_unittest.cc
index 0f0e3ac..cbfc07e 100644
--- a/chrome/browser/page_cycler/page_cycler_unittest.cc
+++ b/chrome/browser/page_cycler/page_cycler_unittest.cc
@@ -29,8 +29,8 @@
 using content::RenderViewHost;
 using content::TestBrowserThread;
 using content::WebContentsObserver;
-using file_util::ContentsEqual;
-using file_util::PathExists;
+using base::ContentsEqual;
+using base::PathExists;
 
 namespace {
 const int kFrameID = 1;
@@ -65,7 +65,7 @@
                                             int error_code,
                                             const string16& error_description,
                                             RenderViewHost* render_view_host));
-  MOCK_METHOD1(RenderViewGone, void(base::TerminationStatus status));
+  MOCK_METHOD1(RenderProcessGone, void(base::TerminationStatus status));
 
   void PageCyclerDidFailProvisionalLoad(
       int64 frame_id,
@@ -122,8 +122,8 @@
     errors_file_ = temp_path.AppendASCII("errors_file");
     stats_file_ = temp_path.AppendASCII("stats_file");
 
-    CHECK(!file_util::PathExists(errors_file_));
-    CHECK(!file_util::PathExists(stats_file_));
+    CHECK(!base::PathExists(errors_file_));
+    CHECK(!base::PathExists(stats_file_));
   }
 
   void FailProvisionalLoad(int error_code, string16& error_description) {
diff --git a/chrome/browser/password_manager/login_database_unittest.cc b/chrome/browser/password_manager/login_database_unittest.cc
index 3338058..a0383da 100644
--- a/chrome/browser/password_manager/login_database_unittest.cc
+++ b/chrome/browser/password_manager/login_database_unittest.cc
@@ -40,9 +40,9 @@
     db_.public_suffix_domain_matching_ = enabled;
   }
 
-  LoginDatabase db_;
-  base::FilePath file_;
   base::ScopedTempDir temp_dir_;
+  base::FilePath file_;
+  LoginDatabase db_;
 };
 
 TEST_F(LoginDatabaseTest, Logins) {
diff --git a/chrome/browser/password_manager/password_generation_manager.cc b/chrome/browser/password_manager/password_generation_manager.cc
index 4c8051b..e53f61a 100644
--- a/chrome/browser/password_manager/password_generation_manager.cc
+++ b/chrome/browser/password_manager/password_generation_manager.cc
@@ -47,7 +47,7 @@
 }
 
 // static
-void PasswordGenerationManager::RegisterUserPrefs(
+void PasswordGenerationManager::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kPasswordGenerationEnabled,
diff --git a/chrome/browser/password_manager/password_generation_manager.h b/chrome/browser/password_manager/password_generation_manager.h
index 756a816..b699c2e 100644
--- a/chrome/browser/password_manager/password_generation_manager.h
+++ b/chrome/browser/password_manager/password_generation_manager.h
@@ -46,7 +46,7 @@
       public content::WebContentsUserData<PasswordGenerationManager> {
  public:
   static void CreateForWebContents(content::WebContents* contents);
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
   virtual ~PasswordGenerationManager();
 
  protected:
diff --git a/chrome/browser/password_manager/password_generation_manager_unittest.cc b/chrome/browser/password_manager/password_generation_manager_unittest.cc
index e9fce01..ac691d9 100644
--- a/chrome/browser/password_manager/password_generation_manager_unittest.cc
+++ b/chrome/browser/password_manager/password_generation_manager_unittest.cc
@@ -44,9 +44,6 @@
 class PasswordGenerationManagerTest : public ChromeRenderViewHostTestHarness {
  protected:
   virtual void SetUp() OVERRIDE {
-    TestingProfile* profile = CreateProfile();
-    profile->CreateRequestContext();
-    browser_context_.reset(profile);
 
     SetThreadBundleOptions(content::TestBrowserThreadBundle::REAL_IO_THREAD);
     ChromeRenderViewHostTestHarness::SetUp();
@@ -59,8 +56,10 @@
     ChromeRenderViewHostTestHarness::TearDown();
   }
 
-  virtual TestingProfile* CreateProfile() {
-    return new TestingProfile();
+  virtual content::BrowserContext* CreateBrowserContext() OVERRIDE {
+    TestingProfile* profile = new TestingProfile();
+    profile->CreateRequestContext();
+    return profile;
   }
 
   void UpdateState(bool new_renderer) {
@@ -73,11 +72,12 @@
 class IncognitoPasswordGenerationManagerTest :
     public PasswordGenerationManagerTest {
  public:
-  virtual TestingProfile* CreateProfile() OVERRIDE {
+  virtual content::BrowserContext* CreateBrowserContext() OVERRIDE {
     // Create an incognito profile.
     TestingProfile::Builder builder;
     scoped_ptr<TestingProfile> profile = builder.Build();
     profile->set_incognito(true);
+    profile->CreateRequestContext();
     return profile.release();
   }
 };
diff --git a/chrome/browser/password_manager/password_manager.cc b/chrome/browser/password_manager/password_manager.cc
index 2affc0b..15bfb8c 100644
--- a/chrome/browser/password_manager/password_manager.cc
+++ b/chrome/browser/password_manager/password_manager.cc
@@ -63,7 +63,7 @@
 }  // namespace
 
 // static
-void PasswordManager::RegisterUserPrefs(
+void PasswordManager::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kPasswordManagerEnabled,
diff --git a/chrome/browser/password_manager/password_manager.h b/chrome/browser/password_manager/password_manager.h
index f2a84e4..a0dbd7c 100644
--- a/chrome/browser/password_manager/password_manager.h
+++ b/chrome/browser/password_manager/password_manager.h
@@ -35,7 +35,7 @@
                         public content::WebContentsObserver,
                         public content::WebContentsUserData<PasswordManager> {
  public:
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   static void CreateForWebContentsAndDelegate(
       content::WebContents* contents,
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index 2f4f602..d53db5e 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -4,13 +4,13 @@
 
 #include <string>
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/password_manager/test_password_store.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_observer.h"
diff --git a/chrome/browser/password_manager/password_manager_delegate_impl.cc b/chrome/browser/password_manager/password_manager_delegate_impl.cc
index 1df2755..edf7a23 100644
--- a/chrome/browser/password_manager/password_manager_delegate_impl.cc
+++ b/chrome/browser/password_manager/password_manager_delegate_impl.cc
@@ -81,19 +81,16 @@
                                          PasswordFormManager* form_to_save) {
 #if defined(ENABLE_ONE_CLICK_SIGNIN)
   // Don't show the password manager infobar if this form is for a google
-  // account and we are going to show the one-click singin infobar.
-  // For now, one-click signin is fully implemented only on windows.
+  // account and we are going to show the one-click signin infobar.
   GURL realm(form_to_save->realm());
   // TODO(mathp): Checking only against associated_username() causes a bug
   // referenced here: crbug.com/133275
-  if ((realm == GURL(GaiaUrls::GetInstance()->gaia_login_form_realm()) ||
-       realm == GURL("https://www.google.com/")) &&
+  if (((realm == GURL(GaiaUrls::GetInstance()->gaia_login_form_realm())) ||
+       (realm == GURL("https://www.google.com/"))) &&
       OneClickSigninHelper::CanOffer(
-          web_contents,
-          OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
-          UTF16ToUTF8(form_to_save->associated_username()), NULL)) {
+          web_contents, OneClickSigninHelper::CAN_OFFER_FOR_INTERSTITAL_ONLY,
+          UTF16ToUTF8(form_to_save->associated_username()), NULL))
     return;
-  }
 #endif
 
   InfoBarService* infobar_service =
diff --git a/chrome/browser/password_manager/password_manager_unittest.cc b/chrome/browser/password_manager/password_manager_unittest.cc
index 7cc4438..a724de4 100644
--- a/chrome/browser/password_manager/password_manager_unittest.cc
+++ b/chrome/browser/password_manager/password_manager_unittest.cc
@@ -49,12 +49,10 @@
 class PasswordManagerTest : public ChromeRenderViewHostTestHarness {
  protected:
   virtual void SetUp() {
-    testing_profile_ = new TestingProfile;
+    ChromeRenderViewHostTestHarness::SetUp();
     store_ = static_cast<MockPasswordStore*>(
         PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse(
-            testing_profile_, MockPasswordStore::Build).get());
-    browser_context_.reset(testing_profile_);
-    ChromeRenderViewHostTestHarness::SetUp();
+            profile(), MockPasswordStore::Build).get());
 
     EXPECT_CALL(delegate_, GetProfile()).WillRepeatedly(Return(profile()));
     PasswordManager::CreateForWebContentsAndDelegate(
@@ -89,8 +87,6 @@
 
   scoped_refptr<MockPasswordStore> store_;
   MockPasswordManagerDelegate delegate_;  // Owned by manager_.
-
-  TestingProfile* testing_profile_;
 };
 
 MATCHER_P(FormMatches, form, "") {
@@ -394,8 +390,7 @@
 TEST_F(PasswordManagerTest, SavingDependsOnManagerEnabledPreference) {
   // Test that saving passwords depends on the password manager enabled
   // preference.
-  TestingPrefServiceSyncable* prefService =
-      testing_profile_->GetTestingPrefService();
+  TestingPrefServiceSyncable* prefService = profile()->GetTestingPrefService();
   prefService->SetUserPref(prefs::kPasswordManagerEnabled,
                            Value::CreateBooleanValue(true));
   EXPECT_TRUE(manager()->IsSavingEnabled());
@@ -410,8 +405,7 @@
   std::vector<PasswordForm*> result;
   PasswordForm* existing = new PasswordForm(MakeSimpleForm());
   result.push_back(existing);
-  TestingPrefServiceSyncable* prefService =
-      testing_profile_->GetTestingPrefService();
+  TestingPrefServiceSyncable* prefService = profile()->GetTestingPrefService();
   prefService->SetUserPref(prefs::kPasswordManagerEnabled,
                            Value::CreateBooleanValue(false));
   EXPECT_CALL(delegate_, FillPasswordForm(_));
diff --git a/chrome/browser/password_manager/password_store_default.cc b/chrome/browser/password_manager/password_store_default.cc
index 8ae53fb..c5be4c9 100644
--- a/chrome/browser/password_manager/password_store_default.cc
+++ b/chrome/browser/password_manager/password_store_default.cc
@@ -9,10 +9,10 @@
 #include "base/logging.h"
 #include "base/prefs/pref_service.h"
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/password_manager/password_store_change.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/password_manager/password_store_default_unittest.cc b/chrome/browser/password_manager/password_store_default_unittest.cc
index a949061..594d23f 100644
--- a/chrome/browser/password_manager/password_store_default_unittest.cc
+++ b/chrome/browser/password_manager/password_store_default_unittest.cc
@@ -11,11 +11,11 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/password_manager/password_form_data.h"
 #include "chrome/browser/password_manager/password_store_change.h"
 #include "chrome/browser/password_manager/password_store_consumer.h"
 #include "chrome/browser/password_manager/password_store_default.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/password_manager/password_store_factory.cc b/chrome/browser/password_manager/password_store_factory.cc
index b0f48c8..a838886 100644
--- a/chrome/browser/password_manager/password_store_factory.cc
+++ b/chrome/browser/password_manager/password_store_factory.cc
@@ -195,7 +195,7 @@
   return ps;
 }
 
-void PasswordStoreFactory::RegisterUserPrefs(
+void PasswordStoreFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
 #if !defined(OS_CHROMEOS) && defined(USE_X11)
   registry->RegisterIntegerPref(
@@ -205,7 +205,7 @@
 
   // Notice that the preprocessor conditions above are exactly those that will
   // result in using PasswordStoreX in CreatePasswordStore() below.
-  PasswordStoreX::RegisterUserPrefs(registry);
+  PasswordStoreX::RegisterProfilePrefs(registry);
 #endif
 }
 
diff --git a/chrome/browser/password_manager/password_store_factory.h b/chrome/browser/password_manager/password_store_factory.h
index 2207df1..4349038 100644
--- a/chrome/browser/password_manager/password_store_factory.h
+++ b/chrome/browser/password_manager/password_store_factory.h
@@ -45,7 +45,7 @@
   // BrowserContextKeyedServiceFactory:
   virtual scoped_refptr<RefcountedBrowserContextKeyedService>
       BuildServiceInstanceFor(content::BrowserContext* context) const OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const OVERRIDE;
diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc
index ec7452b..b441746 100644
--- a/chrome/browser/password_manager/password_store_mac.cc
+++ b/chrome/browser/password_manager/password_store_mac.cc
@@ -18,9 +18,9 @@
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/password_manager/login_database.h"
 #include "chrome/browser/password_manager/password_store_change.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "crypto/apple_keychain.h"
 
diff --git a/chrome/browser/password_manager/password_store_unittest.cc b/chrome/browser/password_manager/password_store_unittest.cc
index 458d222..0c179b6 100644
--- a/chrome/browser/password_manager/password_store_unittest.cc
+++ b/chrome/browser/password_manager/password_store_unittest.cc
@@ -8,10 +8,10 @@
 #include "base/strings/string_util.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/password_manager/password_form_data.h"
 #include "chrome/browser/password_manager/password_store_consumer.h"
 #include "chrome/browser/password_manager/password_store_default.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_registrar.h"
diff --git a/chrome/browser/password_manager/password_store_x.cc b/chrome/browser/password_manager/password_store_x.cc
index 20823f5..cc6b6cf 100644
--- a/chrome/browser/password_manager/password_store_x.cc
+++ b/chrome/browser/password_manager/password_store_x.cc
@@ -12,8 +12,8 @@
 #include "base/logging.h"
 #include "base/prefs/pref_service.h"
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/password_manager/password_store_change.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/browser_thread.h"
@@ -271,7 +271,7 @@
 
 #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) && defined(OS_POSIX)
 // static
-void PasswordStoreX::RegisterUserPrefs(
+void PasswordStoreX::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   // Normally we should be on the UI thread here, but in tests we might not.
   registry->RegisterBooleanPref(
diff --git a/chrome/browser/password_manager/password_store_x.h b/chrome/browser/password_manager/password_store_x.h
index 05e0351..f4e3bfd 100644
--- a/chrome/browser/password_manager/password_store_x.h
+++ b/chrome/browser/password_manager/password_store_x.h
@@ -60,7 +60,7 @@
 
 #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) && defined(OS_POSIX)
   // Registers the pref setting used for the methods below.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Returns true if passwords have been tagged with the local profile id.
   static bool PasswordsUseLocalProfileId(PrefService* prefs);
diff --git a/chrome/browser/password_manager/password_store_x_unittest.cc b/chrome/browser/password_manager/password_store_x_unittest.cc
index 8b5cb44..ed6e8fe 100644
--- a/chrome/browser/password_manager/password_store_x_unittest.cc
+++ b/chrome/browser/password_manager/password_store_x_unittest.cc
@@ -15,11 +15,11 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/password_manager/password_form_data.h"
 #include "chrome/browser/password_manager/password_store_change.h"
 #include "chrome/browser/password_manager/password_store_consumer.h"
 #include "chrome/browser/password_manager/password_store_x.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/pepper_broker_infobar_delegate.cc b/chrome/browser/pepper_broker_infobar_delegate.cc
index f638a5b..66624ec 100644
--- a/chrome/browser/pepper_broker_infobar_delegate.cc
+++ b/chrome/browser/pepper_broker_infobar_delegate.cc
@@ -27,17 +27,10 @@
 #include "base/android/context_types.h"
 #endif
 
-// The URL for the "learn more" article about the PPAPI broker.
-const char kPpapiBrokerLearnMoreUrl[] =
-    "https://support.google.com/chrome/?p=ib_pepper_broker";
-
-using content::OpenURLParams;
-using content::Referrer;
-using content::WebContents;
 
 // static
 void PepperBrokerInfoBarDelegate::Create(
-    WebContents* web_contents,
+    content::WebContents* web_contents,
     const GURL& url,
     const base::FilePath& plugin_path,
     const base::Callback<void(bool)>& callback) {
@@ -53,8 +46,8 @@
       TabSpecificContentSettings::FromWebContents(web_contents);
 
 #if defined(OS_CHROMEOS)
-  // On ChromeOS, we're ok with granting broker access to Netflix and Widevine
-  // plugin, since it can only come installed with the OS.
+  // On ChromeOS, we're ok with granting broker access to the Netflix and
+  // Widevine plugins, since they can only come installed with the OS.
   const char kNetflixPluginFileName[] = "libnetflixplugin2.so";
   const char kWidevinePluginFileName[] = "libwidevinecdmadapter.so";
   base::FilePath plugin_file_name = plugin_path.BaseName();
@@ -67,18 +60,20 @@
 #endif
 
 #if defined(GOOGLE_TV)
-  // On GoogleTV, Netflix crypto plugin and DRM server adapter plugin can only
-  // come pre-installed with the OS, so we're willing to auto-grant access
+  // On GoogleTV, Netflix crypto/mdx plugin and DRM server adapter plugin can
+  // only come pre-installed with the OS, so we're willing to auto-grant access
   // to them. PluginRootName should be matched with PEPPER_PLUGIN_ROOT
   // in PepperPluginManager.java.
   const char kPluginRootName[] = "/system/lib/pepperplugin";
   const char kNetflixCryptoPluginFileName[] = "libnrddpicrypto.so";
+  const char kNetflixMdxPluginFileName[] = "libnrdmdx.so";
   const char kDrmServerAdapterPluginFileName[] = "libdrmserveradapter.so";
   base::FilePath::StringType plugin_dir_name = plugin_path.DirName().value();
   base::FilePath::StringType plugin_file_name = plugin_path.BaseName().value();
   if (base::android::IsRunningInWebapp() &&
       plugin_dir_name == FILE_PATH_LITERAL(kPluginRootName) &&
       (plugin_file_name == FILE_PATH_LITERAL(kNetflixCryptoPluginFileName) ||
+       plugin_file_name == FILE_PATH_LITERAL(kNetflixMdxPluginFileName) ||
        plugin_file_name ==
           FILE_PATH_LITERAL(kDrmServerAdapterPluginFileName))) {
     tab_content_settings->SetPepperBrokerAllowed(true);
@@ -93,38 +88,26 @@
       content_settings->GetContentSetting(url, url,
                                           CONTENT_SETTINGS_TYPE_PPAPI_BROKER,
                                           std::string());
-  switch (setting) {
-    case CONTENT_SETTING_ALLOW: {
-      content::RecordAction(
-          content::UserMetricsAction("PPAPI.BrokerSettingAllow"));
-      tab_content_settings->SetPepperBrokerAllowed(true);
-      callback.Run(true);
-      break;
-    }
-    case CONTENT_SETTING_BLOCK: {
-      content::RecordAction(
-          content::UserMetricsAction("PPAPI.BrokerSettingDeny"));
-      tab_content_settings->SetPepperBrokerAllowed(false);
-      callback.Run(false);
-      break;
-    }
-    case CONTENT_SETTING_ASK: {
-      content::RecordAction(
-          content::UserMetricsAction("PPAPI.BrokerInfobarDisplayed"));
 
-      InfoBarService* infobar_service =
-          InfoBarService::FromWebContents(web_contents);
-      std::string languages =
-          profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
-      infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
-          new PepperBrokerInfoBarDelegate(
-              infobar_service, url, plugin_path, languages, content_settings,
-              tab_content_settings, callback)));
-      break;
-    }
-    default:
-      NOTREACHED();
+  if (setting == CONTENT_SETTING_ASK) {
+    content::RecordAction(
+        content::UserMetricsAction("PPAPI.BrokerInfobarDisplayed"));
+    InfoBarService* infobar_service =
+        InfoBarService::FromWebContents(web_contents);
+    infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
+        new PepperBrokerInfoBarDelegate(
+            infobar_service, url, plugin_path,
+            profile->GetPrefs()->GetString(prefs::kAcceptLanguages),
+            content_settings, tab_content_settings, callback)));
+    return;
   }
+
+  bool allowed = (setting == CONTENT_SETTING_ALLOW);
+  content::RecordAction(allowed ?
+      content::UserMetricsAction("PPAPI.BrokerSettingAllow") :
+      content::UserMetricsAction("PPAPI.BrokerSettingDeny"));
+  tab_content_settings->SetPepperBrokerAllowed(allowed);
+  callback.Run(allowed);
 }
 
 PepperBrokerInfoBarDelegate::PepperBrokerInfoBarDelegate(
@@ -167,21 +150,10 @@
                                                    languages_));
 }
 
-int PepperBrokerInfoBarDelegate::GetButtons() const {
-  return BUTTON_OK | BUTTON_CANCEL;
-}
-
 string16 PepperBrokerInfoBarDelegate::GetButtonLabel(
     InfoBarButton button) const {
-  switch (button) {
-    case BUTTON_OK:
-      return l10n_util::GetStringUTF16(IDS_PEPPER_BROKER_ALLOW_BUTTON);
-    case BUTTON_CANCEL:
-      return l10n_util::GetStringUTF16(IDS_PEPPER_BROKER_DENY_BUTTON);
-    default:
-      NOTREACHED();
-      return string16();
-  }
+  return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
+      IDS_PEPPER_BROKER_ALLOW_BUTTON : IDS_PEPPER_BROKER_DENY_BUTTON);
 }
 
 bool PepperBrokerInfoBarDelegate::Accept() {
@@ -200,12 +172,11 @@
 
 bool PepperBrokerInfoBarDelegate::LinkClicked(
     WindowOpenDisposition disposition) {
-  OpenURLParams params(
-      GURL(kPpapiBrokerLearnMoreUrl), Referrer(),
+  GURL learn_more_url("https://support.google.com/chrome/?p=ib_pepper_broker");
+  web_contents()->OpenURL(content::OpenURLParams(
+      learn_more_url, content::Referrer(),
       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
-      content::PAGE_TRANSITION_LINK,
-      false);
-  web_contents()->OpenURL(params);
+      content::PAGE_TRANSITION_LINK, false));
   return false;
 }
 
diff --git a/chrome/browser/pepper_broker_infobar_delegate.h b/chrome/browser/pepper_broker_infobar_delegate.h
index fa5a936..33574d1 100644
--- a/chrome/browser/pepper_broker_infobar_delegate.h
+++ b/chrome/browser/pepper_broker_infobar_delegate.h
@@ -33,20 +33,18 @@
                      const base::Callback<void(bool)>& callback);
 
  private:
-  PepperBrokerInfoBarDelegate(
-      InfoBarService* infobar_service,
-      const GURL& url,
-      const base::FilePath& plugin_path,
-      const std::string& languages,
-      HostContentSettingsMap* content_settings,
-      TabSpecificContentSettings* tab_content_settings,
-      const base::Callback<void(bool)>& callback);
+  PepperBrokerInfoBarDelegate(InfoBarService* infobar_service,
+                              const GURL& url,
+                              const base::FilePath& plugin_path,
+                              const std::string& languages,
+                              HostContentSettingsMap* content_settings,
+                              TabSpecificContentSettings* tab_content_settings,
+                              const base::Callback<void(bool)>& callback);
   virtual ~PepperBrokerInfoBarDelegate();
 
   // ConfirmInfoBarDelegate:
   virtual int GetIconID() const OVERRIDE;
   virtual string16 GetMessageText() const OVERRIDE;
-  virtual int GetButtons() const OVERRIDE;
   virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
   virtual bool Accept() OVERRIDE;
   virtual bool Cancel() OVERRIDE;
diff --git a/chrome/browser/pepper_flash_settings_manager.cc b/chrome/browser/pepper_flash_settings_manager.cc
index c6454bd..2886b4e 100644
--- a/chrome/browser/pepper_flash_settings_manager.cc
+++ b/chrome/browser/pepper_flash_settings_manager.cc
@@ -461,7 +461,7 @@
   // Wipe that file.
   const base::FilePath& device_id_path =
       chrome::DeviceIDFetcher::GetLegacyDeviceIDPath(profile_path);
-  bool success = base::Delete(device_id_path, false);
+  bool success = base::DeleteFile(device_id_path, false);
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
@@ -969,7 +969,7 @@
 }
 
 // static
-void PepperFlashSettingsManager::RegisterUserPrefs(
+void PepperFlashSettingsManager::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kDeauthorizeContentLicenses,
diff --git a/chrome/browser/pepper_flash_settings_manager.h b/chrome/browser/pepper_flash_settings_manager.h
index 3956ac3..cefb9c5 100644
--- a/chrome/browser/pepper_flash_settings_manager.h
+++ b/chrome/browser/pepper_flash_settings_manager.h
@@ -66,7 +66,7 @@
   static bool IsPepperFlashInUse(PluginPrefs* plugin_prefs,
                                  webkit::WebPluginInfo* plugin_info);
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Requests to deauthorize content licenses.
   // Client::OnDeauthorizeContentLicensesCompleted() will be called when the
diff --git a/chrome/browser/performance_monitor/database.cc b/chrome/browser/performance_monitor/database.cc
index 36bc93c..0485e35 100644
--- a/chrome/browser/performance_monitor/database.cc
+++ b/chrome/browser/performance_monitor/database.cc
@@ -91,7 +91,7 @@
     path = path.AppendASCII(kDbDir);
   }
   scoped_ptr<Database> database;
-  if (!file_util::DirectoryExists(path) && !file_util::CreateDirectory(path))
+  if (!base::DirectoryExists(path) && !file_util::CreateDirectory(path))
     return database.Pass();
   database.reset(new Database(path));
 
@@ -442,6 +442,7 @@
 bool Database::InitDBs() {
   CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   leveldb::Options open_options;
+  open_options.max_open_files = 0;  // Use minimum.
   open_options.create_if_missing = true;
 
   // TODO (rdevlin.cronin): This code is ugly. Fix it.
diff --git a/chrome/browser/performance_monitor/performance_monitor.cc b/chrome/browser/performance_monitor/performance_monitor.cc
index 6d7ed4f..1886a2d 100644
--- a/chrome/browser/performance_monitor/performance_monitor.cc
+++ b/chrome/browser/performance_monitor/performance_monitor.cc
@@ -17,6 +17,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/performance_monitor/constants.h"
 #include "chrome/browser/performance_monitor/performance_monitor_util.h"
@@ -24,7 +25,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_iterator.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/extensions/extension.h"
diff --git a/chrome/browser/performance_monitor/performance_monitor_browsertest.cc b/chrome/browser/performance_monitor/performance_monitor_browsertest.cc
index 3d2c95c..bb5a877 100644
--- a/chrome/browser/performance_monitor/performance_monitor_browsertest.cc
+++ b/chrome/browser/performance_monitor/performance_monitor_browsertest.cc
@@ -9,6 +9,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/performance_monitor/constants.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
@@ -307,12 +307,12 @@
     PathService::Get(chrome::DIR_TEST_DATA, &stock_prefs_file);
     stock_prefs_file = stock_prefs_file.AppendASCII("performance_monitor")
                                        .AppendASCII("unclean_exit_prefs");
-    CHECK(file_util::PathExists(stock_prefs_file));
+    CHECK(base::PathExists(stock_prefs_file));
 
     base::FilePath first_profile_prefs_file =
         first_profile.Append(chrome::kPreferencesFilename);
-    CHECK(file_util::CopyFile(stock_prefs_file, first_profile_prefs_file));
-    CHECK(file_util::PathExists(first_profile_prefs_file));
+    CHECK(base::CopyFile(stock_prefs_file, first_profile_prefs_file));
+    CHECK(base::PathExists(first_profile_prefs_file));
 
     second_profile_name_ =
         std::string(chrome::kMultiProfileDirPrefix)
@@ -324,8 +324,8 @@
 
     base::FilePath second_profile_prefs_file =
         second_profile.Append(chrome::kPreferencesFilename);
-    CHECK(file_util::CopyFile(stock_prefs_file, second_profile_prefs_file));
-    CHECK(file_util::PathExists(second_profile_prefs_file));
+    CHECK(base::CopyFile(stock_prefs_file, second_profile_prefs_file));
+    CHECK(base::PathExists(second_profile_prefs_file));
 
     return true;
   }
diff --git a/chrome/browser/performance_monitor/startup_timer.cc b/chrome/browser/performance_monitor/startup_timer.cc
index 8256ba3..d6aee73 100644
--- a/chrome/browser/performance_monitor/startup_timer.cc
+++ b/chrome/browser/performance_monitor/startup_timer.cc
@@ -7,9 +7,9 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/performance_monitor/database.h"
 #include "chrome/browser/performance_monitor/performance_monitor.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/platform_util_linux.cc b/chrome/browser/platform_util_linux.cc
index 9ac22d7..6f88b16 100644
--- a/chrome/browser/platform_util_linux.cc
+++ b/chrome/browser/platform_util_linux.cc
@@ -56,7 +56,7 @@
 // show the folder.
 void ShowItemInFolderOnFileThread(const base::FilePath& full_path) {
   base::FilePath dir = full_path.DirName();
-  if (!file_util::DirectoryExists(dir))
+  if (!base::DirectoryExists(dir))
     return;
 
   XDGOpen(dir.value());
diff --git a/chrome/browser/plugins/chrome_plugin_service_filter.cc b/chrome/browser/plugins/chrome_plugin_service_filter.cc
index 853018e..633d758 100644
--- a/chrome/browser/plugins/chrome_plugin_service_filter.cc
+++ b/chrome/browser/plugins/chrome_plugin_service_filter.cc
@@ -6,16 +6,15 @@
 
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/plugins/plugin_metadata.h"
 #include "chrome/browser/plugins/plugin_prefs.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/resource_context.h"
-#include "webkit/plugins/npapi/plugin_list.h"
 
 using content::BrowserThread;
 using content::PluginService;
diff --git a/chrome/browser/plugins/plugin_finder_unittest.cc b/chrome/browser/plugins/plugin_finder_unittest.cc
index 86b9ead..726b146 100644
--- a/chrome/browser/plugins/plugin_finder_unittest.cc
+++ b/chrome/browser/plugins/plugin_finder_unittest.cc
@@ -7,11 +7,9 @@
 #include "base/values.h"
 #include "chrome/browser/plugins/plugin_metadata.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "webkit/plugins/npapi/plugin_list.h"
 
 using base::DictionaryValue;
 using base::ListValue;
-using webkit::npapi::PluginList;
 
 TEST(PluginFinderTest, JsonSyntax) {
   scoped_ptr<DictionaryValue> plugin_list(
diff --git a/chrome/browser/plugins/plugin_infobar_delegates.cc b/chrome/browser/plugins/plugin_infobar_delegates.cc
index 920217f..2ad36c7 100644
--- a/chrome/browser/plugins/plugin_infobar_delegates.cc
+++ b/chrome/browser/plugins/plugin_infobar_delegates.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/plugins/plugin_infobar_delegates.h"
 
+#include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/google/google_util.h"
@@ -12,8 +13,11 @@
 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
 #include "chrome/browser/plugins/plugin_metadata.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/shell_integration.h"
+#include "chrome/browser/ui/browser_commands.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/common/url_constants.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/user_metrics.h"
@@ -23,30 +27,26 @@
 #include "grit/theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
-#if defined(OS_WIN)
-#include <shellapi.h>
-#include "ui/base/win/shell.h"
-#endif
-
 #if defined(ENABLE_PLUGIN_INSTALLATION)
 #if defined(OS_WIN)
 #include "base/win/metro.h"
 #endif
 #include "chrome/browser/plugins/plugin_installer.h"
-#endif  // defined(ENABLE_PLUGIN_INSTALLATION)
+#endif
 
-using content::OpenURLParams;
-using content::Referrer;
+#if defined(OS_WIN)
+#include <shellapi.h>
+#include "ui/base/win/shell.h"
+#endif
+
 using content::UserMetricsAction;
 
 
 // PluginInfoBarDelegate ------------------------------------------------------
 
 PluginInfoBarDelegate::PluginInfoBarDelegate(InfoBarService* infobar_service,
-                                             const string16& name,
                                              const std::string& identifier)
     : ConfirmInfoBarDelegate(infobar_service),
-      name_(name),
       identifier_(identifier) {
 }
 
@@ -54,23 +54,19 @@
 }
 
 bool PluginInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition) {
-  OpenURLParams params(
-      GURL(GetLearnMoreURL()), Referrer(),
+  web_contents()->OpenURL(content::OpenURLParams(
+      GURL(GetLearnMoreURL()), content::Referrer(),
       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
-      content::PAGE_TRANSITION_LINK,
-      false);
-  web_contents()->OpenURL(params);
+      content::PAGE_TRANSITION_LINK, false));
   return false;
 }
 
 void PluginInfoBarDelegate::LoadBlockedPlugins() {
-  if (web_contents()) {
-    content::RenderViewHost* host = web_contents()->GetRenderViewHost();
-    ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins(
-        host->GetProcess()->GetID());
-    host->Send(new ChromeViewMsg_LoadBlockedPlugins(
-        host->GetRoutingID(), identifier_));
-  }
+  content::RenderViewHost* host = web_contents()->GetRenderViewHost();
+  ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins(
+      host->GetProcess()->GetID());
+  host->Send(new ChromeViewMsg_LoadBlockedPlugins(
+      host->GetRoutingID(), identifier_));
 }
 
 int PluginInfoBarDelegate::GetIconID() const {
@@ -88,38 +84,39 @@
 void UnauthorizedPluginInfoBarDelegate::Create(
     InfoBarService* infobar_service,
     HostContentSettingsMap* content_settings,
-    const string16& utf16_name,
+    const string16& name,
     const std::string& identifier) {
   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
       new UnauthorizedPluginInfoBarDelegate(infobar_service, content_settings,
-                                            utf16_name, identifier)));
+                                            name, identifier)));
 
   content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Shown"));
-  std::string name(UTF16ToUTF8(utf16_name));
-  if (name == PluginMetadata::kJavaGroupName)
-    content::RecordAction(
-        UserMetricsAction("BlockedPluginInfobar.Shown.Java"));
-  else if (name == PluginMetadata::kQuickTimeGroupName)
+  std::string utf8_name(UTF16ToUTF8(name));
+  if (utf8_name == PluginMetadata::kJavaGroupName) {
+    content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Shown.Java"));
+  } else if (utf8_name == PluginMetadata::kQuickTimeGroupName) {
     content::RecordAction(
         UserMetricsAction("BlockedPluginInfobar.Shown.QuickTime"));
-  else if (name == PluginMetadata::kShockwaveGroupName)
+  } else if (utf8_name == PluginMetadata::kShockwaveGroupName) {
     content::RecordAction(
         UserMetricsAction("BlockedPluginInfobar.Shown.Shockwave"));
-  else if (name == PluginMetadata::kRealPlayerGroupName)
+  } else if (utf8_name == PluginMetadata::kRealPlayerGroupName) {
     content::RecordAction(
         UserMetricsAction("BlockedPluginInfobar.Shown.RealPlayer"));
-  else if (name == PluginMetadata::kWindowsMediaPlayerGroupName)
+  } else if (utf8_name == PluginMetadata::kWindowsMediaPlayerGroupName) {
     content::RecordAction(
         UserMetricsAction("BlockedPluginInfobar.Shown.WindowsMediaPlayer"));
+  }
 }
 
 UnauthorizedPluginInfoBarDelegate::UnauthorizedPluginInfoBarDelegate(
     InfoBarService* infobar_service,
     HostContentSettingsMap* content_settings,
-    const string16& utf16_name,
+    const string16& name,
     const std::string& identifier)
-    : PluginInfoBarDelegate(infobar_service, utf16_name, identifier),
-      content_settings_(content_settings) {
+    : PluginInfoBarDelegate(infobar_service, identifier),
+      content_settings_(content_settings),
+      name_(name) {
 }
 
 UnauthorizedPluginInfoBarDelegate::~UnauthorizedPluginInfoBarDelegate() {
@@ -148,26 +145,21 @@
 }
 
 bool UnauthorizedPluginInfoBarDelegate::Cancel() {
-  content::RecordAction(
-      UserMetricsAction("BlockedPluginInfobar.AlwaysAllow"));
-  content_settings_->AddExceptionForURL(web_contents()->GetURL(),
-                                        web_contents()->GetURL(),
-                                        CONTENT_SETTINGS_TYPE_PLUGINS,
-                                        std::string(),
-                                        CONTENT_SETTING_ALLOW);
+  content::RecordAction(UserMetricsAction("BlockedPluginInfobar.AlwaysAllow"));
+  const GURL& url = web_contents()->GetURL();
+  content_settings_->AddExceptionForURL(url, url, CONTENT_SETTINGS_TYPE_PLUGINS,
+                                        std::string(), CONTENT_SETTING_ALLOW);
   LoadBlockedPlugins();
   return true;
 }
 
 void UnauthorizedPluginInfoBarDelegate::InfoBarDismissed() {
-  content::RecordAction(
-      UserMetricsAction("BlockedPluginInfobar.Dismissed"));
+  content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Dismissed"));
 }
 
 bool UnauthorizedPluginInfoBarDelegate::LinkClicked(
     WindowOpenDisposition disposition) {
-  content::RecordAction(
-      UserMetricsAction("BlockedPluginInfobar.LearnMore"));
+  content::RecordAction(UserMetricsAction("BlockedPluginInfobar.LearnMore"));
   return PluginInfoBarDelegate::LinkClicked(disposition);
 }
 
@@ -180,20 +172,14 @@
     InfoBarService* infobar_service,
     PluginInstaller* installer,
     scoped_ptr<PluginMetadata> plugin_metadata) {
-  string16 message;
-  switch (installer->state()) {
-    case PluginInstaller::INSTALLER_STATE_IDLE:
-      message = l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED_PROMPT,
-                                           plugin_metadata->name());
-      break;
-    case PluginInstaller::INSTALLER_STATE_DOWNLOADING:
-      message = l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING,
-                                           plugin_metadata->name());
-      break;
-  }
+  string16 name(plugin_metadata->name());
   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
       new OutdatedPluginInfoBarDelegate(
-          infobar_service, installer, plugin_metadata.Pass(), message)));
+          infobar_service, installer, plugin_metadata.Pass(),
+          l10n_util::GetStringFUTF16(
+              (installer->state() == PluginInstaller::INSTALLER_STATE_IDLE) ?
+                  IDS_PLUGIN_OUTDATED_PROMPT : IDS_PLUGIN_DOWNLOADING,
+              name))));
 }
 
 OutdatedPluginInfoBarDelegate::OutdatedPluginInfoBarDelegate(
@@ -201,33 +187,31 @@
     PluginInstaller* installer,
     scoped_ptr<PluginMetadata> plugin_metadata,
     const string16& message)
-    : PluginInfoBarDelegate(
-          infobar_service,
-          plugin_metadata->name(),
-          plugin_metadata->identifier()),
+    : PluginInfoBarDelegate(infobar_service, plugin_metadata->identifier()),
       WeakPluginInstallerObserver(installer),
       plugin_metadata_(plugin_metadata.Pass()),
       message_(message) {
   content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Shown"));
   std::string name = UTF16ToUTF8(plugin_metadata_->name());
-  if (name == PluginMetadata::kJavaGroupName)
+  if (name == PluginMetadata::kJavaGroupName) {
     content::RecordAction(
         UserMetricsAction("OutdatedPluginInfobar.Shown.Java"));
-  else if (name == PluginMetadata::kQuickTimeGroupName)
+  } else if (name == PluginMetadata::kQuickTimeGroupName) {
     content::RecordAction(
         UserMetricsAction("OutdatedPluginInfobar.Shown.QuickTime"));
-  else if (name == PluginMetadata::kShockwaveGroupName)
+  } else if (name == PluginMetadata::kShockwaveGroupName) {
     content::RecordAction(
         UserMetricsAction("OutdatedPluginInfobar.Shown.Shockwave"));
-  else if (name == PluginMetadata::kRealPlayerGroupName)
+  } else if (name == PluginMetadata::kRealPlayerGroupName) {
     content::RecordAction(
         UserMetricsAction("OutdatedPluginInfobar.Shown.RealPlayer"));
-  else if (name == PluginMetadata::kSilverlightGroupName)
+  } else if (name == PluginMetadata::kSilverlightGroupName) {
     content::RecordAction(
         UserMetricsAction("OutdatedPluginInfobar.Shown.Silverlight"));
-  else if (name == PluginMetadata::kAdobeReaderGroupName)
+  } else if (name == PluginMetadata::kAdobeReaderGroupName) {
     content::RecordAction(
         UserMetricsAction("OutdatedPluginInfobar.Shown.Reader"));
+  }
 }
 
 OutdatedPluginInfoBarDelegate::~OutdatedPluginInfoBarDelegate() {
@@ -249,16 +233,11 @@
 }
 
 bool OutdatedPluginInfoBarDelegate::Accept() {
+  DCHECK_EQ(PluginInstaller::INSTALLER_STATE_IDLE, installer()->state());
   content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Update"));
-  if (installer()->state() != PluginInstaller::INSTALLER_STATE_IDLE) {
-    NOTREACHED();
-    return false;
-  }
-
   // A call to any of |OpenDownloadURL()| or |StartInstalling()| will
   // result in deleting ourselves. Accordingly, we make sure to
   // not pass a reference to an object that can go away.
-  // http://crbug.com/54167
   GURL plugin_url(plugin_metadata_->plugin_url());
   if (plugin_metadata_->url_for_display())
     installer()->OpenDownloadURL(plugin_url, web_contents());
@@ -275,14 +254,12 @@
 }
 
 void OutdatedPluginInfoBarDelegate::InfoBarDismissed() {
-  content::RecordAction(
-      UserMetricsAction("OutdatedPluginInfobar.Dismissed"));
+  content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Dismissed"));
 }
 
 bool OutdatedPluginInfoBarDelegate::LinkClicked(
     WindowOpenDisposition disposition) {
-  content::RecordAction(
-      UserMetricsAction("OutdatedPluginInfobar.LearnMore"));
+  content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.LearnMore"));
   return PluginInfoBarDelegate::LinkClicked(disposition);
 }
 
@@ -292,9 +269,8 @@
 }
 
 void OutdatedPluginInfoBarDelegate::DownloadError(const std::string& message) {
-  ReplaceWithInfoBar(
-      l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT,
-                                 plugin_metadata_->name()));
+  ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT,
+                                                plugin_metadata_->name()));
 }
 
 void OutdatedPluginInfoBarDelegate::DownloadCancelled() {
@@ -341,20 +317,15 @@
     return;
   }
 #endif
-  string16 message;
-  switch (installer->state()) {
-    case PluginInstaller::INSTALLER_STATE_IDLE:
-      message = l10n_util::GetStringFUTF16(
-          IDS_PLUGININSTALLER_INSTALLPLUGIN_PROMPT, name);
-      break;
-    case PluginInstaller::INSTALLER_STATE_DOWNLOADING:
-      message = l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING, name);
-      break;
-  }
   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
       new PluginInstallerInfoBarDelegate(
           infobar_service, installer, plugin_metadata.Pass(), callback, true,
-          message)));
+          l10n_util::GetStringFUTF16(
+              (installer->state() == PluginInstaller::INSTALLER_STATE_IDLE) ?
+                  IDS_PLUGININSTALLER_INSTALLPLUGIN_PROMPT :
+                  IDS_PLUGIN_DOWNLOADING,
+              name))));
+
 }
 
 void PluginInstallerInfoBarDelegate::Replace(
@@ -413,9 +384,9 @@
 }
 
 string16 PluginInstallerInfoBarDelegate::GetLinkText() const {
-  return l10n_util::GetStringUTF16(
-      new_install_ ? IDS_PLUGININSTALLER_PROBLEMSINSTALLING
-                   : IDS_PLUGININSTALLER_PROBLEMSUPDATING);
+  return l10n_util::GetStringUTF16(new_install_ ?
+      IDS_PLUGININSTALLER_PROBLEMSINSTALLING :
+      IDS_PLUGININSTALLER_PROBLEMSUPDATING);
 }
 
 bool PluginInstallerInfoBarDelegate::LinkClicked(
@@ -423,14 +394,13 @@
   GURL url(plugin_metadata_->help_url());
   if (url.is_empty()) {
     url = google_util::AppendGoogleLocaleParam(GURL(
-      "https://www.google.com/support/chrome/bin/answer.py?answer=142064"));
+        "https://www.google.com/support/chrome/bin/answer.py?answer=142064"));
   }
 
-  OpenURLParams params(
-      url, Referrer(),
+  web_contents()->OpenURL(content::OpenURLParams(
+      url, content::Referrer(),
       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
-      content::PAGE_TRANSITION_LINK, false);
-  web_contents()->OpenURL(params);
+      content::PAGE_TRANSITION_LINK, false));
   return false;
 }
 
@@ -445,14 +415,14 @@
 }
 
 void PluginInstallerInfoBarDelegate::DownloadError(const std::string& message) {
-  ReplaceWithInfoBar(
-      l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT,
-                                 plugin_metadata_->name()));
+  ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT,
+                                                plugin_metadata_->name()));
 }
 
 void PluginInstallerInfoBarDelegate::DownloadFinished() {
-  ReplaceWithInfoBar(l10n_util::GetStringFUTF16(
-      new_install_ ? IDS_PLUGIN_INSTALLING : IDS_PLUGIN_UPDATING,
+  ReplaceWithInfoBar(
+      l10n_util::GetStringFUTF16(
+          new_install_ ? IDS_PLUGIN_INSTALLING : IDS_PLUGIN_UPDATING,
           plugin_metadata_->name()));
 }
 
@@ -520,24 +490,43 @@
       IDS_WIN8_DESKTOP_RESTART : IDS_WIN8_RESTART);
 }
 
+void LaunchDesktopInstanceHelper(const string16& url) {
+  base::FilePath exe_path;
+  if (!PathService::Get(base::FILE_EXE, &exe_path))
+    return;
+  base::FilePath shortcut_path(
+      ShellIntegration::GetStartMenuShortcut(exe_path));
+
+  SHELLEXECUTEINFO sei = { sizeof(sei) };
+  sei.fMask = SEE_MASK_FLAG_LOG_USAGE;
+  sei.nShow = SW_SHOWNORMAL;
+  sei.lpFile = shortcut_path.value().c_str();
+  sei.lpDirectory = L"";
+  sei.lpParameters = url.c_str();
+  ShellExecuteEx(&sei);
+}
+
 bool PluginMetroModeInfoBarDelegate::Accept() {
+#if defined(USE_AURA) && defined(USE_ASH)
+  // We need to PostTask as there is some IO involved.
+  content::BrowserThread::PostTask(
+      content::BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
+      base::Bind(&LaunchDesktopInstanceHelper,
+                 UTF8ToUTF16(web_contents()->GetURL().spec())));
+#else
   chrome::AttemptRestartWithModeSwitch();
+#endif
   return true;
 }
 
 bool PluginMetroModeInfoBarDelegate::Cancel() {
   DCHECK_EQ(DESKTOP_MODE_REQUIRED, mode_);
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents()->GetBrowserContext());
-  HostContentSettingsMap* content_settings =
-      profile->GetHostContentSettingsMap();
-  GURL url = web_contents()->GetURL();
-  content_settings->SetContentSetting(
-      ContentSettingsPattern::FromURL(url),
-      ContentSettingsPattern::Wildcard(),
-      CONTENT_SETTINGS_TYPE_METRO_SWITCH_TO_DESKTOP,
-      std::string(),
-      CONTENT_SETTING_BLOCK);
+  Profile::FromBrowserContext(web_contents()->GetBrowserContext())->
+      GetHostContentSettingsMap()->SetContentSetting(
+          ContentSettingsPattern::FromURL(web_contents()->GetURL()),
+          ContentSettingsPattern::Wildcard(),
+          CONTENT_SETTINGS_TYPE_METRO_SWITCH_TO_DESKTOP, std::string(),
+          CONTENT_SETTING_BLOCK);
   return true;
 }
 
@@ -547,14 +536,13 @@
 
 bool PluginMetroModeInfoBarDelegate::LinkClicked(
     WindowOpenDisposition disposition) {
-  OpenURLParams params(
+  web_contents()->OpenURL(content::OpenURLParams(
       GURL((mode_ == MISSING_PLUGIN) ?
           "https://support.google.com/chrome/?p=ib_display_in_desktop" :
           "https://support.google.com/chrome/?p=ib_redirect_to_desktop"),
-      Referrer(),
+      content::Referrer(),
       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
-      content::PAGE_TRANSITION_LINK, false);
-  web_contents()->OpenURL(params);
+      content::PAGE_TRANSITION_LINK, false));
   return false;
 }
 
diff --git a/chrome/browser/plugins/plugin_infobar_delegates.h b/chrome/browser/plugins/plugin_infobar_delegates.h
index 5e4cb31..72ab27c 100644
--- a/chrome/browser/plugins/plugin_infobar_delegates.h
+++ b/chrome/browser/plugins/plugin_infobar_delegates.h
@@ -11,7 +11,7 @@
 
 #if defined(ENABLE_PLUGIN_INSTALLATION)
 #include "chrome/browser/plugins/plugin_installer_observer.h"
-#endif  // defined(ENABLE_PLUGIN_INSTALLATION)
+#endif
 
 class InfoBarService;
 class HostContentSettingsMap;
@@ -25,7 +25,6 @@
 class PluginInfoBarDelegate : public ConfirmInfoBarDelegate {
  public:
   PluginInfoBarDelegate(InfoBarService* infobar_service,
-                        const string16& name,
                         const std::string& identifier);
 
  protected:
@@ -38,8 +37,6 @@
 
   void LoadBlockedPlugins();
 
-  string16 name_;
-
  private:
   // ConfirmInfoBarDelegate:
   virtual int GetIconID() const OVERRIDE;
@@ -76,6 +73,7 @@
   virtual std::string GetLearnMoreURL() const OVERRIDE;
 
   HostContentSettingsMap* content_settings_;
+  string16 name_;
 
   DISALLOW_COPY_AND_ASSIGN(UnauthorizedPluginInfoBarDelegate);
 };
diff --git a/chrome/browser/plugins/plugin_installer.cc b/chrome/browser/plugins/plugin_installer.cc
index bd68407..653d129 100644
--- a/chrome/browser/plugins/plugin_installer.cc
+++ b/chrome/browser/plugins/plugin_installer.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/process.h"
+#include "base/strings/stringprintf.h"
 #include "chrome/browser/download/download_service.h"
 #include "chrome/browser/download/download_service_factory.h"
 #include "chrome/browser/download/download_util.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/download_id.h"
 #include "content/public/browser/download_item.h"
 #include "content/public/browser/download_save_info.h"
 #include "content/public/browser/render_process_host.h"
@@ -54,7 +54,7 @@
       render_view_host_routing_id,
       true,  // prefer_cache
       scoped_ptr<content::DownloadSaveInfo>(new content::DownloadSaveInfo()),
-      content::DownloadId::Invalid(),
+      content::DownloadItem::kInvalidId,
       callback);
 
   if (error != net::OK) {
diff --git a/chrome/browser/plugins/plugin_observer.cc b/chrome/browser/plugins/plugin_observer.cc
index 234922d..a6a64a2 100644
--- a/chrome/browser/plugins/plugin_observer.cc
+++ b/chrome/browser/plugins/plugin_observer.cc
@@ -6,6 +6,7 @@
 
 #include "base/auto_reset.h"
 #include "base/bind.h"
+#include "base/debug/crash_logging.h"
 #include "base/metrics/histogram.h"
 #include "base/process_util.h"
 #include "base/stl_util.h"
@@ -296,10 +297,8 @@
   // Find plugin to update.
   PluginInstaller* installer = NULL;
   scoped_ptr<PluginMetadata> plugin;
-  if (!finder->FindPluginWithIdentifier(identifier, &installer, &plugin)) {
-    NOTREACHED();
-    return;
-  }
+  bool ret = finder->FindPluginWithIdentifier(identifier, &installer, &plugin);
+  DCHECK(ret);
 
   plugin_placeholders_[placeholder_id] =
       new PluginPlaceholderHost(this, placeholder_id,
@@ -330,8 +329,7 @@
   DCHECK(plugin_metadata.get());
 
   plugin_placeholders_[placeholder_id] =
-      new PluginPlaceholderHost(this, placeholder_id,
-                                plugin_metadata->name(),
+      new PluginPlaceholderHost(this, placeholder_id, plugin_metadata->name(),
                                 installer);
   PluginInstallerInfoBarDelegate::Create(
       InfoBarService::FromWebContents(web_contents()), installer,
@@ -382,7 +380,7 @@
       IDR_INFOBAR_PLUGIN_CRASHED,
       l10n_util::GetStringFUTF16(IDS_PLUGIN_INITIALIZATION_ERROR_PROMPT,
                                  plugin_name),
-      true  /* auto_expire */);
+      true);
 }
 
 void PluginObserver::OnNPAPINotSupported(const std::string& identifier) {
@@ -405,11 +403,9 @@
     return;
 
   scoped_ptr<PluginMetadata> plugin;
-  if (!PluginFinder::GetInstance()->FindPluginWithIdentifier(
-          identifier, NULL, &plugin)) {
-    NOTREACHED();
-    return;
-  }
+  bool ret = PluginFinder::GetInstance()->FindPluginWithIdentifier(
+          identifier, NULL, &plugin);
+  DCHECK(ret);
 
   PluginMetroModeInfoBarDelegate::Create(
       InfoBarService::FromWebContents(web_contents()),
diff --git a/chrome/browser/plugins/plugin_prefs.cc b/chrome/browser/plugins/plugin_prefs.cc
index 5ee19fd..7be5d5a 100644
--- a/chrome/browser/plugins/plugin_prefs.cc
+++ b/chrome/browser/plugins/plugin_prefs.cc
@@ -16,6 +16,7 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/plugins/plugin_installer.h"
 #include "chrome/browser/plugins/plugin_metadata.h"
 #include "chrome/browser/plugins/plugin_prefs_factory.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_content_client.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/plugins/plugin_prefs_factory.cc b/chrome/browser/plugins/plugin_prefs_factory.cc
index a5cb5cc..bcb6326 100644
--- a/chrome/browser/plugins/plugin_prefs_factory.cc
+++ b/chrome/browser/plugins/plugin_prefs_factory.cc
@@ -51,7 +51,7 @@
   return plugin_prefs;
 }
 
-void PluginPrefsFactory::RegisterUserPrefs(
+void PluginPrefsFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   base::FilePath internal_dir;
   PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &internal_dir);
diff --git a/chrome/browser/plugins/plugin_prefs_factory.h b/chrome/browser/plugins/plugin_prefs_factory.h
index 4e2137b..092250b 100644
--- a/chrome/browser/plugins/plugin_prefs_factory.h
+++ b/chrome/browser/plugins/plugin_prefs_factory.h
@@ -35,7 +35,7 @@
       BuildServiceInstanceFor(content::BrowserContext* context) const OVERRIDE;
 
   // BrowserContextKeyedServiceFactory methods:
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const OVERRIDE;
diff --git a/chrome/browser/plugins/plugin_status_pref_setter.cc b/chrome/browser/plugins/plugin_status_pref_setter.cc
index 79beda9..09bf546 100644
--- a/chrome/browser/plugins/plugin_status_pref_setter.cc
+++ b/chrome/browser/plugins/plugin_status_pref_setter.cc
@@ -6,11 +6,11 @@
 
 #include "base/bind.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/pepper_flash_settings_manager.h"
 #include "chrome/browser/plugins/plugin_data_remover_helper.h"
 #include "chrome/browser/plugins/plugin_prefs.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/policy/async_policy_provider_unittest.cc b/chrome/browser/policy/async_policy_provider_unittest.cc
index 0d04efe..3bd8fd9 100644
--- a/chrome/browser/policy/async_policy_provider_unittest.cc
+++ b/chrome/browser/policy/async_policy_provider_unittest.cc
@@ -4,9 +4,11 @@
 
 #include "chrome/browser/policy/async_policy_provider.h"
 
+#include "base/callback.h"
 #include "base/message_loop.h"
 #include "base/values.h"
 #include "chrome/browser/policy/async_policy_loader.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread.h"
@@ -30,7 +32,8 @@
       .Set(name,
            POLICY_LEVEL_MANDATORY,
            POLICY_SCOPE_USER,
-           base::Value::CreateStringValue(value));
+           base::Value::CreateStringValue(value),
+           NULL);
 }
 
 class MockPolicyLoader : public AsyncPolicyLoader {
diff --git a/chrome/browser/policy/browser_policy_connector.cc b/chrome/browser/policy/browser_policy_connector.cc
index 18ad7af..e01e1bb 100644
--- a/chrome/browser/policy/browser_policy_connector.cc
+++ b/chrome/browser/policy/browser_policy_connector.cc
@@ -49,7 +49,7 @@
 #endif
 
 #if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/policy/app_pack_updater.h"
 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
@@ -218,7 +218,7 @@
     network_configuration_updater_.reset(
         new NetworkConfigurationUpdaterImplCros(
             GetPolicyService(),
-            chromeos::CrosLibrary::Get()->GetNetworkLibrary(),
+            chromeos::NetworkLibrary::Get(),
             make_scoped_ptr(new chromeos::CertificateHandler)));
   }
 #endif
diff --git a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
index 0327d98..d129f0a 100644
--- a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/callback.h"
 #include "base/command_line.h"
 #include "base/file_util.h"
 #include "base/files/file_path.h"
@@ -12,10 +13,12 @@
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/policy/cloud/cloud_policy_client.h"
 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
 #include "chrome/browser/policy/cloud/mock_cloud_policy_client.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_service.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
@@ -24,7 +27,6 @@
 #include "chrome/browser/policy/test_utils.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/browser_thread.h"
@@ -113,18 +115,18 @@
 
 void GetExpectedTestPolicy(PolicyMap* expected) {
   expected->Set(key::kShowHomeButton, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                base::Value::CreateBooleanValue(true));
+                base::Value::CreateBooleanValue(true), NULL);
   expected->Set(key::kRestoreOnStartup, POLICY_LEVEL_MANDATORY,
-                POLICY_SCOPE_USER, base::Value::CreateIntegerValue(4));
+                POLICY_SCOPE_USER, base::Value::CreateIntegerValue(4), NULL);
   base::ListValue list;
   list.AppendString("dev.chromium.org");
   list.AppendString("youtube.com");
   expected->Set(
       key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-      list.DeepCopy());
+      list.DeepCopy(), NULL);
   expected->Set(
       key::kHomepageLocation, POLICY_LEVEL_RECOMMENDED,
-      POLICY_SCOPE_USER, base::Value::CreateStringValue("google.com"));
+      POLICY_SCOPE_USER, base::Value::CreateStringValue("google.com"), NULL);
 }
 
 }  // namespace
diff --git a/chrome/browser/policy/cloud/cloud_policy_client_registration_helper.cc b/chrome/browser/policy/cloud/cloud_policy_client_registration_helper.cc
index 7f0b36e..224977f 100644
--- a/chrome/browser/policy/cloud/cloud_policy_client_registration_helper.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_client_registration_helper.cc
@@ -6,13 +6,22 @@
 
 #include <vector>
 
+#include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/logging.h"
 #include "base/time/time.h"
 #include "base/values.h"
 #include "google_apis/gaia/gaia_constants.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "google_apis/gaia/google_service_auth_error.h"
+
+#if defined(OS_ANDROID)
+#include "chrome/browser/signin/android_profile_oauth2_token_service.h"
+#include "chrome/browser/signin/oauth2_token_service.h"
+#else
+#include "google_apis/gaia/oauth2_access_token_consumer.h"
 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
+#endif
 
 namespace policy {
 
@@ -26,8 +35,129 @@
 // response.
 const char kGetHostedDomainKey[] = "hd";
 
+typedef base::Callback<void(const std::string&)> StringCallback;
+
 }  // namespace
 
+#if defined(OS_ANDROID)
+
+// This class fetches an OAuth2 token scoped for the userinfo and DM services.
+// The AccountManager is used to mint the token on the Java side, given the
+// username of an account that is known to exist on the device.
+// This allows fetching the token before the sign-in process is finished.
+class CloudPolicyClientRegistrationHelper::TokenHelperAndroid
+    : public OAuth2TokenService::Consumer {
+ public:
+  TokenHelperAndroid();
+
+  void FetchAccessToken(AndroidProfileOAuth2TokenService* token_service,
+                        const std::string& username,
+                        const StringCallback& callback);
+
+ private:
+  // OAuth2TokenService::Consumer implementation:
+  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                                 const std::string& access_token,
+                                 const base::Time& expiration_time) OVERRIDE;
+  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                                 const GoogleServiceAuthError& error) OVERRIDE;
+
+  StringCallback callback_;
+  scoped_ptr<OAuth2TokenService::Request> token_request_;
+};
+
+CloudPolicyClientRegistrationHelper::TokenHelperAndroid::TokenHelperAndroid() {}
+
+void CloudPolicyClientRegistrationHelper::TokenHelperAndroid::FetchAccessToken(
+    AndroidProfileOAuth2TokenService* token_service,
+    const std::string& username,
+    const StringCallback& callback) {
+  callback_ = callback;
+
+  OAuth2TokenService::ScopeSet scopes;
+  scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth);
+  scopes.insert(kServiceScopeGetUserInfo);
+
+  token_request_ =
+      token_service->StartRequestForUsername(username, scopes, this);
+}
+
+void CloudPolicyClientRegistrationHelper::TokenHelperAndroid::OnGetTokenSuccess(
+    const OAuth2TokenService::Request* request,
+    const std::string& access_token,
+    const base::Time& expiration_time) {
+  DCHECK_EQ(token_request_.get(), request);
+  callback_.Run(access_token);
+}
+
+void CloudPolicyClientRegistrationHelper::TokenHelperAndroid::OnGetTokenFailure(
+    const OAuth2TokenService::Request* request,
+    const GoogleServiceAuthError& error) {
+  DCHECK_EQ(token_request_.get(), request);
+  callback_.Run("");
+}
+
+#else
+
+// This class fetches the OAuth2 token scoped for the userinfo and DM services.
+// It uses an OAuth2AccessTokenFetcher to fetch it, given a login refresh token
+// that can be used to authorize that request.
+class CloudPolicyClientRegistrationHelper::TokenHelper
+    : public OAuth2AccessTokenConsumer {
+ public:
+  TokenHelper();
+
+  void FetchAccessToken(const std::string& login_refresh_token,
+                        net::URLRequestContextGetter* context,
+                        const StringCallback& callback);
+
+ private:
+  // OAuth2AccessTokenConsumer implementation:
+  virtual void OnGetTokenSuccess(const std::string& access_token,
+                                 const base::Time& expiration_time) OVERRIDE;
+  virtual void OnGetTokenFailure(
+      const GoogleServiceAuthError& error) OVERRIDE;
+
+  StringCallback callback_;
+  scoped_ptr<OAuth2AccessTokenFetcher> oauth2_access_token_fetcher_;
+};
+
+CloudPolicyClientRegistrationHelper::TokenHelper::TokenHelper() {}
+
+void CloudPolicyClientRegistrationHelper::TokenHelper::FetchAccessToken(
+    const std::string& login_refresh_token,
+    net::URLRequestContextGetter* context,
+    const StringCallback& callback) {
+  callback_ = callback;
+
+  // Start fetching an OAuth2 access token for the device management and
+  // userinfo services.
+  oauth2_access_token_fetcher_.reset(
+      new OAuth2AccessTokenFetcher(this, context));
+  std::vector<std::string> scopes;
+  scopes.push_back(GaiaConstants::kDeviceManagementServiceOAuth);
+  scopes.push_back(kServiceScopeGetUserInfo);
+  GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
+  oauth2_access_token_fetcher_->Start(
+      gaia_urls->oauth2_chrome_client_id(),
+      gaia_urls->oauth2_chrome_client_secret(),
+      login_refresh_token,
+      scopes);
+}
+
+void CloudPolicyClientRegistrationHelper::TokenHelper::OnGetTokenSuccess(
+    const std::string& access_token,
+    const base::Time& expiration_time) {
+  callback_.Run(access_token);
+}
+
+void CloudPolicyClientRegistrationHelper::TokenHelper::OnGetTokenFailure(
+    const GoogleServiceAuthError& error) {
+  callback_.Run("");
+}
+
+#endif
+
 CloudPolicyClientRegistrationHelper::CloudPolicyClientRegistrationHelper(
     net::URLRequestContextGetter* context,
     CloudPolicyClient* client,
@@ -48,6 +178,27 @@
     client_->RemoveObserver(this);
 }
 
+#if defined(OS_ANDROID)
+
+void CloudPolicyClientRegistrationHelper::StartRegistration(
+    AndroidProfileOAuth2TokenService* token_service,
+    const std::string& username,
+    const base::Closure& callback) {
+  DVLOG(1) << "Starting registration process with username";
+  DCHECK(!client_->is_registered());
+  callback_ = callback;
+  client_->AddObserver(this);
+
+  token_helper_.reset(new TokenHelperAndroid());
+  token_helper_->FetchAccessToken(
+      token_service,
+      username,
+      base::Bind(&CloudPolicyClientRegistrationHelper::OnTokenFetched,
+                 base::Unretained(this)));
+}
+
+#else
+
 void CloudPolicyClientRegistrationHelper::StartRegistrationWithLoginToken(
     const std::string& login_refresh_token,
     const base::Closure& callback) {
@@ -56,48 +207,30 @@
   callback_ = callback;
   client_->AddObserver(this);
 
-  // Start fetching an OAuth2 access token for the device management and
-  // userinfo services.
-  oauth2_access_token_fetcher_.reset(
-      new OAuth2AccessTokenFetcher(this, context_));
-  std::vector<std::string> scopes;
-  scopes.push_back(GaiaConstants::kDeviceManagementServiceOAuth);
-  scopes.push_back(kServiceScopeGetUserInfo);
-  GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
-  oauth2_access_token_fetcher_->Start(
-      gaia_urls->oauth2_chrome_client_id(),
-      gaia_urls->oauth2_chrome_client_secret(),
+  token_helper_.reset(new TokenHelper());
+  token_helper_->FetchAccessToken(
       login_refresh_token,
-      scopes);
+      context_,
+      base::Bind(&CloudPolicyClientRegistrationHelper::OnTokenFetched,
+                 base::Unretained(this)));
 }
 
-void CloudPolicyClientRegistrationHelper::StartRegistrationWithServicesToken(
-    const std::string& services_token,
-    const base::Closure& callback) {
-  DVLOG(1) << "Starting registration process with services token";
-  DCHECK(!client_->is_registered());
-  callback_ = callback;
-  client_->AddObserver(this);
-  OnGetTokenSuccess(services_token, base::Time());
-}
+#endif
 
-void CloudPolicyClientRegistrationHelper::OnGetTokenFailure(
-    const GoogleServiceAuthError& error) {
-  DLOG(WARNING) << "Could not fetch access token for "
-                << GaiaConstants::kDeviceManagementServiceOAuth;
-  oauth2_access_token_fetcher_.reset();
+void CloudPolicyClientRegistrationHelper::OnTokenFetched(
+    const std::string& access_token) {
+  token_helper_.reset();
 
-  // Invoke the callback to let them know the fetch failed.
-  RequestCompleted();
-}
+  if (access_token.empty()) {
+    DLOG(WARNING) << "Could not fetch access token for "
+                  << GaiaConstants::kDeviceManagementServiceOAuth;
+    RequestCompleted();
+    return;
+  }
 
-void CloudPolicyClientRegistrationHelper::OnGetTokenSuccess(
-    const std::string& access_token,
-    const base::Time& expiration_time) {
   // Cache the access token to be used after the GetUserInfo call.
   oauth_access_token_ = access_token;
   DVLOG(1) << "Fetched new scoped OAuth token:" << oauth_access_token_;
-  oauth2_access_token_fetcher_.reset();
   // Now we've gotten our access token - contact GAIA to see if this is a
   // hosted domain.
   user_info_fetcher_.reset(new UserInfoFetcher(this, context_));
diff --git a/chrome/browser/policy/cloud/cloud_policy_client_registration_helper.h b/chrome/browser/policy/cloud/cloud_policy_client_registration_helper.h
index 4dc3568..330cfbd 100644
--- a/chrome/browser/policy/cloud/cloud_policy_client_registration_helper.h
+++ b/chrome/browser/policy/cloud/cloud_policy_client_registration_helper.h
@@ -10,12 +10,12 @@
 #include "base/basictypes.h"
 #include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
 #include "chrome/browser/policy/cloud/cloud_policy_client.h"
 #include "chrome/browser/policy/cloud/user_info_fetcher.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
-#include "google_apis/gaia/oauth2_access_token_consumer.h"
 
-class OAuth2AccessTokenFetcher;
+class AndroidProfileOAuth2TokenService;
 
 namespace net {
 class URLRequestContextGetter;
@@ -26,8 +26,7 @@
 // Helper class that registers a CloudPolicyClient. It fetches an OAuth2 token
 // for the DM service if needed, and checks with Gaia if the account has policy
 // management enabled.
-class CloudPolicyClientRegistrationHelper : public OAuth2AccessTokenConsumer,
-                                            public UserInfoFetcher::Delegate,
+class CloudPolicyClientRegistrationHelper : public UserInfoFetcher::Delegate,
                                             public CloudPolicyClient::Observer {
  public:
   // |context| and |client| are not owned and must outlive this object.
@@ -41,23 +40,30 @@
       enterprise_management::DeviceRegisterRequest::Type registration_type);
   virtual ~CloudPolicyClientRegistrationHelper();
 
+#if defined(OS_ANDROID)
+  // Starts the client registration process. This version uses the
+  // AndroidProfileOAuth2TokenService to mint the new token for the userinfo
+  // and DM services, using the |username| account.
+  // |callback| is invoked when the registration is complete.
+  void StartRegistration(AndroidProfileOAuth2TokenService* token_service,
+                         const std::string& username,
+                         const base::Closure& callback);
+#else
   // Starts the client registration process. The |login_refresh_token| is used
   // to mint a new token for the userinfo and DM services.
   // |callback| is invoked when the registration is complete.
   void StartRegistrationWithLoginToken(const std::string& login_refresh_token,
                                        const base::Closure& callback);
-
-  // Starts the client registration process. The |services_token| is an OAuth2
-  // token scoped for the userinfo and DM services.
-  // |callback| is invoked when the registration is complete.
-  void StartRegistrationWithServicesToken(const std::string& services_token,
-                                          const base::Closure& callback);
+#endif
 
  private:
-  // OAuth2AccessTokenConsumer implementation:
-  virtual void OnGetTokenSuccess(const std::string& access_token,
-                                 const base::Time& expiration_time) OVERRIDE;
-  virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
+#if defined(OS_ANDROID)
+  class TokenHelperAndroid;
+#else
+  class TokenHelper;
+#endif
+
+  void OnTokenFetched(const std::string& oauth_access_token);
 
   // UserInfoFetcher::Delegate implementation:
   virtual void OnGetUserInfoSuccess(
@@ -73,8 +79,14 @@
   // Invoked when the registration request has been completed.
   void RequestCompleted();
 
-  // Fetcher used while obtaining an OAuth token for client registration.
-  scoped_ptr<OAuth2AccessTokenFetcher> oauth2_access_token_fetcher_;
+  // Internal helper used to fetch the access token. There is an OS_ANDROID
+  // implementation which uses the AccountManager and a known account name,
+  // and a desktop implementation which uses an OAuth2AccessTokenFetcher.
+#if defined(OS_ANDROID)
+  scoped_ptr<TokenHelperAndroid> token_helper_;
+#else
+  scoped_ptr<TokenHelper> token_helper_;
+#endif
 
   // Helper class for fetching information from GAIA about the currently
   // signed-in user.
diff --git a/chrome/browser/policy/cloud/cloud_policy_manager_unittest.cc b/chrome/browser/policy/cloud/cloud_policy_manager_unittest.cc
index 5fbd2eb..eb029de 100644
--- a/chrome/browser/policy/cloud/cloud_policy_manager_unittest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_manager_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/policy/cloud/cloud_policy_manager.h"
 
 #include "base/basictypes.h"
+#include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
@@ -13,6 +14,7 @@
 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h"
 #include "chrome/browser/policy/cloud/policy_builder.h"
 #include "chrome/browser/policy/configuration_policy_provider_test.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -82,32 +84,32 @@
 void TestHarness::InstallStringPolicy(const std::string& policy_name,
                                       const std::string& policy_value) {
   store_.policy_map_.Set(policy_name, policy_level(), policy_scope(),
-                         base::Value::CreateStringValue(policy_value));
+                         base::Value::CreateStringValue(policy_value), NULL);
 }
 
 void TestHarness::InstallIntegerPolicy(const std::string& policy_name,
                                        int policy_value) {
   store_.policy_map_.Set(policy_name, policy_level(), policy_scope(),
-                         base::Value::CreateIntegerValue(policy_value));
+                         base::Value::CreateIntegerValue(policy_value), NULL);
 }
 
 void TestHarness::InstallBooleanPolicy(const std::string& policy_name,
                                        bool policy_value) {
   store_.policy_map_.Set(policy_name, policy_level(), policy_scope(),
-                         base::Value::CreateBooleanValue(policy_value));
+                         base::Value::CreateBooleanValue(policy_value), NULL);
 }
 
 void TestHarness::InstallStringListPolicy(const std::string& policy_name,
                                           const base::ListValue* policy_value) {
   store_.policy_map_.Set(policy_name, policy_level(), policy_scope(),
-                         policy_value->DeepCopy());
+                         policy_value->DeepCopy(), NULL);
 }
 
 void TestHarness::InstallDictionaryPolicy(
     const std::string& policy_name,
     const base::DictionaryValue* policy_value) {
   store_.policy_map_.Set(policy_name, policy_level(), policy_scope(),
-                         policy_value->DeepCopy());
+                         policy_value->DeepCopy(), NULL);
 }
 
 // static
@@ -158,7 +160,7 @@
   virtual void SetUp() OVERRIDE {
     // Set up a policy map for testing.
     policy_map_.Set("key", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                    base::Value::CreateStringValue("value"));
+                    base::Value::CreateStringValue("value"), NULL);
     expected_bundle_.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
         .CopyFrom(policy_map_);
 
diff --git a/chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.cc b/chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.cc
index 30565c6..0631673 100644
--- a/chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.cc
@@ -12,8 +12,8 @@
 #include "base/sequenced_task_runner.h"
 #include "base/time/default_tick_clock.h"
 #include "base/time/tick_clock.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 
 namespace policy {
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_service_unittest.cc b/chrome/browser/policy/cloud/component_cloud_policy_service_unittest.cc
index 1a229c5..17f7da9 100644
--- a/chrome/browser/policy/cloud/component_cloud_policy_service_unittest.cc
+++ b/chrome/browser/policy/cloud/component_cloud_policy_service_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/policy/cloud/component_cloud_policy_service.h"
 
+#include "base/callback.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/message_loop.h"
 #include "base/pickle.h"
@@ -17,12 +18,13 @@
 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h"
 #include "chrome/browser/policy/cloud/policy_builder.h"
 #include "chrome/browser/policy/cloud/resource_cache.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_domain_descriptor.h"
 #include "chrome/browser/policy/policy_map.h"
-#include "chrome/browser/policy/policy_schema.h"
 #include "chrome/browser/policy/policy_types.h"
 #include "chrome/browser/policy/proto/cloud/chrome_extension_policy.pb.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
+#include "chrome/common/policy/policy_schema.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread.h"
 #include "net/url_request/test_url_fetcher_factory.h"
@@ -116,9 +118,9 @@
     builder_.payload().set_secure_hash(base::SHA1HashString(kTestPolicy));
 
     expected_policy_.Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                         base::Value::CreateStringValue("disabled"));
+                         base::Value::CreateStringValue("disabled"), NULL);
     expected_policy_.Set("Second", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-                         base::Value::CreateStringValue("maybe"));
+                         base::Value::CreateStringValue("maybe"), NULL);
 
     // A NULL |request_context_| is enough to construct the updater, but
     // ComponentCloudPolicyService::Backend::LoadStore() tests the pointer when
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_store.cc b/chrome/browser/policy/cloud/component_cloud_policy_store.cc
index afd627a..20bf955 100644
--- a/chrome/browser/policy/cloud/component_cloud_policy_store.cc
+++ b/chrome/browser/policy/cloud/component_cloud_policy_store.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/policy/cloud/component_cloud_policy_store.h"
 
+#include "base/callback.h"
 #include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/sha1.h"
@@ -12,6 +13,7 @@
 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
 #include "chrome/browser/policy/cloud/cloud_policy_validator.h"
 #include "chrome/browser/policy/cloud/resource_cache.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/proto/cloud/chrome_extension_policy.pb.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
@@ -334,7 +336,7 @@
     // If policy for components is ever used for device-level settings then
     // this must support a configurable scope; assuming POLICY_SCOPE_USER is
     // fine for now.
-    policy->Set(it.key(), level, POLICY_SCOPE_USER, value);
+    policy->Set(it.key(), level, POLICY_SCOPE_USER, value, NULL);
   }
 
   return true;
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_store_unittest.cc b/chrome/browser/policy/cloud/component_cloud_policy_store_unittest.cc
index 7c2c60a..123dead 100644
--- a/chrome/browser/policy/cloud/component_cloud_policy_store_unittest.cc
+++ b/chrome/browser/policy/cloud/component_cloud_policy_store_unittest.cc
@@ -9,12 +9,14 @@
 #include <string>
 
 #include "base/basictypes.h"
+#include "base/callback.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/sha1.h"
 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
 #include "chrome/browser/policy/cloud/policy_builder.h"
 #include "chrome/browser/policy/cloud/resource_cache.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/proto/cloud/chrome_extension_policy.pb.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -73,9 +75,9 @@
     PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
     PolicyMap& policy = expected_bundle_.Get(ns);
     policy.Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateStringValue("disabled"));
+               base::Value::CreateStringValue("disabled"), NULL);
     policy.Set("Second", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-               base::Value::CreateStringValue("maybe"));
+               base::Value::CreateStringValue("maybe"), NULL);
   }
 
   // Returns true if the policy exposed by the |store_| is empty.
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_updater_unittest.cc b/chrome/browser/policy/cloud/component_cloud_policy_updater_unittest.cc
index 11a73b5..a92e071 100644
--- a/chrome/browser/policy/cloud/component_cloud_policy_updater_unittest.cc
+++ b/chrome/browser/policy/cloud/component_cloud_policy_updater_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/sequenced_task_runner.h"
@@ -16,6 +17,7 @@
 #include "chrome/browser/policy/cloud/component_cloud_policy_store.h"
 #include "chrome/browser/policy/cloud/policy_builder.h"
 #include "chrome/browser/policy/cloud/resource_cache.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_bundle.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_types.h"
@@ -103,9 +105,9 @@
   PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
   PolicyMap& policy = expected_bundle_.Get(ns);
   policy.Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("disabled"));
+             base::Value::CreateStringValue("disabled"), NULL);
   policy.Set("Second", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("maybe"));
+             base::Value::CreateStringValue("maybe"), NULL);
 }
 
 scoped_ptr<em::PolicyFetchResponse>
diff --git a/chrome/browser/policy/cloud/resource_cache.cc b/chrome/browser/policy/cloud/resource_cache.cc
index 2214a2e..5523782 100644
--- a/chrome/browser/policy/cloud/resource_cache.cc
+++ b/chrome/browser/policy/cloud/resource_cache.cc
@@ -62,7 +62,7 @@
   // to protect against such races, especially as the cache is cross-platform
   // and therefore cannot use any POSIX-only tricks.
   return VerifyKeyPathAndGetSubkeyPath(key, true, subkey, &subkey_path) &&
-         base::Delete(subkey_path, false) &&
+         base::DeleteFile(subkey_path, false) &&
          file_util::WriteFile(subkey_path, data.data(), data.size());
 }
 
@@ -109,11 +109,11 @@
   DCHECK(CalledOnValidThread());
   base::FilePath subkey_path;
   if (VerifyKeyPathAndGetSubkeyPath(key, false, subkey, &subkey_path))
-    base::Delete(subkey_path, false);
+    base::DeleteFile(subkey_path, false);
   // Delete() does nothing if the directory given to it is not empty. Hence, the
   // call below deletes the directory representing |key| if its last subkey was
   // just removed and does nothing otherwise.
-  base::Delete(subkey_path.DirName(), false);
+  base::DeleteFile(subkey_path.DirName(), false);
 }
 
 void ResourceCache::PurgeOtherSubkeys(
@@ -138,12 +138,12 @@
        path = enumerator.Next()) {
     const std::string name(path.BaseName().MaybeAsASCII());
     if (encoded_subkeys_to_keep.find(name) == encoded_subkeys_to_keep.end())
-      base::Delete(path, false);
+      base::DeleteFile(path, false);
   }
   // Delete() does nothing if the directory given to it is not empty. Hence, the
   // call below deletes the directory representing |key| if all of its subkeys
   // were just removed and does nothing otherwise.
-  base::Delete(key_path, false);
+  base::DeleteFile(key_path, false);
 }
 
 bool ResourceCache::VerifyKeyPath(const std::string& key,
@@ -154,7 +154,7 @@
     return false;
   *path = cache_dir_.AppendASCII(encoded);
   return allow_create ? file_util::CreateDirectory(*path) :
-                        file_util::DirectoryExists(*path);
+                        base::DirectoryExists(*path);
 }
 
 bool ResourceCache::VerifyKeyPathAndGetSubkeyPath(const std::string& key,
diff --git a/chrome/browser/policy/cloud/user_cloud_policy_manager_unittest.cc b/chrome/browser/policy/cloud/user_cloud_policy_manager_unittest.cc
index 6f4629d..032ba5b 100644
--- a/chrome/browser/policy/cloud/user_cloud_policy_manager_unittest.cc
+++ b/chrome/browser/policy/cloud/user_cloud_policy_manager_unittest.cc
@@ -5,9 +5,11 @@
 #include "chrome/browser/policy/cloud/user_cloud_policy_manager.h"
 
 #include "base/basictypes.h"
+#include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "chrome/browser/policy/cloud/mock_user_cloud_policy_store.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -30,7 +32,7 @@
   virtual void SetUp() OVERRIDE {
     // Set up a policy map for testing.
     policy_map_.Set("key", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                    base::Value::CreateStringValue("value"));
+                    base::Value::CreateStringValue("value"), NULL);
     expected_bundle_.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
         .CopyFrom(policy_map_);
   }
diff --git a/chrome/browser/policy/cloud/user_cloud_policy_store.cc b/chrome/browser/policy/cloud/user_cloud_policy_store.cc
index 1381d98..3fa53d5 100644
--- a/chrome/browser/policy/cloud/user_cloud_policy_store.cc
+++ b/chrome/browser/policy/cloud/user_cloud_policy_store.cc
@@ -51,7 +51,7 @@
 policy::PolicyLoadResult LoadPolicyFromDisk(const base::FilePath& path) {
   policy::PolicyLoadResult result;
   // If the backing file does not exist, just return.
-  if (!file_util::PathExists(path)) {
+  if (!base::PathExists(path)) {
     result.status = policy::LOAD_RESULT_NO_POLICY_FILE;
     return result;
   }
@@ -122,7 +122,7 @@
 void UserCloudPolicyStore::Clear() {
   content::BrowserThread::PostTask(
       content::BrowserThread::FILE, FROM_HERE,
-      base::Bind(base::IgnoreResult(&base::Delete),
+      base::Bind(base::IgnoreResult(&base::DeleteFile),
                  backing_file_path_,
                  false));
   policy_.reset();
diff --git a/chrome/browser/policy/cloud/user_cloud_policy_store_unittest.cc b/chrome/browser/policy/cloud/user_cloud_policy_store_unittest.cc
index 671f914..1f5b21e 100644
--- a/chrome/browser/policy/cloud/user_cloud_policy_store_unittest.cc
+++ b/chrome/browser/policy/cloud/user_cloud_policy_store_unittest.cc
@@ -199,14 +199,14 @@
   EXPECT_FALSE(store_->policy_map().empty());
 
   // Policy file should exist.
-  ASSERT_TRUE(file_util::PathExists(policy_file()));
+  ASSERT_TRUE(base::PathExists(policy_file()));
 
   EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
   store_->Clear();
   RunUntilIdle();
 
   // Policy file should not exist.
-  ASSERT_TRUE(!file_util::PathExists(policy_file()));
+  ASSERT_TRUE(!base::PathExists(policy_file()));
 
   // Policy should be gone.
   EXPECT_FALSE(store_->policy());
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service.cc b/chrome/browser/policy/cloud/user_policy_signin_service.cc
index 542e458..4091e32 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service.cc
@@ -9,6 +9,7 @@
 #include "base/callback.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/policy/cloud/cloud_policy_client_registration_helper.h"
 #include "chrome/browser/policy/cloud/user_cloud_policy_manager.h"
 #include "chrome/browser/profiles/profile.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/signin/token_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "google_apis/gaia/gaia_constants.h"
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_android.cc b/chrome/browser/policy/cloud/user_policy_signin_service_android.cc
index 80bed74..70d60ac 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_android.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_android.cc
@@ -8,24 +8,30 @@
 #include "base/bind_helpers.h"
 #include "base/callback.h"
 #include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/prefs/pref_service.h"
+#include "base/time/time.h"
 #include "chrome/browser/policy/cloud/cloud_policy_client_registration_helper.h"
 #include "chrome/browser/policy/cloud/user_cloud_policy_manager.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/common/pref_names.h"
+#include "net/base/network_change_notifier.h"
 
 namespace policy {
 
 UserPolicySigninService::UserPolicySigninService(Profile* profile)
-    : UserPolicySigninServiceBase(profile) {}
+    : UserPolicySigninServiceBase(profile),
+      weak_factory_(this) {}
 
 UserPolicySigninService::~UserPolicySigninService() {}
 
 void UserPolicySigninService::RegisterPolicyClient(
     const std::string& username,
-    const std::string& services_token,
     const PolicyRegistrationCallback& callback) {
-  DCHECK(!services_token.empty());
-
   // Create a new CloudPolicyClient for fetching the DMToken.
   scoped_ptr<CloudPolicyClient> policy_client = PrepareToRegister(username);
   if (!policy_client) {
@@ -33,6 +39,8 @@
     return;
   }
 
+  CancelPendingRegistration();
+
   // Fire off the registration process. Callback keeps the CloudPolicyClient
   // alive for the length of the registration process.
   // TODO(joaodasilva): use DeviceRegisterRequest::ANDROID_BROWSER here once
@@ -43,8 +51,9 @@
       policy_client.get(),
       force_load_policy,
       enterprise_management::DeviceRegisterRequest::BROWSER));
-  registration_helper_->StartRegistrationWithServicesToken(
-      services_token,
+  registration_helper_->StartRegistration(
+      ProfileOAuth2TokenServiceFactory::GetForProfile(profile()),
+      username,
       base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback,
                  base::Unretained(this),
                  base::Passed(&policy_client),
@@ -63,6 +72,7 @@
 }
 
 void UserPolicySigninService::Shutdown() {
+  CancelPendingRegistration();
   registration_helper_.reset();
   UserPolicySigninServiceBase::Shutdown();
 }
@@ -77,12 +87,72 @@
   // client registration.
   if (manager->IsClientRegistered()) {
     DVLOG(1) << "Client already registered - not fetching DMToken";
-  } else {
-    // TODO(joaodasilva): figure out what to do in this case: a signed-in user
-    // just started Chrome but hasn't registered for policy yet.
-    // If a registration attempt is started from here then make sure this
-    // doesn't happen on every startup.
+    return;
   }
+
+  net::NetworkChangeNotifier::ConnectionType connection_type =
+      net::NetworkChangeNotifier::GetConnectionType();
+  base::TimeDelta retry_delay = base::TimeDelta::FromDays(3);
+  if (connection_type == net::NetworkChangeNotifier::CONNECTION_ETHERNET ||
+      connection_type == net::NetworkChangeNotifier::CONNECTION_WIFI) {
+    retry_delay = base::TimeDelta::FromDays(1);
+  }
+
+  base::Time last_check_time = base::Time::FromInternalValue(
+      profile()->GetPrefs()->GetInt64(prefs::kLastPolicyCheckTime));
+  base::Time now = base::Time::Now();
+  base::Time next_check_time = last_check_time + retry_delay;
+
+  // Check immediately if no check was ever done before (last_check_time == 0),
+  // or if the last check was in the future (?), or if we're already past the
+  // next check time. Otherwise, delay checking until the next check time.
+  base::TimeDelta try_registration_delay = base::TimeDelta::FromSeconds(5);
+  if (now > last_check_time && now < next_check_time)
+    try_registration_delay = next_check_time - now;
+
+  base::MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&UserPolicySigninService::RegisterCloudPolicyService,
+                 weak_factory_.GetWeakPtr()),
+      try_registration_delay);
+}
+
+void UserPolicySigninService::RegisterCloudPolicyService() {
+  // If the user signed-out while this task was waiting then Shutdown() would
+  // have been called, which would have invalidated this task. Since we're here
+  // then the user must still be signed-in.
+  SigninManager* signin_manager =
+      SigninManagerFactory::GetForProfile(profile());
+  const std::string& username = signin_manager->GetAuthenticatedUsername();
+  DCHECK(!username.empty());
+  DCHECK(!GetManager()->IsClientRegistered());
+  DCHECK(GetManager()->core()->client());
+
+  // Persist the current time as the last policy registration attempt time.
+  profile()->GetPrefs()->SetInt64(prefs::kLastPolicyCheckTime,
+                                  base::Time::Now().ToInternalValue());
+
+  // TODO(joaodasilva): use DeviceRegisterRequest::ANDROID_BROWSER here once
+  // the server is ready. http://crbug.com/248527
+  const bool force_load_policy = false;
+  registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
+      profile()->GetRequestContext(),
+      GetManager()->core()->client(),
+      force_load_policy,
+      enterprise_management::DeviceRegisterRequest::BROWSER));
+  registration_helper_->StartRegistration(
+      ProfileOAuth2TokenServiceFactory::GetForProfile(profile()),
+      username,
+      base::Bind(&UserPolicySigninService::OnRegistrationDone,
+                 base::Unretained(this)));
+}
+
+void UserPolicySigninService::CancelPendingRegistration() {
+  weak_factory_.InvalidateWeakPtrs();
+}
+
+void UserPolicySigninService::OnRegistrationDone() {
+  registration_helper_.reset();
 }
 
 }  // namespace policy
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_android.h b/chrome/browser/policy/cloud/user_policy_signin_service_android.h
index 0cabf6a..d6c1349 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_android.h
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_android.h
@@ -10,6 +10,7 @@
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "chrome/browser/policy/cloud/user_policy_signin_service_base.h"
 
 class Profile;
@@ -26,11 +27,11 @@
   virtual ~UserPolicySigninService();
 
   // Registers a CloudPolicyClient for fetching policy for |username|.
-  // |services_token| is an OAuth2 token for the userinfo and DM services.
+  // This requests an OAuth2 token for the services involved, and contacts
+  // the policy service if the account has management enabled.
   // |callback| is invoked once the CloudPolicyClient is ready to fetch policy,
   // or once it is determined that |username| is not a managed account.
   void RegisterPolicyClient(const std::string& username,
-                            const std::string& services_token,
                             const PolicyRegistrationCallback& callback);
 
  private:
@@ -43,7 +44,16 @@
   // CloudPolicyService::Observer implementation:
   virtual void OnInitializationCompleted(CloudPolicyService* service) OVERRIDE;
 
+  // Registers for cloud policy for an already signed-in user.
+  void RegisterCloudPolicyService();
+
+  // Cancels a pending cloud policy registration attempt.
+  void CancelPendingRegistration();
+
+  void OnRegistrationDone();
+
   scoped_ptr<CloudPolicyClientRegistrationHelper> registration_helper_;
+  base::WeakPtrFactory<UserPolicySigninService> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(UserPolicySigninService);
 };
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_base.cc b/chrome/browser/policy/cloud/user_policy_signin_service_base.cc
index de3f7b2..ca6b560 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_base.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_base.cc
@@ -9,13 +9,13 @@
 #include "base/message_loop.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/policy/cloud/user_cloud_policy_manager.h"
 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc b/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc
index 8461391..7804541 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc
@@ -14,6 +14,7 @@
 
 #if defined(OS_ANDROID)
 #include "chrome/browser/policy/cloud/user_policy_signin_service_android.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #else
 #include "chrome/browser/policy/cloud/user_policy_signin_service.h"
 #include "chrome/browser/signin/token_service_factory.h"
@@ -25,7 +26,9 @@
     : BrowserContextKeyedServiceFactory(
         "UserPolicySigninService",
         BrowserContextDependencyManager::GetInstance()) {
-#if !defined(OS_ANDROID)
+#if defined(OS_ANDROID)
+  DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
+#else
   DependsOn(TokenServiceFactory::GetInstance());
 #endif
   DependsOn(SigninManagerFactory::GetInstance());
@@ -59,12 +62,18 @@
   return true;
 }
 
-void UserPolicySigninServiceFactory::RegisterUserPrefs(
+void UserPolicySigninServiceFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* user_prefs) {
   user_prefs->RegisterBooleanPref(
       prefs::kDisableCloudPolicyOnSignin,
       false,
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+#if defined(OS_ANDROID)
+  user_prefs->RegisterInt64Pref(
+      prefs::kLastPolicyCheckTime,
+      0,
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+#endif
 }
 
 }  // namespace policy
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_factory.h b/chrome/browser/policy/cloud/user_policy_signin_service_factory.h
index 9f925ec..8ced58c 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_factory.h
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_factory.h
@@ -39,7 +39,7 @@
   virtual bool ServiceIsCreatedWithBrowserContext() const OVERRIDE;
 
   // Register the preferences related to cloud-based user policy.
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
 
  private:
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
index 7954e17..e94caff 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
@@ -7,7 +7,9 @@
 #include "base/message_loop.h"
 #include "base/prefs/pref_service.h"
 #include "base/run_loop.h"
+#include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
 #include "chrome/browser/policy/cloud/mock_device_management_service.h"
@@ -15,18 +17,20 @@
 #include "chrome/browser/policy/cloud/user_cloud_policy_manager.h"
 #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
 #include "chrome/browser/prefs/browser_prefs.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/fake_signin_manager.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_pref_service_syncable.h"
 #include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/test/test_browser_thread.h"
 #include "google_apis/gaia/gaia_constants.h"
+#include "google_apis/gaia/google_service_auth_error.h"
 #include "net/http/http_status_code.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "net/url_request/url_request_context_getter.h"
@@ -36,6 +40,8 @@
 
 #if defined(OS_ANDROID)
 #include "chrome/browser/policy/cloud/user_policy_signin_service_android.h"
+#include "chrome/browser/signin/android_profile_oauth2_token_service.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #else
 #include "chrome/browser/policy/cloud/user_policy_signin_service.h"
 #include "chrome/browser/signin/token_service.h"
@@ -52,6 +58,8 @@
 
 namespace {
 
+const char kTestUser[] = "testuser@test.com";
+
 const char kValidTokenResponse[] =
     "{"
     "  \"access_token\": \"at1\","
@@ -64,6 +72,10 @@
     "  \"hd\": \"test.com\""
     "}";
 
+const char kCombinedScopes[] =
+    "https://www.googleapis.com/auth/chromeosdevicemanagement "
+    "https://www.googleapis.com/auth/userinfo.email";
+
 class SigninManagerFake : public FakeSigninManager {
  public:
   explicit SigninManagerFake(Profile* profile)
@@ -82,6 +94,50 @@
   }
 };
 
+#if defined(OS_ANDROID)
+
+class FakeProfileOAuth2TokenService : public AndroidProfileOAuth2TokenService {
+ public:
+  explicit FakeProfileOAuth2TokenService(Profile* profile)
+      : AndroidProfileOAuth2TokenService(profile->GetRequestContext()) {
+    Initialize(profile);
+  }
+
+  static BrowserContextKeyedService* Build(content::BrowserContext* profile) {
+    return new FakeProfileOAuth2TokenService(static_cast<Profile*>(profile));
+  }
+
+  // AndroidProfileOAuth2TokenService overrides:
+  virtual void FetchOAuth2Token(
+      const std::string& username,
+      const std::string& scope,
+      const FetchOAuth2TokenCallback& callback) OVERRIDE {
+    ASSERT_TRUE(!HasPendingRequest());
+    ASSERT_EQ(kTestUser, username);
+    ASSERT_EQ(kCombinedScopes, scope);
+    pending_callback_ = callback;
+  }
+
+  void IssueToken(const std::string& token) {
+    ASSERT_TRUE(HasPendingRequest());
+    GoogleServiceAuthError error = GoogleServiceAuthError::AuthErrorNone();
+    if (token.empty())
+      error = GoogleServiceAuthError::FromServiceError("fail");
+    pending_callback_.Run(
+        error, token, base::Time::Now() + base::TimeDelta::FromDays(1));
+    pending_callback_.Reset();
+  }
+
+  bool HasPendingRequest() const {
+    return !pending_callback_.is_null();
+  }
+
+ private:
+  FetchOAuth2TokenCallback pending_callback_;
+};
+
+#endif
+
 class UserPolicySigninServiceTest : public testing::Test {
  public:
   UserPolicySigninServiceTest()
@@ -100,8 +156,10 @@
 
   void RegisterPolicyClientWithCallback(UserPolicySigninService* service) {
     service->RegisterPolicyClient(
-        "testuser@test.com",
+        kTestUser,
+#if !defined(OS_ANDROID)
         "mock_oauth_token",
+#endif
         base::Bind(&UserPolicySigninServiceTest::OnRegisterCompleted,
                    base::Unretained(this)));
     ASSERT_TRUE(IsRequestActive());
@@ -125,7 +183,7 @@
     // up a UserCloudPolicyManager with a MockUserCloudPolicyStore.
     scoped_ptr<TestingPrefServiceSyncable> prefs(
         new TestingPrefServiceSyncable());
-    chrome::RegisterUserPrefs(prefs->registry());
+    chrome::RegisterUserProfilePrefs(prefs->registry());
     TestingProfile::Builder builder;
     builder.SetPrefService(scoped_ptr<PrefServiceSyncable>(prefs.Pass()));
     profile_ = builder.Build().Pass();
@@ -139,6 +197,14 @@
         SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse(
             profile_.get(), SigninManagerFake::Build));
 
+#if defined(OS_ANDROID)
+    ProfileOAuth2TokenServiceFactory* factory =
+        ProfileOAuth2TokenServiceFactory::GetInstance();
+    token_service_ = static_cast<FakeProfileOAuth2TokenService*>(
+        factory->SetTestingFactoryAndUse(profile_.get(),
+                                         FakeProfileOAuth2TokenService::Build));
+#endif
+
     // Make sure the UserPolicySigninService is created.
     UserPolicySigninServiceFactory::GetForProfile(profile_.get());
     Mock::VerifyAndClearExpectations(mock_store_);
@@ -158,15 +224,24 @@
   }
 
   bool IsRequestActive() {
+#if defined(OS_ANDROID)
+    if (token_service_->HasPendingRequest())
+      return true;
+#endif
     return url_factory_.GetFetcherByID(0);
   }
 
   void MakeOAuthTokenFetchSucceed() {
+#if defined(OS_ANDROID)
+    ASSERT_TRUE(token_service_->HasPendingRequest());
+    token_service_->IssueToken("fake_token");
+#else
     ASSERT_TRUE(IsRequestActive());
     net::TestURLFetcher* fetcher = url_factory_.GetFetcherByID(0);
     fetcher->set_response_code(net::HTTP_OK);
     fetcher->SetResponseString(kValidTokenResponse);
     fetcher->delegate()->OnURLFetchComplete(fetcher);
+#endif
   }
 
   void ReportHostedDomainStatus(bool is_hosted_domain) {
@@ -183,10 +258,8 @@
     EXPECT_CALL(*this, OnPolicyRefresh(true)).Times(0);
     RegisterPolicyClientWithCallback(signin_service);
 
-#if !defined(OS_ANDROID)
     // Mimic successful oauth token fetch.
     MakeOAuthTokenFetchSucceed();
-#endif
 
     // When the user is from a hosted domain, this should kick off client
     // registration.
@@ -276,6 +349,9 @@
   net::TestURLFetcherFactory url_factory_;
 
   SigninManagerFake* signin_manager_;
+#if defined(OS_ANDROID)
+  FakeProfileOAuth2TokenService* token_service_;  // Not owned.
+#endif
 
   // Used in conjunction with OnRegisterCompleted() to test client registration
   // callbacks.
@@ -315,7 +391,7 @@
 TEST_F(UserPolicySigninServiceTest, InitWhileSignedIn) {
   // Set the user as signed in.
   SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
-      "testuser@test.com");
+      kTestUser);
 
   // Let the SigninService know that the profile has been created.
   content::NotificationService::current()->Notify(
@@ -354,7 +430,7 @@
 
   // Now sign in the user.
   SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
-      "testuser@test.com");
+      kTestUser);
 
   // Complete initialization of the store.
   mock_store_->NotifyStoreLoaded();
@@ -413,7 +489,7 @@
 
   // Now sign in the user.
   SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
-      "testuser@test.com");
+      kTestUser);
 
   // Make oauth token available.
   TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
@@ -447,7 +523,7 @@
 
   // Now sign in the user.
   SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
-      "testuser@test.com");
+      kTestUser);
 
   // Make oauth token available.
   TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
@@ -480,7 +556,7 @@
   EXPECT_CALL(*mock_store_, Clear());
   // Set the user as signed in.
   SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
-      "testuser@test.com");
+      kTestUser);
 
   // Let the SigninService know that the profile has been created.
   content::NotificationService::current()->Notify(
@@ -510,9 +586,15 @@
   EXPECT_FALSE(register_completed_);
 
   // Cause the access token fetch to fail - callback should be invoked.
+#if defined(OS_ANDROID)
+  ASSERT_TRUE(token_service_->HasPendingRequest());
+  token_service_->IssueToken("");
+#else
   net::TestURLFetcher* fetcher = url_factory_.GetFetcherByID(0);
   fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, -1));
   fetcher->delegate()->OnURLFetchComplete(fetcher);
+#endif
+
   EXPECT_TRUE(register_completed_);
   EXPECT_FALSE(created_client_.get());
   EXPECT_FALSE(IsRequestActive());
@@ -527,14 +609,12 @@
   ASSERT_FALSE(manager_->core()->service());
   ASSERT_TRUE(IsRequestActive());
 
-#if !defined(OS_ANDROID)
   // Cause the access token request to succeed.
   MakeOAuthTokenFetchSucceed();
 
   // Should be a follow-up fetch to check the hosted-domain status.
   ASSERT_TRUE(IsRequestActive());
   Mock::VerifyAndClearExpectations(this);
-#endif
 
   EXPECT_FALSE(register_completed_);
 
@@ -557,10 +637,8 @@
   // UserCloudPolicyManager should not be initialized.
   ASSERT_FALSE(manager_->core()->service());
 
-#if !defined(OS_ANDROID)
   // Mimic successful oauth token fetch.
   MakeOAuthTokenFetchSucceed();
-#endif
 
   EXPECT_FALSE(register_completed_);
 
@@ -595,10 +673,8 @@
       UserPolicySigninServiceFactory::GetForProfile(profile_.get());
   RegisterPolicyClientWithCallback(signin_service);
 
-#if !defined(OS_ANDROID)
   // Mimic successful oauth token fetch.
   MakeOAuthTokenFetchSucceed();
-#endif
 
   // When the user is from a hosted domain, this should kick off client
   // registration.
diff --git a/chrome/browser/policy/configuration_policy_handler.cc b/chrome/browser/policy/configuration_policy_handler.cc
index d3e2c89..030b4d5 100644
--- a/chrome/browser/policy/configuration_policy_handler.cc
+++ b/chrome/browser/policy/configuration_policy_handler.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <string>
 
+#include "base/callback.h"
 #include "base/files/file_path.h"
 #include "base/json/json_writer.h"
 #include "base/logging.h"
@@ -15,9 +16,11 @@
 #include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_util.h"
 #include "chrome/browser/extensions/external_policy_loader.h"
 #include "chrome/browser/policy/configuration_policy_pref_store.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_error_map.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/prefs/proxy_config_dictionary.h"
@@ -25,7 +28,6 @@
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/search_engines/search_terms_data.h"
 #include "chrome/browser/search_engines/template_url.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
@@ -169,7 +171,10 @@
     const PolicyMap::Entry& entry = it->second;
     if (entry.value->GetAsDictionary(&dict)) {
       base::StringValue* value = DictionaryToJSONString(dict);
-      policies->Set(it->first, entry.level, entry.scope, value);
+      policies->Set(it->first, entry.level, entry.scope,
+                    value, entry.external_data_fetcher ?
+                        new ExternalDataFetcher(*entry.external_data_fetcher) :
+                        NULL);
     } else if (entry.value->GetAsList(&list)) {
       for (size_t i = 0; i < list->GetSize(); ++i) {
         if (list->GetDictionary(i, &dict)) {
diff --git a/chrome/browser/policy/configuration_policy_handler_unittest.cc b/chrome/browser/policy/configuration_policy_handler_unittest.cc
index a57f1fb..44426ca 100644
--- a/chrome/browser/policy/configuration_policy_handler_unittest.cc
+++ b/chrome/browser/policy/configuration_policy_handler_unittest.cc
@@ -2,10 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/prefs/pref_value_map.h"
 #include "chrome/browser/extensions/external_policy_loader.h"
 #include "chrome/browser/policy/configuration_policy_handler.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_error_map.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/common/pref_names.h"
@@ -34,28 +36,29 @@
       kTestTypeMap, kTestTypeMap + arraysize(kTestTypeMap));
 
   policy_map.Set(key::kExtensionAllowedTypes, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   list.AppendString("one");
   policy_map.Set(key::kExtensionAllowedTypes, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   list.AppendString("invalid");
   policy_map.Set(key::kExtensionAllowedTypes, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
   EXPECT_FALSE(errors.GetErrors(key::kExtensionAllowedTypes).empty());
 
   policy_map.Set(key::kExtensionAllowedTypes, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateStringValue("no list"));
+                 POLICY_SCOPE_USER,
+                 base::Value::CreateStringValue("no list"), NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -73,7 +76,7 @@
       kTestTypeMap, kTestTypeMap + arraysize(kTestTypeMap));
 
   policy_map.Set(key::kExtensionAllowedTypes, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   handler.ApplyPolicySettings(policy_map, &prefs);
   EXPECT_TRUE(prefs.GetValue(prefs::kExtensionAllowedTypes, &value));
   EXPECT_TRUE(base::Value::Equals(&expected, value));
@@ -81,14 +84,14 @@
   list.AppendString("two");
   expected.AppendInteger(2);
   policy_map.Set(key::kExtensionAllowedTypes, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   handler.ApplyPolicySettings(policy_map, &prefs);
   EXPECT_TRUE(prefs.GetValue(prefs::kExtensionAllowedTypes, &value));
   EXPECT_TRUE(base::Value::Equals(&expected, value));
 
   list.AppendString("invalid");
   policy_map.Set(key::kExtensionAllowedTypes, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   handler.ApplyPolicySettings(policy_map, &prefs);
   EXPECT_TRUE(prefs.GetValue(prefs::kExtensionAllowedTypes, &value));
   EXPECT_TRUE(base::Value::Equals(&expected, value));
@@ -104,19 +107,19 @@
 
   // Check that values lying in the accepted range are not rejected.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
@@ -124,21 +127,22 @@
   // Check that values lying outside the accepted range are not rejected
   // (because clamping is enabled) but do yield a warning message.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
 
   // Check that an entirely invalid value is rejected and yields an error
   // message.
-  policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateStringValue("invalid"));
+  policy_map.Set(key::kDiskCacheSize,
+                 POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+                 base::Value::CreateStringValue("invalid"), NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -154,19 +158,19 @@
 
   // Check that values lying in the accepted range are not rejected.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
@@ -174,21 +178,21 @@
   // Check that values lying outside the accepted range are rejected and yield
   // an error message.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5), NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15), NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
 
   // Check that an entirely invalid value is rejected and yields an error
   // message.
-  policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateStringValue("invalid"));
+  policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+                 base::Value::CreateStringValue("invalid"), NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -206,7 +210,7 @@
 
   // Check that values lying in the accepted range are written to the pref.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateIntegerValue(0));
@@ -214,7 +218,7 @@
   EXPECT_TRUE(base::Value::Equals(expected.get(), value));
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateIntegerValue(5));
@@ -222,7 +226,7 @@
   EXPECT_TRUE(base::Value::Equals(expected.get(), value));
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateIntegerValue(10));
@@ -232,7 +236,7 @@
   // Check that values lying outside the accepted range are clamped and written
   // to the pref.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateIntegerValue(0));
@@ -240,7 +244,7 @@
   EXPECT_TRUE(base::Value::Equals(expected.get(), value));
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateIntegerValue(10));
@@ -260,7 +264,7 @@
 
   // Check that values lying in the accepted range are written to the pref.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateIntegerValue(0));
@@ -268,7 +272,7 @@
   EXPECT_TRUE(base::Value::Equals(expected.get(), value));
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateIntegerValue(5));
@@ -276,7 +280,7 @@
   EXPECT_TRUE(base::Value::Equals(expected.get(), value));
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateIntegerValue(10));
@@ -295,19 +299,19 @@
 
   // Check that values lying in the accepted range are not rejected.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
@@ -315,21 +319,21 @@
   // Check that values lying outside the accepted range are not rejected
   // (because clamping is enabled) but do yield a warning message.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
 
   // Check that an entirely invalid value is rejected and yields an error
   // message.
-  policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateStringValue("invalid"));
+  policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+                 base::Value::CreateStringValue("invalid"), NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -346,19 +350,19 @@
 
   // Check that values lying in the accepted range are not rejected.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
@@ -366,21 +370,21 @@
   // Check that values lying outside the accepted range are rejected and yield
   // an error message.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5), NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15), NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
 
   // Check that an entirely invalid value is rejected and yields an error
   // message.
-  policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateStringValue("invalid"));
+  policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+                 base::Value::CreateStringValue("invalid"), NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -399,7 +403,7 @@
 
   // Check that values lying in the accepted range are written to the pref.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateDoubleValue(0.0));
@@ -407,7 +411,7 @@
   EXPECT_TRUE(base::Value::Equals(expected.get(), value));
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateDoubleValue(0.05));
@@ -415,7 +419,7 @@
   EXPECT_TRUE(base::Value::Equals(expected.get(), value));
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateDoubleValue(0.1));
@@ -425,7 +429,7 @@
   // Check that values lying outside the accepted range are clamped and written
   // to the pref.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(-5), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateDoubleValue(0.0));
@@ -433,7 +437,7 @@
   EXPECT_TRUE(base::Value::Equals(expected.get(), value));
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(15), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateDoubleValue(0.1));
@@ -454,7 +458,7 @@
 
   // Check that values lying in the accepted range are written to the pref.
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateDoubleValue(0.0));
@@ -462,7 +466,7 @@
   EXPECT_TRUE(base::Value::Equals(expected.get(), value));
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(5), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateDoubleValue(0.05));
@@ -470,7 +474,7 @@
   EXPECT_TRUE(base::Value::Equals(expected.get(), value));
 
   policy_map.Set(key::kDiskCacheSize, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10));
+                 POLICY_SCOPE_USER, base::Value::CreateIntegerValue(10), NULL);
   prefs.Clear();
   handler.ApplyPolicySettings(policy_map, &prefs);
   expected.reset(base::Value::CreateDoubleValue(0.1));
@@ -487,28 +491,28 @@
                                      true);
 
   policy_map.Set(key::kExtensionInstallBlacklist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   list.Append(Value::CreateStringValue("abcdefghijklmnopabcdefghijklmnop"));
   policy_map.Set(key::kExtensionInstallBlacklist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   list.Append(Value::CreateStringValue("*"));
   policy_map.Set(key::kExtensionInstallBlacklist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   list.Append(Value::CreateStringValue("invalid"));
   policy_map.Set(key::kExtensionInstallBlacklist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -529,14 +533,14 @@
   expected.Append(Value::CreateStringValue("abcdefghijklmnopabcdefghijklmnop"));
 
   policy_map.Set(key::kExtensionInstallBlacklist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, policy.DeepCopy());
+                 POLICY_SCOPE_USER, policy.DeepCopy(), NULL);
   handler.ApplyPolicySettings(policy_map, &prefs);
   EXPECT_TRUE(prefs.GetValue(prefs::kExtensionInstallDenyList, &value));
   EXPECT_TRUE(base::Value::Equals(&expected, value));
 
   policy.Append(Value::CreateStringValue("invalid"));
   policy_map.Set(key::kExtensionInstallBlacklist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, policy.DeepCopy());
+                 POLICY_SCOPE_USER, policy.DeepCopy(), NULL);
   handler.ApplyPolicySettings(policy_map, &prefs);
   EXPECT_TRUE(prefs.GetValue(prefs::kExtensionInstallDenyList, &value));
   EXPECT_TRUE(base::Value::Equals(&expected, value));
@@ -549,14 +553,14 @@
   ExtensionInstallForcelistPolicyHandler handler;
 
   policy_map.Set(key::kExtensionInstallForcelist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   list.AppendString("abcdefghijklmnopabcdefghijklmnop;http://example.com");
   policy_map.Set(key::kExtensionInstallForcelist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
@@ -565,7 +569,7 @@
   // entry should still be translated successfully.
   list.AppendString("adfasdf;http://example.com");
   policy_map.Set(key::kExtensionInstallForcelist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_EQ(1U, errors.size());
@@ -573,7 +577,7 @@
   // Add an entry with bad URL, which should generate another error.
   list.AppendString("abcdefghijklmnopabcdefghijklmnop;nourl");
   policy_map.Set(key::kExtensionInstallForcelist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_EQ(2U, errors.size());
@@ -581,7 +585,7 @@
   // Just an extension ID should also generate an error.
   list.AppendString("abcdefghijklmnopabcdefghijklmnop");
   policy_map.Set(key::kExtensionInstallForcelist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_EQ(3U, errors.size());
@@ -600,7 +604,7 @@
   EXPECT_FALSE(value);
 
   policy_map.Set(key::kExtensionInstallForcelist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, policy.DeepCopy());
+                 POLICY_SCOPE_USER, policy.DeepCopy(), NULL);
   handler.ApplyPolicySettings(policy_map, &prefs);
   EXPECT_TRUE(prefs.GetValue(prefs::kExtensionInstallForceList, &value));
   EXPECT_TRUE(base::Value::Equals(&expected, value));
@@ -609,14 +613,14 @@
   extensions::ExternalPolicyLoader::AddExtension(
       &expected, "abcdefghijklmnopabcdefghijklmnop", "http://example.com");
   policy_map.Set(key::kExtensionInstallForcelist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, policy.DeepCopy());
+                 POLICY_SCOPE_USER, policy.DeepCopy(), NULL);
   handler.ApplyPolicySettings(policy_map, &prefs);
   EXPECT_TRUE(prefs.GetValue(prefs::kExtensionInstallForceList, &value));
   EXPECT_TRUE(base::Value::Equals(&expected, value));
 
   policy.AppendString("invalid");
   policy_map.Set(key::kExtensionInstallForcelist, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, policy.DeepCopy());
+                 POLICY_SCOPE_USER, policy.DeepCopy(), NULL);
   handler.ApplyPolicySettings(policy_map, &prefs);
   EXPECT_TRUE(prefs.GetValue(prefs::kExtensionInstallForceList, &value));
   EXPECT_TRUE(base::Value::Equals(&expected, value));
@@ -631,28 +635,28 @@
       prefs::kExtensionAllowedInstallSites);
 
   policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   list.Append(Value::CreateStringValue("http://*.google.com/*"));
   policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   list.Append(Value::CreateStringValue("<all_urls>"));
   policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_TRUE(errors.empty());
 
   list.Append(Value::CreateStringValue("invalid"));
   policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -662,7 +666,7 @@
   // would be compatible today, it would be brittle, so we disallow.
   list.Append(Value::CreateStringValue("*"));
   policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -680,7 +684,7 @@
 
   list.Append(Value::CreateStringValue("https://corp.monkey.net/*"));
   policy_map.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, list.DeepCopy());
+                 POLICY_SCOPE_USER, list.DeepCopy(), NULL);
   handler.ApplyPolicySettings(policy_map, &prefs);
   ASSERT_TRUE(prefs.GetValue(prefs::kExtensionAllowedInstallSites, &value));
   EXPECT_TRUE(base::Value::Equals(&list, value));
diff --git a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
index b0e723a..eb76ecc 100644
--- a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
+++ b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
@@ -4,6 +4,7 @@
 
 #include <string>
 
+#include "base/callback.h"
 #include "base/files/file_path.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop.h"
@@ -11,6 +12,7 @@
 #include "base/run_loop.h"
 #include "chrome/browser/policy/configuration_policy_handler.h"
 #include "chrome/browser/policy/configuration_policy_pref_store.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_service_impl.h"
@@ -87,7 +89,7 @@
   in_value->Append(base::Value::CreateStringValue("test2,"));
   PolicyMap policy;
   policy.Set(GetParam().policy_name(), POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, in_value);
+             POLICY_SCOPE_USER, in_value, NULL);
   UpdateProviderPolicy(policy);
   const base::Value* value = NULL;
   EXPECT_TRUE(store_->GetValue(GetParam().pref_name(), &value));
@@ -127,7 +129,7 @@
   PolicyMap policy;
   policy.Set(GetParam().policy_name(), POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("http://chromium.org"));
+             base::Value::CreateStringValue("http://chromium.org"), NULL);
   UpdateProviderPolicy(policy);
   const base::Value* value = NULL;
   EXPECT_TRUE(store_->GetValue(GetParam().pref_name(), &value));
@@ -179,7 +181,7 @@
 TEST_P(ConfigurationPolicyPrefStoreBooleanTest, SetValue) {
   PolicyMap policy;
   policy.Set(GetParam().policy_name(), POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policy);
   const base::Value* value = NULL;
   EXPECT_TRUE(store_->GetValue(GetParam().pref_name(), &value));
@@ -190,7 +192,7 @@
   EXPECT_FALSE(boolean_value);
 
   policy.Set(GetParam().policy_name(), POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policy);
   value = NULL;
   EXPECT_TRUE(store_->GetValue(GetParam().pref_name(), &value));
@@ -328,7 +330,7 @@
 TEST_P(ConfigurationPolicyPrefStoreIntegerTest, SetValue) {
   PolicyMap policy;
   policy.Set(GetParam().policy_name(), POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateIntegerValue(2));
+             POLICY_SCOPE_USER, base::Value::CreateIntegerValue(2), NULL);
   UpdateProviderPolicy(policy);
   const base::Value* value = NULL;
   EXPECT_TRUE(store_->GetValue(GetParam().pref_name(), &value));
@@ -405,13 +407,15 @@
 TEST_F(ConfigurationPolicyPrefStoreProxyTest, ManualOptions) {
   PolicyMap policy;
   policy.Set(key::kProxyBypassList, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("http://chromium.org/override"));
+             base::Value::CreateStringValue("http://chromium.org/override"),
+             NULL);
   policy.Set(key::kProxyServer, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("chromium.org"));
+             base::Value::CreateStringValue("chromium.org"), NULL);
   policy.Set(
       key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
       base::Value::CreateIntegerValue(
-          ProxyPolicyHandler::PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE));
+          ProxyPolicyHandler::PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE),
+      NULL);
   UpdateProviderPolicy(policy);
 
   VerifyProxyPrefs("chromium.org",
@@ -425,11 +429,13 @@
   policy.Set(
       key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
       base::Value::CreateIntegerValue(
-          ProxyPolicyHandler::PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE));
+          ProxyPolicyHandler::PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE),
+      NULL);
   policy.Set(key::kProxyBypassList, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("http://chromium.org/override"));
+             base::Value::CreateStringValue("http://chromium.org/override"),
+             NULL);
   policy.Set(key::kProxyServer, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("chromium.org"));
+             base::Value::CreateStringValue("chromium.org"), NULL);
   UpdateProviderPolicy(policy);
 
   VerifyProxyPrefs("chromium.org",
@@ -443,7 +449,8 @@
   policy.Set(
       key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
       base::Value::CreateIntegerValue(
-          ProxyPolicyHandler::PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE));
+          ProxyPolicyHandler::PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE),
+      NULL);
   UpdateProviderPolicy(policy);
 
   const base::Value* value = NULL;
@@ -455,7 +462,8 @@
   PolicyMap policy;
   policy.Set(key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              base::Value::CreateIntegerValue(
-                 ProxyPolicyHandler::PROXY_SERVER_MODE));
+                 ProxyPolicyHandler::PROXY_SERVER_MODE),
+             NULL);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(
       std::string(), std::string(), std::string(), ProxyPrefs::MODE_DIRECT);
@@ -464,7 +472,8 @@
 TEST_F(ConfigurationPolicyPrefStoreProxyTest, NoProxyModeName) {
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue(ProxyPrefs::kDirectProxyModeName));
+             base::Value::CreateStringValue(ProxyPrefs::kDirectProxyModeName),
+             NULL);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(
       std::string(), std::string(), std::string(), ProxyPrefs::MODE_DIRECT);
@@ -475,7 +484,8 @@
   policy.Set(
       key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
       base::Value::CreateIntegerValue(
-          ProxyPolicyHandler::PROXY_AUTO_DETECT_PROXY_SERVER_MODE));
+          ProxyPolicyHandler::PROXY_AUTO_DETECT_PROXY_SERVER_MODE),
+      NULL);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(std::string(),
                    std::string(),
@@ -487,7 +497,8 @@
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              base::Value::CreateStringValue(
-                 ProxyPrefs::kAutoDetectProxyModeName));
+                 ProxyPrefs::kAutoDetectProxyModeName),
+             NULL);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(std::string(),
                    std::string(),
@@ -498,10 +509,12 @@
 TEST_F(ConfigurationPolicyPrefStoreProxyTest, PacScriptProxyMode) {
   PolicyMap policy;
   policy.Set(key::kProxyPacUrl, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("http://short.org/proxy.pac"));
+             base::Value::CreateStringValue("http://short.org/proxy.pac"),
+             NULL);
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              base::Value::CreateStringValue(
-                 ProxyPrefs::kPacScriptProxyModeName));
+                 ProxyPrefs::kPacScriptProxyModeName),
+             NULL);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(std::string(),
                    "http://short.org/proxy.pac",
@@ -513,7 +526,8 @@
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              base::Value::CreateStringValue(
-                 ProxyPrefs::kPacScriptProxyModeName));
+                 ProxyPrefs::kPacScriptProxyModeName),
+             NULL);
   UpdateProviderPolicy(policy);
   const base::Value* value = NULL;
   EXPECT_FALSE(store_->GetValue(prefs::kProxy, &value));
@@ -526,14 +540,17 @@
   policy.Set(key::kProxyServer,
              POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER,
-             base::Value::CreateStringValue(std::string()));
+             base::Value::CreateStringValue(std::string()),
+             NULL);
   policy.Set(key::kProxyPacUrl,
              POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("http://short.org/proxy.pac"));
+             base::Value::CreateStringValue("http://short.org/proxy.pac"),
+             NULL);
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              base::Value::CreateStringValue(
-                 ProxyPrefs::kPacScriptProxyModeName));
+                 ProxyPrefs::kPacScriptProxyModeName),
+             NULL);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(std::string(),
                    "http://short.org/proxy.pac",
@@ -545,7 +562,8 @@
   PolicyMap policy;
   policy.Set(key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
       base::Value::CreateIntegerValue(
-          ProxyPolicyHandler::PROXY_USE_SYSTEM_PROXY_SERVER_MODE));
+          ProxyPolicyHandler::PROXY_USE_SYSTEM_PROXY_SERVER_MODE),
+      NULL);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(
       std::string(), std::string(), std::string(), ProxyPrefs::MODE_SYSTEM);
@@ -554,7 +572,8 @@
 TEST_F(ConfigurationPolicyPrefStoreProxyTest, UseSystemProxyMode) {
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue(ProxyPrefs::kSystemProxyModeName));
+             base::Value::CreateStringValue(ProxyPrefs::kSystemProxyModeName),
+             NULL);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(
       std::string(), std::string(), std::string(), ProxyPrefs::MODE_SYSTEM);
@@ -565,10 +584,12 @@
   PolicyMap policy;
   policy.Set(key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              base::Value::CreateIntegerValue(
-                 ProxyPolicyHandler::PROXY_SERVER_MODE));
+                 ProxyPolicyHandler::PROXY_SERVER_MODE),
+             NULL);
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              base::Value::CreateStringValue(
-                 ProxyPrefs::kAutoDetectProxyModeName));
+                 ProxyPrefs::kAutoDetectProxyModeName),
+             NULL);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(std::string(),
                    std::string(),
@@ -580,14 +601,16 @@
   // No mode expects all three parameters being set.
   PolicyMap policy;
   policy.Set(key::kProxyPacUrl, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("http://short.org/proxy.pac"));
+             base::Value::CreateStringValue("http://short.org/proxy.pac"),
+             NULL);
   policy.Set(key::kProxyBypassList, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("http://chromium.org/override"));
+             base::Value::CreateStringValue("http://chromium.org/override"),
+             NULL);
   policy.Set(key::kProxyServer, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("chromium.org"));
+             base::Value::CreateStringValue("chromium.org"), NULL);
   for (int i = 0; i < ProxyPolicyHandler::MODE_COUNT; ++i) {
     policy.Set(key::kProxyServerMode, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateIntegerValue(i));
+               POLICY_SCOPE_USER, base::Value::CreateIntegerValue(i), NULL);
     UpdateProviderPolicy(policy);
     const base::Value* value = NULL;
     EXPECT_FALSE(store_->GetValue(prefs::kProxy, &value));
@@ -639,24 +662,28 @@
   encodings->AppendString("UTF-16");
   encodings->AppendString("UTF-8");
   policy->Set(key::kDefaultSearchProviderEnabled, POLICY_LEVEL_MANDATORY,
-              POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+              POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   policy->Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
-              POLICY_SCOPE_USER, base::Value::CreateStringValue(kSearchURL));
+              POLICY_SCOPE_USER, base::Value::CreateStringValue(kSearchURL),
+              NULL);
   policy->Set(key::kDefaultSearchProviderName, POLICY_LEVEL_MANDATORY,
-              POLICY_SCOPE_USER, base::Value::CreateStringValue(kName));
+              POLICY_SCOPE_USER, base::Value::CreateStringValue(kName), NULL);
   policy->Set(key::kDefaultSearchProviderKeyword, POLICY_LEVEL_MANDATORY,
-              POLICY_SCOPE_USER, base::Value::CreateStringValue(kKeyword));
+              POLICY_SCOPE_USER, base::Value::CreateStringValue(kKeyword),
+              NULL);
   policy->Set(key::kDefaultSearchProviderSuggestURL, POLICY_LEVEL_MANDATORY,
-              POLICY_SCOPE_USER, base::Value::CreateStringValue(kSuggestURL));
+              POLICY_SCOPE_USER, base::Value::CreateStringValue(kSuggestURL),
+              NULL);
   policy->Set(key::kDefaultSearchProviderIconURL, POLICY_LEVEL_MANDATORY,
-              POLICY_SCOPE_USER, base::Value::CreateStringValue(kIconURL));
+              POLICY_SCOPE_USER, base::Value::CreateStringValue(kIconURL),
+              NULL);
   policy->Set(key::kDefaultSearchProviderEncodings, POLICY_LEVEL_MANDATORY,
-              POLICY_SCOPE_USER, encodings);
+              POLICY_SCOPE_USER, encodings, NULL);
   policy->Set(key::kDefaultSearchProviderAlternateURLs, POLICY_LEVEL_MANDATORY,
-              POLICY_SCOPE_USER, default_alternate_urls_.DeepCopy());
+              POLICY_SCOPE_USER, default_alternate_urls_.DeepCopy(), NULL);
   policy->Set(key::kDefaultSearchProviderSearchTermsReplacementKey,
               POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-              base::Value::CreateStringValue(kReplacementKey));
+              base::Value::CreateStringValue(kReplacementKey), NULL);
 }
 
 // Checks that if the policy for default search is valid, i.e. there's a
@@ -664,9 +691,10 @@
 TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, MinimallyDefined) {
   PolicyMap policy;
   policy.Set(key::kDefaultSearchProviderEnabled, POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   policy.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateStringValue(kSearchURL));
+             POLICY_SCOPE_USER, base::Value::CreateStringValue(kSearchURL),
+             NULL);
   UpdateProviderPolicy(policy);
 
   const base::Value* value = NULL;
@@ -768,7 +796,7 @@
   const char* const bad_search_url = "http://test.com/noSearchTerms";
   policy.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER,
-             base::Value::CreateStringValue(bad_search_url));
+             base::Value::CreateStringValue(bad_search_url), NULL);
   UpdateProviderPolicy(policy);
 
   EXPECT_FALSE(store_->GetValue(prefs::kDefaultSearchProviderSearchURL, NULL));
@@ -788,7 +816,7 @@
 TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, Disabled) {
   PolicyMap policy;
   policy.Set(key::kDefaultSearchProviderEnabled, POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policy);
 
   const base::Value* value = NULL;
@@ -819,12 +847,14 @@
       policy.Set(key::kIncognitoEnabled, POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER,
                  base::Value::CreateBooleanValue(
-                     incognito_enabled == INCOGNITO_ENABLED_TRUE));
+                     incognito_enabled == INCOGNITO_ENABLED_TRUE),
+                 NULL);
     }
     if (availability >= 0) {
       policy.Set(key::kIncognitoModeAvailability, POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER,
-                 base::Value::CreateIntegerValue(availability));
+                 base::Value::CreateIntegerValue(availability),
+                 NULL);
     }
     UpdateProviderPolicy(policy);
   }
@@ -902,7 +932,7 @@
 TEST_F(ConfigurationPolicyPrefStoreSyncTest, Enabled) {
   PolicyMap policy;
   policy.Set(key::kSyncDisabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateBooleanValue(false));
+             base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policy);
   // Enabling Sync should not set the pref.
   EXPECT_FALSE(store_->GetValue(prefs::kSyncManaged, NULL));
@@ -911,7 +941,7 @@
 TEST_F(ConfigurationPolicyPrefStoreSyncTest, Disabled) {
   PolicyMap policy;
   policy.Set(key::kSyncDisabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateBooleanValue(true));
+             base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policy);
   // Sync should be flagged as managed.
   const base::Value* value = NULL;
@@ -939,7 +969,8 @@
   policy.Set(key::kDownloadDirectory,
              POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER,
-             base::Value::CreateStringValue(std::string()));
+             base::Value::CreateStringValue(std::string()),
+             NULL);
   UpdateProviderPolicy(policy);
 
   // Setting a DownloadDirectory should disable the PromptForDownload pref.
@@ -959,7 +990,7 @@
   PolicyMap policy;
   EXPECT_FALSE(store_->GetValue(prefs::kPromptForDownload, NULL));
   policy.Set(key::kAllowFileSelectionDialogs, POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policy);
 
   // Allowing file-selection dialogs should not influence the PromptForDownload
@@ -972,7 +1003,7 @@
   PolicyMap policy;
   EXPECT_FALSE(store_->GetValue(prefs::kPromptForDownload, NULL));
   policy.Set(key::kAllowFileSelectionDialogs, POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policy);
 
   // Disabling file-selection dialogs should disable the PromptForDownload pref.
@@ -997,7 +1028,7 @@
 TEST_F(ConfigurationPolicyPrefStoreAutofillTest, Enabled) {
   PolicyMap policy;
   policy.Set(key::kAutoFillEnabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateBooleanValue(true));
+             base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policy);
   // Enabling Autofill should not set the pref.
   EXPECT_FALSE(store_->GetValue(autofill::prefs::kAutofillEnabled, NULL));
@@ -1006,7 +1037,7 @@
 TEST_F(ConfigurationPolicyPrefStoreAutofillTest, Disabled) {
   PolicyMap policy;
   policy.Set(key::kAutoFillEnabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateBooleanValue(false));
+             base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policy);
   // Disabling Autofill should switch the pref to managed.
   const base::Value* value = NULL;
@@ -1031,7 +1062,7 @@
 TEST_F(ConfigurationPolicyPrefStoreScreenMagnifierTypeTest, Disabled) {
   PolicyMap policy;
   policy.Set(key::kScreenMagnifierType, POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0));
+             POLICY_SCOPE_USER, base::Value::CreateIntegerValue(0), NULL);
   UpdateProviderPolicy(policy);
   const base::Value* enabled = NULL;
   EXPECT_TRUE(store_->GetValue(prefs::kScreenMagnifierEnabled, &enabled));
@@ -1046,7 +1077,7 @@
 TEST_F(ConfigurationPolicyPrefStoreScreenMagnifierTypeTest, Enabled) {
   PolicyMap policy;
   policy.Set(key::kScreenMagnifierType, POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateIntegerValue(1));
+             POLICY_SCOPE_USER, base::Value::CreateIntegerValue(1), NULL);
   UpdateProviderPolicy(policy);
   const base::Value* enabled = NULL;
   EXPECT_TRUE(store_->GetValue(prefs::kScreenMagnifierEnabled, &enabled));
@@ -1083,7 +1114,7 @@
   EXPECT_CALL(observer_, OnPrefValueChanged(prefs::kHomePage)).Times(1);
   PolicyMap policy;
   policy.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateStringValue("http://www.chromium.org"));
+             base::Value::CreateStringValue("http://www.chromium.org"), NULL);
   UpdateProviderPolicy(policy);
   Mock::VerifyAndClearExpectations(&observer_);
   EXPECT_TRUE(store_->GetValue(prefs::kHomePage, &value));
@@ -1120,11 +1151,11 @@
   EXPECT_FALSE(store_->GetValue(prefs::kManagedDefaultJavaScriptSetting, NULL));
   PolicyMap policy;
   policy.Set(key::kJavascriptEnabled, POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policy);
   EXPECT_FALSE(store_->GetValue(prefs::kManagedDefaultJavaScriptSetting, NULL));
   policy.Set(key::kJavascriptEnabled, POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policy);
   const base::Value* value = NULL;
   EXPECT_TRUE(store_->GetValue(prefs::kManagedDefaultJavaScriptSetting,
@@ -1136,7 +1167,7 @@
   EXPECT_FALSE(store_->GetValue(prefs::kManagedDefaultJavaScriptSetting, NULL));
   PolicyMap policy;
   policy.Set(key::kJavascriptEnabled, POLICY_LEVEL_MANDATORY,
-             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+             POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policy);
   const base::Value* value = NULL;
   EXPECT_TRUE(store_->GetValue(prefs::kManagedDefaultJavaScriptSetting,
@@ -1145,7 +1176,8 @@
   // DefaultJavaScriptSetting overrides JavascriptEnabled.
   policy.Set(key::kDefaultJavaScriptSetting, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER,
-             base::Value::CreateIntegerValue(CONTENT_SETTING_ALLOW));
+             base::Value::CreateIntegerValue(CONTENT_SETTING_ALLOW),
+             NULL);
   UpdateProviderPolicy(policy);
   EXPECT_TRUE(store_->GetValue(prefs::kManagedDefaultJavaScriptSetting,
                                &value));
diff --git a/chrome/browser/policy/configuration_policy_provider.cc b/chrome/browser/policy/configuration_policy_provider.cc
index ea7d378..18f849c 100644
--- a/chrome/browser/policy/configuration_policy_provider.cc
+++ b/chrome/browser/policy/configuration_policy_provider.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/policy/configuration_policy_provider.h"
 
+#include "base/callback.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_domain_descriptor.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "policy/policy_constants.h"
@@ -56,7 +58,8 @@
     policies->Set(key::kProxySettings,
                   current_priority.level,
                   current_priority.scope,
-                  proxy_settings.release());
+                  proxy_settings.release(),
+                  NULL);
   }
 }
 
diff --git a/chrome/browser/policy/configuration_policy_provider_test.cc b/chrome/browser/policy/configuration_policy_provider_test.cc
index 00cb606..c0af27f 100644
--- a/chrome/browser/policy/configuration_policy_provider_test.cc
+++ b/chrome/browser/policy/configuration_policy_provider_test.cc
@@ -5,9 +5,11 @@
 #include "chrome/browser/policy/configuration_policy_provider_test.h"
 
 #include "base/bind.h"
+#include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/policy/configuration_policy_provider.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_bundle.h"
 #include "chrome/browser/policy/policy_map.h"
@@ -113,7 +115,8 @@
       .Set(policy_name,
            test_harness_->policy_level(),
            test_harness_->policy_scope(),
-           expected_value.DeepCopy());
+           expected_value.DeepCopy(),
+           NULL);
   EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
   // TODO(joaodasilva): set the policy in the POLICY_DOMAIN_EXTENSIONS too,
   // and extend the |expected_bundle|, once all providers are ready.
@@ -228,7 +231,8 @@
       .Set(test_policy_definitions::kKeyString,
            test_harness_->policy_level(),
            test_harness_->policy_scope(),
-           base::Value::CreateStringValue("value"));
+           base::Value::CreateStringValue("value"),
+           NULL);
   EXPECT_TRUE(provider_->policies().Equals(bundle));
   provider_->RemoveObserver(&observer);
 }
@@ -238,18 +242,21 @@
   policy_map.Set(key::kProxyServerMode,
                  POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER,
-                 base::Value::CreateIntegerValue(3));
+                 base::Value::CreateIntegerValue(3),
+                 NULL);
 
   // Both these policies should be ignored, since there's a higher priority
   // policy available.
   policy_map.Set(key::kProxyMode,
                  POLICY_LEVEL_RECOMMENDED,
                  POLICY_SCOPE_USER,
-                 base::Value::CreateStringValue("pac_script"));
+                 base::Value::CreateStringValue("pac_script"),
+                 NULL);
   policy_map.Set(key::kProxyPacUrl,
                  POLICY_LEVEL_RECOMMENDED,
                  POLICY_SCOPE_USER,
-                 base::Value::CreateStringValue("http://example.com/wpad.dat"));
+                 base::Value::CreateStringValue("http://example.com/wpad.dat"),
+                 NULL);
 
   MockConfigurationPolicyProvider provider;
   provider.Init();
@@ -262,7 +269,8 @@
       .Set(key::kProxySettings,
            POLICY_LEVEL_MANDATORY,
            POLICY_SCOPE_USER,
-           expected_value);
+           expected_value,
+           NULL);
   EXPECT_TRUE(provider.policies().Equals(expected_bundle));
   provider.Shutdown();
 }
@@ -313,7 +321,8 @@
   expected_policy.Set(test_policy_definitions::kKeyDictionary,
                       test_harness_->policy_level(),
                       test_harness_->policy_scope(),
-                      policy_dict.DeepCopy());
+                      policy_dict.DeepCopy(),
+                      NULL);
   PolicyBundle expected_bundle;
   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
       .CopyFrom(expected_policy);
diff --git a/chrome/browser/policy/external_data_fetcher.cc b/chrome/browser/policy/external_data_fetcher.cc
new file mode 100644
index 0000000..7a01607
--- /dev/null
+++ b/chrome/browser/policy/external_data_fetcher.cc
@@ -0,0 +1,50 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/external_data_fetcher.h"
+
+#include "base/callback.h"
+
+#if defined(ENABLE_CONFIGURATION_POLICY)
+#include "chrome/browser/policy/external_data_manager.h"
+#else
+#include "chrome/browser/policy/stub_external_data_manager.h"
+#endif
+
+namespace policy {
+
+ExternalDataFetcher::ExternalDataFetcher(const ExternalDataFetcher& other)
+    : manager_(other.manager_),
+      policy_(other.policy_) {
+}
+
+ExternalDataFetcher::~ExternalDataFetcher() {
+}
+
+// static
+bool ExternalDataFetcher::Equals(const ExternalDataFetcher* first,
+                                 const ExternalDataFetcher* second) {
+  if (!first && !second)
+    return true;
+  if (!first || !second)
+    return false;
+  return first->manager_.get() == second->manager_.get() &&
+         first->policy_ == second->policy_;
+}
+
+void ExternalDataFetcher::Fetch(const FetchCallback& callback) const {
+  if (manager_)
+    manager_->Fetch(policy_, callback);
+  else
+    callback.Run(STATUS_NO_DATA, make_scoped_ptr(new std::string));
+}
+
+ExternalDataFetcher::ExternalDataFetcher(
+    base::WeakPtr<ExternalDataManager> manager,
+    const std::string& policy)
+    : manager_(manager),
+      policy_(policy) {
+}
+
+}  // namespace policy
diff --git a/chrome/browser/policy/external_data_fetcher.h b/chrome/browser/policy/external_data_fetcher.h
new file mode 100644
index 0000000..4e2f55d
--- /dev/null
+++ b/chrome/browser/policy/external_data_fetcher.h
@@ -0,0 +1,59 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_EXTERNAL_DATA_FETCHER_H_
+#define CHROME_BROWSER_POLICY_EXTERNAL_DATA_FETCHER_H_
+
+#include <string>
+
+#include "base/callback_forward.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+
+namespace policy {
+
+class ExternalDataManager;
+
+// A helper that encapsulates the parameters required to retrieve the external
+// data for a policy.
+class ExternalDataFetcher {
+ public:
+  enum Status {
+    // This policy does not reference any external data.
+    STATUS_NO_DATA,
+    // This policy references external data. The data has been requested but is
+    // not available yet. Once the data is successfully downloaded and verified,
+    // the PolicyService that this ExternalDataFetcher belongs to will invoke
+    // OnPolicyUpdated() to inform its observers that the data is available.
+    STATUS_DATA_PENDING,
+    // This external data referenced by the policy has been downloaded, verified
+    // and is included in the callback.
+    STATUS_DATA_AVAILABLE
+  };
+
+  typedef base::Callback<void(Status, scoped_ptr<std::string>)> FetchCallback;
+
+  ExternalDataFetcher(const ExternalDataFetcher& other);
+  ~ExternalDataFetcher();
+
+  static bool Equals(const ExternalDataFetcher* first,
+                     const ExternalDataFetcher* second);
+
+  void Fetch(const FetchCallback& callback) const;
+
+ protected:
+  friend class PolicyDomainDescriptorTest;
+  friend class PolicyMapTest;
+
+  ExternalDataFetcher(base::WeakPtr<ExternalDataManager> manager,
+                      const std::string& policy);
+
+ private:
+  base::WeakPtr<ExternalDataManager> manager_;
+  std::string policy_;
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_POLICY_EXTERNAL_DATA_FETCHER_H_
diff --git a/chrome/browser/policy/external_data_manager.cc b/chrome/browser/policy/external_data_manager.cc
new file mode 100644
index 0000000..bb10886
--- /dev/null
+++ b/chrome/browser/policy/external_data_manager.cc
@@ -0,0 +1,18 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/external_data_manager.h"
+
+#include "base/callback.h"
+
+namespace policy {
+
+void ExternalDataManager::Fetch(
+    const std::string& policy,
+    const ExternalDataFetcher::FetchCallback& callback) {
+  // TODO(bartfab): Implement support for fetching external policy data.
+  // crbug.com/256635
+}
+
+}  // policy
diff --git a/chrome/browser/policy/external_data_manager.h b/chrome/browser/policy/external_data_manager.h
new file mode 100644
index 0000000..dc61987
--- /dev/null
+++ b/chrome/browser/policy/external_data_manager.h
@@ -0,0 +1,30 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_EXTERNAL_DATA_MANAGER_H_
+#define CHROME_BROWSER_POLICY_EXTERNAL_DATA_MANAGER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
+
+namespace policy {
+
+// Downloads, verifies, caches and retrieves external data referenced by
+// policies.
+// TODO(bartfab): Implement support for fetching external policy data.
+// http://crbug.com/256635
+class ExternalDataManager {
+ public:
+  void Fetch(const std::string& policy,
+             const ExternalDataFetcher::FetchCallback& callback);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ExternalDataManager);
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_POLICY_EXTERNAL_DATA_MANAGER_H_
diff --git a/chrome/browser/policy/managed_mode_policy_provider.cc b/chrome/browser/policy/managed_mode_policy_provider.cc
index ec6fba6..cff8971 100644
--- a/chrome/browser/policy/managed_mode_policy_provider.cc
+++ b/chrome/browser/policy/managed_mode_policy_provider.cc
@@ -4,12 +4,14 @@
 
 #include "chrome/browser/policy/managed_mode_policy_provider.h"
 
+#include "base/callback.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/prefs/json_pref_store.h"
 #include "base/strings/string_util.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/managed_mode/managed_mode_url_filter.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_bundle.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
 #include "chrome/browser/profiles/profile.h"
@@ -364,7 +366,7 @@
       continue;
 
     policy_map->Set(it.key(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                    it.value().DeepCopy());
+                    it.value().DeepCopy(), NULL);
   }
 
   DictionaryValue* split_settings = GetSplitSettings();
@@ -374,7 +376,7 @@
       continue;
 
     policy_map->Set(it.key(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                    it.value().DeepCopy());
+                    it.value().DeepCopy(), NULL);
   }
   UpdatePolicy(policy_bundle.Pass());
 }
diff --git a/chrome/browser/policy/managed_mode_policy_provider_unittest.cc b/chrome/browser/policy/managed_mode_policy_provider_unittest.cc
index 5b0d661..b4ba945 100644
--- a/chrome/browser/policy/managed_mode_policy_provider_unittest.cc
+++ b/chrome/browser/policy/managed_mode_policy_provider_unittest.cc
@@ -2,10 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/callback.h"
 #include "base/json/json_reader.h"
 #include "base/prefs/testing_pref_store.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/policy/configuration_policy_provider_test.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/managed_mode_policy_provider.h"
 #include "chrome/browser/policy/policy_bundle.h"
 #include "chrome/browser/policy/policy_map.h"
@@ -382,7 +384,8 @@
   policy_map->Set(kPolicyKey,
                   POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_USER,
-                  policy_value.DeepCopy());
+                  policy_value.DeepCopy(),
+                  NULL);
   EXPECT_TRUE(provider_.policies().Equals(expected_bundle));
 }
 
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index f10972e..87f9f7e 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/callback.h"
 #include "base/command_line.h"
 #include "base/file_util.h"
 #include "base/files/file_enumerator.h"
@@ -27,6 +28,7 @@
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/autocomplete/autocomplete_controller.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/download/download_prefs.h"
@@ -43,6 +45,7 @@
 #include "chrome/browser/plugins/plugin_prefs.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/policy/cloud/test_request_interceptor.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
@@ -64,9 +67,7 @@
 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
 #include "chrome/browser/ui/omnibox/omnibox_view.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_process_type.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/content_settings_pattern.h"
@@ -286,14 +287,14 @@
       content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
   base::FilePath downloaded = dir.Append(file);
-  EXPECT_FALSE(file_util::PathExists(downloaded));
+  EXPECT_FALSE(base::PathExists(downloaded));
   ui_test_utils::NavigateToURLWithDisposition(
       browser, url, CURRENT_TAB,
       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   observer.WaitForFinished();
   EXPECT_EQ(
       1u, observer.NumDownloadsSeenInState(content::DownloadItem::COMPLETE));
-  EXPECT_TRUE(file_util::PathExists(downloaded));
+  EXPECT_TRUE(base::PathExists(downloaded));
   base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES);
   EXPECT_EQ(file, enumerator.Next().BaseName());
   EXPECT_EQ(base::FilePath(), enumerator.Next());
@@ -472,8 +473,9 @@
 
   void SetScreenshotPolicy(bool enabled) {
     PolicyMap policies;
-    policies.Set(key::kDisableScreenshots, POLICY_LEVEL_MANDATORY,
-                 POLICY_SCOPE_USER, base::Value::CreateBooleanValue(!enabled));
+    policies.Set(key::kDisableScreenshots,
+                 POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+                 base::Value::CreateBooleanValue(!enabled), NULL);
     UpdateProviderPolicy(policies);
   }
 
@@ -627,7 +629,7 @@
     PolicyMap policies;
     policies.Set(
         key::kApplicationLocaleValue, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        base::Value::CreateStringValue("fr"));
+        base::Value::CreateStringValue("fr"), NULL);
     provider_.UpdateChromePolicy(policies);
     // The "en-US" ResourceBundle is always loaded before this step for tests,
     // but in this test we want the browser to load the bundle as it
@@ -665,7 +667,7 @@
 
   PolicyMap policies;
   policies.Set(key::kBookmarkBarEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_TRUE(prefs->IsManagedPreference(prefs::kShowBookmarkBar));
   EXPECT_TRUE(prefs->GetBoolean(prefs::kShowBookmarkBar));
@@ -676,7 +678,7 @@
   EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state());
 
   policies.Set(key::kBookmarkBarEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_TRUE(prefs->IsManagedPreference(prefs::kShowBookmarkBar));
   EXPECT_FALSE(prefs->GetBoolean(prefs::kShowBookmarkBar));
@@ -712,7 +714,7 @@
   // Now set the policy and the cookie should be gone after another restart.
   PolicyMap policies;
   policies.Set(key::kDefaultCookiesSetting, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateIntegerValue(4));
+               POLICY_SCOPE_USER, base::Value::CreateIntegerValue(4), NULL);
   UpdateProviderPolicy(policies);
 }
 
@@ -750,19 +752,22 @@
   // Override the default search provider using policies.
   PolicyMap policies;
   policies.Set(key::kDefaultSearchProviderEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
-  policies.Set(key::kDefaultSearchProviderKeyword, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateStringValue(kKeyword));
-  policies.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateStringValue(kSearchURL));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
+  policies.Set(key::kDefaultSearchProviderKeyword,
+               POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+               base::Value::CreateStringValue(kKeyword), NULL);
+  policies.Set(key::kDefaultSearchProviderSearchURL,
+               POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+               base::Value::CreateStringValue(kSearchURL), NULL);
   base::ListValue* alternate_urls = new base::ListValue();
   alternate_urls->AppendString(kAlternateURL0);
   alternate_urls->AppendString(kAlternateURL1);
   policies.Set(key::kDefaultSearchProviderAlternateURLs, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, alternate_urls);
+               POLICY_SCOPE_USER, alternate_urls, NULL);
   policies.Set(key::kDefaultSearchProviderSearchTermsReplacementKey,
                POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateStringValue(kSearchTermsReplacementKey));
+               base::Value::CreateStringValue(kSearchTermsReplacementKey),
+               NULL);
   UpdateProviderPolicy(policies);
   default_search = service->GetDefaultSearchProvider();
   ASSERT_TRUE(default_search);
@@ -788,7 +793,7 @@
   // Verify that searching from the omnibox can be disabled.
   ui_test_utils::NavigateToURL(browser(), GURL(content::kAboutBlankURL));
   policies.Set(key::kDefaultSearchProviderEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   EXPECT_TRUE(service->GetDefaultSearchProvider());
   UpdateProviderPolicy(policies);
   EXPECT_FALSE(service->GetDefaultSearchProvider());
@@ -830,7 +835,7 @@
   // Override the default SafeSearch setting using policies.
   PolicyMap policies;
   policies.Set(key::kForceSafeSearch, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
 
   EXPECT_TRUE(prefs->IsManagedPreference(prefs::kForceSafeSearch));
@@ -886,21 +891,25 @@
   // Override the default search provider using policies.
   PolicyMap policies;
   policies.Set(key::kDefaultSearchProviderEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
-  policies.Set(key::kDefaultSearchProviderKeyword, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateStringValue(kKeyword));
-  policies.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateStringValue(kSearchURL));
-  policies.Set(key::kDefaultSearchProviderInstantURL, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateStringValue(kInstantURL));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
+  policies.Set(key::kDefaultSearchProviderKeyword,
+               POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+               base::Value::CreateStringValue(kKeyword), NULL);
+  policies.Set(key::kDefaultSearchProviderSearchURL,
+               POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+               base::Value::CreateStringValue(kSearchURL), NULL);
+  policies.Set(key::kDefaultSearchProviderInstantURL,
+               POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+               base::Value::CreateStringValue(kInstantURL), NULL);
   base::ListValue* alternate_urls = new base::ListValue();
   alternate_urls->AppendString(kAlternateURL0);
   alternate_urls->AppendString(kAlternateURL1);
   policies.Set(key::kDefaultSearchProviderAlternateURLs, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, alternate_urls);
+               POLICY_SCOPE_USER, alternate_urls, NULL);
   policies.Set(key::kDefaultSearchProviderSearchTermsReplacementKey,
                POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateStringValue(kSearchTermsReplacementKey));
+               base::Value::CreateStringValue(kSearchTermsReplacementKey),
+               NULL);
   UpdateProviderPolicy(policies);
   default_search = service->GetDefaultSearchProvider();
   ASSERT_TRUE(default_search);
@@ -973,7 +982,7 @@
   // Disable with a policy.
   PolicyMap policies;
   policies.Set(key::kDisable3DAPIs, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
   // Crash and reload the tab to get a new renderer.
   content::CrashTab(contents);
@@ -981,7 +990,7 @@
   EXPECT_FALSE(IsWebGLEnabled(contents));
   // Enable with a policy.
   policies.Set(key::kDisable3DAPIs, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policies);
   content::CrashTab(contents);
   EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_RELOAD));
@@ -994,14 +1003,14 @@
   EXPECT_TRUE(net::HttpStreamFactory::spdy_enabled());
   PolicyMap policies;
   policies.Set(key::kDisableSpdy, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
   content::RunAllPendingInMessageLoop();
   EXPECT_FALSE(net::HttpStreamFactory::spdy_enabled());
   // Verify that it can be force-enabled too.
   browser()->profile()->GetPrefs()->SetBoolean(prefs::kDisableSpdy, true);
   policies.Set(key::kDisableSpdy, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policies);
   content::RunAllPendingInMessageLoop();
   EXPECT_TRUE(net::HttpStreamFactory::spdy_enabled());
@@ -1030,7 +1039,7 @@
   disabled_plugins.Append(base::Value::CreateStringValue("*Flash*"));
   PolicyMap policies;
   policies.Set(key::kDisabledPlugins, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, disabled_plugins.DeepCopy());
+               POLICY_SCOPE_USER, disabled_plugins.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_FALSE(plugin_prefs->IsPluginEnabled(*flash));
   // The user shouldn't be able to enable it.
@@ -1057,7 +1066,7 @@
   disabled_plugins.Append(base::Value::CreateStringValue("*"));
   PolicyMap policies;
   policies.Set(key::kDisabledPlugins, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, disabled_plugins.DeepCopy());
+               POLICY_SCOPE_USER, disabled_plugins.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_FALSE(plugin_prefs->IsPluginEnabled(*flash));
   // The user shouldn't be able to enable it.
@@ -1069,7 +1078,7 @@
   disabled_plugins_exceptions.Append(
       base::Value::CreateStringValue("*Flash*"));
   policies.Set(key::kDisabledPluginsExceptions, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, disabled_plugins_exceptions.DeepCopy());
+               POLICY_SCOPE_USER, disabled_plugins_exceptions.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   // It should revert to the user's preference automatically.
   EXPECT_TRUE(plugin_prefs->IsPluginEnabled(*flash));
@@ -1098,7 +1107,7 @@
   plugin_list.Append(base::Value::CreateStringValue(kFlashPluginName));
   PolicyMap policies;
   policies.Set(key::kEnabledPlugins, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, plugin_list.DeepCopy());
+               POLICY_SCOPE_USER, plugin_list.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_TRUE(plugin_prefs->IsPluginEnabled(*flash));
   // The user can't disable it anymore.
@@ -1107,7 +1116,7 @@
 
   // When a plugin is both enabled and disabled, the whitelist takes precedence.
   policies.Set(key::kDisabledPlugins, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, plugin_list.DeepCopy());
+               POLICY_SCOPE_USER, plugin_list.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_TRUE(plugin_prefs->IsPluginEnabled(*flash));
 }
@@ -1118,7 +1127,7 @@
 
   // Verify that the test page exists. It is only present in checkouts with
   // src-internal.
-  if (!file_util::PathExists(ui_test_utils::GetTestFilePath(
+  if (!base::PathExists(ui_test_utils::GetTestFilePath(
       base::FilePath(FILE_PATH_LITERAL("plugin")),
       base::FilePath(FILE_PATH_LITERAL("quicktime.html"))))) {
     LOG(INFO) <<
@@ -1150,7 +1159,7 @@
   // Now set a policy to always authorize this.
   PolicyMap policies;
   policies.Set(key::kAlwaysAuthorizePlugins, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
   // Reloading the page shouldn't trigger the infobar this time.
   ui_test_utils::NavigateToURL(browser(), url);
@@ -1171,7 +1180,7 @@
   // Disable devtools via policy.
   PolicyMap policies;
   policies.Set(key::kDeveloperToolsDisabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
   // The existing devtools window should have closed.
   EXPECT_FALSE(DevToolsWindow::GetDockedInstanceForInspectedTab(contents));
@@ -1201,7 +1210,7 @@
   // Turn off the web store icons.
   PolicyMap policies;
   policies.Set(key::kHideWebStoreIcon, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
 
   // The web store icons should now be hidden.
@@ -1236,11 +1245,11 @@
   PolicyMap policies;
   policies.Set(key::kDownloadDirectory, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER,
-               base::Value::CreateStringValue(forced_dir.path().value()));
+               base::Value::CreateStringValue(forced_dir.path().value()), NULL);
   UpdateProviderPolicy(policies);
   DownloadAndVerifyFile(browser(), forced_dir.path(), file);
   // Verify that the first download location wasn't affected.
-  EXPECT_FALSE(file_util::PathExists(initial_dir.path().Append(file)));
+  EXPECT_FALSE(base::PathExists(initial_dir.path().Append(file)));
 }
 #endif
 
@@ -1260,7 +1269,7 @@
   blacklist.Append(base::Value::CreateStringValue(kGoodCrxId));
   PolicyMap policies;
   policies.Set(key::kExtensionInstallBlacklist, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, blacklist.DeepCopy());
+               POLICY_SCOPE_USER, blacklist.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
 
   // "good.crx" is blacklisted.
@@ -1278,7 +1287,7 @@
   blacklist.Clear();
   blacklist.Append(base::Value::CreateStringValue("*"));
   policies.Set(key::kExtensionInstallBlacklist, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, blacklist.DeepCopy());
+               POLICY_SCOPE_USER, blacklist.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   // AdBlock was automatically removed.
   ASSERT_FALSE(service->GetExtensionById(kAdBlockCrxId, true));
@@ -1300,9 +1309,9 @@
   whitelist.Append(base::Value::CreateStringValue(kGoodCrxId));
   PolicyMap policies;
   policies.Set(key::kExtensionInstallBlacklist, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, blacklist.DeepCopy());
+               POLICY_SCOPE_USER, blacklist.DeepCopy(), NULL);
   policies.Set(key::kExtensionInstallWhitelist, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, whitelist.DeepCopy());
+               POLICY_SCOPE_USER, whitelist.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   // "adblock.crx" is blacklisted.
   EXPECT_FALSE(InstallExtension(kAdBlockCrxName));
@@ -1335,7 +1344,7 @@
       "%s;%s", kGoodCrxId, url.spec().c_str())));
   PolicyMap policies;
   policies.Set(key::kExtensionInstallForcelist, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, forcelist.DeepCopy());
+               POLICY_SCOPE_USER, forcelist.DeepCopy(), NULL);
   content::WindowedNotificationObserver observer(
       chrome::NOTIFICATION_EXTENSION_INSTALLED,
       content::NotificationService::AllSources());
@@ -1400,7 +1409,7 @@
   allowed_types.AppendString("hosted_app");
   PolicyMap policies;
   policies.Set(key::kExtensionAllowedTypes, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, allowed_types.DeepCopy());
+               POLICY_SCOPE_USER, allowed_types.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
 
   // "good.crx" is blocked.
@@ -1446,7 +1455,7 @@
   install_sources.AppendString(referrer_url.spec());
   PolicyMap policies;
   policies.Set(key::kExtensionInstallSources, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, install_sources.DeepCopy());
+               POLICY_SCOPE_USER, install_sources.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
 
   content::WindowedNotificationObserver observer(
@@ -1482,14 +1491,15 @@
   PolicyMap policies;
   policies.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER,
-               base::Value::CreateStringValue(chrome::kChromeUICreditsURL));
+               base::Value::CreateStringValue(chrome::kChromeUICreditsURL),
+               NULL);
   UpdateProviderPolicy(policies);
   EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_HOME));
   content::WaitForLoadStop(contents);
   EXPECT_EQ(GURL(chrome::kChromeUICreditsURL), contents->GetURL());
 
   policies.Set(key::kHomepageIsNewTabPage, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_HOME));
   content::WaitForLoadStop(contents);
@@ -1508,7 +1518,7 @@
   EXPECT_FALSE(BrowserList::IsOffTheRecordSessionActive());
   PolicyMap policies;
   policies.Set(key::kIncognitoEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_FALSE(chrome::ExecuteCommand(browser(), IDC_NEW_INCOGNITO_WINDOW));
   EXPECT_EQ(1u, active_browser_list->size());
@@ -1516,7 +1526,7 @@
 
   // Enable via policy and verify that incognito windows can be opened.
   policies.Set(key::kIncognitoEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_NEW_INCOGNITO_WINDOW));
   EXPECT_EQ(2u, active_browser_list->size());
@@ -1534,7 +1544,7 @@
   // Disable Javascript via policy.
   PolicyMap policies;
   policies.Set(key::kJavascriptEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policies);
   // Reload the page.
   ui_test_utils::NavigateToURL(browser(), GURL(content::kAboutBlankURL));
@@ -1551,7 +1561,7 @@
   EXPECT_FALSE(IsJavascriptEnabled(contents));
   policies.Set(key::kDefaultJavaScriptSetting, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(CONTENT_SETTING_ALLOW));
+               base::Value::CreateIntegerValue(CONTENT_SETTING_ALLOW), NULL);
   UpdateProviderPolicy(policies);
   ui_test_utils::NavigateToURL(browser(), GURL(content::kAboutBlankURL));
   EXPECT_TRUE(IsJavascriptEnabled(contents));
@@ -1561,7 +1571,7 @@
   // Verifies that browsing history is not saved.
   PolicyMap policies;
   policies.Set(key::kSavingBrowserHistoryDisabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
   GURL url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
@@ -1573,7 +1583,7 @@
 
   // Now flip the policy and try again.
   policies.Set(key::kSavingBrowserHistoryDisabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policies);
   ui_test_utils::NavigateToURL(browser(), url);
   // Verify that the navigation was saved in the history.
@@ -1597,7 +1607,7 @@
   // Force enable the translate feature.
   PolicyMap policies;
   policies.Set(key::kTranslateEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
   // Instead of waiting for NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, this test
   // waits for NOTIFICATION_TAB_LANGUAGE_DETERMINED because that's what the
@@ -1638,7 +1648,7 @@
   infobar_service->RemoveInfoBar(infobar_delegate);
   EXPECT_EQ(0u, infobar_service->infobar_count());
   policies.Set(key::kTranslateEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policies);
   // Navigating to the same URL now doesn't trigger an infobar.
   content::WindowedNotificationObserver language_observer2(
@@ -1678,7 +1688,7 @@
   blacklist.Append(base::Value::CreateStringValue("bbb.com"));
   PolicyMap policies;
   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, blacklist.DeepCopy());
+               POLICY_SCOPE_USER, blacklist.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   FlushBlacklistPolicy();
   // All bbb.com URLs are blocked, and "aaa.com" is still unblocked.
@@ -1691,7 +1701,7 @@
   whitelist.Append(base::Value::CreateStringValue("sub.bbb.com"));
   whitelist.Append(base::Value::CreateStringValue("bbb.com/policy"));
   policies.Set(key::kURLWhitelist, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, whitelist.DeepCopy());
+               POLICY_SCOPE_USER, whitelist.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   FlushBlacklistPolicy();
   CheckURLIsBlocked(browser(), kURLS[1]);
@@ -1727,7 +1737,7 @@
   blacklist.Append(base::Value::CreateStringValue("file://*"));
   PolicyMap policies;
   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, blacklist.DeepCopy());
+               POLICY_SCOPE_USER, blacklist.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   FlushBlacklistPolicy();
 
@@ -1737,7 +1747,7 @@
   // Replace the URLblacklist with disabling the file scheme.
   blacklist.Remove(base::StringValue("file://*"), NULL);
   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, blacklist.DeepCopy());
+               POLICY_SCOPE_USER, blacklist.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   FlushBlacklistPolicy();
 
@@ -1749,7 +1759,7 @@
   base::ListValue disabledscheme;
   disabledscheme.Append(base::Value::CreateStringValue("file"));
   policies.Set(key::kDisabledSchemes, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, disabledscheme.DeepCopy());
+               POLICY_SCOPE_USER, disabledscheme.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   FlushBlacklistPolicy();
 
@@ -1761,10 +1771,10 @@
   base::ListValue whitelist;
   whitelist.Append(base::Value::CreateStringValue(base_path));
   policies.Set(key::kURLWhitelist, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, whitelist.DeepCopy());
+               POLICY_SCOPE_USER, whitelist.DeepCopy(), NULL);
   blacklist.Append(base::Value::CreateStringValue(folder_path));
   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, blacklist.DeepCopy());
+               POLICY_SCOPE_USER, blacklist.DeepCopy(), NULL);
   UpdateProviderPolicy(policies);
   FlushBlacklistPolicy();
 
@@ -1817,7 +1827,7 @@
   EXPECT_CALL(*mock, OnMuteToggled()).Times(1);
   PolicyMap policies;
   policies.Set(key::kAudioOutputAllowed, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_TRUE(audio_handler->IsMuted());
   // This should not change the state now and should not trigger OnMuteToggled.
@@ -1827,7 +1837,7 @@
   // Toggle back and observe if the trigger was successful.
   EXPECT_CALL(*mock, OnMuteToggled()).Times(1);
   policies.Set(key::kAudioOutputAllowed, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+               POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_FALSE(audio_handler->IsMuted());
   EXPECT_CALL(*mock, OnMuteToggled()).Times(1);
@@ -1862,7 +1872,8 @@
   PolicyMap policies;
   policies.Set(key::kSessionLengthLimit, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(180 * 60 * 1000));  // 3 hours.
+               base::Value::CreateIntegerValue(180 * 60 * 1000),  // 3 hours.
+               NULL);
   UpdateProviderPolicy(policies);
   base::RunLoop().RunUntilIdle();
   Mock::VerifyAndClearExpectations(&observer);
@@ -1872,7 +1883,8 @@
   EXPECT_CALL(observer, Observe(chrome::NOTIFICATION_APP_TERMINATING, _, _));
   policies.Set(key::kSessionLengthLimit, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(60 * 60 * 1000));  // 1 hour.
+               base::Value::CreateIntegerValue(60 * 60 * 1000),  // 1 hour.
+               NULL);
   UpdateProviderPolicy(policies);
   base::RunLoop().RunUntilIdle();
   Mock::VerifyAndClearExpectations(&observer);
@@ -1892,7 +1904,7 @@
   PolicyMap policies;
   policies.Set(key::kLargeCursorEnabled, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER,
-               base::Value::CreateBooleanValue(false));
+               base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_FALSE(accessibility_manager->IsLargeCursorEnabled());
 
@@ -1916,7 +1928,7 @@
   PolicyMap policies;
   policies.Set(key::kSpokenFeedbackEnabled, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER,
-               base::Value::CreateBooleanValue(false));
+               base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_FALSE(accessibility_manager->IsSpokenFeedbackEnabled());
 
@@ -1940,7 +1952,7 @@
   PolicyMap policies;
   policies.Set(key::kHighContrastEnabled, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER,
-               base::Value::CreateBooleanValue(false));
+               base::Value::CreateBooleanValue(false), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_FALSE(accessibility_manager->IsHighContrastEnabled());
 
@@ -1964,7 +1976,7 @@
   PolicyMap policies;
   policies.Set(key::kScreenMagnifierType, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(0));
+               base::Value::CreateIntegerValue(0), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_FALSE(magnification_manager->IsMagnifierEnabled());
 
@@ -1985,7 +1997,7 @@
   PolicyMap policies;
   policies.Set(key::kScreenMagnifierType, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(ash::MAGNIFIER_FULL));
+               base::Value::CreateIntegerValue(ash::MAGNIFIER_FULL), NULL);
   UpdateProviderPolicy(policies);
   EXPECT_EQ(ash::MAGNIFIER_FULL, magnification_manager->GetMagnifierType());
   EXPECT_TRUE(magnification_manager->IsMagnifierEnabled());
@@ -2055,13 +2067,14 @@
     policies.Set(
         key::kRestoreOnStartup, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
         base::Value::CreateIntegerValue(
-            SessionStartupPref::kPrefValueHomePage));
+            SessionStartupPref::kPrefValueHomePage),
+        NULL);
     policies.Set(
         key::kHomepageIsNewTabPage, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        base::Value::CreateBooleanValue(false));
+        base::Value::CreateBooleanValue(false), NULL);
     policies.Set(
         key::kHomepageLocation, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        base::Value::CreateStringValue(kRestoredURLs[1]));
+        base::Value::CreateStringValue(kRestoredURLs[1]), NULL);
     provider_.UpdateChromePolicy(policies);
 
     expected_urls_.push_back(GURL(kRestoredURLs[1]));
@@ -2074,10 +2087,11 @@
     policies.Set(
         key::kRestoreOnStartup, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
         base::Value::CreateIntegerValue(
-            SessionStartupPref::kPrefValueHomePage));
+            SessionStartupPref::kPrefValueHomePage),
+        NULL);
     policies.Set(
         key::kHomepageIsNewTabPage, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        base::Value::CreateBooleanValue(true));
+        base::Value::CreateBooleanValue(true), NULL);
     provider_.UpdateChromePolicy(policies);
 
     expected_urls_.push_back(GURL(chrome::kChromeUINewTabURL));
@@ -2093,10 +2107,11 @@
     PolicyMap policies;
     policies.Set(
         key::kRestoreOnStartup, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        base::Value::CreateIntegerValue(SessionStartupPref::kPrefValueURLs));
+        base::Value::CreateIntegerValue(SessionStartupPref::kPrefValueURLs),
+        NULL);
     policies.Set(
         key::kRestoreOnStartupURLs, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        urls.DeepCopy());
+        urls.DeepCopy(), NULL);
     provider_.UpdateChromePolicy(policies);
   }
 
@@ -2105,7 +2120,8 @@
     PolicyMap policies;
     policies.Set(
         key::kRestoreOnStartup, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        base::Value::CreateIntegerValue(SessionStartupPref::kPrefValueNewTab));
+        base::Value::CreateIntegerValue(SessionStartupPref::kPrefValueNewTab),
+        NULL);
     provider_.UpdateChromePolicy(policies);
     expected_urls_.push_back(GURL(chrome::kChromeUINewTabURL));
   }
@@ -2115,7 +2131,8 @@
     PolicyMap policies;
     policies.Set(
         key::kRestoreOnStartup, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        base::Value::CreateIntegerValue(SessionStartupPref::kPrefValueLast));
+        base::Value::CreateIntegerValue(SessionStartupPref::kPrefValueLast),
+        NULL);
     provider_.UpdateChromePolicy(policies);
     // This should restore the tabs opened at PRE_RunTest below.
     for (size_t i = 0; i < arraysize(kRestoredURLs); ++i)
@@ -2170,13 +2187,13 @@
     PolicyMap policies;
     policies.Set(
         key::kShowHomeButton, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        base::Value::CreateBooleanValue(true));
+        base::Value::CreateBooleanValue(true), NULL);
     policies.Set(
         key::kBookmarkBarEnabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        base::Value::CreateBooleanValue(false));
+        base::Value::CreateBooleanValue(false), NULL);
     policies.Set(
         key::kHomepageLocation, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        base::Value::CreateStringValue("http://chromium.org"));
+        base::Value::CreateStringValue("http://chromium.org"), NULL);
     provider_.UpdateChromePolicy(policies);
   }
 };
@@ -2241,7 +2258,7 @@
                           const char* whitelist_policy,
                           const char* allow_rule) {
     policies->Set(policy_name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        base::Value::CreateBooleanValue(policy_value_));
+        base::Value::CreateBooleanValue(policy_value_), NULL);
 
     if (whitelist_policy) {
       // TODO(tommi): Remove the kiosk mode flag when the whitelist is visible
@@ -2264,7 +2281,7 @@
         request_url_allowed_via_whitelist_ = false;
       }
       policies->Set(whitelist_policy, POLICY_LEVEL_MANDATORY,
-                    POLICY_SCOPE_USER, list);
+                    POLICY_SCOPE_USER, list, NULL);
     }
   }
 
@@ -2279,9 +2296,10 @@
   }
 
   void FinishAudioTest() {
-    content::MediaStreamRequest request(0, 0, request_url_.GetOrigin(),
+    content::MediaStreamRequest request(0, 0, 0, std::string(),
+                                        request_url_.GetOrigin(),
                                         content::MEDIA_DEVICE_ACCESS,
-                                        "fake_dev",
+                                        std::string(), std::string(),
                                         content::MEDIA_DEVICE_AUDIO_CAPTURE,
                                         content::MEDIA_NO_SERVICE);
     // TODO(raymes): Test MEDIA_DEVICE_OPEN (Pepper) which grants both webcam
@@ -2297,9 +2315,11 @@
   void FinishVideoTest() {
     // TODO(raymes): Test MEDIA_DEVICE_OPEN (Pepper) which grants both webcam
     // and microphone permissions at the same time.
-    content::MediaStreamRequest request(0, 0, request_url_.GetOrigin(),
+    content::MediaStreamRequest request(0, 0, 0, std::string(),
+                                        request_url_.GetOrigin(),
                                         content::MEDIA_DEVICE_ACCESS,
-                                        "fake_dev",
+                                        std::string(),
+                                        std::string(),
                                         content::MEDIA_NO_SERVICE,
                                         content::MEDIA_DEVICE_VIDEO_CAPTURE);
     MediaStreamDevicesController controller(
@@ -2450,7 +2470,8 @@
         key::kVariationsRestrictParameter,
         POLICY_LEVEL_MANDATORY,
         POLICY_SCOPE_USER,
-        base::Value::CreateStringValue("restricted"));
+        base::Value::CreateStringValue("restricted"),
+        NULL);
     provider_.UpdateChromePolicy(policies);
   }
 };
diff --git a/chrome/browser/policy/policy_bundle_unittest.cc b/chrome/browser/policy/policy_bundle_unittest.cc
index f06207a..502da1c 100644
--- a/chrome/browser/policy/policy_bundle_unittest.cc
+++ b/chrome/browser/policy/policy_bundle_unittest.cc
@@ -4,8 +4,10 @@
 
 #include "chrome/browser/policy/policy_bundle.h"
 
+#include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/values.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "policy/policy_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -27,17 +29,17 @@
 // Adds test policies to |policy|.
 void AddTestPolicies(PolicyMap* policy) {
   policy->Set("mandatory-user", POLICY_LEVEL_MANDATORY,
-              POLICY_SCOPE_USER, base::Value::CreateIntegerValue(123));
-  policy->Set("mandatory-machine", POLICY_LEVEL_MANDATORY,
-              POLICY_SCOPE_MACHINE, base::Value::CreateStringValue("omg"));
+              POLICY_SCOPE_USER, base::Value::CreateIntegerValue(123), NULL);
+  policy->Set("mandatory-machine", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
+              base::Value::CreateStringValue("omg"), NULL);
   policy->Set("recommended-user", POLICY_LEVEL_RECOMMENDED,
-              POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true));
+              POLICY_SCOPE_USER, base::Value::CreateBooleanValue(true), NULL);
   base::DictionaryValue* dict = new base::DictionaryValue();
   dict->SetBoolean("false", false);
   dict->SetInteger("int", 456);
   dict->SetString("str", "bbq");
   policy->Set("recommended-machine", POLICY_LEVEL_RECOMMENDED,
-              POLICY_SCOPE_MACHINE, dict);
+              POLICY_SCOPE_MACHINE, dict, NULL);
 }
 
 // Adds test policies to |policy| based on the parameters:
@@ -50,11 +52,11 @@
                                PolicyLevel level,
                                PolicyScope scope) {
   policy->Set(kPolicyClashing0, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-              base::Value::CreateIntegerValue(value));
+              base::Value::CreateIntegerValue(value), NULL);
   policy->Set(kPolicyClashing1, level, scope,
-              base::Value::CreateIntegerValue(value));
+              base::Value::CreateIntegerValue(value), NULL);
   policy->Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-              base::Value::CreateIntegerValue(value));
+              base::Value::CreateIntegerValue(value), NULL);
 }
 
 // Returns true if |bundle| is empty.
@@ -182,15 +184,15 @@
   // - kPolicyN are merged from each bundle.
   PolicyMap expected;
   expected.Set(kPolicyClashing0, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(0));
+               base::Value::CreateIntegerValue(0), NULL);
   expected.Set(kPolicyClashing1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-               base::Value::CreateIntegerValue(1));
+               base::Value::CreateIntegerValue(1), NULL);
   expected.Set(kPolicy0, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(0));
+               base::Value::CreateIntegerValue(0), NULL);
   expected.Set(kPolicy1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(1));
+               base::Value::CreateIntegerValue(1), NULL);
   expected.Set(kPolicy2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(2));
+               base::Value::CreateIntegerValue(2), NULL);
   EXPECT_TRUE(merged.Get(PolicyNamespace(POLICY_DOMAIN_CHROME,
                                          std::string())).Equals(expected));
   EXPECT_TRUE(merged.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
@@ -232,7 +234,8 @@
       .Set(kPolicy0,
            POLICY_LEVEL_MANDATORY,
            POLICY_SCOPE_USER,
-           base::Value::CreateIntegerValue(123));
+           base::Value::CreateIntegerValue(123),
+           NULL);
   EXPECT_FALSE(bundle.Equals(other));
   other.CopyFrom(bundle);
   EXPECT_TRUE(bundle.Equals(other));
@@ -240,7 +243,8 @@
       .Set(kPolicy0,
            POLICY_LEVEL_MANDATORY,
            POLICY_SCOPE_MACHINE,
-           base::Value::CreateIntegerValue(123));
+           base::Value::CreateIntegerValue(123),
+           NULL);
   EXPECT_FALSE(bundle.Equals(other));
 
   // Test non-const Get().
@@ -250,7 +254,7 @@
       bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
   EXPECT_TRUE(bundle.Equals(other));
   policy_map.Set(kPolicy0, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 base::Value::CreateIntegerValue(123));
+                 base::Value::CreateIntegerValue(123), NULL);
   EXPECT_FALSE(bundle.Equals(other));
 }
 
diff --git a/chrome/browser/policy/policy_domain_descriptor.cc b/chrome/browser/policy/policy_domain_descriptor.cc
index 158ae35..0999062 100644
--- a/chrome/browser/policy/policy_domain_descriptor.cc
+++ b/chrome/browser/policy/policy_domain_descriptor.cc
@@ -9,7 +9,7 @@
 #include "base/values.h"
 #include "chrome/browser/policy/policy_bundle.h"
 #include "chrome/browser/policy/policy_map.h"
-#include "chrome/browser/policy/policy_schema.h"
+#include "chrome/common/policy/policy_schema.h"
 
 namespace policy {
 
diff --git a/chrome/browser/policy/policy_domain_descriptor_unittest.cc b/chrome/browser/policy/policy_domain_descriptor_unittest.cc
index 5edea9e..06e103d 100644
--- a/chrome/browser/policy/policy_domain_descriptor_unittest.cc
+++ b/chrome/browser/policy/policy_domain_descriptor_unittest.cc
@@ -4,15 +4,33 @@
 
 #include "chrome/browser/policy/policy_domain_descriptor.h"
 
+#include <string>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
 #include "base/values.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
+#include "chrome/browser/policy/external_data_manager.h"
 #include "chrome/browser/policy/policy_bundle.h"
 #include "chrome/browser/policy/policy_map.h"
-#include "chrome/browser/policy/policy_schema.h"
+#include "chrome/common/policy/policy_schema.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace policy {
 
-TEST(PolicyDomainDescriptor, FilterBundle) {
+class PolicyDomainDescriptorTest : public testing::Test {
+ protected:
+  scoped_ptr<ExternalDataFetcher> CreateExternalDataFetcher() const;
+};
+
+scoped_ptr<ExternalDataFetcher>
+    PolicyDomainDescriptorTest::CreateExternalDataFetcher() const {
+  return make_scoped_ptr(
+      new ExternalDataFetcher(base::WeakPtr<ExternalDataManager>(),
+                              std::string()));
+}
+
+TEST_F(PolicyDomainDescriptorTest, FilterBundle) {
   scoped_refptr<PolicyDomainDescriptor> descriptor =
       new PolicyDomainDescriptor(POLICY_DOMAIN_EXTENSIONS);
   EXPECT_EQ(POLICY_DOMAIN_EXTENSIONS, descriptor->domain());
@@ -60,7 +78,8 @@
   expected_bundle.Get(chrome_ns).Set("ChromePolicy",
                                      POLICY_LEVEL_MANDATORY,
                                      POLICY_SCOPE_USER,
-                                     base::Value::CreateStringValue("value"));
+                                     base::Value::CreateStringValue("value"),
+                                     NULL);
   bundle.CopyFrom(expected_bundle);
   // Unknown components of the domain are filtered out.
   PolicyNamespace another_extension_ns(POLICY_DOMAIN_EXTENSIONS, "xyz");
@@ -68,7 +87,8 @@
       "AnotherExtensionPolicy",
       POLICY_LEVEL_MANDATORY,
       POLICY_SCOPE_USER,
-      base::Value::CreateStringValue("value"));
+      base::Value::CreateStringValue("value"),
+      NULL);
   descriptor->FilterBundle(&bundle);
   EXPECT_TRUE(bundle.Equals(expected_bundle));
 
@@ -78,27 +98,29 @@
   list.AppendString("a");
   list.AppendString("b");
   map.Set("Array", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-          list.DeepCopy());
+          list.DeepCopy(), NULL);
   map.Set("Boolean", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-          base::Value::CreateBooleanValue(true));
+          base::Value::CreateBooleanValue(true), NULL);
   map.Set("Integer", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-          base::Value::CreateIntegerValue(1));
+          base::Value::CreateIntegerValue(1), NULL);
   map.Set("Null", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-          base::Value::CreateNullValue());
+          base::Value::CreateNullValue(), NULL);
   map.Set("Number", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-          base::Value::CreateDoubleValue(1.2));
+          base::Value::CreateDoubleValue(1.2), NULL);
   base::DictionaryValue dict;
   dict.SetString("a", "b");
   dict.SetInteger("b", 2);
-  map.Set("Object", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, dict.DeepCopy());
+  map.Set("Object", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+          dict.DeepCopy(), NULL);
   map.Set("String", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-          base::Value::CreateStringValue("value"));
+          base::Value::CreateStringValue("value"), NULL);
 
   bundle.MergeFrom(expected_bundle);
   bundle.Get(extension_ns).Set("Unexpected",
                                POLICY_LEVEL_MANDATORY,
                                POLICY_SCOPE_USER,
-                               base::Value::CreateStringValue("to-be-removed"));
+                               base::Value::CreateStringValue("to-be-removed"),
+                               NULL);
 
   descriptor->FilterBundle(&bundle);
   EXPECT_TRUE(bundle.Equals(expected_bundle));
@@ -107,19 +129,19 @@
   bundle.Clear();
   PolicyMap& badmap = bundle.Get(extension_ns);
   badmap.Set("Array", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateBooleanValue(false));
+             base::Value::CreateBooleanValue(false), NULL);
   badmap.Set("Boolean", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateIntegerValue(0));
+             base::Value::CreateIntegerValue(0), NULL);
   badmap.Set("Integer", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateBooleanValue(false));
+             base::Value::CreateBooleanValue(false), NULL);
   badmap.Set("Null", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateBooleanValue(false));
+             base::Value::CreateBooleanValue(false), NULL);
   badmap.Set("Number", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateBooleanValue(false));
+             base::Value::CreateBooleanValue(false), NULL);
   badmap.Set("Object", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateBooleanValue(false));
+             base::Value::CreateBooleanValue(false), NULL);
   badmap.Set("String", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             base::Value::CreateBooleanValue(false));
+             NULL, CreateExternalDataFetcher().release());
 
   descriptor->FilterBundle(&bundle);
   EXPECT_TRUE(bundle.Equals(empty_bundle));
diff --git a/chrome/browser/policy/policy_loader_mac.cc b/chrome/browser/policy/policy_loader_mac.cc
index 0cbb519..4a94bbb 100644
--- a/chrome/browser/policy/policy_loader_mac.cc
+++ b/chrome/browser/policy/policy_loader_mac.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/callback.h"
 #include "base/file_util.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
@@ -13,13 +14,14 @@
 #include "base/platform_file.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_bundle.h"
 #include "chrome/browser/policy/policy_domain_descriptor.h"
 #include "chrome/browser/policy/policy_load_status.h"
 #include "chrome/browser/policy/policy_map.h"
-#include "chrome/browser/policy/policy_schema.h"
 #include "chrome/browser/policy/preferences_mac.h"
 #include "chrome/common/chrome_paths.h"
+#include "chrome/common/policy/policy_schema.h"
 #include "policy/policy_constants.h"
 
 using base::mac::CFCast;
@@ -122,7 +124,7 @@
     // TODO(joaodasilva): figure the policy scope.
     base::Value* policy = CreateValueFromProperty(value);
     if (policy)
-      chrome_policy.Set(current->name, level, POLICY_SCOPE_USER, policy);
+      chrome_policy.Set(current->name, level, POLICY_SCOPE_USER, policy, NULL);
     else
       status.Add(POLICY_LOAD_STATUS_PARSE_ERROR);
   }
@@ -258,7 +260,8 @@
                                  POLICY_LEVEL_RECOMMENDED;
     scoped_ptr<base::Value> policy_value(CreateValueFromProperty(value));
     if (policy_value)
-      policy->Set(it->first, level, POLICY_SCOPE_USER, policy_value.release());
+      policy->Set(it->first, level, POLICY_SCOPE_USER,
+                  policy_value.release(), NULL);
   }
 }
 
diff --git a/chrome/browser/policy/policy_loader_mac_unittest.cc b/chrome/browser/policy/policy_loader_mac_unittest.cc
index 12c21bd..8d725a2 100644
--- a/chrome/browser/policy/policy_loader_mac_unittest.cc
+++ b/chrome/browser/policy/policy_loader_mac_unittest.cc
@@ -5,11 +5,13 @@
 #include <CoreFoundation/CoreFoundation.h>
 
 #include "base/basictypes.h"
+#include "base/callback.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/policy/async_policy_provider.h"
 #include "chrome/browser/policy/configuration_policy_provider_test.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_bundle.h"
 #include "chrome/browser/policy/policy_loader_mac.h"
 #include "chrome/browser/policy/policy_map.h"
@@ -282,7 +284,8 @@
       .Set(test_policy_definitions::kKeyString,
            POLICY_LEVEL_RECOMMENDED,
            POLICY_SCOPE_USER,
-           base::Value::CreateStringValue("string value"));
+           base::Value::CreateStringValue("string value"),
+           NULL);
   EXPECT_TRUE(provider_.policies().Equals(expected_bundle));
 }
 
diff --git a/chrome/browser/policy/policy_loader_win.cc b/chrome/browser/policy/policy_loader_win.cc
index 947d70c..e52a866 100644
--- a/chrome/browser/policy/policy_loader_win.cc
+++ b/chrome/browser/policy/policy_loader_win.cc
@@ -583,12 +583,12 @@
   // access to the %WINDIR%/System32/GroupPolicy directory to
   // %WINDIR%/SysWOW64/GroupPolicy, but the file is actually in the
   // system-native directory.
-  if (file_util::PathExists(preg_file)) {
+  if (base::PathExists(preg_file)) {
     return preg_parser::ReadFile(preg_file, chrome_policy_key_, policy, status);
   } else {
     // Try with redirection switched off.
     ScopedDisableWow64Redirection redirection_disable;
-    if (redirection_disable.is_active() && file_util::PathExists(preg_file)) {
+    if (redirection_disable.is_active() && base::PathExists(preg_file)) {
       status->Add(POLICY_LOAD_STATUS_WOW64_REDIRECTION_DISABLED);
       return preg_parser::ReadFile(preg_file, chrome_policy_key_, policy,
                                    status);
diff --git a/chrome/browser/policy/policy_loader_win_unittest.cc b/chrome/browser/policy/policy_loader_win_unittest.cc
index 7e33ce7..a6492de 100644
--- a/chrome/browser/policy/policy_loader_win_unittest.cc
+++ b/chrome/browser/policy/policy_loader_win_unittest.cc
@@ -13,6 +13,7 @@
 #include <iterator>
 #include <vector>
 
+#include "base/callback.h"
 #include "base/file_util.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
@@ -28,6 +29,7 @@
 #include "base/win/registry.h"
 #include "chrome/browser/policy/async_policy_provider.h"
 #include "chrome/browser/policy/configuration_policy_provider_test.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_bundle.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/preg_parser_win.h"
@@ -878,7 +880,7 @@
       .Set(test_policy_definitions::kKeyString,
            POLICY_LEVEL_MANDATORY,
            POLICY_SCOPE_MACHINE,
-           base::Value::CreateStringValue("hklm"));
+           base::Value::CreateStringValue("hklm"), NULL);
   EXPECT_TRUE(Matches(expected));
 }
 
@@ -944,13 +946,14 @@
   PolicyMap& expected_policy =
       expected.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "merge"));
   expected_policy.Set("a", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-                      base::Value::CreateStringValue(kMachineMandatory));
+                      base::Value::CreateStringValue(kMachineMandatory), NULL);
   expected_policy.Set("b", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                      base::Value::CreateStringValue(kUserMandatory));
+                      base::Value::CreateStringValue(kUserMandatory), NULL);
   expected_policy.Set("c", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
-                      base::Value::CreateStringValue(kMachineRecommended));
+                      base::Value::CreateStringValue(kMachineRecommended),
+                      NULL);
   expected_policy.Set("d", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-                      base::Value::CreateStringValue(kUserRecommended));
+                      base::Value::CreateStringValue(kUserRecommended), NULL);
   EXPECT_TRUE(Matches(expected));
 }
 
diff --git a/chrome/browser/policy/policy_map.cc b/chrome/browser/policy/policy_map.cc
index 6a52c53..ff90cf0 100644
--- a/chrome/browser/policy/policy_map.cc
+++ b/chrome/browser/policy/policy_map.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 
+#include "base/callback.h"
 #include "base/stl_util.h"
 
 namespace policy {
@@ -21,7 +22,9 @@
 bool PolicyMap::Entry::Equals(const PolicyMap::Entry& other) const {
   return level == other.level &&
          scope == other.scope &&
-         Value::Equals(value, other.value);
+         Value::Equals(value, other.value) &&
+         ExternalDataFetcher::Equals(external_data_fetcher,
+                                     other.external_data_fetcher);
 }
 
 PolicyMap::PolicyMap() {
@@ -44,18 +47,22 @@
 void PolicyMap::Set(const std::string& policy,
                     PolicyLevel level,
                     PolicyScope scope,
-                    Value* value) {
+                    Value* value,
+                    ExternalDataFetcher* external_data_fetcher) {
   Entry& entry = map_[policy];
   delete entry.value;
+  delete entry.external_data_fetcher;
   entry.level = level;
   entry.scope = scope;
   entry.value = value;
+  entry.external_data_fetcher = external_data_fetcher;
 }
 
 void PolicyMap::Erase(const std::string& policy) {
   PolicyMapType::iterator it = map_.find(policy);
   if (it != map_.end()) {
     delete it->second.value;
+    delete it->second.external_data_fetcher;
     map_.erase(it);
   }
 }
@@ -68,7 +75,9 @@
   Clear();
   for (const_iterator it = other.begin(); it != other.end(); ++it) {
     const Entry& entry = it->second;
-    Set(it->first, entry.level, entry.scope, entry.value->DeepCopy());
+    Set(it->first, entry.level, entry.scope,
+        entry.value->DeepCopy(), entry.external_data_fetcher ?
+            new ExternalDataFetcher(*entry.external_data_fetcher) : NULL);
   }
 }
 
@@ -83,7 +92,9 @@
     const Entry* entry = Get(it->first);
     if (!entry || it->second.has_higher_priority_than(*entry)) {
       Set(it->first, it->second.level, it->second.scope,
-          it->second.value->DeepCopy());
+          it->second.value->DeepCopy(), it->second.external_data_fetcher ?
+              new ExternalDataFetcher(*it->second.external_data_fetcher) :
+              NULL);
     }
   }
 }
@@ -93,7 +104,7 @@
     PolicyLevel level,
     PolicyScope scope) {
   for (DictionaryValue::Iterator it(*policies); !it.IsAtEnd(); it.Advance())
-    Set(it.key(), level, scope, it.value().DeepCopy());
+    Set(it.key(), level, scope, it.value().DeepCopy(), NULL);
 }
 
 void PolicyMap::GetDifferingKeys(const PolicyMap& other,
@@ -129,6 +140,7 @@
   while (iter != map_.end()) {
     if (iter->second.level != level) {
       delete iter->second.value;
+      delete iter->second.external_data_fetcher;
       map_.erase(iter++);
     } else {
       ++iter;
@@ -158,8 +170,10 @@
 }
 
 void PolicyMap::Clear() {
-  for (PolicyMapType::iterator it = map_.begin(); it != map_.end(); ++it)
+  for (PolicyMapType::iterator it = map_.begin(); it != map_.end(); ++it) {
     delete it->second.value;
+    delete it->second.external_data_fetcher;
+  }
   map_.clear();
 }
 
diff --git a/chrome/browser/policy/policy_map.h b/chrome/browser/policy/policy_map.h
index 3d12fc3..d2d6f65 100644
--- a/chrome/browser/policy/policy_map.h
+++ b/chrome/browser/policy/policy_map.h
@@ -11,6 +11,7 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "base/values.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_types.h"
 
 namespace policy {
@@ -24,11 +25,13 @@
     PolicyLevel level;
     PolicyScope scope;
     base::Value* value;
+    ExternalDataFetcher* external_data_fetcher;
 
     Entry()
         : level(POLICY_LEVEL_RECOMMENDED),
           scope(POLICY_SCOPE_USER),
-          value(NULL) {}
+          value(NULL),
+          external_data_fetcher(NULL) {}
 
     // Returns true if |this| has higher priority than |other|.
     bool has_higher_priority_than(const Entry& other) const;
@@ -52,12 +55,13 @@
   // This is equivalent to Get(policy)->value, when it doesn't return NULL.
   const base::Value* GetValue(const std::string& policy) const;
 
-  // Takes ownership of |value|. Overwrites any existing value stored in the
-  // map for the key |policy|.
+  // Takes ownership of |value| and |external_data_fetcher|. Overwrites any
+  // existing information stored in the map for the key |policy|.
   void Set(const std::string& policy,
            PolicyLevel level,
            PolicyScope scope,
-           base::Value* value);
+           base::Value* value,
+           ExternalDataFetcher* external_data_fetcher);
 
   // Erase the given |policy|, if it exists in this map.
   void Erase(const std::string& policy);
@@ -85,9 +89,9 @@
                 PolicyScope scope);
 
   // Compares this value map against |other| and stores all key names that have
-  // different values in |differing_keys|. This includes keys that are present
-  // only in one of the maps. |differing_keys| is not cleared before the keys
-  // are added.
+  // different values or reference different external data in |differing_keys|.
+  // This includes keys that are present only in one of the maps.
+  // |differing_keys| is not cleared before the keys are added.
   void GetDifferingKeys(const PolicyMap& other,
                         std::set<std::string>* differing_keys) const;
 
diff --git a/chrome/browser/policy/policy_map_unittest.cc b/chrome/browser/policy/policy_map_unittest.cc
index 367ce06..1386618 100644
--- a/chrome/browser/policy/policy_map_unittest.cc
+++ b/chrome/browser/policy/policy_map_unittest.cc
@@ -4,10 +4,9 @@
 
 #include "chrome/browser/policy/policy_map.h"
 
-#include <set>
-#include <string>
-
-#include "base/memory/scoped_ptr.h"
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/policy/external_data_manager.h"
 #include "policy/policy_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -15,12 +14,33 @@
 
 namespace {
 
-// Utility function for the tests.
+// Utility functions for the tests.
 void SetPolicy(PolicyMap* map, const char* name, Value* value) {
-  map->Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, value);
+  map->Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, value, NULL);
 }
 
-TEST(PolicyMapTest, SetAndGet) {
+void SetPolicy(PolicyMap* map,
+               const char* name,
+               ExternalDataFetcher* external_data_fetcher) {
+  map->Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+           NULL, external_data_fetcher);
+}
+
+}  // namespace
+
+class PolicyMapTest : public testing::Test {
+ protected:
+  scoped_ptr<ExternalDataFetcher> CreateExternalDataFetcher(
+      const std::string& policy) const;
+};
+
+scoped_ptr<ExternalDataFetcher> PolicyMapTest::CreateExternalDataFetcher(
+    const std::string& policy) const {
+  return make_scoped_ptr(
+      new ExternalDataFetcher(base::WeakPtr<ExternalDataManager>(), policy));
+}
+
+TEST_F(PolicyMapTest, SetAndGet) {
   PolicyMap map;
   SetPolicy(&map, key::kHomepageLocation, Value::CreateStringValue("aaa"));
   StringValue expected("aaa");
@@ -28,19 +48,26 @@
   SetPolicy(&map, key::kHomepageLocation, Value::CreateStringValue("bbb"));
   StringValue expected_b("bbb");
   EXPECT_TRUE(expected_b.Equals(map.GetValue(key::kHomepageLocation)));
+  SetPolicy(&map, key::kHomepageLocation,
+            CreateExternalDataFetcher("dummy").release());
+  EXPECT_FALSE(map.GetValue(key::kHomepageLocation));
   const PolicyMap::Entry* entry = map.Get(key::kHomepageLocation);
   ASSERT_TRUE(entry != NULL);
   EXPECT_EQ(POLICY_LEVEL_MANDATORY, entry->level);
   EXPECT_EQ(POLICY_SCOPE_USER, entry->scope);
+  EXPECT_TRUE(ExternalDataFetcher::Equals(
+      entry->external_data_fetcher, CreateExternalDataFetcher("dummy").get()));
   map.Set(key::kHomepageLocation, POLICY_LEVEL_RECOMMENDED,
-          POLICY_SCOPE_MACHINE, NULL);
+          POLICY_SCOPE_MACHINE, NULL, NULL);
+  EXPECT_FALSE(map.GetValue(key::kHomepageLocation));
   entry = map.Get(key::kHomepageLocation);
   ASSERT_TRUE(entry != NULL);
   EXPECT_EQ(POLICY_LEVEL_RECOMMENDED, entry->level);
   EXPECT_EQ(POLICY_SCOPE_MACHINE, entry->scope);
+  EXPECT_FALSE(entry->external_data_fetcher);
 }
 
-TEST(PolicyMapTest, Equals) {
+TEST_F(PolicyMapTest, Equals) {
   PolicyMap a;
   SetPolicy(&a, key::kHomepageLocation, Value::CreateStringValue("aaa"));
   PolicyMap a2;
@@ -50,12 +77,39 @@
   PolicyMap c;
   SetPolicy(&c, key::kHomepageLocation, Value::CreateStringValue("aaa"));
   SetPolicy(&c, key::kHomepageIsNewTabPage, Value::CreateBooleanValue(true));
+  PolicyMap d;
+  SetPolicy(&d, key::kHomepageLocation,
+            CreateExternalDataFetcher("ddd").release());
+  PolicyMap d2;
+  SetPolicy(&d2, key::kHomepageLocation,
+            CreateExternalDataFetcher("ddd").release());
+  PolicyMap e;
+  SetPolicy(&e, key::kHomepageLocation,
+            CreateExternalDataFetcher("eee").release());
   EXPECT_FALSE(a.Equals(b));
-  EXPECT_FALSE(b.Equals(a));
   EXPECT_FALSE(a.Equals(c));
+  EXPECT_FALSE(a.Equals(d));
+  EXPECT_FALSE(a.Equals(e));
+  EXPECT_FALSE(b.Equals(a));
+  EXPECT_FALSE(b.Equals(c));
+  EXPECT_FALSE(b.Equals(d));
+  EXPECT_FALSE(b.Equals(e));
   EXPECT_FALSE(c.Equals(a));
+  EXPECT_FALSE(c.Equals(b));
+  EXPECT_FALSE(c.Equals(d));
+  EXPECT_FALSE(c.Equals(e));
+  EXPECT_FALSE(d.Equals(a));
+  EXPECT_FALSE(d.Equals(b));
+  EXPECT_FALSE(d.Equals(c));
+  EXPECT_FALSE(d.Equals(e));
+  EXPECT_FALSE(e.Equals(a));
+  EXPECT_FALSE(e.Equals(b));
+  EXPECT_FALSE(e.Equals(c));
+  EXPECT_FALSE(e.Equals(d));
   EXPECT_TRUE(a.Equals(a2));
   EXPECT_TRUE(a2.Equals(a));
+  EXPECT_TRUE(d.Equals(d2));
+  EXPECT_TRUE(d2.Equals(d));
   PolicyMap empty1;
   PolicyMap empty2;
   EXPECT_TRUE(empty1.Equals(empty2));
@@ -64,19 +118,30 @@
   EXPECT_FALSE(a.Equals(empty1));
 }
 
-TEST(PolicyMapTest, Swap) {
+TEST_F(PolicyMapTest, Swap) {
   PolicyMap a;
   SetPolicy(&a, key::kHomepageLocation, Value::CreateStringValue("aaa"));
+  SetPolicy(&a, key::kAlternateErrorPagesEnabled,
+            CreateExternalDataFetcher("dummy").release());
   PolicyMap b;
   SetPolicy(&b, key::kHomepageLocation, Value::CreateStringValue("bbb"));
   SetPolicy(&b, key::kHomepageIsNewTabPage, Value::CreateBooleanValue(true));
+
   a.Swap(&b);
   base::StringValue expected("bbb");
   EXPECT_TRUE(expected.Equals(a.GetValue(key::kHomepageLocation)));
   base::FundamentalValue expected_bool(true);
   EXPECT_TRUE(expected_bool.Equals(a.GetValue(key::kHomepageIsNewTabPage)));
+  EXPECT_FALSE(a.GetValue(key::kAlternateErrorPagesEnabled));
+  EXPECT_FALSE(a.Get(key::kAlternateErrorPagesEnabled));
   StringValue expected_a("aaa");
   EXPECT_TRUE(expected_a.Equals(b.GetValue(key::kHomepageLocation)));
+  EXPECT_FALSE(b.GetValue(key::kHomepageIsNewTabPage));
+  EXPECT_FALSE(a.GetValue(key::kAlternateErrorPagesEnabled));
+  const PolicyMap::Entry* entry = b.Get(key::kAlternateErrorPagesEnabled);
+  ASSERT_TRUE(entry);
+  EXPECT_TRUE(ExternalDataFetcher::Equals(
+      CreateExternalDataFetcher("dummy").get(), entry->external_data_fetcher));
 
   b.Clear();
   a.Swap(&b);
@@ -85,81 +150,107 @@
   EXPECT_FALSE(b.Equals(empty));
 }
 
-TEST(PolicyMapTest, MergeFrom) {
+TEST_F(PolicyMapTest, MergeFrom) {
   PolicyMap a;
   a.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        Value::CreateStringValue("google.com"));
+        Value::CreateStringValue("google.com"), NULL);
   a.Set(key::kShowHomeButton, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-        Value::CreateBooleanValue(true));
+        Value::CreateBooleanValue(true), NULL);
+  a.Set(key::kAlternateErrorPagesEnabled,
+        POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
+        NULL, CreateExternalDataFetcher("a").release());
   a.Set(key::kBookmarkBarEnabled, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-        Value::CreateBooleanValue(false));
-  a.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_RECOMMENDED,
-        POLICY_SCOPE_MACHINE, Value::CreateStringValue("google.com/q={x}"));
+        Value::CreateBooleanValue(false), NULL);
+  a.Set(key::kDefaultSearchProviderSearchURL,
+        POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
+        Value::CreateStringValue("google.com/q={x}"), NULL);
 
   PolicyMap b;
   b.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-        Value::CreateStringValue("chromium.org"));
+        Value::CreateStringValue("chromium.org"), NULL);
   b.Set(key::kShowHomeButton, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-        Value::CreateBooleanValue(false));
+        Value::CreateBooleanValue(false), NULL);
+  b.Set(key::kAlternateErrorPagesEnabled,
+        POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
+        NULL, CreateExternalDataFetcher("b").release());
   b.Set(key::kBookmarkBarEnabled, POLICY_LEVEL_RECOMMENDED,
-        POLICY_SCOPE_MACHINE, Value::CreateBooleanValue(true));
+        POLICY_SCOPE_MACHINE, Value::CreateBooleanValue(true), NULL);
   b.Set(key::kDefaultSearchProviderSearchURL,
         POLICY_LEVEL_MANDATORY,
         POLICY_SCOPE_MACHINE,
-        Value::CreateStringValue(std::string()));
+        Value::CreateStringValue(std::string()),
+        NULL);
   b.Set(key::kDisableSpdy,
         POLICY_LEVEL_RECOMMENDED,
         POLICY_SCOPE_USER,
-        Value::CreateBooleanValue(true));
+        Value::CreateBooleanValue(true),
+        NULL);
 
   a.MergeFrom(b);
 
   PolicyMap c;
   // POLICY_SCOPE_MACHINE over POLICY_SCOPE_USER.
   c.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-        Value::CreateStringValue("chromium.org"));
+        Value::CreateStringValue("chromium.org"), NULL);
   // |a| has precedence over |b|.
   c.Set(key::kShowHomeButton, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-        Value::CreateBooleanValue(true));
+        Value::CreateBooleanValue(true), NULL);
+  c.Set(key::kAlternateErrorPagesEnabled,
+        POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
+        NULL, CreateExternalDataFetcher("a").release());
   // POLICY_SCOPE_MACHINE over POLICY_SCOPE_USER for POLICY_LEVEL_RECOMMENDED.
   c.Set(key::kBookmarkBarEnabled, POLICY_LEVEL_RECOMMENDED,
-        POLICY_SCOPE_MACHINE, Value::CreateBooleanValue(true));
+        POLICY_SCOPE_MACHINE, Value::CreateBooleanValue(true), NULL);
   // POLICY_LEVEL_MANDATORY over POLICY_LEVEL_RECOMMENDED.
   c.Set(key::kDefaultSearchProviderSearchURL,
         POLICY_LEVEL_MANDATORY,
         POLICY_SCOPE_MACHINE,
-        Value::CreateStringValue(std::string()));
+        Value::CreateStringValue(std::string()),
+        NULL);
   // Merge new ones.
   c.Set(key::kDisableSpdy, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-        Value::CreateBooleanValue(true));
+        Value::CreateBooleanValue(true), NULL);
 
   EXPECT_TRUE(a.Equals(c));
 }
 
-TEST(PolicyMapTest, GetDifferingKeys) {
+TEST_F(PolicyMapTest, GetDifferingKeys) {
   PolicyMap a;
   a.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        Value::CreateStringValue("google.com"));
+        Value::CreateStringValue("google.com"), NULL);
+  a.Set(key::kSearchSuggestEnabled,
+        POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
+        NULL, CreateExternalDataFetcher("dummy").release());
   a.Set(key::kShowHomeButton, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-        Value::CreateBooleanValue(true));
+        Value::CreateBooleanValue(true), NULL);
+  a.Set(key::kAlternateErrorPagesEnabled,
+        POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
+        NULL, CreateExternalDataFetcher("a").release());
   a.Set(key::kBookmarkBarEnabled, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-        Value::CreateBooleanValue(false));
-  a.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_RECOMMENDED,
-        POLICY_SCOPE_MACHINE, Value::CreateStringValue("google.com/q={x}"));
+        Value::CreateBooleanValue(false), NULL);
+  a.Set(key::kDefaultSearchProviderSearchURL,
+        POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
+        Value::CreateStringValue("google.com/q={x}"), NULL);
   a.Set(key::kDisable3DAPIs, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        Value::CreateBooleanValue(true));
+        Value::CreateBooleanValue(true), NULL);
 
   PolicyMap b;
   b.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        Value::CreateStringValue("google.com"));
+        Value::CreateStringValue("google.com"), NULL);
+  b.Set(key::kSearchSuggestEnabled,
+        POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
+        NULL, CreateExternalDataFetcher("dummy").release());
   b.Set(key::kShowHomeButton, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-        Value::CreateBooleanValue(false));
+        Value::CreateBooleanValue(false), NULL);
+  b.Set(key::kAlternateErrorPagesEnabled,
+        POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
+        NULL, CreateExternalDataFetcher("b").release());
   b.Set(key::kBookmarkBarEnabled, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        Value::CreateBooleanValue(false));
+        Value::CreateBooleanValue(false), NULL);
   b.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_RECOMMENDED,
-        POLICY_SCOPE_USER, Value::CreateStringValue("google.com/q={x}"));
+        POLICY_SCOPE_USER, Value::CreateStringValue("google.com/q={x}"), NULL);
   b.Set(key::kDisableSpdy, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-        Value::CreateBooleanValue(true));
+        Value::CreateBooleanValue(true), NULL);
 
   std::set<std::string> diff;
   std::set<std::string> diff2;
@@ -169,8 +260,11 @@
   EXPECT_EQ(diff, diff2);
   // No change.
   EXPECT_TRUE(diff.find(key::kHomepageLocation) == diff.end());
+  EXPECT_TRUE(diff.find(key::kSearchSuggestEnabled) == diff.end());
   // Different values.
   EXPECT_TRUE(diff.find(key::kShowHomeButton) != diff.end());
+  // Different external data references.
+  EXPECT_TRUE(diff.find(key::kAlternateErrorPagesEnabled) != diff.end());
   // Different levels.
   EXPECT_TRUE(diff.find(key::kBookmarkBarEnabled) != diff.end());
   // Different scopes.
@@ -180,9 +274,7 @@
   // Not in |b|.
   EXPECT_TRUE(diff.find(key::kDisable3DAPIs) != diff.end());
   // No surprises.
-  EXPECT_EQ(5u, diff.size());
+  EXPECT_EQ(6u, diff.size());
 }
 
-}  // namespace
-
 }  // namespace policy
diff --git a/chrome/browser/policy/policy_schema.cc b/chrome/browser/policy/policy_schema.cc
deleted file mode 100644
index c693140..0000000
--- a/chrome/browser/policy/policy_schema.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/policy/policy_schema.h"
-
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/stl_util.h"
-#include "chrome/common/json_schema/json_schema_constants.h"
-#include "chrome/common/json_schema/json_schema_validator.h"
-
-namespace policy {
-
-namespace {
-
-const char kJSONSchemaVersion[] = "http://json-schema.org/draft-03/schema#";
-
-// Describes the properties of a TYPE_DICTIONARY policy schema.
-class DictionaryPolicySchema : public PolicySchema {
- public:
-  static scoped_ptr<PolicySchema> Parse(const base::DictionaryValue& schema,
-                                        std::string* error);
-
-  virtual ~DictionaryPolicySchema();
-
-  virtual const PolicySchemaMap* GetProperties() const OVERRIDE;
-  virtual const PolicySchema* GetSchemaForAdditionalProperties() const OVERRIDE;
-
- private:
-  DictionaryPolicySchema();
-
-  PolicySchemaMap properties_;
-  scoped_ptr<PolicySchema> additional_properties_;
-
-  DISALLOW_COPY_AND_ASSIGN(DictionaryPolicySchema);
-};
-
-// Describes the items of a TYPE_LIST policy schema.
-class ListPolicySchema : public PolicySchema {
- public:
-  static scoped_ptr<PolicySchema> Parse(const base::DictionaryValue& schema,
-                                        std::string* error);
-
-  virtual ~ListPolicySchema();
-
-  virtual const PolicySchema* GetSchemaForItems() const OVERRIDE;
-
- private:
-  ListPolicySchema();
-
-  scoped_ptr<PolicySchema> items_schema_;
-
-  DISALLOW_COPY_AND_ASSIGN(ListPolicySchema);
-};
-
-bool SchemaTypeToValueType(const std::string& type_string,
-                           base::Value::Type* type) {
-  // Note: "any" is not an accepted type.
-  static const struct {
-    const char* schema_type;
-    base::Value::Type value_type;
-  } kSchemaToValueTypeMap[] = {
-    { json_schema_constants::kArray,        base::Value::TYPE_LIST       },
-    { json_schema_constants::kBoolean,      base::Value::TYPE_BOOLEAN    },
-    { json_schema_constants::kInteger,      base::Value::TYPE_INTEGER    },
-    { json_schema_constants::kNull,         base::Value::TYPE_NULL       },
-    { json_schema_constants::kNumber,       base::Value::TYPE_DOUBLE     },
-    { json_schema_constants::kObject,       base::Value::TYPE_DICTIONARY },
-    { json_schema_constants::kString,       base::Value::TYPE_STRING     },
-  };
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSchemaToValueTypeMap); ++i) {
-    if (kSchemaToValueTypeMap[i].schema_type == type_string) {
-      *type = kSchemaToValueTypeMap[i].value_type;
-      return true;
-    }
-  }
-  return false;
-}
-
-scoped_ptr<PolicySchema> ParseSchema(const base::DictionaryValue& schema,
-                                     std::string* error) {
-  std::string type_string;
-  if (!schema.GetString(json_schema_constants::kType, &type_string)) {
-    *error = "The schema type must be declared.";
-    return scoped_ptr<PolicySchema>();
-  }
-
-  base::Value::Type type = base::Value::TYPE_NULL;
-  if (!SchemaTypeToValueType(type_string, &type)) {
-    *error = "The \"any\" type can't be used.";
-    return scoped_ptr<PolicySchema>();
-  }
-
-  switch (type) {
-    case base::Value::TYPE_DICTIONARY:
-      return DictionaryPolicySchema::Parse(schema, error);
-    case base::Value::TYPE_LIST:
-      return ListPolicySchema::Parse(schema, error);
-    default:
-      return make_scoped_ptr(new PolicySchema(type));
-  }
-}
-
-DictionaryPolicySchema::DictionaryPolicySchema()
-    : PolicySchema(base::Value::TYPE_DICTIONARY) {}
-
-DictionaryPolicySchema::~DictionaryPolicySchema() {
-  STLDeleteValues(&properties_);
-}
-
-const PolicySchemaMap* DictionaryPolicySchema::GetProperties() const {
-  return &properties_;
-}
-
-const PolicySchema*
-    DictionaryPolicySchema::GetSchemaForAdditionalProperties() const {
-  return additional_properties_.get();
-}
-
-// static
-scoped_ptr<PolicySchema> DictionaryPolicySchema::Parse(
-    const base::DictionaryValue& schema,
-    std::string* error) {
-  scoped_ptr<DictionaryPolicySchema> dict_schema(new DictionaryPolicySchema());
-
-  const base::DictionaryValue* dict = NULL;
-  const base::DictionaryValue* properties = NULL;
-  if (schema.GetDictionary(json_schema_constants::kProperties, &properties)) {
-    for (base::DictionaryValue::Iterator it(*properties);
-         !it.IsAtEnd(); it.Advance()) {
-      // This should have been verified by the JSONSchemaValidator.
-      CHECK(it.value().GetAsDictionary(&dict));
-      scoped_ptr<PolicySchema> sub_schema = ParseSchema(*dict, error);
-      if (!sub_schema)
-        return scoped_ptr<PolicySchema>();
-      dict_schema->properties_[it.key()] = sub_schema.release();
-    }
-  }
-
-  if (schema.GetDictionary(json_schema_constants::kAdditionalProperties,
-                           &dict)) {
-    scoped_ptr<PolicySchema> sub_schema = ParseSchema(*dict, error);
-    if (!sub_schema)
-      return scoped_ptr<PolicySchema>();
-    dict_schema->additional_properties_ = sub_schema.Pass();
-  }
-
-  return dict_schema.PassAs<PolicySchema>();
-}
-
-ListPolicySchema::ListPolicySchema()
-    : PolicySchema(base::Value::TYPE_LIST) {}
-
-ListPolicySchema::~ListPolicySchema() {}
-
-const PolicySchema* ListPolicySchema::GetSchemaForItems() const {
-  return items_schema_.get();
-}
-
-scoped_ptr<PolicySchema> ListPolicySchema::Parse(
-    const base::DictionaryValue& schema,
-    std::string* error) {
-  const base::DictionaryValue* dict = NULL;
-  if (!schema.GetDictionary(json_schema_constants::kItems, &dict)) {
-    *error = "Arrays must declare a single schema for their items.";
-    return scoped_ptr<PolicySchema>();
-  }
-  scoped_ptr<PolicySchema> items_schema = ParseSchema(*dict, error);
-  if (!items_schema)
-    return scoped_ptr<PolicySchema>();
-
-  scoped_ptr<ListPolicySchema> list_schema(new ListPolicySchema());
-  list_schema->items_schema_ = items_schema.Pass();
-  return list_schema.PassAs<PolicySchema>();
-}
-
-}  // namespace
-
-PolicySchema::PolicySchema(base::Value::Type type)
-    : type_(type) {}
-
-PolicySchema::~PolicySchema() {}
-
-const PolicySchemaMap* PolicySchema::GetProperties() const {
-  NOTREACHED();
-  return NULL;
-}
-
-const PolicySchema* PolicySchema::GetSchemaForAdditionalProperties() const {
-  NOTREACHED();
-  return NULL;
-}
-
-const PolicySchema* PolicySchema::GetSchemaForProperty(
-    const std::string& key) const {
-  const PolicySchemaMap* properties = GetProperties();
-  PolicySchemaMap::const_iterator it = properties->find(key);
-  return it == properties->end() ? GetSchemaForAdditionalProperties()
-                                 : it->second;
-}
-
-const PolicySchema* PolicySchema::GetSchemaForItems() const {
-  NOTREACHED();
-  return NULL;
-}
-
-// static
-scoped_ptr<PolicySchema> PolicySchema::Parse(const std::string& content,
-                                             std::string* error) {
-  // Validate as a generic JSON schema.
-  scoped_ptr<base::DictionaryValue> dict =
-      JSONSchemaValidator::IsValidSchema(content, error);
-  if (!dict)
-    return scoped_ptr<PolicySchema>();
-
-  // Validate the schema version.
-  std::string string_value;
-  if (!dict->GetString(json_schema_constants::kSchema, &string_value) ||
-      string_value != kJSONSchemaVersion) {
-    *error = "Must declare JSON Schema v3 version in \"$schema\".";
-    return scoped_ptr<PolicySchema>();
-  }
-
-  // Validate the main type.
-  if (!dict->GetString(json_schema_constants::kType, &string_value) ||
-      string_value != json_schema_constants::kObject) {
-    *error =
-        "The main schema must have a type attribute with \"object\" value.";
-    return scoped_ptr<PolicySchema>();
-  }
-
-  // Checks for invalid attributes at the top-level.
-  if (dict->HasKey(json_schema_constants::kAdditionalProperties) ||
-      dict->HasKey(json_schema_constants::kPatternProperties)) {
-    *error = "\"additionalProperties\" and \"patternProperties\" are not "
-             "supported at the main schema.";
-    return scoped_ptr<PolicySchema>();
-  }
-
-  return ParseSchema(*dict, error);
-}
-
-}  // namespace policy
diff --git a/chrome/browser/policy/policy_schema.h b/chrome/browser/policy/policy_schema.h
deleted file mode 100644
index b030b1e..0000000
--- a/chrome/browser/policy/policy_schema.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_POLICY_POLICY_SCHEMA_H_
-#define CHROME_BROWSER_POLICY_POLICY_SCHEMA_H_
-
-#include <map>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/values.h"
-
-namespace policy {
-
-class PolicySchema;
-typedef std::map<std::string, PolicySchema*> PolicySchemaMap;
-
-// Maps known policy keys to their expected types, and recursively describes
-// the known keys within dictionary or list types.
-class PolicySchema {
- public:
-
-  // Parses |schema| as a JSON v3 schema, and additionally verifies that:
-  // - the version is JSON schema v3;
-  // - the top-level entry is of type "object";
-  // - the top-level object doesn't contain "additionalProperties" nor
-  //   "patternProperties";
-  // - each "property" maps to a schema with one "type";
-  // - the type "any" is not used.
-  // If all the checks pass then the parsed PolicySchema is returned; otherwise
-  // returns NULL.
-  static scoped_ptr<PolicySchema> Parse(const std::string& schema,
-                                        std::string* error);
-
-  explicit PolicySchema(base::Value::Type type);
-  virtual ~PolicySchema();
-
-  // Returns the expected type for this policy. At the top-level PolicySchema
-  // this is always TYPE_DICTIONARY.
-  base::Value::Type type() const { return type_; }
-
-  // It is invalid to call these methods when type() is not TYPE_DICTIONARY.
-  //
-  // GetProperties() returns a map of the known property names to their schemas;
-  // the map is never NULL.
-  // GetSchemaForAdditionalProperties() returns the schema that should be used
-  // for keys not found in the map, and may be NULL.
-  // GetSchemaForProperty() is a utility method that combines both, returning
-  // the mapped schema if found in GetProperties(), otherwise returning
-  // GetSchemaForAdditionalProperties().
-  virtual const PolicySchemaMap* GetProperties() const;
-  virtual const PolicySchema* GetSchemaForAdditionalProperties() const;
-  const PolicySchema* GetSchemaForProperty(const std::string& key) const;
-
-  // It is invalid to call this method when type() is not TYPE_LIST.
-  // Returns the type of the entries of this "array", which is never NULL.
-  virtual const PolicySchema* GetSchemaForItems() const;
-
- private:
-  const base::Value::Type type_;
-
-  DISALLOW_COPY_AND_ASSIGN(PolicySchema);
-};
-
-}  // namespace policy
-
-#endif  // CHROME_BROWSER_POLICY_POLICY_SCHEMA_H_
diff --git a/chrome/browser/policy/policy_schema_unittest.cc b/chrome/browser/policy/policy_schema_unittest.cc
deleted file mode 100644
index 620eaf0..0000000
--- a/chrome/browser/policy/policy_schema_unittest.cc
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/policy/policy_schema.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace policy {
-
-namespace {
-
-#define SCHEMA_VERSION "\"$schema\":\"http://json-schema.org/draft-03/schema#\""
-#define OBJECT_TYPE "\"type\":\"object\""
-
-bool ParseFails(const std::string& content) {
-  std::string error;
-  scoped_ptr<PolicySchema> schema = PolicySchema::Parse(content, &error);
-  EXPECT_TRUE(schema || !error.empty());
-  return !schema;
-}
-
-}  // namespace
-
-TEST(PolicySchemaTest, MinimalSchema) {
-  EXPECT_FALSE(ParseFails(
-      "{"
-        SCHEMA_VERSION ","
-        OBJECT_TYPE
-      "}"));
-}
-
-TEST(PolicySchemaTest, InvalidSchemas) {
-  EXPECT_TRUE(ParseFails(""));
-  EXPECT_TRUE(ParseFails("omg"));
-  EXPECT_TRUE(ParseFails("\"omg\""));
-  EXPECT_TRUE(ParseFails("123"));
-  EXPECT_TRUE(ParseFails("[]"));
-  EXPECT_TRUE(ParseFails("null"));
-  EXPECT_TRUE(ParseFails("{}"));
-  EXPECT_TRUE(ParseFails("{" SCHEMA_VERSION "}"));
-  EXPECT_TRUE(ParseFails("{" OBJECT_TYPE "}"));
-
-  EXPECT_TRUE(ParseFails(
-      "{"
-        SCHEMA_VERSION ","
-        OBJECT_TYPE ","
-        "\"additionalProperties\": { \"type\":\"object\" }"
-      "}"));
-
-  EXPECT_TRUE(ParseFails(
-      "{"
-        SCHEMA_VERSION ","
-        OBJECT_TYPE ","
-        "\"patternProperties\": { \"a+b*\": { \"type\": \"object\" } }"
-      "}"));
-
-  EXPECT_TRUE(ParseFails(
-      "{"
-        SCHEMA_VERSION ","
-        OBJECT_TYPE ","
-        "\"properties\": { \"Policy\": { \"type\": \"bogus\" } }"
-      "}"));
-
-  EXPECT_TRUE(ParseFails(
-      "{"
-        SCHEMA_VERSION ","
-        OBJECT_TYPE ","
-        "\"properties\": { \"Policy\": { \"type\": [\"string\", \"number\"] } }"
-      "}"));
-
-  EXPECT_TRUE(ParseFails(
-      "{"
-        SCHEMA_VERSION ","
-        OBJECT_TYPE ","
-        "\"properties\": { \"Policy\": { \"type\": \"any\" } }"
-      "}"));
-}
-
-TEST(PolicySchemaTest, ValidSchema) {
-  std::string error;
-  scoped_ptr<PolicySchema> schema = PolicySchema::Parse(
-      "{"
-        SCHEMA_VERSION ","
-        OBJECT_TYPE ","
-        "\"properties\": {"
-        "  \"Boolean\": { \"type\": \"boolean\" },"
-        "  \"Integer\": { \"type\": \"integer\" },"
-        "  \"Null\": { \"type\": \"null\" },"
-        "  \"Number\": { \"type\": \"number\" },"
-        "  \"String\": { \"type\": \"string\" },"
-        "  \"Array\": {"
-        "    \"type\": \"array\","
-        "    \"items\": { \"type\": \"string\" }"
-        "  },"
-        "  \"ArrayOfObjects\": {"
-        "    \"type\": \"array\","
-        "    \"items\": {"
-        "      \"type\": \"object\","
-        "      \"properties\": {"
-        "        \"one\": { \"type\": \"string\" },"
-        "        \"two\": { \"type\": \"integer\" }"
-        "      }"
-        "    }"
-        "  },"
-        "  \"ArrayOfArray\": {"
-        "    \"type\": \"array\","
-        "    \"items\": {"
-        "      \"type\": \"array\","
-        "      \"items\": { \"type\": \"string\" }"
-        "    }"
-        "  },"
-        "  \"Object\": {"
-        "    \"type\": \"object\","
-        "    \"properties\": {"
-        "      \"one\": { \"type\": \"boolean\" },"
-        "      \"two\": { \"type\": \"integer\" }"
-        "    },"
-        "    \"additionalProperties\": { \"type\": \"string\" }"
-        "  }"
-        "}"
-      "}", &error);
-  ASSERT_TRUE(schema) << error;
-
-  ASSERT_EQ(base::Value::TYPE_DICTIONARY, schema->type());
-  EXPECT_FALSE(schema->GetSchemaForProperty("invalid"));
-
-  const PolicySchema* sub = schema->GetSchemaForProperty("Boolean");
-  ASSERT_TRUE(sub);
-  EXPECT_EQ(base::Value::TYPE_BOOLEAN, sub->type());
-
-  sub = schema->GetSchemaForProperty("Integer");
-  ASSERT_TRUE(sub);
-  EXPECT_EQ(base::Value::TYPE_INTEGER, sub->type());
-
-  sub = schema->GetSchemaForProperty("Null");
-  ASSERT_TRUE(sub);
-  EXPECT_EQ(base::Value::TYPE_NULL, sub->type());
-
-  sub = schema->GetSchemaForProperty("Number");
-  ASSERT_TRUE(sub);
-  EXPECT_EQ(base::Value::TYPE_DOUBLE, sub->type());
-  sub = schema->GetSchemaForProperty("String");
-  ASSERT_TRUE(sub);
-  EXPECT_EQ(base::Value::TYPE_STRING, sub->type());
-
-  sub = schema->GetSchemaForProperty("Array");
-  ASSERT_TRUE(sub);
-  ASSERT_EQ(base::Value::TYPE_LIST, sub->type());
-  sub = sub->GetSchemaForItems();
-  ASSERT_TRUE(sub);
-  EXPECT_EQ(base::Value::TYPE_STRING, sub->type());
-
-  sub = schema->GetSchemaForProperty("ArrayOfObjects");
-  ASSERT_TRUE(sub);
-  ASSERT_EQ(base::Value::TYPE_LIST, sub->type());
-  sub = sub->GetSchemaForItems();
-  ASSERT_TRUE(sub);
-  EXPECT_EQ(base::Value::TYPE_DICTIONARY, sub->type());
-  const PolicySchema* subsub = sub->GetSchemaForProperty("one");
-  ASSERT_TRUE(subsub);
-  EXPECT_EQ(base::Value::TYPE_STRING, subsub->type());
-  subsub = sub->GetSchemaForProperty("two");
-  ASSERT_TRUE(subsub);
-  EXPECT_EQ(base::Value::TYPE_INTEGER, subsub->type());
-  subsub = sub->GetSchemaForProperty("invalid");
-  EXPECT_FALSE(subsub);
-
-  sub = schema->GetSchemaForProperty("ArrayOfArray");
-  ASSERT_TRUE(sub);
-  ASSERT_EQ(base::Value::TYPE_LIST, sub->type());
-  sub = sub->GetSchemaForItems();
-  ASSERT_TRUE(sub);
-  ASSERT_EQ(base::Value::TYPE_LIST, sub->type());
-  sub = sub->GetSchemaForItems();
-  ASSERT_TRUE(sub);
-  EXPECT_EQ(base::Value::TYPE_STRING, sub->type());
-
-  sub = schema->GetSchemaForProperty("Object");
-  ASSERT_TRUE(sub);
-  ASSERT_EQ(base::Value::TYPE_DICTIONARY, sub->type());
-  subsub = sub->GetSchemaForProperty("one");
-  ASSERT_TRUE(subsub);
-  EXPECT_EQ(base::Value::TYPE_BOOLEAN, subsub->type());
-  subsub = sub->GetSchemaForProperty("two");
-  ASSERT_TRUE(subsub);
-  EXPECT_EQ(base::Value::TYPE_INTEGER, subsub->type());
-  subsub = sub->GetSchemaForProperty("undeclared");
-  ASSERT_TRUE(subsub);
-  EXPECT_EQ(base::Value::TYPE_STRING, subsub->type());
-}
-
-}  // namespace policy
diff --git a/chrome/browser/policy/policy_service_impl_unittest.cc b/chrome/browser/policy/policy_service_impl_unittest.cc
index f5efb78..ad4fdcb 100644
--- a/chrome/browser/policy/policy_service_impl_unittest.cc
+++ b/chrome/browser/policy/policy_service_impl_unittest.cc
@@ -6,14 +6,16 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/callback.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "base/run_loop.h"
 #include "base/values.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_domain_descriptor.h"
-#include "chrome/browser/policy/policy_schema.h"
+#include "chrome/common/policy/policy_schema.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -61,15 +63,16 @@
   PolicyMap* policy_map =
       &bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
   policy_map->Set(kSameLevelPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                  base::Value::CreateStringValue(value));
+                  base::Value::CreateStringValue(value), NULL);
   policy_map->Set(kDiffLevelPolicy, level, scope,
-                  base::Value::CreateStringValue(value));
+                  base::Value::CreateStringValue(value), NULL);
   policy_map =
       &bundle->Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension));
   policy_map->Set(kSameLevelPolicy, POLICY_LEVEL_MANDATORY,
-                  POLICY_SCOPE_USER, base::Value::CreateStringValue(value));
+                  POLICY_SCOPE_USER, base::Value::CreateStringValue(value),
+                  NULL);
   policy_map->Set(kDiffLevelPolicy, level, scope,
-                  base::Value::CreateStringValue(value));
+                  base::Value::CreateStringValue(value), NULL);
 }
 
 // Observer class that changes the policy in the passed provider when the
@@ -85,7 +88,7 @@
                                const PolicyMap& current) OVERRIDE {
     PolicyMap new_policy;
     new_policy.Set("foo", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                   base::Value::CreateIntegerValue(14));
+                   base::Value::CreateIntegerValue(14), NULL);
     provider_->UpdateChromePolicy(new_policy);
     observer_invoked_ = true;
   }
@@ -115,7 +118,7 @@
     provider2_.Init();
 
     policy0_.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 base::Value::CreateIntegerValue(13));
+                 base::Value::CreateIntegerValue(13), NULL);
     provider0_.UpdateChromePolicy(policy0_);
 
     PolicyServiceImpl::Providers providers;
@@ -169,7 +172,7 @@
 TEST_F(PolicyServiceTest, LoadsPoliciesBeforeProvidersRefresh) {
   PolicyMap expected;
   expected.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(13));
+               base::Value::CreateIntegerValue(13), NULL);
   EXPECT_TRUE(VerifyPolicies(
       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()), expected));
 }
@@ -180,14 +183,14 @@
 
   PolicyMap expectedPrevious;
   expectedPrevious.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                       base::Value::CreateIntegerValue(13));
+                       base::Value::CreateIntegerValue(13), NULL);
 
   PolicyMap expectedCurrent;
   expectedCurrent.CopyFrom(expectedPrevious);
   expectedCurrent.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                      base::Value::CreateIntegerValue(123));
+                      base::Value::CreateIntegerValue(123), NULL);
   policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(123));
+               base::Value::CreateIntegerValue(123), NULL);
   EXPECT_CALL(observer, OnPolicyUpdated(PolicyNamespace(POLICY_DOMAIN_CHROME,
                                                         std::string()),
                                         PolicyEquals(&expectedPrevious),
@@ -205,9 +208,9 @@
   // New policy.
   expectedPrevious.CopyFrom(expectedCurrent);
   expectedCurrent.Set("bbb", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                      base::Value::CreateIntegerValue(456));
+                      base::Value::CreateIntegerValue(456), NULL);
   policy0_.Set("bbb", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(456));
+               base::Value::CreateIntegerValue(456), NULL);
   EXPECT_CALL(observer, OnPolicyUpdated(PolicyNamespace(POLICY_DOMAIN_CHROME,
                                                         std::string()),
                                         PolicyEquals(&expectedPrevious),
@@ -229,9 +232,9 @@
   // Changed policy.
   expectedPrevious.CopyFrom(expectedCurrent);
   expectedCurrent.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                      base::Value::CreateIntegerValue(789));
+                      base::Value::CreateIntegerValue(789), NULL);
   policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(789));
+               base::Value::CreateIntegerValue(789), NULL);
 
   EXPECT_CALL(observer, OnPolicyUpdated(PolicyNamespace(POLICY_DOMAIN_CHROME,
                                                         std::string()),
@@ -261,11 +264,11 @@
 
   PolicyMap previous_policy_map;
   previous_policy_map.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                          base::Value::CreateIntegerValue(13));
+                          base::Value::CreateIntegerValue(13), NULL);
   PolicyMap policy_map;
   policy_map.CopyFrom(previous_policy_map);
   policy_map.Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 base::Value::CreateStringValue("value"));
+                 base::Value::CreateStringValue("value"), NULL);
 
   scoped_ptr<PolicyBundle> bundle(new PolicyBundle());
   // The initial setup includes a policy for chrome that is now changing.
@@ -304,7 +307,7 @@
   bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
       .CopyFrom(policy_map);
   policy_map.Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 base::Value::CreateStringValue("another value"));
+                 base::Value::CreateStringValue("another value"), NULL);
   bundle->Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension1))
       .CopyFrom(policy_map);
   bundle->Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension2))
@@ -340,9 +343,9 @@
   ChangePolicyObserver observer(&provider0_);
   policy_service_->AddObserver(POLICY_DOMAIN_CHROME, &observer);
   policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(123));
+               base::Value::CreateIntegerValue(123), NULL);
   policy0_.Set("bbb", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(1234));
+               base::Value::CreateIntegerValue(1234), NULL);
   // Should not crash.
   UpdateProviderPolicy(policy0_);
   policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, &observer);
@@ -352,15 +355,15 @@
 TEST_F(PolicyServiceTest, Priorities) {
   PolicyMap expected;
   expected.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(13));
+               base::Value::CreateIntegerValue(13), NULL);
   expected.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(0));
+               base::Value::CreateIntegerValue(0), NULL);
   policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(0));
+               base::Value::CreateIntegerValue(0), NULL);
   policy1_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(1));
+               base::Value::CreateIntegerValue(1), NULL);
   policy2_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(2));
+               base::Value::CreateIntegerValue(2), NULL);
   provider0_.UpdateChromePolicy(policy0_);
   provider1_.UpdateChromePolicy(policy1_);
   provider2_.UpdateChromePolicy(policy2_);
@@ -368,16 +371,16 @@
       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()), expected));
 
   expected.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(1));
+               base::Value::CreateIntegerValue(1), NULL);
   policy0_.Erase("aaa");
   provider0_.UpdateChromePolicy(policy0_);
   EXPECT_TRUE(VerifyPolicies(
       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()), expected));
 
   expected.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(2));
+               base::Value::CreateIntegerValue(2), NULL);
   policy1_.Set("aaa", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-               base::Value::CreateIntegerValue(1));
+               base::Value::CreateIntegerValue(1), NULL);
   provider1_.UpdateChromePolicy(policy1_);
   EXPECT_TRUE(VerifyPolicies(
       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()), expected));
@@ -403,14 +406,14 @@
   base::FundamentalValue kValue0(0);
   EXPECT_CALL(*this, OnPolicyValueUpdated(NULL, ValueEquals(&kValue0)));
   policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               kValue0.DeepCopy());
+               kValue0.DeepCopy(), NULL);
   UpdateProviderPolicy(policy0_);
   Mock::VerifyAndClearExpectations(this);
 
   // Changing other values doesn't trigger a notification.
   EXPECT_CALL(*this, OnPolicyValueUpdated(_, _)).Times(0);
   policy0_.Set("bbb", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               kValue0.DeepCopy());
+               kValue0.DeepCopy(), NULL);
   UpdateProviderPolicy(policy0_);
   Mock::VerifyAndClearExpectations(this);
 
@@ -419,7 +422,7 @@
   EXPECT_CALL(*this, OnPolicyValueUpdated(ValueEquals(&kValue0),
                                           ValueEquals(&kValue1)));
   policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               kValue1.DeepCopy());
+               kValue1.DeepCopy(), NULL);
   UpdateProviderPolicy(policy0_);
   Mock::VerifyAndClearExpectations(this);
 
@@ -433,9 +436,9 @@
   EXPECT_CALL(*this, OnPolicyValueUpdated(_, _)).Times(0);
   registrar.reset();
   policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               kValue1.DeepCopy());
+               kValue1.DeepCopy(), NULL);
   policy0_.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               kValue1.DeepCopy());
+               kValue1.DeepCopy(), NULL);
   UpdateProviderPolicy(policy0_);
   Mock::VerifyAndClearExpectations(this);
 }
@@ -460,14 +463,14 @@
   EXPECT_CALL(*this, OnPolicyRefresh()).Times(0);
   base::FundamentalValue kValue0(0);
   policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               kValue0.DeepCopy());
+               kValue0.DeepCopy(), NULL);
   UpdateProviderPolicy(policy0_);
   Mock::VerifyAndClearExpectations(this);
 
   EXPECT_CALL(*this, OnPolicyRefresh()).Times(0);
   base::FundamentalValue kValue1(1);
   policy1_.Set("aaa", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-               kValue1.DeepCopy());
+               kValue1.DeepCopy(), NULL);
   provider1_.UpdateChromePolicy(policy1_);
   RunUntilIdle();
   Mock::VerifyAndClearExpectations(this);
@@ -477,7 +480,7 @@
   // refreshed.
   EXPECT_CALL(*this, OnPolicyRefresh()).Times(0);
   policy1_.Set("bbb", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-               kValue1.DeepCopy());
+               kValue1.DeepCopy(), NULL);
   provider1_.UpdateChromePolicy(policy1_);
   RunUntilIdle();
   Mock::VerifyAndClearExpectations(this);
@@ -493,7 +496,7 @@
 
   EXPECT_CALL(*this, OnPolicyRefresh()).Times(0);
   policy2_.Set("bbb", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               kValue0.DeepCopy());
+               kValue0.DeepCopy(), NULL);
   provider2_.UpdateChromePolicy(policy2_);
   RunUntilIdle();
   Mock::VerifyAndClearExpectations(this);
@@ -502,7 +505,7 @@
   EXPECT_CALL(*this, OnPolicyRefresh()).Times(2);
   base::FundamentalValue kValue2(2);
   policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               kValue2.DeepCopy());
+               kValue2.DeepCopy(), NULL);
   provider0_.UpdateChromePolicy(policy0_);
   provider1_.UpdateChromePolicy(policy1_);
   RunUntilIdle();
@@ -534,11 +537,11 @@
   // For policies of the same level and scope, the first provider takes
   // precedence, on every namespace.
   expected.Set(kSameLevelPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               base::Value::CreateStringValue("bundle0"));
+               base::Value::CreateStringValue("bundle0"), NULL);
   // For policies with different levels and scopes, the highest priority
   // level/scope combination takes precedence, on every namespace.
   expected.Set(kDiffLevelPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-               base::Value::CreateStringValue("bundle2"));
+               base::Value::CreateStringValue("bundle2"), NULL);
   EXPECT_TRUE(policy_service_->GetPolicies(
       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())).Equals(expected));
   EXPECT_TRUE(policy_service_->GetPolicies(
diff --git a/chrome/browser/policy/policy_statistics_collector_unittest.cc b/chrome/browser/policy/policy_statistics_collector_unittest.cc
index 06a68ca..aafea13 100644
--- a/chrome/browser/policy/policy_statistics_collector_unittest.cc
+++ b/chrome/browser/policy/policy_statistics_collector_unittest.cc
@@ -5,6 +5,7 @@
 #include <cstring>
 #include <string>
 
+#include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
@@ -12,6 +13,7 @@
 #include "base/test/test_simple_task_runner.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_policy_service.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_statistics_collector.h"
@@ -92,7 +94,7 @@
 
   void SetPolicy(const std::string& name) {
     policy_map_.Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                    base::Value::CreateBooleanValue(true));
+                    base::Value::CreateBooleanValue(true), NULL);
   }
 
   base::TimeDelta GetFirstDelay() const {
diff --git a/chrome/browser/policy/profile_policy_connector_factory.cc b/chrome/browser/policy/profile_policy_connector_factory.cc
index 26a87a2..774208c 100644
--- a/chrome/browser/policy/profile_policy_connector_factory.cc
+++ b/chrome/browser/policy/profile_policy_connector_factory.cc
@@ -108,7 +108,7 @@
   BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context);
 }
 
-void ProfilePolicyConnectorFactory::RegisterUserPrefs(
+void ProfilePolicyConnectorFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
 #if defined(OS_CHROMEOS)
   registry->RegisterBooleanPref(
diff --git a/chrome/browser/policy/profile_policy_connector_factory.h b/chrome/browser/policy/profile_policy_connector_factory.h
index 04ca3e4..a44fdee 100644
--- a/chrome/browser/policy/profile_policy_connector_factory.h
+++ b/chrome/browser/policy/profile_policy_connector_factory.h
@@ -73,7 +73,7 @@
       content::BrowserContext* context) OVERRIDE;
   virtual void BrowserContextDestroyed(
       content::BrowserContext* context) OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual void SetEmptyTestingFactory(
       content::BrowserContext* context) OVERRIDE;
diff --git a/chrome/browser/policy/proto/chromeos/chrome_device_policy.proto b/chrome/browser/policy/proto/chromeos/chrome_device_policy.proto
index 65fe798..48b268a 100644
--- a/chrome/browser/policy/proto/chromeos/chrome_device_policy.proto
+++ b/chrome/browser/policy/proto/chromeos/chrome_device_policy.proto
@@ -93,6 +93,7 @@
   optional bool report_activity_times = 2;
   optional bool report_boot_mode = 3;
   optional bool report_location = 4;
+  optional bool report_network_interfaces = 5;
 }
 
 message EphemeralUsersEnabledProto {
diff --git a/chrome/browser/policy/proto/cloud/device_management_backend.proto b/chrome/browser/policy/proto/cloud/device_management_backend.proto
index 2d1e856..c92152f 100644
--- a/chrome/browser/policy/proto/cloud/device_management_backend.proto
+++ b/chrome/browser/policy/proto/cloud/device_management_backend.proto
@@ -359,6 +359,33 @@
   optional string error_message = 10;
 }
 
+// Details about a network interface.
+message NetworkInterface {
+  // Indicates the type of network device.
+  enum NetworkDeviceType {
+    TYPE_ETHERNET = 0;
+    TYPE_WIFI = 1;
+    TYPE_WIMAX = 2;
+    TYPE_BLUETOOTH = 3;
+    TYPE_CELLULAR = 4;
+  }
+
+  // Network device type.
+  optional NetworkDeviceType type = 1;
+
+  // MAC address (if applicable) of the corresponding network device. This is
+  // formatted as an ASCII string with 12 hex digits. Example: A0B1C2D3E4F5.
+  optional string mac_address = 2;
+
+  // MEID (if applicable) of the corresponding network device. Formatted as
+  // ASCII string composed of 14 hex digits. Example: A10000009296F2.
+  optional string meid = 3;
+
+  // IMEI (if applicable) of the corresponding network device. 15-16 decimal
+  // digits encoded as ASCII string. Example: 355402040158759.
+  optional string imei = 4;
+}
+
 // Report device level status.
 message DeviceStatusReportRequest {
   // The OS version reported by the device is a platform version
@@ -383,6 +410,9 @@
 
   // The device location.
   optional DeviceLocation device_location = 7;
+
+  // List of network interfaces.
+  repeated NetworkInterface network_interface = 8;
 }
 
 // Report session (a user on one device) level status.
diff --git a/chrome/browser/policy/stub_external_data_manager.h b/chrome/browser/policy/stub_external_data_manager.h
new file mode 100644
index 0000000..6ccf125
--- /dev/null
+++ b/chrome/browser/policy/stub_external_data_manager.h
@@ -0,0 +1,27 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_STUB_EXTERNAL_DATA_MANAGER_H_
+#define CHROME_BROWSER_POLICY_STUB_EXTERNAL_DATA_MANAGER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
+
+namespace policy {
+
+// A stub ExternalDataManager that is used when policy support is disabled.
+class ExternalDataManager {
+ public:
+  void Fetch(const std::string& policy,
+             const ExternalDataFetcher::FetchCallback& callback) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ExternalDataManager);
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_POLICY_STUB_EXTERNAL_DATA_MANAGER_H_
diff --git a/chrome/browser/policy/url_blacklist_manager.cc b/chrome/browser/policy/url_blacklist_manager.cc
index 66a496e..69e4b03 100644
--- a/chrome/browser/policy/url_blacklist_manager.cc
+++ b/chrome/browser/policy/url_blacklist_manager.cc
@@ -11,8 +11,8 @@
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/net/url_fixer_upper.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/browser_thread.h"
@@ -391,7 +391,7 @@
 }
 
 // static
-void URLBlacklistManager::RegisterUserPrefs(
+void URLBlacklistManager::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(prefs::kUrlBlacklist,
                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
diff --git a/chrome/browser/policy/url_blacklist_manager.h b/chrome/browser/policy/url_blacklist_manager.h
index c9bb522..f502369 100644
--- a/chrome/browser/policy/url_blacklist_manager.h
+++ b/chrome/browser/policy/url_blacklist_manager.h
@@ -144,7 +144,7 @@
   virtual void SetBlacklist(scoped_ptr<URLBlacklist> blacklist);
 
   // Registers the preferences related to blacklisting in the given PrefService.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  protected:
   // Used to delay updating the blacklist while the preferences are
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.cc b/chrome/browser/predictors/autocomplete_action_predictor.cc
index 80276b2..2b9e732 100644
--- a/chrome/browser/predictors/autocomplete_action_predictor.cc
+++ b/chrome/browser/predictors/autocomplete_action_predictor.cc
@@ -17,6 +17,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
 #include "chrome/browser/autocomplete/autocomplete_result.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
@@ -30,7 +31,6 @@
 #include "chrome/browser/prerender/prerender_manager.h"
 #include "chrome/browser/prerender/prerender_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.cc b/chrome/browser/predictors/resource_prefetch_predictor.cc
index 7453009..d0f3865 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_database.h"
 #include "chrome/browser/history/history_db_task.h"
 #include "chrome/browser/history/history_notifications.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/predictors/predictor_database_factory.h"
 #include "chrome/browser/predictors/resource_prefetcher_manager.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index d70c205..69c7e85 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -69,6 +69,7 @@
 #include "chrome/browser/translate/translate_prefs.h"
 #include "chrome/browser/ui/alternate_error_tab_observer.h"
 #include "chrome/browser/ui/app_list/app_list_service.h"
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
 #include "chrome/browser/ui/browser_ui_prefs.h"
 #include "chrome/browser/ui/network_profile_bubble.h"
@@ -107,6 +108,7 @@
 
 #if defined(OS_MACOSX)
 #include "chrome/browser/ui/cocoa/confirm_quit.h"
+#include "chrome/browser/ui/cocoa/extensions/browser_actions_controller_prefs.h"
 #endif
 
 #if defined(TOOLKIT_VIEWS)
@@ -132,11 +134,11 @@
 #include "chrome/browser/chromeos/login/user_image_manager.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/wallpaper_manager.h"
+#include "chrome/browser/chromeos/net/proxy_config_handler.h"
 #include "chrome/browser/chromeos/policy/auto_enrollment_client.h"
 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_status_collector.h"
 #include "chrome/browser/chromeos/preferences.h"
-#include "chrome/browser/chromeos/proxy_config_service_impl.h"
 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
 #include "chrome/browser/chromeos/settings/device_settings_cache.h"
 #include "chrome/browser/chromeos/status/data_promo_notification.h"
@@ -261,7 +263,6 @@
   chromeos::KioskAppManager::RegisterPrefs(registry);
   chromeos::LoginUtils::RegisterPrefs(registry);
   chromeos::Preferences::RegisterPrefs(registry);
-  chromeos::ProxyConfigServiceImpl::RegisterPrefs(registry);
   chromeos::RegisterDisplayLocalStatePrefs(registry);
   chromeos::ServicesCustomizationDocument::RegisterPrefs(registry);
   chromeos::system::AutomaticRebootManager::RegisterPrefs(registry);
@@ -279,67 +280,68 @@
 #endif
 }
 
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+// Register prefs applicable to all profiles.
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
   TRACE_EVENT0("browser", "chrome::RegisterUserPrefs");
   // User prefs. Please keep this list alphabetized.
-  AlternateErrorPageTabObserver::RegisterUserPrefs(registry);
-  apps::RegisterUserPrefs(registry);
-  autofill::AutofillDialogControllerImpl::RegisterUserPrefs(registry);
-  autofill::AutofillManager::RegisterUserPrefs(registry);
-  BookmarkPromptPrefs::RegisterUserPrefs(registry);
-  bookmark_utils::RegisterUserPrefs(registry);
-  browser_sync::SyncPrefs::RegisterUserPrefs(registry);
-  chrome::RegisterInstantUserPrefs(registry);
-  ChromeContentBrowserClient::RegisterUserPrefs(registry);
-  ChromeVersionService::RegisterUserPrefs(registry);
-  chrome_browser_net::HttpServerPropertiesManager::RegisterUserPrefs(
+  AlternateErrorPageTabObserver::RegisterProfilePrefs(registry);
+  apps::RegisterProfilePrefs(registry);
+  autofill::AutofillCreditCardBubbleController::RegisterUserPrefs(registry);
+  autofill::AutofillDialogControllerImpl::RegisterProfilePrefs(registry);
+  autofill::AutofillManager::RegisterProfilePrefs(registry);
+  BookmarkPromptPrefs::RegisterProfilePrefs(registry);
+  bookmark_utils::RegisterProfilePrefs(registry);
+  browser_sync::SyncPrefs::RegisterProfilePrefs(registry);
+  ChromeContentBrowserClient::RegisterProfilePrefs(registry);
+  ChromeVersionService::RegisterProfilePrefs(registry);
+  chrome_browser_net::HttpServerPropertiesManager::RegisterProfilePrefs(
       registry);
-  chrome_browser_net::Predictor::RegisterUserPrefs(registry);
-  DownloadPrefs::RegisterUserPrefs(registry);
-  extensions::ExtensionPrefs::RegisterUserPrefs(registry);
-  ExtensionWebUI::RegisterUserPrefs(registry);
-  first_run::RegisterUserPrefs(registry);
-  HostContentSettingsMap::RegisterUserPrefs(registry);
-  IncognitoModePrefs::RegisterUserPrefs(registry);
-  InstantUI::RegisterUserPrefs(registry);
-  MediaCaptureDevicesDispatcher::RegisterUserPrefs(registry);
-  MediaStreamDevicesController::RegisterUserPrefs(registry);
-  NetPrefObserver::RegisterUserPrefs(registry);
-  NewTabUI::RegisterUserPrefs(registry);
-  PasswordGenerationManager::RegisterUserPrefs(registry);
-  PasswordManager::RegisterUserPrefs(registry);
-  PrefProxyConfigTrackerImpl::RegisterUserPrefs(registry);
-  PrefsTabHelper::RegisterUserPrefs(registry);
-  Profile::RegisterUserPrefs(registry);
-  ProfileImpl::RegisterUserPrefs(registry);
-  PromoResourceService::RegisterUserPrefs(registry);
-  ProtocolHandlerRegistry::RegisterUserPrefs(registry);
+  chrome_browser_net::Predictor::RegisterProfilePrefs(registry);
+  DownloadPrefs::RegisterProfilePrefs(registry);
+  extensions::ExtensionPrefs::RegisterProfilePrefs(registry);
+  ExtensionWebUI::RegisterProfilePrefs(registry);
+  first_run::RegisterProfilePrefs(registry);
+  HostContentSettingsMap::RegisterProfilePrefs(registry);
+  IncognitoModePrefs::RegisterProfilePrefs(registry);
+  InstantUI::RegisterProfilePrefs(registry);
+  MediaCaptureDevicesDispatcher::RegisterProfilePrefs(registry);
+  MediaStreamDevicesController::RegisterProfilePrefs(registry);
+  NetPrefObserver::RegisterProfilePrefs(registry);
+  NewTabUI::RegisterProfilePrefs(registry);
+  PasswordGenerationManager::RegisterProfilePrefs(registry);
+  PasswordManager::RegisterProfilePrefs(registry);
+  PrefProxyConfigTrackerImpl::RegisterProfilePrefs(registry);
+  PrefsTabHelper::RegisterProfilePrefs(registry);
+  Profile::RegisterProfilePrefs(registry);
+  ProfileImpl::RegisterProfilePrefs(registry);
+  PromoResourceService::RegisterProfilePrefs(registry);
+  ProtocolHandlerRegistry::RegisterProfilePrefs(registry);
   RegisterBrowserUserPrefs(registry);
-  SessionStartupPref::RegisterUserPrefs(registry);
-  TemplateURLPrepopulateData::RegisterUserPrefs(registry);
-  TranslatePrefs::RegisterUserPrefs(registry);
+  SessionStartupPref::RegisterProfilePrefs(registry);
+  TemplateURLPrepopulateData::RegisterProfilePrefs(registry);
+  TranslatePrefs::RegisterProfilePrefs(registry);
 
 #if defined(ENABLE_CONFIGURATION_POLICY)
-  policy::URLBlacklistManager::RegisterUserPrefs(registry);
+  policy::URLBlacklistManager::RegisterProfilePrefs(registry);
 #endif
 
 #if defined(ENABLE_MANAGED_USERS)
-  ManagedUserService::RegisterUserPrefs(registry);
-  ManagedUserRegistrationService::RegisterUserPrefs(registry);
+  ManagedUserService::RegisterProfilePrefs(registry);
+  ManagedUserRegistrationService::RegisterProfilePrefs(registry);
 #endif
 
 #if defined(ENABLE_NOTIFICATIONS)
-  DesktopNotificationService::RegisterUserPrefs(registry);
+  DesktopNotificationService::RegisterProfilePrefs(registry);
 #endif
 
 #if defined(TOOLKIT_VIEWS)
   RegisterInvertBubbleUserPrefs(registry);
 #elif defined(TOOLKIT_GTK)
-  BrowserWindowGtk::RegisterUserPrefs(registry);
+  BrowserWindowGtk::RegisterProfilePrefs(registry);
 #endif
 
 #if defined(OS_ANDROID)
-  PromoHandler::RegisterUserPrefs(registry);
+  PromoHandler::RegisterProfilePrefs(registry);
 #endif
 
 #if defined(USE_ASH)
@@ -347,37 +349,41 @@
 #endif
 
 #if !defined(OS_ANDROID)
-  extensions::TabsCaptureVisibleTabFunction::RegisterUserPrefs(registry);
-  ChromeToMobileService::RegisterUserPrefs(registry);
-  DeviceIDFetcher::RegisterUserPrefs(registry);
-  DevToolsWindow::RegisterUserPrefs(registry);
-  extensions::CommandService::RegisterUserPrefs(registry);
-  ExtensionSettingsHandler::RegisterUserPrefs(registry);
-  PepperFlashSettingsManager::RegisterUserPrefs(registry);
-  PinnedTabCodec::RegisterUserPrefs(registry);
-  PluginsUI::RegisterUserPrefs(registry);
-  CloudPrintURL::RegisterUserPrefs(registry);
-  print_dialog_cloud::RegisterUserPrefs(registry);
-  printing::StickySettings::RegisterUserPrefs(registry);
+  extensions::TabsCaptureVisibleTabFunction::RegisterProfilePrefs(registry);
+  ChromeToMobileService::RegisterProfilePrefs(registry);
+  DeviceIDFetcher::RegisterProfilePrefs(registry);
+  DevToolsWindow::RegisterProfilePrefs(registry);
+  extensions::CommandService::RegisterProfilePrefs(registry);
+  ExtensionSettingsHandler::RegisterProfilePrefs(registry);
+  PepperFlashSettingsManager::RegisterProfilePrefs(registry);
+  PinnedTabCodec::RegisterProfilePrefs(registry);
+  PluginsUI::RegisterProfilePrefs(registry);
+  CloudPrintURL::RegisterProfilePrefs(registry);
+  print_dialog_cloud::RegisterProfilePrefs(registry);
+  printing::StickySettings::RegisterProfilePrefs(registry);
   RegisterAutolaunchUserPrefs(registry);
-  SyncPromoUI::RegisterUserPrefs(registry);
+  SyncPromoUI::RegisterProfilePrefs(registry);
 #endif
 
 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
-  default_apps::RegisterUserPrefs(registry);
+  default_apps::RegisterProfilePrefs(registry);
 #endif
 
 #if defined(OS_CHROMEOS)
-  chromeos::OAuth2LoginManager::RegisterUserPrefs(registry);
-  chromeos::Preferences::RegisterUserPrefs(registry);
-  chromeos::ProxyConfigServiceImpl::RegisterUserPrefs(registry);
+  chromeos::OAuth2LoginManager::RegisterProfilePrefs(registry);
+  chromeos::Preferences::RegisterProfilePrefs(registry);
+  chromeos::proxy_config::RegisterProfilePrefs(registry);
   extensions::EnterprisePlatformKeysPrivateChallengeUserKeyFunction::
-      RegisterUserPrefs(registry);
-  FlagsUI::RegisterUserPrefs(registry);
+      RegisterProfilePrefs(registry);
+  FlagsUI::RegisterProfilePrefs(registry);
 #endif
 
 #if defined(OS_WIN)
-  NetworkProfileBubble::RegisterUserPrefs(registry);
+  NetworkProfileBubble::RegisterProfilePrefs(registry);
+#endif
+
+#if defined(OS_MACOSX)
+  RegisterBrowserActionsControllerProfilePrefs(registry);
 #endif
 
   // Prefs registered only for migration (clearing or moving to a new
@@ -388,6 +394,16 @@
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 }
 
+void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
+  RegisterProfilePrefs(registry);
+}
+
+#if defined(OS_CHROMEOS)
+void RegisterLoginProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
+  RegisterProfilePrefs(registry);
+}
+#endif
+
 void MigrateUserPrefs(Profile* profile) {
   PrefService* prefs = profile->GetPrefs();
 
diff --git a/chrome/browser/prefs/browser_prefs.h b/chrome/browser/prefs/browser_prefs.h
index ecd9736..1ca7077 100644
--- a/chrome/browser/prefs/browser_prefs.h
+++ b/chrome/browser/prefs/browser_prefs.h
@@ -18,8 +18,15 @@
 // Register all prefs that will be used via the local state PrefService.
 void RegisterLocalState(PrefRegistrySimple* registry);
 
-// Register all prefs that will be used via a PrefService attached to a Profile.
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+// Register all prefs that will be used via a PrefService attached to a user
+// Profile.
+void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
+#if defined(OS_CHROMEOS)
+// Register all prefs that will be used via a PrefService attached to the login
+// Profile.
+void RegisterLoginProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+#endif
 
 // Migrates prefs from |local_state| to |profile|'s pref store.
 void MigrateBrowserPrefs(Profile* profile, PrefService* local_state);
diff --git a/chrome/browser/prefs/chrome_pref_service_unittest.cc b/chrome/browser/prefs/chrome_pref_service_unittest.cc
index 226c6cf..39d9786 100644
--- a/chrome/browser/prefs/chrome_pref_service_unittest.cc
+++ b/chrome/browser/prefs/chrome_pref_service_unittest.cc
@@ -67,7 +67,7 @@
 
     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_dir_));
     data_dir_ = data_dir_.AppendASCII("pref_service");
-    ASSERT_TRUE(file_util::PathExists(data_dir_));
+    ASSERT_TRUE(base::PathExists(data_dir_));
   }
 
   void ClearListValue(PrefService* prefs, const char* key) {
@@ -93,7 +93,7 @@
 TEST_F(ChromePrefServiceUserFilePrefsTest, PreserveEmptyValue) {
   base::FilePath pref_file = temp_dir_.path().AppendASCII("write.json");
 
-  ASSERT_TRUE(file_util::CopyFile(
+  ASSERT_TRUE(base::CopyFile(
       data_dir_.AppendASCII("read.need_empty_value.json"),
       pref_file));
 
@@ -137,8 +137,8 @@
   // Compare to expected output.
   base::FilePath golden_output_file =
       data_dir_.AppendASCII("write.golden.need_empty_value.json");
-  ASSERT_TRUE(file_util::PathExists(golden_output_file));
-  EXPECT_TRUE(file_util::TextContentsEqual(golden_output_file, pref_file));
+  ASSERT_TRUE(base::PathExists(golden_output_file));
+  EXPECT_TRUE(base::TextContentsEqual(golden_output_file, pref_file));
 }
 
 class ChromePrefServiceWebKitPrefs : public ChromeRenderViewHostTestHarness {
diff --git a/chrome/browser/prefs/command_line_pref_store.cc b/chrome/browser/prefs/command_line_pref_store.cc
index 8e20f13..f600683 100644
--- a/chrome/browser/prefs/command_line_pref_store.cc
+++ b/chrome/browser/prefs/command_line_pref_store.cc
@@ -69,14 +69,11 @@
       { chromeos::switches::kDisableDrive, prefs::kDisableDrive, true },
       { chromeos::switches::kEnableTouchpadThreeFingerClick,
           prefs::kEnableTouchpadThreeFingerClick, true },
-      { chromeos::switches::kEnableTouchpadThreeFingerSwipe,
-          prefs::kEnableTouchpadThreeFingerSwipe, true },
 #endif
       { switches::kDisableCloudPolicyOnSignin,
           prefs::kDisableCloudPolicyOnSignin, true },
       { switches::kDisableAsyncDns, prefs::kBuiltInDnsClientEnabled, false },
       { switches::kEnableAsyncDns, prefs::kBuiltInDnsClientEnabled, true },
-      { switches::kEnableSyncFavicons, prefs::kSyncFaviconsEnabled, false },
 };
 
 const CommandLinePrefStore::IntegerSwitchToPreferenceMapEntry
diff --git a/chrome/browser/prefs/incognito_mode_prefs.cc b/chrome/browser/prefs/incognito_mode_prefs.cc
index e6a0e50..7ca0e29 100644
--- a/chrome/browser/prefs/incognito_mode_prefs.cc
+++ b/chrome/browser/prefs/incognito_mode_prefs.cc
@@ -54,7 +54,7 @@
 }
 
 // static
-void IncognitoModePrefs::RegisterUserPrefs(
+void IncognitoModePrefs::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       prefs::kIncognitoModeAvailability,
diff --git a/chrome/browser/prefs/incognito_mode_prefs.h b/chrome/browser/prefs/incognito_mode_prefs.h
index 3215311..9f366a6 100644
--- a/chrome/browser/prefs/incognito_mode_prefs.h
+++ b/chrome/browser/prefs/incognito_mode_prefs.h
@@ -35,7 +35,7 @@
   };
 
   // Register incognito related preferences.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Returns kIncognitoModeAvailability preference value stored
   // in the given pref service.
diff --git a/chrome/browser/prefs/incognito_mode_prefs_unittest.cc b/chrome/browser/prefs/incognito_mode_prefs_unittest.cc
index 8c9f07f..598606e 100644
--- a/chrome/browser/prefs/incognito_mode_prefs_unittest.cc
+++ b/chrome/browser/prefs/incognito_mode_prefs_unittest.cc
@@ -11,7 +11,7 @@
 class IncognitoModePrefsTest : public testing::Test {
  protected:
   virtual void SetUp() {
-    IncognitoModePrefs::RegisterUserPrefs(prefs_.registry());
+    IncognitoModePrefs::RegisterProfilePrefs(prefs_.registry());
   }
 
   TestingPrefServiceSyncable prefs_;
diff --git a/chrome/browser/prefs/pref_model_associator.cc b/chrome/browser/prefs/pref_model_associator.cc
index 07792cb..42cd194 100644
--- a/chrome/browser/prefs/pref_model_associator.cc
+++ b/chrome/browser/prefs/pref_model_associator.cc
@@ -12,8 +12,8 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "sync/api/sync_change.h"
 #include "sync/api/sync_error_factory.h"
diff --git a/chrome/browser/prefs/pref_service_browsertest.cc b/chrome/browser/prefs/pref_service_browsertest.cc
index 3b6f712..fc1ba42 100644
--- a/chrome/browser/prefs/pref_service_browsertest.cc
+++ b/chrome/browser/prefs/pref_service_browsertest.cc
@@ -77,10 +77,10 @@
       tmp_pref_file_ = user_data_directory.Append(chrome::kLocalStateFilename);
     }
 
-    CHECK(file_util::PathExists(reference_pref_file));
+    CHECK(base::PathExists(reference_pref_file));
     // Copy only the Preferences file if |new_profile_|, or Local State if not,
     // and the rest will be automatically created.
-    CHECK(file_util::CopyFile(reference_pref_file, tmp_pref_file_));
+    CHECK(base::CopyFile(reference_pref_file, tmp_pref_file_));
 
 #if defined(OS_WIN)
     // Make the copy writable.  On POSIX we assume the umask allows files
diff --git a/chrome/browser/prefs/proxy_policy_unittest.cc b/chrome/browser/prefs/proxy_policy_unittest.cc
index f3d92be..60e1943 100644
--- a/chrome/browser/prefs/proxy_policy_unittest.cc
+++ b/chrome/browser/prefs/proxy_policy_unittest.cc
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/callback.h"
 #include "base/command_line.h"
 #include "base/memory/ref_counted.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_service_impl.h"
@@ -102,7 +104,7 @@
     scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
         new user_prefs::PrefRegistrySyncable);
     PrefServiceSyncable* prefs = builder.CreateSyncable(registry.get());
-    chrome::RegisterUserPrefs(registry.get());
+    chrome::RegisterUserProfilePrefs(registry.get());
     return prefs;
   }
 
@@ -118,11 +120,11 @@
       ProxyPrefs::kFixedServersProxyModeName);
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             mode_name);
+             mode_name, NULL);
   policy.Set(key::kProxyBypassList, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             Value::CreateStringValue("abc"));
+             Value::CreateStringValue("abc"), NULL);
   policy.Set(key::kProxyServer, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             Value::CreateStringValue("ghi"));
+             Value::CreateStringValue("ghi"), NULL);
   provider_.UpdateChromePolicy(policy);
 
   // First verify that command-line options are set correctly when
@@ -152,7 +154,7 @@
       ProxyPrefs::kAutoDetectProxyModeName);
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             mode_name);
+             mode_name, NULL);
   provider_.UpdateChromePolicy(policy);
 
   // First verify that command-line options are set correctly when
@@ -179,7 +181,7 @@
       ProxyPrefs::kAutoDetectProxyModeName);
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             mode_name);
+             mode_name, NULL);
   provider_.UpdateChromePolicy(policy);
 
   // First verify that command-line options are set correctly when
@@ -202,7 +204,7 @@
       ProxyPrefs::kDirectProxyModeName);
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             mode_name);
+             mode_name, NULL);
   provider_.UpdateChromePolicy(policy);
 
   // First verify that the auto-detect is set if there is no managed
diff --git a/chrome/browser/prefs/session_startup_pref.cc b/chrome/browser/prefs/session_startup_pref.cc
index 8560558..df16539 100644
--- a/chrome/browser/prefs/session_startup_pref.cc
+++ b/chrome/browser/prefs/session_startup_pref.cc
@@ -54,7 +54,7 @@
 }  // namespace
 
 // static
-void SessionStartupPref::RegisterUserPrefs(
+void SessionStartupPref::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       prefs::kRestoreOnStartup,
diff --git a/chrome/browser/prefs/session_startup_pref.h b/chrome/browser/prefs/session_startup_pref.h
index 379451e..75ea9d3 100644
--- a/chrome/browser/prefs/session_startup_pref.h
+++ b/chrome/browser/prefs/session_startup_pref.h
@@ -44,7 +44,7 @@
   static const int kPrefValueURLs = 4;
   static const int kPrefValueNewTab = 5;
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Returns the default value for |type|.
   static Type GetDefaultStartupType();
diff --git a/chrome/browser/prefs/session_startup_pref_unittest.cc b/chrome/browser/prefs/session_startup_pref_unittest.cc
index 2e3aeb3..9279bf0 100644
--- a/chrome/browser/prefs/session_startup_pref_unittest.cc
+++ b/chrome/browser/prefs/session_startup_pref_unittest.cc
@@ -18,7 +18,7 @@
  public:
   virtual void SetUp() {
     pref_service_.reset(new TestingPrefServiceSyncable);
-    SessionStartupPref::RegisterUserPrefs(registry());
+    SessionStartupPref::RegisterProfilePrefs(registry());
     registry()->RegisterBooleanPref(
         prefs::kHomePageIsNewTabPage,
         true,
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 47117f1..621d253 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -15,6 +15,7 @@
 #include "base/values.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_remover.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
 #include "chrome/browser/extensions/extension_apitest.h"
@@ -36,7 +37,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -271,7 +271,7 @@
     }
   }
 
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE {
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE {
     // On quit, it's possible to end up here when render processes are closed
     // before the PrerenderManager is destroyed.  As a result, it's possible to
     // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED
@@ -285,7 +285,7 @@
       expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED;
     }
 
-    PrerenderContents::RenderViewGone(status);
+    PrerenderContents::RenderProcessGone(status);
   }
 
   virtual bool AddAliasURL(const GURL& url) OVERRIDE {
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index de1ec58..957809f 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_tab_helper.h"
 #include "chrome/browser/history/history_tab_helper.h"
 #include "chrome/browser/history/history_types.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tab_contents.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/prerender_messages.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/browser_child_process_host.h"
@@ -94,7 +94,9 @@
       int route_id,
       WindowContainerType window_container_type,
       const string16& frame_name,
-      const GURL& target_url) OVERRIDE {
+      const GURL& target_url,
+      WindowOpenDisposition disposition,
+      bool user_gesture) OVERRIDE {
     // Since we don't want to permit child windows that would have a
     // window.opener property, terminate prerendering.
     prerender_contents_->Destroy(FINAL_STATUS_CREATE_NEW_WINDOW);
@@ -559,7 +561,7 @@
                        std::bind2nd(std::equal_to<GURL>(), url)) != 0;
 }
 
-void PrerenderContents::RenderViewGone(base::TerminationStatus status) {
+void PrerenderContents::RenderProcessGone(base::TerminationStatus status) {
   Destroy(FINAL_STATUS_RENDERER_CRASHED);
 }
 
diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h
index fca0c8f..a3030f9 100644
--- a/chrome/browser/prerender/prerender_contents.h
+++ b/chrome/browser/prerender/prerender_contents.h
@@ -231,7 +231,7 @@
   virtual void DidUpdateFaviconURL(int32 page_id,
       const std::vector<content::FaviconURL>& urls) OVERRIDE;
 
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
 
   // content::NotificationObserver
   virtual void Observe(int type,
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index b54d8d0..7e5f146 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -20,6 +20,7 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/common/cancelable_request.h"
 #include "chrome/browser/favicon/favicon_tab_helper.h"
 #include "chrome/browser/net/chrome_cookie_notification_details.h"
@@ -40,7 +41,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/prerender_messages.h"
diff --git a/chrome/browser/printing/background_printing_manager.cc b/chrome/browser/printing/background_printing_manager.cc
index c97f89a..4db8f15 100644
--- a/chrome/browser/printing/background_printing_manager.cc
+++ b/chrome/browser/printing/background_printing_manager.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/printing/background_printing_manager.h"
 
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/printing/print_job.h"
 #include "chrome/browser/printing/print_preview_dialog_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc
index 6e5976e..a51f5cf 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc
+++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc
@@ -16,13 +16,13 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/notifications/desktop_notification_service.h"
 #include "chrome/browser/notifications/notification.h"
 #include "chrome/browser/notifications/notification_ui_manager.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/service/service_process_control.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/cloud_print/cloud_print_proxy_info.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/printing/cloud_print/cloud_print_url.cc b/chrome/browser/printing/cloud_print/cloud_print_url.cc
index 2e46123..de9967b 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_url.cc
+++ b/chrome/browser/printing/cloud_print/cloud_print_url.cc
@@ -28,7 +28,7 @@
     "http://www.google.com/landing/cloudprint/enable.html?print=true";
 
 // static
-void CloudPrintURL::RegisterUserPrefs(
+void CloudPrintURL::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterStringPref(
       prefs::kCloudPrintServiceURL,
diff --git a/chrome/browser/printing/cloud_print/cloud_print_url.h b/chrome/browser/printing/cloud_print/cloud_print_url.h
index 5c85734..91080ed 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_url.h
+++ b/chrome/browser/printing/cloud_print/cloud_print_url.h
@@ -17,7 +17,7 @@
 // Centralize URL management for the cloud print service.
 class CloudPrintURL {
  public:
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   explicit CloudPrintURL(Profile* profile) : profile_(profile) {}
 
diff --git a/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc b/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc
index e47423e..6433df6 100644
--- a/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc
+++ b/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc
@@ -6,7 +6,7 @@
 #include "base/path_service.h"
 #include "base/process_util.h"
 #include "base/test/test_timeouts.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/chrome_result_codes.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/printing/print_dialog_cloud.cc b/chrome/browser/printing/print_dialog_cloud.cc
index 984a4e7..49fd150 100644
--- a/chrome/browser/printing/print_dialog_cloud.cc
+++ b/chrome/browser/printing/print_dialog_cloud.cc
@@ -682,14 +682,14 @@
                  browser_context, modal_parent, data, print_job_title,
                  print_ticket, file_type));
   if (delete_on_close)
-    base::Delete(path_to_file, false);
+    base::DeleteFile(path_to_file, false);
 }
 
 }  // namespace internal_cloud_print_helpers
 
 namespace print_dialog_cloud {
 
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       prefs::kCloudPrintDialogWidth,
       kDefaultWidth,
diff --git a/chrome/browser/printing/print_dialog_cloud.h b/chrome/browser/printing/print_dialog_cloud.h
index c235387..422e16a 100644
--- a/chrome/browser/printing/print_dialog_cloud.h
+++ b/chrome/browser/printing/print_dialog_cloud.h
@@ -29,7 +29,7 @@
 
 namespace print_dialog_cloud {
 
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
 // Creates a print dialog to print a file on disk.
 // Called on the FILE or UI thread. Even though this may start up a modal
diff --git a/chrome/browser/printing/print_dialog_gtk.cc b/chrome/browser/printing/print_dialog_gtk.cc
index a7bf21c..5b8f748 100644
--- a/chrome/browser/printing/print_dialog_gtk.cc
+++ b/chrome/browser/printing/print_dialog_gtk.cc
@@ -275,7 +275,7 @@
 
   if (!error && !metafile->SaveTo(path_to_pdf_)) {
     LOG(ERROR) << "Saving metafile failed";
-    base::Delete(path_to_pdf_, false);
+    base::DeleteFile(path_to_pdf_, false);
     error = true;
   }
 
@@ -406,7 +406,7 @@
     LOG(ERROR) << "Printing failed: " << error->message;
   if (print_job)
     g_object_unref(print_job);
-  base::FileUtilProxy::Delete(
+  base::FileUtilProxy::DeleteFile(
       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(),
       path_to_pdf_,
       false,
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc
index 65b8d3e77..7cfa461 100644
--- a/chrome/browser/printing/print_job.cc
+++ b/chrome/browser/printing/print_job.cc
@@ -10,8 +10,8 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/worker_pool.h"
 #include "base/timer/timer.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/printing/print_job_worker.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "printing/printed_document.h"
 #include "printing/printed_page.h"
diff --git a/chrome/browser/printing/print_job_manager.cc b/chrome/browser/printing/print_job_manager.cc
index bb669ec..87119c5 100644
--- a/chrome/browser/printing/print_job_manager.cc
+++ b/chrome/browser/printing/print_job_manager.cc
@@ -4,9 +4,9 @@
 
 #include "chrome/browser/printing/print_job_manager.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/printing/print_job.h"
 #include "chrome/browser/printing/printer_query.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "printing/printed_document.h"
 #include "printing/printed_page.h"
diff --git a/chrome/browser/printing/print_job_unittest.cc b/chrome/browser/printing/print_job_unittest.cc
index f9dfe8c..6019370 100644
--- a/chrome/browser/printing/print_job_unittest.cc
+++ b/chrome/browser/printing/print_job_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "base/message_loop.h"
 #include "base/strings/string16.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/printing/print_job.h"
 #include "chrome/browser/printing/print_job_worker.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
 #include "printing/printed_pages_source.h"
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
index 5e0cd88..4f425ee 100644
--- a/chrome/browser/printing/print_job_worker.cc
+++ b/chrome/browser/printing/print_job_worker.cc
@@ -11,8 +11,8 @@
 #include "base/message_loop.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/printing/print_job.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "grit/generated_resources.h"
@@ -40,12 +40,13 @@
                           JobEventDetails::Type detail_type,
                           PrintedDocument* document,
                           PrintedPage* page) {
-  JobEventDetails* details = new JobEventDetails(detail_type, document, page);
+  scoped_refptr<JobEventDetails> details(new JobEventDetails(detail_type,
+                                                             document, page));
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_PRINT_JOB_EVENT,
       // We know that is is a PrintJob object in this circumstance.
       content::Source<PrintJob>(static_cast<PrintJob*>(print_job)),
-      content::Details<JobEventDetails>(details));
+      content::Details<JobEventDetails>(details.get()));
 }
 
 PrintJobWorker::PrintJobWorker(PrintJobWorkerOwner* owner)
diff --git a/chrome/browser/printing/print_preview_dialog_controller.cc b/chrome/browser/printing/print_preview_dialog_controller.cc
index f5d8a57..5088ffb 100644
--- a/chrome/browser/printing/print_preview_dialog_controller.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller.cc
@@ -12,6 +12,7 @@
 #include "base/command_line.h"
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
 #include "chrome/browser/printing/print_view_manager.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
 #include "chrome/common/chrome_content_client.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
index 9cecc56..b9bcb4e 100644
--- a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
@@ -3,12 +3,14 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/run_loop.h"
 #include "chrome/browser/printing/print_preview_dialog_controller.h"
-#include "chrome/browser/printing/print_view_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/common/print_messages.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -16,75 +18,176 @@
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "url/gurl.h"
+#include "ipc/ipc_message_macros.h"
 
 using content::WebContents;
+using content::WebContentsObserver;
 
-class PrintPreviewDialogControllerBrowserTest : public InProcessBrowserTest {
+class RequestPrintPreviewObserver : public WebContentsObserver {
  public:
-  PrintPreviewDialogControllerBrowserTest() {}
-  virtual ~PrintPreviewDialogControllerBrowserTest() {}
-
-  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
-#if !defined(GOOGLE_CHROME_BUILD)
-    command_line->AppendSwitch(switches::kEnablePrintPreview);
-#endif
+  explicit RequestPrintPreviewObserver(WebContents* dialog)
+      : WebContentsObserver(dialog) {
   }
+  virtual ~RequestPrintPreviewObserver() {}
+
+  void set_quit_closure(const base::Closure& quit_closure) {
+    quit_closure_ = quit_closure;
+  }
+
+ private:
+  // content::WebContentsObserver implementation.
+  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
+    IPC_BEGIN_MESSAGE_MAP(RequestPrintPreviewObserver, message)
+      IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview,
+                          OnRequestPrintPreview)
+      IPC_MESSAGE_UNHANDLED(break;)
+    IPC_END_MESSAGE_MAP();
+    return false;  // Report not handled so the real handler receives it.
+  }
+
+  void OnRequestPrintPreview(
+      const PrintHostMsg_RequestPrintPreview_Params& /* params */) {
+    base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure_);
+  }
+
+  base::Closure quit_closure_;
+
+  DISALLOW_COPY_AND_ASSIGN(RequestPrintPreviewObserver);
 };
 
-class PrintPreviewDialogDestroyedObserver
-    : public content::WebContentsObserver {
+class PrintPreviewDialogClonedObserver : public WebContentsObserver {
+ public:
+  explicit PrintPreviewDialogClonedObserver(WebContents* dialog)
+      : WebContentsObserver(dialog) {
+  }
+  virtual ~PrintPreviewDialogClonedObserver() {}
+
+  RequestPrintPreviewObserver* request_preview_tab_observer() {
+    return request_preview_tab_observer_.get();
+  }
+
+ private:
+  // content::WebContentsObserver implementation.
+  virtual void DidCloneToNewWebContents(
+      WebContents* old_web_contents,
+      WebContents* new_web_contents) OVERRIDE {
+    request_preview_tab_observer_.reset(
+        new RequestPrintPreviewObserver(new_web_contents));
+  }
+
+  scoped_ptr<RequestPrintPreviewObserver> request_preview_tab_observer_;
+
+  DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogClonedObserver);
+};
+
+class PrintPreviewDialogDestroyedObserver : public WebContentsObserver {
  public:
   explicit PrintPreviewDialogDestroyedObserver(WebContents* dialog)
-      : content::WebContentsObserver(dialog),
+      : WebContentsObserver(dialog),
         dialog_destroyed_(false) {
   }
   virtual ~PrintPreviewDialogDestroyedObserver() {}
 
-  bool dialog_destroyed() { return dialog_destroyed_; }
+  bool dialog_destroyed() const { return dialog_destroyed_; }
 
  private:
+  // content::WebContentsObserver implementation.
   virtual void WebContentsDestroyed(WebContents* contents) OVERRIDE {
     dialog_destroyed_ = true;
   }
 
   bool dialog_destroyed_;
+
+  DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogDestroyedObserver);
+};
+
+class PrintPreviewDialogControllerBrowserTest : public InProcessBrowserTest {
+ public:
+  PrintPreviewDialogControllerBrowserTest() : initiator_tab_(NULL) {}
+  virtual ~PrintPreviewDialogControllerBrowserTest() {}
+
+  WebContents* initiator_tab() {
+    return initiator_tab_;
+  }
+
+  void PrintPreview() {
+    base::RunLoop run_loop;
+    request_preview_tab_observer()->set_quit_closure(run_loop.QuitClosure());
+    chrome::Print(browser());
+    run_loop.Run();
+  }
+
+  WebContents* GetPrintPreviewDialog() {
+    printing::PrintPreviewDialogController* dialog_controller =
+        printing::PrintPreviewDialogController::GetInstance();
+    return dialog_controller->GetPrintPreviewForContents(initiator_tab_);
+  }
+
+ private:
+  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+#if !defined(GOOGLE_CHROME_BUILD)
+    command_line->AppendSwitch(switches::kEnablePrintPreview);
+#endif
+  }
+
+  virtual void SetUpOnMainThread() OVERRIDE {
+    WebContents* first_tab =
+        browser()->tab_strip_model()->GetActiveWebContents();
+    ASSERT_TRUE(first_tab);
+
+    // Open a new tab so |cloned_tab_observer_| can see it first and attach a
+    // RequestPrintPreviewObserver to it before the real
+    // PrintPreviewMessageHandler gets created. Thus enabling
+    // RequestPrintPreviewObserver to get messages first for the purposes of
+    // this test.
+    cloned_tab_observer_.reset(new PrintPreviewDialogClonedObserver(first_tab));
+    chrome::DuplicateTab(browser());
+
+    initiator_tab_ = browser()->tab_strip_model()->GetActiveWebContents();
+    ASSERT_TRUE(initiator_tab_);
+    ASSERT_NE(first_tab, initiator_tab_);
+  }
+
+  virtual void CleanUpOnMainThread() OVERRIDE {
+    cloned_tab_observer_.reset();
+    initiator_tab_ = NULL;
+  }
+
+  RequestPrintPreviewObserver* request_preview_tab_observer() {
+    return cloned_tab_observer_->request_preview_tab_observer();
+  }
+
+  scoped_ptr<PrintPreviewDialogClonedObserver> cloned_tab_observer_;
+  WebContents* initiator_tab_;
+
+  DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogControllerBrowserTest);
 };
 
 // Test to verify that when a initiator tab navigates, we can create a new
 // preview dialog for the new tab contents.
 IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
                        NavigateFromInitiatorTab) {
-  // Create a reference to initiator tab contents.
-  WebContents* initiator_tab =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  ASSERT_TRUE(initiator_tab);
-
-  printing::PrintPreviewDialogController* dialog_controller =
-      printing::PrintPreviewDialogController::GetInstance();
-  ASSERT_TRUE(dialog_controller);
+  // print for the first time.
+  PrintPreview();
 
   // Get the preview dialog for the initiator tab.
-  printing::PrintViewManager* print_view_manager =
-      printing::PrintViewManager::FromWebContents(initiator_tab);
-  print_view_manager->PrintPreviewNow(false);
-  WebContents* preview_dialog =
-      dialog_controller->GetOrCreatePreviewDialog(initiator_tab);
+  WebContents* preview_dialog = GetPrintPreviewDialog();
 
   // Check a new print preview dialog got created.
   ASSERT_TRUE(preview_dialog);
-  ASSERT_NE(initiator_tab, preview_dialog);
+  ASSERT_NE(initiator_tab(), preview_dialog);
 
   // Navigate in the initiator tab. Make sure navigating destroys the print
   // preview dialog.
-  PrintPreviewDialogDestroyedObserver observer(preview_dialog);
-  GURL url(chrome::kChromeUINewTabURL);
-  ui_test_utils::NavigateToURL(browser(), url);
-  ASSERT_TRUE(observer.dialog_destroyed());
+  PrintPreviewDialogDestroyedObserver dialog_destroyed_observer(preview_dialog);
+  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL));
+  ASSERT_TRUE(dialog_destroyed_observer.dialog_destroyed());
+
+  // Try printing again.
+  PrintPreview();
 
   // Get the print preview dialog for the initiator tab.
-  print_view_manager->PrintPreviewNow(false);
-  WebContents* new_preview_dialog =
-      dialog_controller->GetOrCreatePreviewDialog(initiator_tab);
+  WebContents* new_preview_dialog = GetPrintPreviewDialog();
 
   // Check a new preview dialog got created.
   EXPECT_TRUE(new_preview_dialog);
@@ -94,25 +197,14 @@
 // print preview dialog.
 IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
                        ReloadInitiatorTab) {
-  // Create a reference to initiator tab contents.
-  WebContents* initiator_tab =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  ASSERT_TRUE(initiator_tab);
+  // print for the first time.
+  PrintPreview();
 
-  printing::PrintPreviewDialogController* dialog_controller =
-      printing::PrintPreviewDialogController::GetInstance();
-  ASSERT_TRUE(dialog_controller);
-
-  // Create a preview dialog for the initiator tab.
-  printing::PrintViewManager* print_view_manager =
-      printing::PrintViewManager::FromWebContents(initiator_tab);
-  print_view_manager->PrintPreviewNow(false);
-  WebContents* preview_dialog =
-      dialog_controller->GetOrCreatePreviewDialog(initiator_tab);
+  WebContents* preview_dialog = GetPrintPreviewDialog();
 
   // Check a new print preview dialog got created.
   ASSERT_TRUE(preview_dialog);
-  ASSERT_NE(initiator_tab, preview_dialog);
+  ASSERT_NE(initiator_tab(), preview_dialog);
 
   // Reload the initiator tab. Make sure reloading destroys the print preview
   // dialog.
@@ -124,10 +216,10 @@
   notification_observer.Wait();
   ASSERT_TRUE(dialog_destroyed_observer.dialog_destroyed());
 
-  // Create a preview dialog for the initiator tab.
-  print_view_manager->PrintPreviewNow(false);
-  WebContents* new_preview_dialog =
-      dialog_controller->GetOrCreatePreviewDialog(initiator_tab);
+  // Try printing again.
+  PrintPreview();
 
+  // Create a preview dialog for the initiator tab.
+  WebContents* new_preview_dialog = GetPrintPreviewDialog();
   EXPECT_TRUE(new_preview_dialog);
 }
diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc
index 2bc5414..cf69caa 100644
--- a/chrome/browser/printing/print_preview_message_handler.cc
+++ b/chrome/browser/printing/print_preview_message_handler.cc
@@ -9,7 +9,7 @@
 #include "base/bind.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/ref_counted_memory.h"
-#include "base/shared_memory.h"
+#include "base/memory/shared_memory.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/printing/print_job_manager.h"
 #include "chrome/browser/printing/print_preview_dialog_controller.h"
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc
index 17666df..7ed48ac 100644
--- a/chrome/browser/printing/print_view_manager.cc
+++ b/chrome/browser/printing/print_view_manager.cc
@@ -15,6 +15,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/printing/print_error_dialog.h"
 #include "chrome/browser/printing/print_job.h"
 #include "chrome/browser/printing/print_job_manager.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/printing/printer_query.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/print_messages.h"
@@ -184,7 +184,7 @@
   TerminatePrintJob(true);
 }
 
-void PrintViewManager::RenderViewGone(base::TerminationStatus status) {
+void PrintViewManager::RenderProcessGone(base::TerminationStatus status) {
   print_preview_state_ = NOT_PREVIEWING;
   ReleasePrinterQuery();
 
diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h
index de950db..55b4708 100644
--- a/chrome/browser/printing/print_view_manager.h
+++ b/chrome/browser/printing/print_view_manager.h
@@ -93,7 +93,7 @@
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
 
   // Terminates or cancels the print job if one was pending.
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
 
   // Cancels the print job.
   virtual void StopNavigation() OVERRIDE;
diff --git a/chrome/browser/printing/printing_layout_browsertest.cc b/chrome/browser/printing/printing_layout_browsertest.cc
index 5ba5b83..4e4f651 100644
--- a/chrome/browser/printing/printing_layout_browsertest.cc
+++ b/chrome/browser/printing/printing_layout_browsertest.cc
@@ -13,12 +13,12 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/test_file_util.h"
 #include "base/threading/simple_thread.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/printing/print_job.h"
 #include "chrome/browser/printing/print_view_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -53,7 +53,7 @@
 
   virtual void TearDown() OVERRIDE {
     InProcessBrowserTest::TearDown();
-    base::Delete(emf_path_, true);
+    base::DeleteFile(emf_path_, true);
   }
 
   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
@@ -127,12 +127,12 @@
     base::FilePath cleartype(
         base_path.Append(verification_name + L"_cleartype.png"));
     // Looks for Cleartype override.
-    if (file_util::PathExists(cleartype) && IsClearTypeEnabled())
+    if (base::PathExists(cleartype) && IsClearTypeEnabled())
       png = cleartype;
 
     if (GenerateFiles()) {
       // Copy the .emf and generate an .png.
-      file_util::CopyFile(test_result, emf);
+      base::CopyFile(test_result, emf);
       Image emf_content(emf);
       emf_content.SaveToPng(png);
       // Saving is always fine.
@@ -151,7 +151,7 @@
         // Backup the result emf file.
         base::FilePath failed(
             base_path.Append(verification_name + L"_failed.emf"));
-        file_util::CopyFile(test_result, failed);
+        base::CopyFile(test_result, failed);
       }
 
       // This verification is only to know that the EMF rendering stays
@@ -221,7 +221,7 @@
               "\" when looking for \"" << verification_name << "\"";
           prn_file = file.value();
           found_prn = true;
-          base::Delete(file, false);
+          base::DeleteFile(file, false);
           continue;
         }
         EXPECT_TRUE(false);
diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc
index 1bbb85b..09ad68f 100644
--- a/chrome/browser/printing/printing_message_filter.cc
+++ b/chrome/browser/printing/printing_message_filter.cc
@@ -132,7 +132,7 @@
     base::SharedMemoryHandle* browser_handle) {
   // Duplicate the handle in this process right now so the memory is kept alive
   // (even if it is not mapped)
-  base::SharedMemory shared_buf(renderer_handle, true, peer_handle());
+  base::SharedMemory shared_buf(renderer_handle, true, PeerHandle());
   shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), browser_handle);
 }
 #endif
diff --git a/chrome/browser/printing/printing_message_filter.h b/chrome/browser/printing/printing_message_filter.h
index b1b23bc..67e4b01 100644
--- a/chrome/browser/printing/printing_message_filter.h
+++ b/chrome/browser/printing/printing_message_filter.h
@@ -11,7 +11,7 @@
 #include "content/public/browser/browser_message_filter.h"
 
 #if defined(OS_WIN)
-#include "base/shared_memory.h"
+#include "base/memory/shared_memory.h"
 #endif
 
 struct PrintHostMsg_ScriptedPrint_Params;
diff --git a/chrome/browser/process_singleton.h b/chrome/browser/process_singleton.h
index 737daba..a584147 100644
--- a/chrome/browser/process_singleton.h
+++ b/chrome/browser/process_singleton.h
@@ -28,6 +28,10 @@
 #include "base/files/scoped_temp_dir.h"
 #endif  // defined(OS_LINUX) || defined(OS_OPENBSD)
 
+#if defined(OS_WIN)
+#include "base/win/message_window.h"
+#endif  // defined(OS_WIN)
+
 class CommandLine;
 
 // ProcessSingleton ----------------------------------------------------------
@@ -84,10 +88,6 @@
   // Clear any lock state during shutdown.
   void Cleanup();
 
-#if defined(OS_WIN)
-  LRESULT WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
-#endif
-
 #if defined(OS_LINUX) || defined(OS_OPENBSD)
   static void DisablePromptForTesting();
 #endif  // defined(OS_LINUX) || defined(OS_OPENBSD)
@@ -123,13 +123,10 @@
   NotificationCallback notification_callback_;  // Handler for notifications.
 
 #if defined(OS_WIN)
-  // This ugly behemoth handles startup commands sent from another process.
-  LRESULT OnCopyData(HWND hwnd, const COPYDATASTRUCT* cds);
-
   bool EscapeVirtualization(const base::FilePath& user_data_dir);
 
   HWND remote_window_;  // The HWND_MESSAGE of another browser.
-  HWND window_;  // The HWND_MESSAGE window.
+  base::win::MessageWindow window_;  // The message-only window.
   bool is_virtualized_;  // Stuck inside Microsoft Softricity VM environment.
   HANDLE lock_file_;
   base::FilePath user_data_dir_;
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
index 237004a..94647c7 100644
--- a/chrome/browser/process_singleton_win.cc
+++ b/chrome/browser/process_singleton_win.cc
@@ -7,6 +7,7 @@
 #include <shellapi.h>
 
 #include "base/base_paths.h"
+#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
@@ -21,7 +22,6 @@
 #include "base/win/scoped_handle.h"
 #include "base/win/win_util.h"
 #include "base/win/windows_version.h"
-#include "base/win/wrapped_window_proc.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/chrome_process_finder_win.h"
@@ -93,24 +93,6 @@
   return !*result;
 }
 
-// This function thunks to the object's version of the windowproc, taking in
-// consideration that there are several messages being dispatched before
-// WM_NCCREATE which we let windows handle.
-LRESULT CALLBACK ThunkWndProc(HWND hwnd, UINT message,
-                              WPARAM wparam, LPARAM lparam) {
-  ProcessSingleton* singleton =
-      reinterpret_cast<ProcessSingleton*>(ui::GetWindowUserData(hwnd));
-  if (message == WM_NCCREATE) {
-    CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lparam);
-    singleton = reinterpret_cast<ProcessSingleton*>(cs->lpCreateParams);
-    CHECK(singleton);
-    ui::SetWindowUserData(hwnd, singleton);
-  } else if (!singleton) {
-    return ::DefWindowProc(hwnd, message, wparam, lparam);
-  }
-  return singleton->WndProc(hwnd, message, wparam, lparam);
-}
-
 bool ParseCommandLine(const COPYDATASTRUCT* cds,
                       CommandLine* parsed_command_line,
                       base::FilePath* current_directory) {
@@ -171,6 +153,31 @@
   return false;
 }
 
+bool ProcessLaunchNotification(
+    const ProcessSingleton::NotificationCallback& notification_callback,
+    UINT message,
+    WPARAM wparam,
+    LPARAM lparam,
+    LRESULT* result) {
+  if (message != WM_COPYDATA)
+    return false;
+
+  // Handle the WM_COPYDATA message from another process.
+  HWND hwnd = reinterpret_cast<HWND>(wparam);
+  const COPYDATASTRUCT* cds = reinterpret_cast<COPYDATASTRUCT*>(lparam);
+
+  CommandLine parsed_command_line(CommandLine::NO_PROGRAM);
+  base::FilePath current_directory;
+  if (!ParseCommandLine(cds, &parsed_command_line, &current_directory)) {
+    *result = TRUE;
+    return true;
+  }
+
+  *result = notification_callback.Run(parsed_command_line, current_directory) ?
+      TRUE : FALSE;
+  return true;
+}
+
 // Returns true if Chrome needs to be relaunched into Windows 8 immersive mode.
 // Following conditions apply:-
 // 1. Windows 8 or greater.
@@ -260,20 +267,12 @@
 ProcessSingleton::ProcessSingleton(
     const base::FilePath& user_data_dir,
     const NotificationCallback& notification_callback)
-    : window_(NULL), notification_callback_(notification_callback),
+    : notification_callback_(notification_callback),
       is_virtualized_(false), lock_file_(INVALID_HANDLE_VALUE),
       user_data_dir_(user_data_dir) {
 }
 
 ProcessSingleton::~ProcessSingleton() {
-  // We need to unregister the window as late as possible so that we can detect
-  // another instance of chrome running. Otherwise we may end up writing out
-  // data while a new chrome is starting up.
-  if (window_) {
-    ::DestroyWindow(window_);
-    ::UnregisterClass(chrome::kMessageWindowClass,
-                      base::GetModuleFromAddress(&ThunkWndProc));
-  }
   if (lock_file_ != INVALID_HANDLE_VALUE)
     ::CloseHandle(lock_file_);
 }
@@ -439,22 +438,12 @@
           << "Lock file can not be created! Error code: " << error;
 
       if (lock_file_ != INVALID_HANDLE_VALUE) {
-        HINSTANCE hinst = base::GetModuleFromAddress(&ThunkWndProc);
-
-        WNDCLASSEX wc = {0};
-        wc.cbSize = sizeof(wc);
-        wc.lpfnWndProc = base::win::WrappedWindowProc<ThunkWndProc>;
-        wc.hInstance = hinst;
-        wc.lpszClassName = chrome::kMessageWindowClass;
-        ATOM clazz = ::RegisterClassEx(&wc);
-        DCHECK(clazz);
-
         // Set the window's title to the path of our user data directory so
         // other Chrome instances can decide if they should forward to us.
-        window_ = ::CreateWindow(MAKEINTATOM(clazz),
-                                 user_data_dir_.value().c_str(),
-                                 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, this);
-        CHECK(window_);
+        bool result = window_.CreateNamed(
+            base::Bind(&ProcessLaunchNotification, notification_callback_),
+            user_data_dir_.value());
+        CHECK(result && window_.hwnd());
       }
 
       if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
@@ -468,30 +457,8 @@
     }
   }
 
-  return window_ != NULL;
+  return window_.hwnd() != NULL;
 }
 
 void ProcessSingleton::Cleanup() {
 }
-
-LRESULT ProcessSingleton::OnCopyData(HWND hwnd, const COPYDATASTRUCT* cds) {
-  CommandLine parsed_command_line(CommandLine::NO_PROGRAM);
-  base::FilePath current_directory;
-  if (!ParseCommandLine(cds, &parsed_command_line, &current_directory))
-    return TRUE;
-  return notification_callback_.Run(parsed_command_line, current_directory) ?
-      TRUE : FALSE;
-}
-
-LRESULT ProcessSingleton::WndProc(HWND hwnd, UINT message,
-                                  WPARAM wparam, LPARAM lparam) {
-  switch (message) {
-    case WM_COPYDATA:
-      return OnCopyData(reinterpret_cast<HWND>(wparam),
-                        reinterpret_cast<COPYDATASTRUCT*>(lparam));
-    default:
-      break;
-  }
-
-  return ::DefWindowProc(hwnd, message, wparam, lparam);
-}
diff --git a/chrome/browser/profile_resetter/brandcode_config_fetcher.cc b/chrome/browser/profile_resetter/brandcode_config_fetcher.cc
new file mode 100644
index 0000000..b3fb98b
--- /dev/null
+++ b/chrome/browser/profile_resetter/brandcode_config_fetcher.cc
@@ -0,0 +1,187 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/profile_resetter/brandcode_config_fetcher.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
+#include "libxml/parser.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_response_headers.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_request_status.h"
+
+namespace {
+
+const int kDownloadTimeoutSec = 10;
+const char kPostXml[] =
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+"<request version=\"1.3.17.0\" protocol=\"3.0\" testsource=\"dev\" "
+    "shell_version=\"1.2.3.5\">\n"
+"  <os platform=\"win\" version=\"6.1\" sp=\"\" arch=\"x86\" />\n"
+"  <app\n"
+"    appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\"\n"
+"    version=\"0.0.0.0\"\n"
+"      >\n"
+"    <updatecheck />\n"
+"    <data name=\"install\" "
+    "index=\"skipfirstrunui-importsearch-defaultbrowser\" />\n"
+"  </app>\n"
+"</request>";
+
+std::string GetUploadData() {
+  return kPostXml;
+}
+
+// Extracts json master prefs from xml.
+class XmlConfigParser {
+ public:
+  XmlConfigParser();
+  ~XmlConfigParser();
+
+  // Returns the content of /response/app/data tag.
+  static void Parse(const std::string& input_buffer,
+                    std::string* output_buffer);
+
+ private:
+  static XmlConfigParser* FromContext(void* ctx);
+  static std::string XMLCharToString(const xmlChar* value);
+  static void StartElementImpl(void* ctx,
+                               const xmlChar* name,
+                               const xmlChar** atts);
+  static void EndElementImpl(void* ctx, const xmlChar* name);
+  static void CharactersImpl(void* ctx, const xmlChar* ch, int len);
+
+  bool IsParsingData() const;
+
+  // Extracted json file.
+  std::string master_prefs_;
+
+  // Current stack of the elements being parsed.
+  std::vector<std::string> elements_;
+
+  DISALLOW_COPY_AND_ASSIGN(XmlConfigParser);
+};
+
+XmlConfigParser::XmlConfigParser() {}
+
+XmlConfigParser::~XmlConfigParser() {}
+
+void XmlConfigParser::Parse(const std::string& input_buffer,
+                            std::string* output_buffer) {
+  using logging::LOG_WARNING;
+
+  DCHECK(output_buffer);
+  xmlSAXHandler sax_handler = {};
+  sax_handler.startElement = &XmlConfigParser::StartElementImpl;
+  sax_handler.endElement = &XmlConfigParser::EndElementImpl;
+  sax_handler.characters = &XmlConfigParser::CharactersImpl;
+  XmlConfigParser parser;
+  int error = xmlSAXUserParseMemory(&sax_handler,
+                                    &parser,
+                                    input_buffer.c_str(),
+                                    input_buffer.size());
+  if (error) {
+    VLOG(LOG_WARNING) << "Error parsing brandcoded master prefs, err=" << error;
+  } else {
+    output_buffer->swap(parser.master_prefs_);
+  }
+}
+
+XmlConfigParser* XmlConfigParser::FromContext(void* ctx) {
+  return static_cast<XmlConfigParser*>(ctx);
+}
+
+std::string XmlConfigParser::XMLCharToString(const xmlChar* value) {
+  return std::string(reinterpret_cast<const char*>(value));
+}
+
+void XmlConfigParser::StartElementImpl(void* ctx,
+                                       const xmlChar* name,
+                                       const xmlChar** atts) {
+  std::string node_name(XMLCharToString(name));
+  XmlConfigParser* context = FromContext(ctx);
+  context->elements_.push_back(node_name);
+  if (context->IsParsingData())
+    context->master_prefs_.clear();
+}
+
+void XmlConfigParser::EndElementImpl(void* ctx, const xmlChar* name) {
+  XmlConfigParser* context = FromContext(ctx);
+  context->elements_.pop_back();
+}
+
+void XmlConfigParser::CharactersImpl(void* ctx, const xmlChar* ch, int len) {
+  XmlConfigParser* context = FromContext(ctx);
+  if (context->IsParsingData()) {
+    context->master_prefs_ +=
+        std::string(reinterpret_cast<const char*>(ch), len);
+  }
+}
+
+bool XmlConfigParser::IsParsingData() const {
+  const std::string data_path[] = {"response", "app", "data"};
+  return elements_.size() == arraysize(data_path) &&
+         std::equal(elements_.begin(), elements_.end(), data_path);
+}
+
+} // namespace
+
+BrandcodeConfigFetcher::BrandcodeConfigFetcher(const FetchCallback& callback,
+                                               const GURL& url)
+    : fetch_callback_(callback) {
+  config_fetcher_.reset(net::URLFetcher::Create(0 /* ID used for testing */,
+                                                url,
+                                                net::URLFetcher::POST,
+                                                this));
+  config_fetcher_->SetRequestContext(
+      g_browser_process->system_request_context());
+  config_fetcher_->SetUploadData("text/xml", GetUploadData());
+  config_fetcher_->AddExtraRequestHeader("Accept: text/xml");
+  config_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
+                                net::LOAD_DO_NOT_SAVE_COOKIES |
+                                net::LOAD_DISABLE_CACHE);
+  config_fetcher_->Start();
+  // Abort the download attempt if it takes too long.
+  download_timer_.Start(FROM_HERE,
+                        base::TimeDelta::FromSeconds(kDownloadTimeoutSec),
+                        this,
+                        &BrandcodeConfigFetcher::OnDownloadTimeout);
+}
+
+BrandcodeConfigFetcher::~BrandcodeConfigFetcher() {}
+
+void BrandcodeConfigFetcher::SetCallback(const FetchCallback& callback) {
+  fetch_callback_ = callback;
+}
+
+void BrandcodeConfigFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
+  if (source != config_fetcher_.get()) {
+    NOTREACHED() << "Callback from foreign URL fetcher";
+    return;
+  }
+  std::string response_string;
+  std::string mime_type;
+  if (config_fetcher_ &&
+      config_fetcher_->GetStatus().is_success() &&
+      config_fetcher_->GetResponseCode() == 200 &&
+      config_fetcher_->GetResponseHeaders()->GetMimeType(&mime_type) &&
+      mime_type == "text/xml" &&
+      config_fetcher_->GetResponseAsString(&response_string)) {
+    std::string master_prefs;
+    XmlConfigParser::Parse(response_string, &master_prefs);
+    default_settings_.reset(new BrandcodedDefaultSettings(master_prefs));
+  }
+  config_fetcher_.reset();
+  download_timer_.Stop();
+  fetch_callback_.Run();
+}
+
+void BrandcodeConfigFetcher::OnDownloadTimeout() {
+  if (config_fetcher_) {
+    config_fetcher_.reset();
+    fetch_callback_.Run();
+  }
+}
diff --git a/chrome/browser/profile_resetter/brandcode_config_fetcher.h b/chrome/browser/profile_resetter/brandcode_config_fetcher.h
new file mode 100644
index 0000000..cacee4d
--- /dev/null
+++ b/chrome/browser/profile_resetter/brandcode_config_fetcher.h
@@ -0,0 +1,57 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PROFILE_RESETTER_BRANDCODE_CONFIG_FETCHER_H_
+#define CHROME_BROWSER_PROFILE_RESETTER_BRANDCODE_CONFIG_FETCHER_H_
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/timer/timer.h"
+#include "net/url_request/url_fetcher_delegate.h"
+
+class BrandcodedDefaultSettings;
+class GURL;
+
+// BrandcodeConfigFetcher fetches and parses the xml containing the brandcoded
+// default settings. Caller should provide a FetchCallback.
+class BrandcodeConfigFetcher : public net::URLFetcherDelegate {
+ public:
+  typedef base::Callback<void ()> FetchCallback;
+
+  BrandcodeConfigFetcher(const FetchCallback& callback,
+                         const GURL& url);
+  virtual ~BrandcodeConfigFetcher();
+
+  bool IsActive() const { return config_fetcher_; }
+
+  scoped_ptr<BrandcodedDefaultSettings> GetSettings() {
+    return default_settings_.Pass();
+  }
+
+  // Sets the new callback. The previous one won't be called.
+  void SetCallback(const FetchCallback& callback);
+
+ private:
+  // net::URLFetcherDelegate:
+  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
+
+  void OnDownloadTimeout();
+
+  // Timer that enforces a timeout on the attempt to download the
+  // config file.
+  base::OneShotTimer<BrandcodeConfigFetcher> download_timer_;
+
+  // |fetch_callback_| called when fetching succeeded or failed.
+  FetchCallback fetch_callback_;
+
+  // Helper to fetch the online config file.
+  scoped_ptr<net::URLFetcher> config_fetcher_;
+
+  // Fetched settings.
+  scoped_ptr<BrandcodedDefaultSettings> default_settings_;
+
+  DISALLOW_COPY_AND_ASSIGN(BrandcodeConfigFetcher);
+};
+
+#endif  // CHROME_BROWSER_PROFILE_RESETTER_BRANDCODE_CONFIG_FETCHER_H_
diff --git a/chrome/browser/profile_resetter/brandcoded_default_settings.cc b/chrome/browser/profile_resetter/brandcoded_default_settings.cc
new file mode 100644
index 0000000..c47e79e
--- /dev/null
+++ b/chrome/browser/profile_resetter/brandcoded_default_settings.cc
@@ -0,0 +1,102 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
+
+#include "base/json/json_string_value_serializer.h"
+#include "base/logging.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/installer/util/master_preferences_constants.h"
+
+BrandcodedDefaultSettings::BrandcodedDefaultSettings() {
+}
+
+BrandcodedDefaultSettings::BrandcodedDefaultSettings(const std::string& prefs) {
+  if (!prefs.empty()) {
+    JSONStringValueSerializer json(prefs);
+    std::string error;
+    scoped_ptr<base::Value> root(json.Deserialize(NULL, &error));
+    if (!root.get()) {
+      VLOG(1) << "Failed to parse brandcode prefs file: " << error;
+      return;
+    }
+    if (!root->IsType(base::Value::TYPE_DICTIONARY)) {
+      VLOG(1) << "Failed to parse brandcode prefs file: "
+              << "Root item must be a dictionary.";
+      return;
+    }
+    master_dictionary_.reset(
+        static_cast<base::DictionaryValue*>(root.release()));
+  }
+}
+
+BrandcodedDefaultSettings::~BrandcodedDefaultSettings() {
+}
+
+scoped_ptr<ListValue> BrandcodedDefaultSettings::GetSearchProviderOverrides(
+    ) const {
+  return ExtractList(prefs::kSearchProviderOverrides);
+}
+
+bool BrandcodedDefaultSettings::GetHomepage(std::string* homepage) const {
+  return master_dictionary_ &&
+         master_dictionary_->GetString(prefs::kHomePage, homepage) &&
+         !homepage->empty();
+}
+
+bool BrandcodedDefaultSettings::GetHomepageIsNewTab(
+    bool* homepage_is_ntp) const {
+  return master_dictionary_ &&
+         master_dictionary_->GetBoolean(prefs::kHomePageIsNewTabPage,
+                                        homepage_is_ntp);
+}
+
+bool BrandcodedDefaultSettings::GetShowHomeButton(
+    bool* show_home_button) const {
+  return master_dictionary_ &&
+         master_dictionary_->GetBoolean(prefs::kShowHomeButton,
+                                        show_home_button);
+}
+
+bool BrandcodedDefaultSettings::GetExtensions(
+    std::vector<std::string>* extension_ids) const {
+  DCHECK(extension_ids);
+  base::DictionaryValue* extensions = NULL;
+  if (master_dictionary_ &&
+      master_dictionary_->GetDictionary(
+          installer::master_preferences::kExtensionsBlock,
+          &extensions)) {
+    for (DictionaryValue::Iterator extension_id(*extensions);
+         !extension_id.IsAtEnd(); extension_id.Advance()) {
+      if (extensions::Extension::IdIsValid(extension_id.key()))
+        extension_ids->push_back(extension_id.key());
+    }
+    return true;
+  }
+  return false;
+}
+
+bool BrandcodedDefaultSettings::GetRestoreOnStartup(
+    int* restore_on_startup) const {
+  return master_dictionary_ &&
+         master_dictionary_->GetInteger(prefs::kRestoreOnStartup,
+                                        restore_on_startup);
+}
+
+scoped_ptr<ListValue> BrandcodedDefaultSettings::GetUrlsToRestoreOnStartup(
+    ) const {
+  return ExtractList(prefs::kURLsToRestoreOnStartup);
+}
+
+scoped_ptr<ListValue> BrandcodedDefaultSettings::ExtractList(
+    const char* pref_name) const {
+  const base::ListValue* value = NULL;
+  if (master_dictionary_ &&
+      master_dictionary_->GetList(pref_name, &value) &&
+      !value->empty()) {
+    return scoped_ptr<ListValue>(value->DeepCopy());
+  }
+  return scoped_ptr<ListValue>();
+}
diff --git a/chrome/browser/profile_resetter/brandcoded_default_settings.h b/chrome/browser/profile_resetter/brandcoded_default_settings.h
new file mode 100644
index 0000000..bdd7adf
--- /dev/null
+++ b/chrome/browser/profile_resetter/brandcoded_default_settings.h
@@ -0,0 +1,48 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PROFILE_RESETTER_BRANDCODED_DEFAULT_SETTINGS_H_
+#define CHROME_BROWSER_PROFILE_RESETTER_BRANDCODED_DEFAULT_SETTINGS_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+
+// BrandcodedDefaultSettings provides a set of default settings
+// for ProfileResetter. They are specific to Chrome distribution channels.
+class BrandcodedDefaultSettings {
+ public:
+  BrandcodedDefaultSettings();
+  // Constructs BrandcodedDefaultSettings directly from preferences.
+  explicit BrandcodedDefaultSettings(const std::string& prefs);
+  ~BrandcodedDefaultSettings();
+
+  // The following methods return non-zero value if the default value was
+  // provided for given setting.
+  // After the call return_value contains a list of default engines.
+  // |return_value[0]| is default one.
+  scoped_ptr<ListValue> GetSearchProviderOverrides() const;
+
+  bool GetHomepage(std::string* homepage) const;
+  bool GetHomepageIsNewTab(bool* homepage_is_ntp) const;
+  bool GetShowHomeButton(bool* show_home_button) const;
+
+  // |extension_ids| is a list of extension ids.
+  bool GetExtensions(std::vector<std::string>* extension_ids) const;
+
+  bool GetRestoreOnStartup(int* restore_on_startup) const;
+  scoped_ptr<ListValue> GetUrlsToRestoreOnStartup() const;
+
+ private:
+  scoped_ptr<ListValue> ExtractList(const char* pref_name) const;
+
+  scoped_ptr<base::DictionaryValue> master_dictionary_;
+
+  DISALLOW_COPY_AND_ASSIGN(BrandcodedDefaultSettings);
+};
+
+#endif  // CHROME_BROWSER_PROFILE_RESETTER_BRANDCODED_DEFAULT_SETTINGS_H_
diff --git a/chrome/browser/profile_resetter/profile_resetter.cc b/chrome/browser/profile_resetter/profile_resetter.cc
index 513719f..297e359 100644
--- a/chrome/browser/profile_resetter/profile_resetter.cc
+++ b/chrome/browser/profile_resetter/profile_resetter.cc
@@ -6,11 +6,13 @@
 
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/management_policy.h"
 #include "chrome/browser/google/google_url_tracker.h"
+#include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
 #include "chrome/browser/search_engines/template_url_service.h"
@@ -18,7 +20,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_source.h"
@@ -39,9 +40,14 @@
     cookies_remover_->RemoveObserver(this);
 }
 
-void ProfileResetter::Reset(ProfileResetter::ResettableFlags resettable_flags,
-                            const base::Closure& callback) {
+void ProfileResetter::Reset(
+    ProfileResetter::ResettableFlags resettable_flags,
+    scoped_ptr<BrandcodedDefaultSettings> master_settings,
+    const base::Closure& callback) {
   DCHECK(CalledOnValidThread());
+  DCHECK(master_settings);
+
+  master_settings_.swap(master_settings);
 
   // We should never be called with unknown flags.
   CHECK_EQ(static_cast<ResettableFlags>(0), resettable_flags & ~ALL);
@@ -95,6 +101,7 @@
     content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
                                      callback_);
     callback_.Reset();
+    master_settings_.reset();
   }
 }
 
@@ -105,12 +112,20 @@
   // If TemplateURLServiceFactory is ready we can clean it right now.
   // Otherwise, load it and continue from ProfileResetter::Observe.
   if (template_url_service_->loaded()) {
+    PrefService* prefs = profile_->GetPrefs();
+    DCHECK(prefs);
     TemplateURLPrepopulateData::ClearPrepopulatedEnginesInPrefs(profile_);
+    scoped_ptr<ListValue> search_engines(
+        master_settings_->GetSearchProviderOverrides());
+    if (search_engines) {
+      // This Chrome distribution channel provides a custom search engine. We
+      // must reset to it.
+      ListPrefUpdate update(prefs, prefs::kSearchProviderOverrides);
+      update->Swap(search_engines.get());
+    }
     template_url_service_->ResetNonExtensionURLs();
 
     // Reset Google search URL.
-    PrefService* prefs = profile_->GetPrefs();
-    DCHECK(prefs);
     prefs->ClearPref(prefs::kLastPromptedGoogleURL);
     const TemplateURL* default_search_provider =
         template_url_service_->GetDefaultSearchProvider();
@@ -128,9 +143,23 @@
   DCHECK(CalledOnValidThread());
   PrefService* prefs = profile_->GetPrefs();
   DCHECK(prefs);
-  prefs->ClearPref(prefs::kHomePageIsNewTabPage);
-  prefs->ClearPref(prefs::kHomePage);
-  prefs->ClearPref(prefs::kShowHomeButton);
+  std::string homepage;
+  bool homepage_is_ntp, show_home_button;
+
+  if (master_settings_->GetHomepage(&homepage))
+    prefs->SetString(prefs::kHomePage, homepage);
+  else
+    prefs->ClearPref(prefs::kHomePage);
+
+  if (master_settings_->GetHomepageIsNewTab(&homepage_is_ntp))
+    prefs->SetBoolean(prefs::kHomePageIsNewTabPage, homepage_is_ntp);
+  else
+    prefs->ClearPref(prefs::kHomePageIsNewTabPage);
+
+  if (master_settings_->GetShowHomeButton(&show_home_button))
+    prefs->SetBoolean(prefs::kShowHomeButton, show_home_button);
+  else
+    prefs->ClearPref(prefs::kShowHomeButton);
   MarkAsDone(HOMEPAGE);
 }
 
@@ -169,9 +198,13 @@
 
 void ProfileResetter::ResetExtensions() {
   DCHECK(CalledOnValidThread());
+
+  std::vector<std::string> brandcode_extensions;
+  master_settings_->GetExtensions(&brandcode_extensions);
+
   ExtensionService* extension_service = profile_->GetExtensionService();
   DCHECK(extension_service);
-  extension_service->DisableUserExtensions();
+  extension_service->DisableUserExtensions(brandcode_extensions);
 
   MarkAsDone(EXTENSIONS);
 }
@@ -180,8 +213,18 @@
   DCHECK(CalledOnValidThread());
   PrefService* prefs = profile_->GetPrefs();
   DCHECK(prefs);
-  prefs->ClearPref(prefs::kRestoreOnStartup);
-  prefs->ClearPref(prefs::kURLsToRestoreOnStartup);
+  scoped_ptr<ListValue> url_list(master_settings_->GetUrlsToRestoreOnStartup());
+  if (url_list)
+    ListPrefUpdate(prefs, prefs::kURLsToRestoreOnStartup)->Swap(url_list.get());
+  else
+    prefs->ClearPref(prefs::kURLsToRestoreOnStartup);
+
+  int restore_on_startup;
+  if (master_settings_->GetRestoreOnStartup(&restore_on_startup))
+    prefs->SetInteger(prefs::kRestoreOnStartup, restore_on_startup);
+  else
+    prefs->ClearPref(prefs::kRestoreOnStartup);
+
   prefs->SetBoolean(prefs::kRestoreOnStartupMigrated, true);
   MarkAsDone(STARTUP_PAGES);
 }
diff --git a/chrome/browser/profile_resetter/profile_resetter.h b/chrome/browser/profile_resetter/profile_resetter.h
index 492d6f6..77e8a1c 100644
--- a/chrome/browser/profile_resetter/profile_resetter.h
+++ b/chrome/browser/profile_resetter/profile_resetter.h
@@ -9,6 +9,7 @@
 #include "base/callback.h"
 #include "base/threading/non_thread_safe.h"
 #include "chrome/browser/browsing_data/browsing_data_remover.h"
+#include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 
@@ -47,9 +48,10 @@
   virtual ~ProfileResetter();
 
   // Resets |resettable_flags| and calls |callback| on the UI thread on
-  // completion. If |resettable_flags| contains EXTENSIONS, these are handled
-  // according to |extension_handling|.
+  // completion. |default_settings| allows the caller to specify some default
+  // settings. |default_settings| shouldn't be NULL.
   void Reset(ResettableFlags resettable_flags,
+             scoped_ptr<BrandcodedDefaultSettings> master_settings,
              const base::Closure& callback);
 
   bool IsActive() const;
@@ -75,7 +77,8 @@
   // BrowsingDataRemover::Observer:
   virtual void OnBrowsingDataRemoverDone() OVERRIDE;
 
-  Profile* profile_;
+  Profile* const profile_;
+  scoped_ptr<BrandcodedDefaultSettings> master_settings_;
   TemplateURLService* template_url_service_;
 
   // Flags of a Resetable indicating which reset operations we are still waiting
diff --git a/chrome/browser/profile_resetter/profile_resetter_browsertest.cc b/chrome/browser/profile_resetter/profile_resetter_browsertest.cc
index f8e0144..c820743 100644
--- a/chrome/browser/profile_resetter/profile_resetter_browsertest.cc
+++ b/chrome/browser/profile_resetter/profile_resetter_browsertest.cc
@@ -166,10 +166,7 @@
   tester.AddCookie(kCookieHostname, kCookieDefinition);
   ASSERT_EQ(kCookieDefinition, tester.GetCookie(kCookieHostname));
 
-  resetter_->Reset(ProfileResetter::COOKIES_AND_SITE_DATA,
-                   base::Bind(&ProfileResetterMockObject::StopLoop,
-                              base::Unretained(&mock_object_)));
-  mock_object_.RunLoop();
+  ResetAndWait(ProfileResetter::COOKIES_AND_SITE_DATA);
 
   EXPECT_EQ("", tester.GetCookie(kCookieHostname));
 }
diff --git a/chrome/browser/profile_resetter/profile_resetter_test_base.cc b/chrome/browser/profile_resetter/profile_resetter_test_base.cc
index b239618..a4c4cf4 100644
--- a/chrome/browser/profile_resetter/profile_resetter_test_base.cc
+++ b/chrome/browser/profile_resetter/profile_resetter_test_base.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/profile_resetter/profile_resetter_test_base.h"
 
-#include "chrome/browser/profile_resetter/profile_resetter.h"
+#include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
 
 ProfileResetterMockObject::ProfileResetterMockObject() {}
 
@@ -25,3 +25,26 @@
 ProfileResetterTestBase::ProfileResetterTestBase() {}
 
 ProfileResetterTestBase::~ProfileResetterTestBase() {}
+
+void ProfileResetterTestBase::ResetAndWait(
+    ProfileResetter::ResettableFlags resettable_flags) {
+  scoped_ptr<BrandcodedDefaultSettings> master_settings(
+      new BrandcodedDefaultSettings);
+  resetter_->Reset(resettable_flags,
+                   master_settings.Pass(),
+                   base::Bind(&ProfileResetterMockObject::StopLoop,
+                              base::Unretained(&mock_object_)));
+  mock_object_.RunLoop();
+}
+
+void ProfileResetterTestBase::ResetAndWait(
+    ProfileResetter::ResettableFlags resettable_flags,
+    const std::string& prefs) {
+  scoped_ptr<BrandcodedDefaultSettings> master_settings(
+      new BrandcodedDefaultSettings(prefs));
+  resetter_->Reset(resettable_flags,
+                   master_settings.Pass(),
+                   base::Bind(&ProfileResetterMockObject::StopLoop,
+                              base::Unretained(&mock_object_)));
+  mock_object_.RunLoop();
+}
diff --git a/chrome/browser/profile_resetter/profile_resetter_test_base.h b/chrome/browser/profile_resetter/profile_resetter_test_base.h
index ef5744f..178035c 100644
--- a/chrome/browser/profile_resetter/profile_resetter_test_base.h
+++ b/chrome/browser/profile_resetter/profile_resetter_test_base.h
@@ -5,16 +5,16 @@
 #ifndef CHROME_BROWSER_PROFILE_RESETTER_PROFILE_RESETTER_TEST_BASE_H_
 #define CHROME_BROWSER_PROFILE_RESETTER_PROFILE_RESETTER_TEST_BASE_H_
 
+#include "chrome/browser/profile_resetter/profile_resetter.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
-class ProfileResetter;
-
 // The ProfileResetterMockObject is used to block the thread until
 // ProfileResetter::Reset has completed:
 
 // ProfileResetterMockObject mock_object;
 // resetter_->Reset(ProfileResetter::ALL,
+//                  pointer,
 //                  base::Bind(&ProfileResetterMockObject::StopLoop,
 //                             base::Unretained(&mock_object)));
 // mock_object.RunLoop();
@@ -40,6 +40,9 @@
   ProfileResetterTestBase();
   ~ProfileResetterTestBase();
 
+  void ResetAndWait(ProfileResetter::ResettableFlags resettable_flags);
+  void ResetAndWait(ProfileResetter::ResettableFlags resettable_flags,
+                    const std::string& prefs);
  protected:
   testing::StrictMock<ProfileResetterMockObject> mock_object_;
   scoped_ptr<ProfileResetter> resetter_;
diff --git a/chrome/browser/profile_resetter/profile_resetter_unittest.cc b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
index b625384..32442f9 100644
--- a/chrome/browser/profile_resetter/profile_resetter_unittest.cc
+++ b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
@@ -5,13 +5,16 @@
 #include "chrome/browser/profile_resetter/profile_resetter.h"
 
 #include "base/prefs/pref_service.h"
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/extensions/extension_service_unittest.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/notifications/desktop_notification_service.h"
 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
+#include "chrome/browser/profile_resetter/brandcode_config_fetcher.h"
 #include "chrome/browser/profile_resetter/profile_resetter_test_base.h"
+#include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_test_util.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
@@ -21,10 +24,51 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "content/public/browser/web_contents.h"
+#include "net/http/http_response_headers.h"
+#include "net/url_request/test_url_fetcher_factory.h"
 
 
 namespace {
 
+const char kDistributionConfig[] = "{"
+    " \"homepage\" : \"http://www.foo.com\","
+    " \"homepage_is_newtabpage\" : false,"
+    " \"browser\" : {"
+    "   \"show_home_button\" : true"
+    "  },"
+    " \"session\" : {"
+    "   \"restore_on_startup\" : 4,"
+    "   \"urls_to_restore_on_startup\" : [\"http://goo.gl\", \"http://foo.de\"]"
+    "  },"
+    " \"search_provider_overrides\" : ["
+    "    {"
+    "      \"name\" : \"first\","
+    "      \"keyword\" : \"firstkey\","
+    "      \"search_url\" : \"http://www.foo.com/s?q={searchTerms}\","
+    "      \"favicon_url\" : \"http://www.foo.com/favicon.ico\","
+    "      \"suggest_url\" : \"http://www.foo.com/s?q={searchTerms}\","
+    "      \"encoding\" : \"UTF-8\","
+    "      \"id\" : 1001"
+    "    }"
+    "  ],"
+    " \"extensions\" : {"
+    "   \"settings\" : {"
+    "     \"placeholder_for_id\": {"
+    "      }"
+    "    }"
+    "  }"
+    "}";
+
+const char kXmlConfig[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+    "<response protocol=\"3.0\" server=\"prod\">"
+      "<app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
+        "<data index=\"skipfirstrunui-importsearch-defaultbrowser\" "
+          "name=\"install\" status=\"ok\">"
+          "placeholder_for_data"
+        "</data>"
+      "</app>"
+    "</response>";
+
 using extensions::Extension;
 using extensions::Manifest;
 
@@ -99,18 +143,97 @@
       content::WebContents::CreateParams(profile()));
 }
 
+class ConfigParserTest : public testing::Test {
+ protected:
+  ConfigParserTest();
+  virtual ~ConfigParserTest();
+
+  MOCK_METHOD0(Callback, void(void));
+
+  scoped_ptr<BrandcodeConfigFetcher> WaitForRequest(const GURL& url);
+
+  static scoped_ptr<net::FakeURLFetcher> CreateFakeURLFetcher(
+      const GURL& url,
+      net::URLFetcherDelegate* d,
+      const std::string& response_data,
+      bool success);
+
+  base::MessageLoop loop_;
+  content::TestBrowserThread ui_thread_;
+  content::TestBrowserThread io_thread_;
+};
+
+ConfigParserTest::ConfigParserTest()
+    : loop_(base::MessageLoop::TYPE_IO),
+      ui_thread_(content::BrowserThread::UI, &loop_),
+      io_thread_(content::BrowserThread::IO, &loop_) {
+}
+
+ConfigParserTest::~ConfigParserTest() {}
+
+scoped_ptr<BrandcodeConfigFetcher> ConfigParserTest::WaitForRequest(
+    const GURL& url) {
+  EXPECT_CALL(*this, Callback());
+  scoped_ptr<BrandcodeConfigFetcher> fetcher(
+      new BrandcodeConfigFetcher(base::Bind(&ConfigParserTest::Callback,
+                                            base::Unretained(this)),
+                                 url));
+  base::MessageLoop::current()->RunUntilIdle();
+  EXPECT_FALSE(fetcher->IsActive());
+  return fetcher.Pass();
+}
+
+scoped_ptr<net::FakeURLFetcher> ConfigParserTest::CreateFakeURLFetcher(
+    const GURL& url,
+    net::URLFetcherDelegate* d,
+    const std::string& response_data,
+    bool success) {
+  scoped_ptr<net::FakeURLFetcher> fetcher(
+      new net::FakeURLFetcher(url, d, response_data, success));
+  scoped_refptr<net::HttpResponseHeaders> download_headers =
+      new net::HttpResponseHeaders("");
+  download_headers->AddHeader("Content-Type: text/xml");
+  fetcher->set_response_headers(download_headers);
+  return fetcher.Pass();
+}
+
+void ReplaceString(std::string* str,
+                   const std::string& placeholder,
+                   const std::string& substitution) {
+  ASSERT_NE(static_cast<std::string*>(NULL), str);
+  size_t placeholder_pos = str->find(placeholder);
+  ASSERT_NE(std::string::npos, placeholder_pos);
+  str->replace(placeholder_pos, placeholder.size(), substitution);
+}
+
+
 /********************* Tests *********************/
 
 TEST_F(ProfileResetterTest, ResetDefaultSearchEngine) {
+  // Search engine's logic is tested by
+  // TemplateURLServiceTest.ResetNonExtensionURLs.
   PrefService* prefs = test_util_.profile()->GetPrefs();
   DCHECK(prefs);
   prefs->SetString(prefs::kLastPromptedGoogleURL, "http://www.foo.com/");
 
-  resetter_->Reset(
-      ProfileResetter::DEFAULT_SEARCH_ENGINE,
-      base::Bind(&ProfileResetterMockObject::StopLoop,
-                 base::Unretained(&mock_object_)));
-  mock_object_.RunLoop();
+  ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE);
+
+  EXPECT_EQ("", prefs->GetString(prefs::kLastPromptedGoogleURL));
+}
+
+TEST_F(ProfileResetterTest, ResetDefaultSearchEngineNonOrganic) {
+  PrefService* prefs = test_util_.profile()->GetPrefs();
+  DCHECK(prefs);
+  prefs->SetString(prefs::kLastPromptedGoogleURL, "http://www.foo.com/");
+
+  ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE, kDistributionConfig);
+
+  EXPECT_EQ(1u, test_util_.model()->GetTemplateURLs().size());
+  TemplateURL* default_engine = test_util_.model()->GetDefaultSearchProvider();
+  ASSERT_NE(static_cast<TemplateURL*>(NULL), default_engine);
+  EXPECT_EQ(ASCIIToUTF16("first"), default_engine->short_name());
+  EXPECT_EQ(ASCIIToUTF16("firstkey"), default_engine->keyword());
+  EXPECT_EQ("http://www.foo.com/s?q={searchTerms}", default_engine->url());
 
   EXPECT_EQ("", prefs->GetString(prefs::kLastPromptedGoogleURL));
 }
@@ -122,17 +245,27 @@
   prefs->SetString(prefs::kHomePage, "http://google.com");
   prefs->SetBoolean(prefs::kShowHomeButton, true);
 
-  resetter_->Reset(
-      ProfileResetter::HOMEPAGE,
-      base::Bind(&ProfileResetterMockObject::StopLoop,
-                 base::Unretained(&mock_object_)));
-  mock_object_.RunLoop();
+  ResetAndWait(ProfileResetter::HOMEPAGE);
 
   EXPECT_TRUE(prefs->GetBoolean(prefs::kHomePageIsNewTabPage));
   EXPECT_EQ(std::string(), prefs->GetString(prefs::kHomePage));
   EXPECT_FALSE(prefs->GetBoolean(prefs::kShowHomeButton));
 }
 
+TEST_F(ProfileResetterTest, ResetHomepageNonOrganic) {
+  PrefService* prefs = test_util_.profile()->GetPrefs();
+  DCHECK(prefs);
+  prefs->SetBoolean(prefs::kHomePageIsNewTabPage, true);
+  prefs->SetString(prefs::kHomePage, "http://google.com");
+  prefs->SetBoolean(prefs::kShowHomeButton, false);
+
+  ResetAndWait(ProfileResetter::HOMEPAGE, kDistributionConfig);
+
+  EXPECT_FALSE(prefs->GetBoolean(prefs::kHomePageIsNewTabPage));
+  EXPECT_EQ("http://www.foo.com", prefs->GetString(prefs::kHomePage));
+  EXPECT_TRUE(prefs->GetBoolean(prefs::kShowHomeButton));
+}
+
 TEST_F(ProfileResetterTest, ResetContentSettings) {
   HostContentSettingsMap* host_content_settings_map =
       test_util_.profile()->GetHostContentSettingsMap();
@@ -172,9 +305,9 @@
             wildcard_setting);
       }
       if (!HostContentSettingsMap::ContentTypeHasCompoundValue(content_type) &&
-          HostContentSettingsMap::IsValueAllowedForType(
+          HostContentSettingsMap::IsSettingAllowedForType(
               test_util_.profile()->GetPrefs(),
-              Value::CreateIntegerValue(site_setting),
+              site_setting,
               content_type)) {
         host_content_settings_map->SetContentSetting(
             pattern,
@@ -190,11 +323,7 @@
     }
   }
 
-  resetter_->Reset(
-      ProfileResetter::CONTENT_SETTINGS,
-      base::Bind(&ProfileResetterMockObject::StopLoop,
-                 base::Unretained(&mock_object_)));
-  mock_object_.RunLoop();
+  ResetAndWait(ProfileResetter::CONTENT_SETTINGS);
 
   for (int type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) {
     if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
@@ -269,11 +398,7 @@
   service_->AddExtension(ext4.get());
   EXPECT_EQ(4u, service_->extensions()->size());
 
-  resetter_->Reset(
-      ProfileResetter::EXTENSIONS,
-      base::Bind(&ProfileResetterMockObject::StopLoop,
-                 base::Unretained(&mock_object_)));
-  mock_object_.RunLoop();
+  ResetAndWait(ProfileResetter::EXTENSIONS);
 
   EXPECT_EQ(2u, service_->extensions()->size());
   EXPECT_TRUE(service_->extensions()->Contains(ext3->id()));
@@ -281,6 +406,31 @@
   EXPECT_TRUE(theme_service->UsingDefaultTheme());
 }
 
+TEST_F(ExtensionsResetTest, ResetExtensionsByDisablingNonOrganic) {
+  scoped_refptr<Extension> ext2 = CreateExtension(
+      "example2",
+      base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
+      Manifest::INVALID_LOCATION,
+      false);
+  service_->AddExtension(ext2.get());
+  // Components and external policy extensions shouldn't be deleted.
+  scoped_refptr<Extension> ext3 = CreateExtension(
+      "example3",
+      base::FilePath(FILE_PATH_LITERAL("//nonexistent2")),
+      Manifest::INVALID_LOCATION,
+      false);
+  service_->AddExtension(ext3.get());
+  EXPECT_EQ(2u, service_->extensions()->size());
+
+  std::string master_prefs(kDistributionConfig);
+  ReplaceString(&master_prefs, "placeholder_for_id", ext3->id());
+
+  ResetAndWait(ProfileResetter::EXTENSIONS, master_prefs);
+
+  EXPECT_EQ(1u, service_->extensions()->size());
+  EXPECT_TRUE(service_->extensions()->Contains(ext3->id()));
+}
+
 TEST_F(ProfileResetterTest, ResetStartPage) {
   PrefService* prefs = test_util_.profile()->GetPrefs();
   DCHECK(prefs);
@@ -290,17 +440,28 @@
   startup_pref.urls.push_back(GURL("http://bar"));
   SessionStartupPref::SetStartupPref(prefs, startup_pref);
 
-  resetter_->Reset(
-      ProfileResetter::STARTUP_PAGES,
-      base::Bind(&ProfileResetterMockObject::StopLoop,
-                 base::Unretained(&mock_object_)));
-  mock_object_.RunLoop();
+  ResetAndWait(ProfileResetter::STARTUP_PAGES);
 
   startup_pref = SessionStartupPref::GetStartupPref(prefs);
   EXPECT_EQ(SessionStartupPref::GetDefaultStartupType(), startup_pref.type);
   EXPECT_EQ(std::vector<GURL>(), startup_pref.urls);
 }
 
+TEST_F(ProfileResetterTest, ResetStartPageNonOrganic) {
+  PrefService* prefs = test_util_.profile()->GetPrefs();
+  DCHECK(prefs);
+
+  SessionStartupPref startup_pref(SessionStartupPref::LAST);
+  SessionStartupPref::SetStartupPref(prefs, startup_pref);
+
+  ResetAndWait(ProfileResetter::STARTUP_PAGES, kDistributionConfig);
+
+  startup_pref = SessionStartupPref::GetStartupPref(prefs);
+  EXPECT_EQ(SessionStartupPref::URLS, startup_pref.type);
+  const GURL urls[] = {GURL("http://goo.gl"), GURL("http://foo.de")};
+  EXPECT_EQ(std::vector<GURL>(urls, urls + arraysize(urls)), startup_pref.urls);
+}
+
 TEST_F(PinnedTabsResetTest, ResetPinnedTabs) {
   scoped_refptr<Extension> extension_app = CreateExtension(
       "hello!",
@@ -329,11 +490,7 @@
   EXPECT_EQ(contents4, tab_strip_model->GetWebContentsAt(3));
   EXPECT_EQ(3, tab_strip_model->IndexOfFirstNonMiniTab());
 
-  resetter_->Reset(
-      ProfileResetter::PINNED_TABS,
-      base::Bind(&ProfileResetterMockObject::StopLoop,
-                 base::Unretained(&mock_object_)));
-  mock_object_.RunLoop();
+  ResetAndWait(ProfileResetter::PINNED_TABS);
 
   EXPECT_EQ(contents1, tab_strip_model->GetWebContentsAt(0));
   EXPECT_EQ(contents2, tab_strip_model->GetWebContentsAt(1));
@@ -344,11 +501,58 @@
 
 TEST_F(ProfileResetterTest, ResetFewFlags) {
   // mock_object_ is a StrictMock, so we verify that it is called only once.
-  resetter_->Reset(
-      ProfileResetter::DEFAULT_SEARCH_ENGINE | ProfileResetter::HOMEPAGE,
-      base::Bind(&ProfileResetterMockObject::StopLoop,
-                 base::Unretained(&mock_object_)));
-  mock_object_.RunLoop();
+  ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE |
+               ProfileResetter::HOMEPAGE);
+}
+
+// Tries to load unavailable config file.
+TEST_F(ConfigParserTest, NoConnectivity) {
+  net::FakeURLFetcherFactory factory(NULL);
+  const std::string url("http://test");
+  factory.SetFakeResponse(url, "", false);
+
+  scoped_ptr<BrandcodeConfigFetcher> fetcher = WaitForRequest(GURL(url));
+  EXPECT_FALSE(fetcher->GetSettings());
+}
+
+// Tries to load available config file.
+TEST_F(ConfigParserTest, ParseConfig) {
+  net::FakeURLFetcherFactory factory(
+      NULL,
+      base::Bind(&ConfigParserTest::CreateFakeURLFetcher));
+  const std::string url("http://test");
+  std::string xml_config(kXmlConfig);
+  ReplaceString(&xml_config, "placeholder_for_data", kDistributionConfig);
+  ReplaceString(&xml_config,
+                "placeholder_for_id",
+                "abbaabbaabbaabbaabbaabbaabbaabba");
+  factory.SetFakeResponse(url, xml_config, true);
+
+  scoped_ptr<BrandcodeConfigFetcher> fetcher = WaitForRequest(GURL(url));
+  scoped_ptr<BrandcodedDefaultSettings> settings = fetcher->GetSettings();
+  ASSERT_TRUE(settings);
+
+  std::vector<std::string> extension_ids;
+  EXPECT_TRUE(settings->GetExtensions(&extension_ids));
+  EXPECT_EQ(1u, extension_ids.size());
+  EXPECT_EQ("abbaabbaabbaabbaabbaabbaabbaabba", extension_ids[0]);
+
+  std::string homepage;
+  EXPECT_TRUE(settings->GetHomepage(&homepage));
+  EXPECT_EQ("http://www.foo.com", homepage);
+
+  scoped_ptr<base::ListValue> startup_list(
+      settings->GetUrlsToRestoreOnStartup());
+  EXPECT_TRUE(startup_list);
+  std::vector<std::string> startup_pages;
+  for (base::ListValue::iterator i = startup_list->begin();
+       i != startup_list->end(); ++i) {
+    std::string url;
+    EXPECT_TRUE((*i)->GetAsString(&url));
+    startup_pages.push_back(url);
+  }
+  EXPECT_EQ("http://goo.gl", startup_pages[0]);
+  EXPECT_EQ("http://foo.de", startup_pages[1]);
 }
 
 }  // namespace
diff --git a/chrome/browser/profiles/avatar_menu_model.cc b/chrome/browser/profiles/avatar_menu_model.cc
index a7e535b..4a86e7f 100644
--- a/chrome/browser/profiles/avatar_menu_model.cc
+++ b/chrome/browser/profiles/avatar_menu_model.cc
@@ -11,6 +11,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/avatar_menu_model_observer.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/browser_thread.h"
@@ -192,6 +192,18 @@
   return profile_info_->GetPathOfProfileAtIndex(item.model_index);
 }
 
+// static
+void AvatarMenuModel::SwitchToGuestProfileWindow(Browser* browser) {
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+  profile_manager->CreateProfileAsync(ProfileManager::GetGuestProfilePath(),
+                                      base::Bind(&OnProfileCreated,
+                                                 false,
+                                                 browser->host_desktop_type()),
+                                      string16(),
+                                      string16(),
+                                      false);
+}
+
 size_t AvatarMenuModel::GetNumberOfItems() {
   return items_.size();
 }
@@ -272,9 +284,12 @@
     DCHECK(ProfileManager::IsMultipleProfilesEnabled());
     return true;
   }
-  return ProfileManager::IsMultipleProfilesEnabled() &&
-      g_browser_process->profile_manager() &&
-      g_browser_process->profile_manager()->GetNumberOfProfiles() > 1;
+  if (ProfileManager::IsMultipleProfilesEnabled()) {
+    return ProfileManager::IsNewProfileManagementEnabled() ||
+           (g_browser_process->profile_manager() &&
+            g_browser_process->profile_manager()->GetNumberOfProfiles() > 1);
+  }
+  return false;
 }
 
 void AvatarMenuModel::RebuildMenu() {
diff --git a/chrome/browser/profiles/avatar_menu_model.h b/chrome/browser/profiles/avatar_menu_model.h
index 0ab6818..95668b4 100644
--- a/chrome/browser/profiles/avatar_menu_model.h
+++ b/chrome/browser/profiles/avatar_menu_model.h
@@ -74,6 +74,8 @@
   void EditProfile(size_t index);
   // Creates a new profile.
   void AddNewProfile(ProfileMetrics::ProfileAdd type);
+  // Creates a new guest user window.
+  static void SwitchToGuestProfileWindow(Browser* browser);
 
   // Gets the path associated with the profile at |index|.
   base::FilePath GetProfilePath(size_t index);
diff --git a/chrome/browser/profiles/avatar_menu_model_browsertest.cc b/chrome/browser/profiles/avatar_menu_model_browsertest.cc
index 634fe75..aa02956 100644
--- a/chrome/browser/profiles/avatar_menu_model_browsertest.cc
+++ b/chrome/browser/profiles/avatar_menu_model_browsertest.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/profiles/avatar_menu_model.h"
 
 #include "base/path_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/testing_browser_process.h"
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index e5ca157..bd26711 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -83,7 +83,6 @@
 #include "chrome/browser/signin/about_signin_internals_factory.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/signin/token_service_factory.h"
-#include "chrome/browser/speech/chrome_speech_recognition_preferences.h"
 #include "chrome/browser/speech/extension_api/tts_extension_api.h"
 #include "chrome/browser/spellchecker/spellcheck_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
@@ -93,7 +92,6 @@
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "chrome/browser/ui/tabs/pinned_tab_service_factory.h"
 #include "chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h"
-#include "chrome/browser/undo/undo_service_factory.h"
 #include "chrome/browser/user_style_sheet_watcher_factory.h"
 #include "chrome/browser/webdata/web_data_service_factory.h"
 
@@ -168,7 +166,6 @@
   BackgroundContentsServiceFactory::GetInstance();
 #endif
   BookmarkModelFactory::GetInstance();
-  UndoServiceFactory::GetInstance();
 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
   captive_portal::CaptivePortalServiceFactory::GetInstance();
 #endif
@@ -176,9 +173,6 @@
 #if defined(OS_CHROMEOS)
   chromeos::NetworkingPrivateEventRouterFactory::GetInstance();
 #endif
-#if defined(ENABLE_INPUT_SPEECH)
-  ChromeSpeechRecognitionPreferences::InitializeFactory();
-#endif
 #if defined(ENABLE_PRINTING)
   CloudPrintProxyServiceFactory::GetInstance();
 #endif
diff --git a/chrome/browser/profiles/chrome_version_service.cc b/chrome/browser/profiles/chrome_version_service.cc
index 52c552c..5a177a6 100644
--- a/chrome/browser/profiles/chrome_version_service.cc
+++ b/chrome/browser/profiles/chrome_version_service.cc
@@ -11,7 +11,7 @@
 #include "components/user_prefs/pref_registry_syncable.h"
 
 // static
-void ChromeVersionService::RegisterUserPrefs(
+void ChromeVersionService::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterStringPref(
       prefs::kProfileCreatedByVersion,
diff --git a/chrome/browser/profiles/chrome_version_service.h b/chrome/browser/profiles/chrome_version_service.h
index 75aecef..4102c45 100644
--- a/chrome/browser/profiles/chrome_version_service.h
+++ b/chrome/browser/profiles/chrome_version_service.h
@@ -20,7 +20,7 @@
 class ChromeVersionService {
  public:
   // Register the user pref we use.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Sets the version string in the pref for the current profile.
   static void SetVersion(PrefService* prefs, const std::string& version);
diff --git a/chrome/browser/profiles/gaia_info_update_service.cc b/chrome/browser/profiles/gaia_info_update_service.cc
index 34f13e8..cd9578e 100644
--- a/chrome/browser/profiles/gaia_info_update_service.cc
+++ b/chrome/browser/profiles/gaia_info_update_service.cc
@@ -7,11 +7,11 @@
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/profiles/gaia_info_update_service_factory.cc b/chrome/browser/profiles/gaia_info_update_service_factory.cc
index bc1e0fe..ce7dc12 100644
--- a/chrome/browser/profiles/gaia_info_update_service_factory.cc
+++ b/chrome/browser/profiles/gaia_info_update_service_factory.cc
@@ -39,7 +39,7 @@
   return new GAIAInfoUpdateService(profile);
 }
 
-void GAIAInfoUpdateServiceFactory::RegisterUserPrefs(
+void GAIAInfoUpdateServiceFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* prefs) {
   prefs->RegisterInt64Pref(prefs::kProfileGAIAInfoUpdateTime,
                            0,
diff --git a/chrome/browser/profiles/gaia_info_update_service_factory.h b/chrome/browser/profiles/gaia_info_update_service_factory.h
index 3ee9bd6..f7d6b02 100644
--- a/chrome/browser/profiles/gaia_info_update_service_factory.h
+++ b/chrome/browser/profiles/gaia_info_update_service_factory.h
@@ -38,7 +38,7 @@
   virtual BrowserContextKeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const OVERRIDE;
 
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual bool ServiceIsNULLWhileTesting() const OVERRIDE;
 
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index 592ed84..931ed9a 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -59,6 +59,7 @@
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/preferences.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/proxy_config_service_impl.h"
 #endif
 
@@ -189,7 +190,7 @@
   return std::string();
 }
 
-base::FilePath OffTheRecordProfileImpl::GetPath() {
+base::FilePath OffTheRecordProfileImpl::GetPath() const {
   return profile_->GetPath();
 }
 
@@ -279,6 +280,15 @@
       .get();
 }
 
+void OffTheRecordProfileImpl::RequestMIDISysExPermission(
+      int render_process_id,
+      int render_view_id,
+      const GURL& requesting_frame,
+      const MIDISysExPermissionCallback& callback) {
+  // TODO(toyoshim): Implement.
+  callback.Run(false);
+}
+
 net::URLRequestContextGetter*
     OffTheRecordProfileImpl::GetRequestContextForExtensions() {
   return io_data_.GetExtensionsRequestContextGetter().get();
@@ -321,11 +331,6 @@
   return ChromeGeolocationPermissionContextFactory::GetForProfile(this);
 }
 
-content::SpeechRecognitionPreferences*
-    OffTheRecordProfileImpl::GetSpeechRecognitionPreferences() {
-  return profile_->GetSpeechRecognitionPreferences();
-}
-
 quota::SpecialStoragePolicy*
     OffTheRecordProfileImpl::GetSpecialStoragePolicy() {
   return GetExtensionSpecialStoragePolicy();
@@ -393,10 +398,8 @@
 #endif  // defined(OS_CHROMEOS)
 
 PrefProxyConfigTracker* OffTheRecordProfileImpl::GetProxyConfigTracker() {
-  if (!pref_proxy_config_tracker_) {
-    pref_proxy_config_tracker_.reset(
-        ProxyServiceFactory::CreatePrefProxyConfigTracker(GetPrefs()));
-  }
+  if (!pref_proxy_config_tracker_)
+    pref_proxy_config_tracker_.reset(CreateProxyConfigTracker());
   return pref_proxy_config_tracker_.get();
 }
 
@@ -470,3 +473,15 @@
        return;
   }
 }
+
+PrefProxyConfigTracker* OffTheRecordProfileImpl::CreateProxyConfigTracker() {
+#if defined(OS_CHROMEOS)
+  if (chromeos::ProfileHelper::IsSigninProfile(this)) {
+    return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
+        g_browser_process->local_state());
+  }
+#endif  // defined(OS_CHROMEOS)
+  return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
+      GetPrefs(), g_browser_process->local_state());
+}
+
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h
index f6053e1..c43ad0a 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.h
+++ b/chrome/browser/profiles/off_the_record_profile_impl.h
@@ -83,7 +83,7 @@
   virtual GURL GetHomePage() OVERRIDE;
 
   // content::BrowserContext implementation:
-  virtual base::FilePath GetPath() OVERRIDE;
+  virtual base::FilePath GetPath() const OVERRIDE;
   virtual scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() OVERRIDE;
   virtual bool IsOffTheRecord() const OVERRIDE;
   virtual content::DownloadManagerDelegate*
@@ -98,11 +98,14 @@
       GetMediaRequestContextForStoragePartition(
           const base::FilePath& partition_path,
           bool in_memory) OVERRIDE;
+  virtual void RequestMIDISysExPermission(
+      int render_process_id,
+      int render_view_id,
+      const GURL& requesting_frame,
+      const MIDISysExPermissionCallback& callback) OVERRIDE;
   virtual content::ResourceContext* GetResourceContext() OVERRIDE;
   virtual content::GeolocationPermissionContext*
       GetGeolocationPermissionContext() OVERRIDE;
-  virtual content::SpeechRecognitionPreferences*
-      GetSpeechRecognitionPreferences() OVERRIDE;
   virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
 
  private:
@@ -114,6 +117,7 @@
 #endif  // defined(OS_ANDROID) || defined(OS_IOS)
 
   void OnZoomLevelChanged(const content::HostZoomMap::ZoomLevelChange& change);
+  PrefProxyConfigTracker* CreateProxyConfigTracker();
 
   // The real underlying profile.
   Profile* profile_;
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index 28b870a..93415c7 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -8,11 +8,12 @@
 
 #include "base/prefs/pref_service.h"
 #include "build/build_config.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/first_run/first_run.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/sync_prefs.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/notification_service.h"
@@ -57,7 +58,7 @@
 const char Profile::kProfileKey[] = "__PROFILE__";
 
 // static
-void Profile::RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+void Profile::RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kSearchSuggestEnabled,
       true,
@@ -111,6 +112,10 @@
       prefs::kDefaultApps,
       "install",
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+  registry->RegisterBooleanPref(
+      prefs::kSpeechRecognitionFilterProfanities,
+      true,
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 #if defined(OS_CHROMEOS)
   // TODO(dilmah): For OS_CHROMEOS we maintain kApplicationLocale in both
   // local state and user's profile.  For other platforms we maintain
@@ -164,7 +169,7 @@
       chromeos::switches::kGuestSession);
   return is_guest_session;
 #else
-  return false;
+  return GetPath() == ProfileManager::GetGuestProfilePath();
 #endif
 }
 
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index 3364332..19a232a 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -147,7 +147,7 @@
 
   // Profile prefs are registered as soon as the prefs are loaded for the first
   // time.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Gets task runner for I/O operations associated with |profile|.
   static scoped_refptr<base::SequencedTaskRunner> GetTaskRunnerForProfile(
@@ -325,7 +325,7 @@
   std::string GetDebugName();
 
   // Returns whether it is a guest session.
-  bool IsGuestSession() const;
+  virtual bool IsGuestSession() const;
 
   // Did the user restore the last session? This is set by SessionRestore.
   void set_restored_last_session(bool restored_last_session) {
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc
index 19a7e0d..6d128a7 100644
--- a/chrome/browser/profiles/profile_browsertest.cc
+++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -9,10 +9,10 @@
 #include "base/platform_file.h"
 #include "base/prefs/pref_service.h"
 #include "base/version.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/chrome_version_service.h"
 #include "chrome/browser/profiles/profile_impl.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -163,7 +163,7 @@
   content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
 
   // Verify that README exists.
-  EXPECT_TRUE(file_util::PathExists(
+  EXPECT_TRUE(base::PathExists(
       temp_dir.path().Append(chrome::kReadmeFilename)));
 }
 
diff --git a/chrome/browser/profiles/profile_downloader.cc b/chrome/browser/profiles/profile_downloader.cc
index 1cb0b1f..2250e06 100644
--- a/chrome/browser/profiles/profile_downloader.cc
+++ b/chrome/browser/profiles/profile_downloader.cc
@@ -14,11 +14,11 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_downloader_delegate.h"
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/signin/token_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_observer.h"
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index a16a24a..b4ef81e 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -28,6 +28,7 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/cookie_settings.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/download/chrome_download_manager_delegate.h"
@@ -67,13 +68,11 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/search_engines/template_url_fetcher.h"
 #include "chrome/browser/sessions/session_service_factory.h"
-#include "chrome/browser/speech/chrome_speech_recognition_preferences.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
 #include "chrome/browser/user_style_sheet_watcher.h"
 #include "chrome/browser/webdata/web_data_service.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths_internal.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
@@ -104,6 +103,7 @@
 #include "chrome/browser/chromeos/locale_change_guard.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/preferences.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/proxy_config_service_impl.h"
 #endif
 
@@ -202,7 +202,7 @@
 
 void EnsureReadmeFile(const base::FilePath& base) {
   base::FilePath readme_path = base.Append(chrome::kReadmeFilename);
-  if (file_util::PathExists(readme_path))
+  if (base::PathExists(readme_path))
     return;
   std::string product_name = l10n_util::GetStringUTF8(IDS_PRODUCT_NAME);
   std::string readme_text = base::StringPrintf(
@@ -253,7 +253,7 @@
     DCHECK(delegate);
     CreateProfileDirectory(sequenced_task_runner.get(), path);
   } else if (create_mode == CREATE_MODE_SYNCHRONOUS) {
-    if (!file_util::PathExists(path)) {
+    if (!base::PathExists(path)) {
       // TODO(tc): http://b/1094718 Bad things happen if we can't write to the
       // profile directory.  We should eventually be able to run in this
       // situation.
@@ -275,7 +275,7 @@
 const char* const ProfileImpl::kPrefExitTypeNormal = "Normal";
 
 // static
-void ProfileImpl::RegisterUserPrefs(
+void ProfileImpl::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kSavingBrowserHistoryDisabled,
@@ -397,7 +397,12 @@
          create_mode == CREATE_MODE_SYNCHRONOUS);
   bool async_prefs = create_mode == CREATE_MODE_ASYNCHRONOUS;
 
-  chrome::RegisterUserPrefs(pref_registry_.get());
+#if defined(OS_CHROMEOS)
+  if (chromeos::ProfileHelper::IsSigninProfile(this))
+    chrome::RegisterLoginProfilePrefs(pref_registry_.get());
+  else
+#endif
+    chrome::RegisterUserProfilePrefs(pref_registry_.get());
 
   {
     // On startup, preference loading is always synchronous so a scoped timer
@@ -658,7 +663,7 @@
   return GetPrefs()->GetString(prefs::kGoogleServicesUsername);
 }
 
-base::FilePath ProfileImpl::GetPath() {
+base::FilePath ProfileImpl::GetPath() const {
   return path_;
 }
 
@@ -857,6 +862,15 @@
       .GetIsolatedMediaRequestContextGetter(partition_path, in_memory).get();
 }
 
+void ProfileImpl::RequestMIDISysExPermission(
+      int render_process_id,
+      int render_view_id,
+      const GURL& requesting_frame,
+      const MIDISysExPermissionCallback& callback) {
+  // TODO(toyoshim): Implement.
+  callback.Run(false);
+}
+
 content::ResourceContext* ProfileImpl::GetResourceContext() {
   return io_data_.GetResourceContext();
 }
@@ -897,15 +911,6 @@
   return ChromeGeolocationPermissionContextFactory::GetForProfile(this);
 }
 
-content::SpeechRecognitionPreferences*
-ProfileImpl::GetSpeechRecognitionPreferences() {
-#if defined(ENABLE_INPUT_SPEECH)
-  return ChromeSpeechRecognitionPreferences::GetForProfile(this).get();
-#else
-  return NULL;
-#endif
-}
-
 DownloadManagerDelegate* ProfileImpl::GetDownloadManagerDelegate() {
   return DownloadServiceFactory::GetForProfile(this)->
       GetDownloadManagerDelegate();
@@ -1065,10 +1070,8 @@
 #endif  // defined(OS_CHROMEOS)
 
 PrefProxyConfigTracker* ProfileImpl::GetProxyConfigTracker() {
-  if (!pref_proxy_config_tracker_) {
-    pref_proxy_config_tracker_.reset(
-        ProxyServiceFactory::CreatePrefProxyConfigTracker(GetPrefs()));
-  }
+  if (!pref_proxy_config_tracker_)
+    pref_proxy_config_tracker_.reset(CreateProxyConfigTracker());
   return pref_proxy_config_tracker_.get();
 }
 
@@ -1157,3 +1160,15 @@
   *max_size = is_media_context ? prefs_->GetInteger(prefs::kMediaCacheSize) :
                                  prefs_->GetInteger(prefs::kDiskCacheSize);
 }
+
+PrefProxyConfigTracker* ProfileImpl::CreateProxyConfigTracker() {
+#if defined(OS_CHROMEOS)
+  if (chromeos::ProfileHelper::IsSigninProfile(this)) {
+    return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
+        g_browser_process->local_state());
+  }
+#endif  // defined(OS_CHROMEOS)
+  return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
+      GetPrefs(), g_browser_process->local_state());
+}
+
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h
index 9f24987..4fb1a51 100644
--- a/chrome/browser/profiles/profile_impl.h
+++ b/chrome/browser/profiles/profile_impl.h
@@ -37,10 +37,6 @@
 class SequencedTaskRunner;
 }
 
-namespace content {
-class SpeechRecognitionPreferences;
-}
-
 namespace extensions {
 class ExtensionSystem;
 }
@@ -62,10 +58,10 @@
 
   virtual ~ProfileImpl();
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // content::BrowserContext implementation:
-  virtual base::FilePath GetPath() OVERRIDE;
+  virtual base::FilePath GetPath() const OVERRIDE;
   virtual content::DownloadManagerDelegate*
       GetDownloadManagerDelegate() OVERRIDE;
   virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE;
@@ -78,11 +74,14 @@
       GetMediaRequestContextForStoragePartition(
           const base::FilePath& partition_path,
           bool in_memory) OVERRIDE;
+  virtual void RequestMIDISysExPermission(
+      int render_process_id,
+      int render_view_id,
+      const GURL& requesting_frame,
+      const MIDISysExPermissionCallback& callback) OVERRIDE;
   virtual content::ResourceContext* GetResourceContext() OVERRIDE;
   virtual content::GeolocationPermissionContext*
       GetGeolocationPermissionContext() OVERRIDE;
-  virtual content::SpeechRecognitionPreferences*
-      GetSpeechRecognitionPreferences() OVERRIDE;
   virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
 
   // Profile implementation:
@@ -191,6 +190,8 @@
                           base::FilePath* cache_path,
                           int* max_size);
 
+  PrefProxyConfigTracker* CreateProxyConfigTracker();
+
   content::HostZoomMap::ZoomLevelChangedCallback zoom_callback_;
   PrefChangeRegistrar pref_change_registrar_;
 
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index 29ce0eb..ee68a4d 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -15,6 +15,7 @@
 #include "base/strings/string_util.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "base/threading/worker_pool.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
 #include "chrome/browser/io_thread.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/net/sqlite_server_bound_cert_store.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc
index 92398d8..dfbc6e1 100644
--- a/chrome/browser/profiles/profile_info_cache.cc
+++ b/chrome/browser/profiles/profile_info_cache.cc
@@ -20,8 +20,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
@@ -122,7 +122,7 @@
 
   // Make sure the destination directory exists.
   base::FilePath dir = image_path.DirName();
-  if (!file_util::DirectoryExists(dir) && !file_util::CreateDirectory(dir)) {
+  if (!base::DirectoryExists(dir) && !file_util::CreateDirectory(dir)) {
     LOG(ERROR) << "Failed to create parent directory.";
     return;
   }
@@ -165,7 +165,7 @@
 
 void DeleteBitmap(const base::FilePath& image_path) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-  base::Delete(image_path, false);
+  base::DeleteFile(image_path, false);
 }
 
 }  // namespace
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc
index 3c2fcaa..2dc49ea 100644
--- a/chrome/browser/profiles/profile_info_cache_unittest.cc
+++ b/chrome/browser/profiles/profile_info_cache_unittest.cc
@@ -8,9 +8,9 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index bca79c5..8335fa5 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -19,6 +19,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/cookie_settings.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
@@ -48,7 +49,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/signin_names_io_thread.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 7be5e41..d0079b7 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
@@ -36,7 +37,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/sync/sync_promo_ui.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths_internal.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/logging_chrome.h"
@@ -202,8 +202,8 @@
     // Delete both the profile directory and its corresponding cache.
     base::FilePath cache_path;
     chrome::GetUserCacheDirectory(*it, &cache_path);
-    base::Delete(*it, true);
-    base::Delete(cache_path, true);
+    base::DeleteFile(*it, true);
+    base::DeleteFile(cache_path, true);
   }
   ProfilesToDelete().clear();
 }
@@ -929,6 +929,16 @@
 }
 
 // static
+base::FilePath ProfileManager::GetGuestProfilePath() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+
+  base::FilePath guest_path = profile_manager->user_data_dir();
+  return guest_path.Append(chrome::kGuestProfileDir);
+}
+
+// static
 void ProfileManager::RegisterPrefs(PrefRegistrySimple* registry) {
   registry->RegisterStringPref(prefs::kProfileLastUsed, std::string());
   registry->RegisterIntegerPref(prefs::kProfilesNumCreated, 1);
@@ -965,6 +975,8 @@
 }
 
 void ProfileManager::AddProfileToCache(Profile* profile) {
+  if (profile->IsGuestSession())
+    return;
   ProfileInfoCache& cache = GetProfileInfoCache();
   if (profile->GetPath().DirName() != cache.GetUserDataDir())
     return;
@@ -998,25 +1010,30 @@
   if (profile->GetPath().DirName() != cache.GetUserDataDir())
     return;
 
+  bool is_managed = false;
   size_t avatar_index;
   std::string profile_name;
-  bool is_managed = false;
-  size_t profile_cache_index =
-      cache.GetIndexOfProfileWithPath(profile->GetPath());
-  // If the cache has an entry for this profile, use the cache data.
-  if (profile_cache_index != std::string::npos) {
-    avatar_index =
-        cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index);
-    profile_name =
-        UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index));
-    is_managed = cache.ProfileIsManagedAtIndex(profile_cache_index);
-  } else if (profile->GetPath() ==
-             GetDefaultProfileDir(cache.GetUserDataDir())) {
+  if (profile->IsGuestSession()) {
+    profile_name = l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME);
     avatar_index = 0;
-    profile_name = l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME);
   } else {
-    avatar_index = cache.ChooseAvatarIconIndexForNewProfile();
-    profile_name = UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index));
+    size_t profile_cache_index =
+        cache.GetIndexOfProfileWithPath(profile->GetPath());
+    // If the cache has an entry for this profile, use the cache data.
+    if (profile_cache_index != std::string::npos) {
+      avatar_index =
+          cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index);
+      profile_name =
+          UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index));
+      is_managed = cache.ProfileIsManagedAtIndex(profile_cache_index);
+    } else if (profile->GetPath() ==
+               GetDefaultProfileDir(cache.GetUserDataDir())) {
+      avatar_index = 0;
+      profile_name = l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME);
+    } else {
+      avatar_index = cache.ChooseAvatarIconIndexForNewProfile();
+      profile_name = UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index));
+    }
   }
 
   if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex))
@@ -1164,6 +1181,12 @@
   return true;
 }
 
+// static
+bool ProfileManager::IsNewProfileManagementEnabled() {
+  return CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kNewProfileManagement);
+}
+
 void ProfileManager::AutoloadProfiles() {
   // If running in the background is disabled for the browser, do not autoload
   // any profiles.
diff --git a/chrome/browser/profiles/profile_manager.h b/chrome/browser/profiles/profile_manager.h
index 1b2ba42..c26bd56 100644
--- a/chrome/browser/profiles/profile_manager.h
+++ b/chrome/browser/profiles/profile_manager.h
@@ -202,6 +202,9 @@
       const CreateCallback& callback,
       bool is_managed);
 
+  // Returns the full path to be used for guest profiles.
+  static base::FilePath GetGuestProfilePath();
+
   // Register multi-profile related preferences in Local State.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
@@ -222,6 +225,9 @@
   // Checks if multiple profiles is enabled.
   static bool IsMultipleProfilesEnabled();
 
+  // Checks if new profile management is enabled.
+  static bool IsNewProfileManagementEnabled();
+
   // Autoloads profiles if they are running background apps.
   void AutoloadProfiles();
 
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index dd46660..86f9f57 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -14,6 +14,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -66,7 +66,7 @@
  protected:
   virtual Profile* CreateProfileHelper(
       const base::FilePath& file_path) OVERRIDE {
-    if (!file_util::PathExists(file_path)) {
+    if (!base::PathExists(file_path)) {
       if (!file_util::CreateDirectory(file_path))
         return NULL;
     }
@@ -302,6 +302,13 @@
   message_loop_.RunUntilIdle();
 }
 
+TEST_F(ProfileManagerTest, GetGuestProfilePath) {
+  base::FilePath guest_path = ProfileManager::GetGuestProfilePath();
+  base::FilePath expected_path = temp_dir_.path();
+  expected_path = expected_path.Append(chrome::kGuestProfileDir);
+  EXPECT_EQ(expected_path, guest_path);
+}
+
 TEST_F(ProfileManagerTest, AutoloadProfilesWithBackgroundApps) {
   ProfileManager* profile_manager = g_browser_process->profile_manager();
   ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
diff --git a/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc b/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
index e4eb340..0f48dac 100644
--- a/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
+++ b/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
@@ -73,7 +73,7 @@
       ASSERT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_name));
       const base::FilePath icon_path =
           profile_path.AppendASCII(profiles::internal::kProfileIconFileName);
-      ASSERT_FALSE(file_util::PathExists(icon_path));
+      ASSERT_FALSE(base::PathExists(icon_path));
     }
   }
 
@@ -121,7 +121,7 @@
 
   // Returns true if the shortcut for this profile exists.
   bool ProfileShortcutExistsAtDefaultPath(const string16& profile_name) {
-    return file_util::PathExists(
+    return base::PathExists(
         GetDefaultShortcutPathForProfile(profile_name));
   }
 
@@ -130,12 +130,12 @@
   void ValidateProfileShortcutAtPath(const tracked_objects::Location& location,
                                      const base::FilePath& shortcut_path,
                                      const base::FilePath& profile_path) {
-    EXPECT_TRUE(file_util::PathExists(shortcut_path)) << location.ToString();
+    EXPECT_TRUE(base::PathExists(shortcut_path)) << location.ToString();
 
     // Ensure that the corresponding icon exists.
     const base::FilePath icon_path =
         profile_path.AppendASCII(profiles::internal::kProfileIconFileName);
-    EXPECT_TRUE(file_util::PathExists(icon_path)) << location.ToString();
+    EXPECT_TRUE(base::PathExists(icon_path)) << location.ToString();
 
     base::win::ShortcutProperties expected_properties;
     expected_properties.set_app_id(
@@ -161,7 +161,7 @@
   void ValidateNonProfileShortcutAtPath(
       const tracked_objects::Location& location,
       const base::FilePath& shortcut_path) {
-    EXPECT_TRUE(file_util::PathExists(shortcut_path)) << location.ToString();
+    EXPECT_TRUE(base::PathExists(shortcut_path)) << location.ToString();
 
     base::win::ShortcutProperties expected_properties;
     expected_properties.set_target(GetExePath());
@@ -197,7 +197,7 @@
       const string16& shortcut_name) {
     const base::FilePath shortcut_path =
         GetUserShortcutsDirectory().Append(shortcut_name + installer::kLnkExt);
-    EXPECT_FALSE(file_util::PathExists(shortcut_path)) << location.ToString();
+    EXPECT_FALSE(base::PathExists(shortcut_path)) << location.ToString();
 
     installer::Product product(GetDistribution());
     ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER);
@@ -206,7 +206,7 @@
     EXPECT_TRUE(ShellUtil::CreateOrUpdateShortcut(
         ShellUtil::SHORTCUT_LOCATION_DESKTOP, GetDistribution(), properties,
         ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)) << location.ToString();
-    EXPECT_TRUE(file_util::PathExists(shortcut_path)) << location.ToString();
+    EXPECT_TRUE(base::PathExists(shortcut_path)) << location.ToString();
 
     return shortcut_path;
   }
@@ -223,7 +223,7 @@
     const base::FilePath system_level_shortcut_path =
         GetSystemShortcutsDirectory().Append(
             distribution->GetAppShortCutName() + installer::kLnkExt);
-    EXPECT_TRUE(file_util::PathExists(system_level_shortcut_path))
+    EXPECT_TRUE(base::PathExists(system_level_shortcut_path))
         << location.ToString();
     return system_level_shortcut_path;
   }
@@ -391,9 +391,9 @@
       GetDefaultShortcutPathForProfile(profile_2_name_);
 
   // Delete the shortcut for the first profile, but keep the one for the 2nd.
-  ASSERT_TRUE(base::Delete(profile_1_shortcut_path, false));
-  ASSERT_FALSE(file_util::PathExists(profile_1_shortcut_path));
-  ASSERT_TRUE(file_util::PathExists(profile_2_shortcut_path));
+  ASSERT_TRUE(base::DeleteFile(profile_1_shortcut_path, false));
+  ASSERT_FALSE(base::PathExists(profile_1_shortcut_path));
+  ASSERT_TRUE(base::PathExists(profile_2_shortcut_path));
 
   // Delete the profile that doesn't have a shortcut.
   profile_info_cache_->DeleteProfileFromCache(profile_1_path_);
@@ -402,8 +402,8 @@
   // Verify that the remaining shortcut does not have a profile name.
   ValidateNonProfileShortcut(FROM_HERE);
   // Verify that shortcuts with profile names do not exist.
-  EXPECT_FALSE(file_util::PathExists(profile_1_shortcut_path));
-  EXPECT_FALSE(file_util::PathExists(profile_2_shortcut_path));
+  EXPECT_FALSE(base::PathExists(profile_1_shortcut_path));
+  EXPECT_FALSE(base::PathExists(profile_2_shortcut_path));
 }
 
 TEST_F(ProfileShortcutManagerTest, DeleteSecondToLastProfileWithShortcut) {
@@ -415,9 +415,9 @@
       GetDefaultShortcutPathForProfile(profile_2_name_);
 
   // Delete the shortcut for the first profile, but keep the one for the 2nd.
-  ASSERT_TRUE(base::Delete(profile_1_shortcut_path, false));
-  ASSERT_FALSE(file_util::PathExists(profile_1_shortcut_path));
-  ASSERT_TRUE(file_util::PathExists(profile_2_shortcut_path));
+  ASSERT_TRUE(base::DeleteFile(profile_1_shortcut_path, false));
+  ASSERT_FALSE(base::PathExists(profile_1_shortcut_path));
+  ASSERT_TRUE(base::PathExists(profile_2_shortcut_path));
 
   // Delete the profile that has a shortcut.
   profile_info_cache_->DeleteProfileFromCache(profile_2_path_);
@@ -426,8 +426,8 @@
   // Verify that the remaining shortcut does not have a profile name.
   ValidateNonProfileShortcut(FROM_HERE);
   // Verify that shortcuts with profile names do not exist.
-  EXPECT_FALSE(file_util::PathExists(profile_1_shortcut_path));
-  EXPECT_FALSE(file_util::PathExists(profile_2_shortcut_path));
+  EXPECT_FALSE(base::PathExists(profile_1_shortcut_path));
+  EXPECT_FALSE(base::PathExists(profile_2_shortcut_path));
 }
 
 TEST_F(ProfileShortcutManagerTest, DeleteOnlyProfileWithShortcuts) {
@@ -444,23 +444,23 @@
       GetDefaultShortcutPathForProfile(profile_3_name_);
 
   // Delete shortcuts for the first two profiles.
-  ASSERT_TRUE(base::Delete(profile_1_shortcut_path, false));
-  ASSERT_TRUE(base::Delete(profile_2_shortcut_path, false));
+  ASSERT_TRUE(base::DeleteFile(profile_1_shortcut_path, false));
+  ASSERT_TRUE(base::DeleteFile(profile_2_shortcut_path, false));
 
   // Only the shortcut to the third profile should exist.
-  ASSERT_FALSE(file_util::PathExists(profile_1_shortcut_path));
-  ASSERT_FALSE(file_util::PathExists(profile_2_shortcut_path));
-  ASSERT_FALSE(file_util::PathExists(non_profile_shortcut_path));
-  ASSERT_TRUE(file_util::PathExists(profile_3_shortcut_path));
+  ASSERT_FALSE(base::PathExists(profile_1_shortcut_path));
+  ASSERT_FALSE(base::PathExists(profile_2_shortcut_path));
+  ASSERT_FALSE(base::PathExists(non_profile_shortcut_path));
+  ASSERT_TRUE(base::PathExists(profile_3_shortcut_path));
 
   // Delete the third profile and check that its shortcut is gone and no
   // shortcuts have been re-created.
   profile_info_cache_->DeleteProfileFromCache(profile_3_path_);
   RunPendingTasks();
-  ASSERT_FALSE(file_util::PathExists(profile_1_shortcut_path));
-  ASSERT_FALSE(file_util::PathExists(profile_2_shortcut_path));
-  ASSERT_FALSE(file_util::PathExists(profile_3_shortcut_path));
-  ASSERT_FALSE(file_util::PathExists(non_profile_shortcut_path));
+  ASSERT_FALSE(base::PathExists(profile_1_shortcut_path));
+  ASSERT_FALSE(base::PathExists(profile_2_shortcut_path));
+  ASSERT_FALSE(base::PathExists(profile_3_shortcut_path));
+  ASSERT_FALSE(base::PathExists(non_profile_shortcut_path));
 }
 
 TEST_F(ProfileShortcutManagerTest, DesktopShortcutsCreateSecond) {
@@ -503,8 +503,8 @@
                                 profile_2_path_);
 
   // Delete the renamed shortcut and try to create it again, which should work.
-  ASSERT_TRUE(base::Delete(profile_2_shortcut_path_2, false));
-  EXPECT_FALSE(file_util::PathExists(profile_2_shortcut_path_2));
+  ASSERT_TRUE(base::DeleteFile(profile_2_shortcut_path_2, false));
+  EXPECT_FALSE(base::PathExists(profile_2_shortcut_path_2));
   profile_shortcut_manager_->CreateProfileShortcut(profile_2_path_);
   RunPendingTasks();
   ValidateProfileShortcut(FROM_HERE, profile_2_name_, profile_2_path_);
@@ -518,7 +518,7 @@
   const base::FilePath profile_2_shortcut_path_2 =
       GetUserShortcutsDirectory().Append(L"MyChrome.lnk");
   // Make a copy of the shortcut.
-  ASSERT_TRUE(file_util::CopyFile(profile_2_shortcut_path_1,
+  ASSERT_TRUE(base::CopyFile(profile_2_shortcut_path_1,
                                   profile_2_shortcut_path_2));
   ValidateProfileShortcutAtPath(FROM_HERE, profile_2_shortcut_path_1,
                                 profile_2_path_);
@@ -528,16 +528,16 @@
   // Also, copy the shortcut for the first user and ensure it gets preserved.
   const base::FilePath preserved_profile_1_shortcut_path =
       GetUserShortcutsDirectory().Append(L"Preserved.lnk");
-  ASSERT_TRUE(file_util::CopyFile(
+  ASSERT_TRUE(base::CopyFile(
       GetDefaultShortcutPathForProfile(profile_1_name_),
       preserved_profile_1_shortcut_path));
-  EXPECT_TRUE(file_util::PathExists(preserved_profile_1_shortcut_path));
+  EXPECT_TRUE(base::PathExists(preserved_profile_1_shortcut_path));
 
   // Delete the profile and ensure both shortcuts were also deleted.
   profile_info_cache_->DeleteProfileFromCache(profile_2_path_);
   RunPendingTasks();
-  EXPECT_FALSE(file_util::PathExists(profile_2_shortcut_path_1));
-  EXPECT_FALSE(file_util::PathExists(profile_2_shortcut_path_2));
+  EXPECT_FALSE(base::PathExists(profile_2_shortcut_path_1));
+  EXPECT_FALSE(base::PathExists(profile_2_shortcut_path_2));
   ValidateNonProfileShortcutAtPath(FROM_HERE,
                                    preserved_profile_1_shortcut_path);
 }
@@ -550,7 +550,7 @@
   const base::FilePath profile_2_shortcut_path_2 =
       GetUserShortcutsDirectory().Append(L"MyChrome.lnk");
   // Make a copy of the shortcut.
-  ASSERT_TRUE(file_util::CopyFile(profile_2_shortcut_path_1,
+  ASSERT_TRUE(base::CopyFile(profile_2_shortcut_path_1,
                                   profile_2_shortcut_path_2));
   ValidateProfileShortcutAtPath(FROM_HERE, profile_2_shortcut_path_1,
                                 profile_2_path_);
@@ -563,7 +563,7 @@
 
   // The original shortcut should be renamed but the copied shortcut should
   // keep its name.
-  EXPECT_FALSE(file_util::PathExists(profile_2_shortcut_path_1));
+  EXPECT_FALSE(base::PathExists(profile_2_shortcut_path_1));
   ValidateProfileShortcutAtPath(FROM_HERE, profile_2_shortcut_path_2,
                                 profile_2_path_);
   ValidateProfileShortcut(FROM_HERE, new_profile_2_name, profile_2_path_);
@@ -574,7 +574,7 @@
 
   // Delete the shortcut that got created for this profile and instead make
   // a new one without any command-line flags.
-  ASSERT_TRUE(base::Delete(GetDefaultShortcutPathForProfile(string16()),
+  ASSERT_TRUE(base::DeleteFile(GetDefaultShortcutPathForProfile(string16()),
                                 false));
   const base::FilePath regular_shortcut_path =
       CreateRegularShortcutWithName(FROM_HERE,
@@ -583,7 +583,7 @@
   // Add another profile and check that the shortcut was replaced with
   // a badged shortcut with the right command line for the profile
   CreateProfileWithShortcut(FROM_HERE, profile_2_name_, profile_2_path_);
-  EXPECT_FALSE(file_util::PathExists(regular_shortcut_path));
+  EXPECT_FALSE(base::PathExists(regular_shortcut_path));
   ValidateProfileShortcut(FROM_HERE, profile_1_name_, profile_1_path_);
 }
 
@@ -592,7 +592,7 @@
 
   // Delete the shortcut that got created for this profile and instead make
   // two new ones without any command-line flags.
-  ASSERT_TRUE(base::Delete(GetDefaultShortcutPathForProfile(string16()),
+  ASSERT_TRUE(base::DeleteFile(GetDefaultShortcutPathForProfile(string16()),
                                 false));
   const base::FilePath regular_shortcut_path =
       CreateRegularShortcutWithName(FROM_HERE,
@@ -603,7 +603,7 @@
   // Add another profile and check that one shortcut was renamed and that the
   // other shortcut was updated but kept the same name.
   CreateProfileWithShortcut(FROM_HERE, profile_2_name_, profile_2_path_);
-  EXPECT_FALSE(file_util::PathExists(regular_shortcut_path));
+  EXPECT_FALSE(base::PathExists(regular_shortcut_path));
   ValidateProfileShortcutAtPath(FROM_HERE, customized_regular_shortcut_path,
                                 profile_1_path_);
   ValidateProfileShortcut(FROM_HERE, profile_1_name_, profile_1_path_);
@@ -623,9 +623,9 @@
       GetUserShortcutsDirectory().Append(L"Copied1.lnk");
   const base::FilePath profile_2_shortcut_path_2 =
       GetUserShortcutsDirectory().Append(L"Copied2.lnk");
-  ASSERT_TRUE(file_util::CopyFile(profile_1_shortcut_path_1,
+  ASSERT_TRUE(base::CopyFile(profile_1_shortcut_path_1,
                                   profile_1_shortcut_path_2));
-  ASSERT_TRUE(file_util::CopyFile(profile_2_shortcut_path_1,
+  ASSERT_TRUE(base::CopyFile(profile_2_shortcut_path_1,
                                   profile_2_shortcut_path_2));
   ValidateProfileShortcutAtPath(FROM_HERE, profile_1_shortcut_path_2,
                                 profile_1_path_);
@@ -636,8 +636,8 @@
   // shortcuts for profile 2 were kept.
   profile_shortcut_manager_->RemoveProfileShortcuts(profile_1_path_);
   RunPendingTasks();
-  EXPECT_FALSE(file_util::PathExists(profile_1_shortcut_path_1));
-  EXPECT_FALSE(file_util::PathExists(profile_1_shortcut_path_2));
+  EXPECT_FALSE(base::PathExists(profile_1_shortcut_path_1));
+  EXPECT_FALSE(base::PathExists(profile_1_shortcut_path_2));
   ValidateProfileShortcutAtPath(FROM_HERE, profile_2_shortcut_path_1,
                                 profile_2_path_);
   ValidateProfileShortcutAtPath(FROM_HERE, profile_2_shortcut_path_2,
@@ -664,8 +664,8 @@
   // Delete the shortcut and check that the function returns false.
   const base::FilePath profile_2_shortcut_path =
       GetDefaultShortcutPathForProfile(profile_2_name_);
-  ASSERT_TRUE(base::Delete(profile_2_shortcut_path, false));
-  EXPECT_FALSE(file_util::PathExists(profile_2_shortcut_path));
+  ASSERT_TRUE(base::DeleteFile(profile_2_shortcut_path, false));
+  EXPECT_FALSE(base::PathExists(profile_2_shortcut_path));
   profile_shortcut_manager_->HasProfileShortcuts(profile_2_path_, callback);
   RunPendingTasks();
   EXPECT_FALSE(result.has_shortcuts);
@@ -682,8 +682,8 @@
   ASSERT_EQ(1U, profile_info_cache_->GetNumberOfProfiles());
 
   // Ensure system-level continues to exist and user-level was not created.
-  EXPECT_TRUE(file_util::PathExists(system_level_shortcut_path));
-  EXPECT_FALSE(file_util::PathExists(
+  EXPECT_TRUE(base::PathExists(system_level_shortcut_path));
+  EXPECT_FALSE(base::PathExists(
                    GetDefaultShortcutPathForProfile(string16())));
 
   // Create another profile with a shortcut and ensure both profiles receive
@@ -691,7 +691,7 @@
   CreateProfileWithShortcut(FROM_HERE, profile_2_name_, profile_2_path_);
   ValidateProfileShortcut(FROM_HERE, profile_1_name_, profile_1_path_);
   ValidateProfileShortcut(FROM_HERE, profile_2_name_, profile_2_path_);
-  EXPECT_TRUE(file_util::PathExists(system_level_shortcut_path));
+  EXPECT_TRUE(base::PathExists(system_level_shortcut_path));
 
   // Create a third profile without a shortcut and ensure it doesn't get one.
   profile_info_cache_->AddProfileToCache(profile_3_path_, profile_3_name_,
@@ -736,7 +736,7 @@
   profile_info_cache_->DeleteProfileFromCache(profile_1_path_);
   RunPendingTasks();
 
-  EXPECT_TRUE(file_util::PathExists(system_level_shortcut_path));
+  EXPECT_TRUE(base::PathExists(system_level_shortcut_path));
   EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(string16()));
   EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_1_name_));
   EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_2_name_));
@@ -752,9 +752,9 @@
       GetDefaultShortcutPathForProfile(profile_2_name_);
 
   // Delete the shortcut for the first profile, but keep the one for the 2nd.
-  ASSERT_TRUE(base::Delete(profile_1_shortcut_path, false));
-  ASSERT_FALSE(file_util::PathExists(profile_1_shortcut_path));
-  ASSERT_TRUE(file_util::PathExists(profile_2_shortcut_path));
+  ASSERT_TRUE(base::DeleteFile(profile_1_shortcut_path, false));
+  ASSERT_FALSE(base::PathExists(profile_1_shortcut_path));
+  ASSERT_TRUE(base::PathExists(profile_2_shortcut_path));
 
   const base::FilePath system_level_shortcut_path =
       CreateRegularSystemLevelShortcut(FROM_HERE);
@@ -766,9 +766,9 @@
   RunPendingTasks();
 
   // Verify that only the system-level shortcut still exists.
-  EXPECT_TRUE(file_util::PathExists(system_level_shortcut_path));
-  EXPECT_FALSE(file_util::PathExists(
+  EXPECT_TRUE(base::PathExists(system_level_shortcut_path));
+  EXPECT_FALSE(base::PathExists(
                    GetDefaultShortcutPathForProfile(string16())));
-  EXPECT_FALSE(file_util::PathExists(profile_1_shortcut_path));
-  EXPECT_FALSE(file_util::PathExists(profile_2_shortcut_path));
+  EXPECT_FALSE(base::PathExists(profile_1_shortcut_path));
+  EXPECT_FALSE(base::PathExists(profile_2_shortcut_path));
 }
diff --git a/chrome/browser/profiles/profile_shortcut_manager_win.cc b/chrome/browser/profiles/profile_shortcut_manager_win.cc
index 239a54e..cc8c250 100644
--- a/chrome/browser/profiles/profile_shortcut_manager_win.cc
+++ b/chrome/browser/profiles/profile_shortcut_manager_win.cc
@@ -286,13 +286,13 @@
   const base::FilePath new_shortcut_path =
       user_shortcuts_directory.Append(new_shortcut_filename);
 
-  if (file_util::PathExists(old_shortcut_path)) {
+  if (base::PathExists(old_shortcut_path)) {
     // Rename the old shortcut unless a system-level shortcut exists at the
     // destination, in which case the old shortcut is simply deleted.
     const base::FilePath possible_new_system_shortcut =
         system_shortcuts_directory.Append(new_shortcut_filename);
-    if (file_util::PathExists(possible_new_system_shortcut))
-      base::Delete(old_shortcut_path, false);
+    if (base::PathExists(possible_new_system_shortcut))
+      base::DeleteFile(old_shortcut_path, false);
     else if (!RenameDesktopShortcut(old_shortcut_path, new_shortcut_path))
       DLOG(ERROR) << "Could not rename Windows profile desktop shortcut.";
   } else {
@@ -304,8 +304,8 @@
     // properties updated by |CreateOrUpdateDesktopShortcutsForProfile()|.
     const base::FilePath possible_old_system_shortcut =
         system_shortcuts_directory.Append(old_shortcut_filename);
-    if (file_util::PathExists(possible_old_system_shortcut))
-      file_util::CopyFile(possible_old_system_shortcut, new_shortcut_path);
+    if (base::PathExists(possible_old_system_shortcut))
+      base::CopyFile(possible_old_system_shortcut, new_shortcut_path);
   }
 }
 
@@ -437,9 +437,9 @@
 
   BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
   for (size_t i = 0; i < shortcuts.size(); ++i) {
-    // Use base::Delete() instead of ShellUtil::RemoveShortcut(), as the
+    // Use base::DeleteFile() instead of ShellUtil::RemoveShortcut(), as the
     // latter causes non-profile taskbar shortcuts to be unpinned.
-    base::Delete(shortcuts[i], false);
+    base::DeleteFile(shortcuts[i], false);
     // Notify the shell that the shortcut was deleted to ensure desktop refresh.
     SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, shortcuts[i].value().c_str(),
                    NULL);
@@ -447,7 +447,7 @@
 
   const base::FilePath icon_path =
       profile_path.AppendASCII(profiles::internal::kProfileIconFileName);
-  base::Delete(icon_path, false);
+  base::DeleteFile(icon_path, false);
 
   // If |ensure_shortcuts_remain| is true and deleting this profile caused the
   // last shortcuts to be removed, re-create a regular non-profile shortcut.
diff --git a/chrome/browser/referrer_policy_browsertest.cc b/chrome/browser/referrer_policy_browsertest.cc
index c682dec..bf6fbb4 100644
--- a/chrome/browser/referrer_policy_browsertest.cc
+++ b/chrome/browser/referrer_policy_browsertest.cc
@@ -6,12 +6,12 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/tab_contents/render_view_context_menu.h"
 #include "chrome/browser/tab_contents/render_view_context_menu_browsertest_util.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc
index 5ab3fe8..4829231 100644
--- a/chrome/browser/renderer_host/chrome_render_message_filter.cc
+++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc
@@ -4,12 +4,13 @@
 
 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
 
+#include <string>
+
 #include "base/bind.h"
-#include "base/command_line.h"
-#include "base/file_util.h"
+#include "base/bind_helpers.h"
 #include "base/metrics/histogram.h"
 #include "chrome/browser/automation/automation_resource_message_filter.h"
-#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/cookie_settings.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/extensions/activity_log/activity_log.h"
@@ -17,34 +18,20 @@
 #include "chrome/browser/extensions/activity_log/dom_actions.h"
 #include "chrome/browser/extensions/api/messaging/message_service.h"
 #include "chrome/browser/extensions/event_router.h"
-#include "chrome/browser/extensions/extension_function_dispatcher.h"
-#include "chrome/browser/extensions/extension_info_map.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
-#include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/nacl_host/nacl_file_host.h"
-#include "chrome/browser/nacl_host/nacl_infobar.h"
-#include "chrome/browser/nacl_host/nacl_process_host.h"
 #include "chrome/browser/net/chrome_url_request_context.h"
 #include "chrome/browser/net/predictor.h"
-#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/task_manager/task_manager.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/api/i18n/default_locale_handler.h"
-#include "chrome/common/extensions/dom_action_types.h"
-#include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_file_util.h"
 #include "chrome/common/extensions/extension_messages.h"
 #include "chrome/common/extensions/message_bundle.h"
 #include "chrome/common/render_messages.h"
-#include "chrome/common/url_constants.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/resource_dispatcher_host.h"
-#include "content/public/common/process_type.h"
 #include "extensions/common/constants.h"
-#include "url/gurl.h"
 
 #if defined(USE_TCMALLOC)
 #include "chrome/browser/browser_about_handler.h"
@@ -71,29 +58,18 @@
   // The ActivityLog can only be accessed from the main (UI) thread.  If we're
   // running on the wrong thread, re-dispatch from the main thread.
   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    BrowserThread::PostTask(BrowserThread::UI,
-                            FROM_HERE,
-                            base::Bind(&AddAPIActionToExtensionActivityLog,
-                                       profile,
-                                       call_type,
-                                       extension_id,
-                                       api_call,
-                                       base::Passed(&args),
-                                       extra));
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::Bind(&AddAPIActionToExtensionActivityLog, profile, call_type,
+                   extension_id, api_call, base::Passed(&args), extra));
   } else {
     extensions::ActivityLog* activity_log =
         extensions::ActivityLog::GetInstance(profile);
     if (activity_log->IsLogEnabled()) {
       if (call_type == ACTIVITYAPI)
-        activity_log->LogAPIAction(extension_id,
-                                   api_call,
-                                   args.get(),
-                                   extra);
+        activity_log->LogAPIAction(extension_id, api_call, args.get(), extra);
       else if (call_type == ACTIVITYEVENT)
-        activity_log->LogEventAction(extension_id,
-                                     api_call,
-                                     args.get(),
-                                     extra);
+        activity_log->LogEventAction(extension_id, api_call, args.get(), extra);
     }
   }
 }
@@ -103,22 +79,18 @@
     const std::string& extension_id,
     const std::string& api_call) {
   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    BrowserThread::PostTask(BrowserThread::UI,
-                            FROM_HERE,
-                            base::Bind(&AddBlockedActionToExtensionActivityLog,
-                                       profile,
-                                       extension_id,
-                                       api_call));
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::Bind(&AddBlockedActionToExtensionActivityLog, profile,
+                   extension_id, api_call));
   } else {
     extensions::ActivityLog* activity_log =
         extensions::ActivityLog::GetInstance(profile);
     if (activity_log->IsLogEnabled()) {
       scoped_ptr<ListValue> empty_args(new ListValue());
-      activity_log->LogBlockedAction(extension_id,
-                                     api_call,
-                                     empty_args.get(),
+      activity_log->LogBlockedAction(extension_id, api_call, empty_args.get(),
                                      extensions::BlockedAction::ACCESS_DENIED,
-                                     "");
+                                     std::string());
     }
   }
 }
@@ -134,23 +106,18 @@
   // The ActivityLog can only be accessed from the main (UI) thread.  If we're
   // running on the wrong thread, re-dispatch from the main thread.
   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    BrowserThread::PostTask(BrowserThread::UI,
-                            FROM_HERE,
-                            base::Bind(&AddDOMActionToExtensionActivityLog,
-                                       profile,
-                                       extension_id,
-                                       url,
-                                       url_title,
-                                       api_call,
-                                       base::Passed(&args),
-                                       call_type));
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::Bind(&AddDOMActionToExtensionActivityLog, profile, extension_id,
+                   url, url_title, api_call, base::Passed(&args), call_type));
   } else {
     extensions::ActivityLog* activity_log =
         extensions::ActivityLog::GetInstance(profile);
     if (activity_log->IsLogEnabled())
       activity_log->LogDOMAction(
           extension_id, url, url_title, api_call, args.get(),
-          static_cast<extensions::DomActionType::Type>(call_type), "");
+          static_cast<extensions::DomActionType::Type>(call_type),
+          std::string());
   }
 }
 
@@ -302,8 +269,8 @@
 
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 #if defined(ENABLE_TASK_MANAGER)
-  TaskManager::GetInstance()->model()->NotifyResourceTypeStats(
-      base::GetProcId(peer_handle()), stats);
+  TaskManager::GetInstance()->model()->NotifyResourceTypeStats(peer_pid(),
+                                                               stats);
 #endif  // defined(ENABLE_TASK_MANAGER)
 }
 
@@ -322,7 +289,7 @@
     return;
   }
 
-  base::ProcessId renderer_id = base::GetProcId(peer_handle());
+  base::ProcessId renderer_id = peer_pid();
 
 #if defined(ENABLE_TASK_MANAGER)
   TaskManager::GetInstance()->model()->NotifyFPS(
@@ -341,13 +308,12 @@
   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
     BrowserThread::PostTask(
         BrowserThread::UI, FROM_HERE,
-        base::Bind(
-            &ChromeRenderMessageFilter::OnV8HeapStats, this,
-            v8_memory_allocated, v8_memory_used));
+        base::Bind(&ChromeRenderMessageFilter::OnV8HeapStats, this,
+                   v8_memory_allocated, v8_memory_used));
     return;
   }
 
-  base::ProcessId renderer_id = base::GetProcId(peer_handle());
+  base::ProcessId renderer_id = peer_pid();
 
 #if defined(ENABLE_TASK_MANAGER)
   TaskManager::GetInstance()->model()->NotifyV8HeapStats(
@@ -372,9 +338,9 @@
 
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::Bind(
-          &ChromeRenderMessageFilter::OpenChannelToExtensionOnUIThread, this,
-          render_process_id_, routing_id, port2_id, info, channel_name));
+      base::Bind(&ChromeRenderMessageFilter::OpenChannelToExtensionOnUIThread,
+                 this, render_process_id_, routing_id, port2_id, info,
+                 channel_name));
 }
 
 void ChromeRenderMessageFilter::OpenChannelToExtensionOnUIThread(
@@ -466,12 +432,10 @@
 
   scoped_ptr<extensions::MessageBundle::SubstitutionMap> dictionary_map(
       extension_file_util::LoadMessageBundleSubstitutionMap(
-          extension_path,
-          extension_id,
-          default_locale));
+          extension_path, extension_id, default_locale));
 
-  ExtensionHostMsg_GetMessageBundle::WriteReplyParams(
-      reply_msg, *dictionary_map);
+  ExtensionHostMsg_GetMessageBundle::WriteReplyParams(reply_msg,
+                                                      *dictionary_map);
   Send(reply_msg);
 }
 
@@ -480,12 +444,11 @@
     const std::string& event_name) {
   content::RenderProcessHost* process =
       content::RenderProcessHost::FromID(render_process_id_);
-  if (!process ||
-      !extensions::ExtensionSystem::Get(profile_)->event_router())
+  if (!process || !extensions::ExtensionSystem::Get(profile_)->event_router())
     return;
 
-  extensions::ExtensionSystem::Get(profile_)->event_router()->
-      AddEventListener(event_name, process, extension_id);
+  extensions::ExtensionSystem::Get(profile_)->event_router()->AddEventListener(
+      event_name, process, extension_id);
 }
 
 void ChromeRenderMessageFilter::OnExtensionRemoveListener(
@@ -493,8 +456,7 @@
     const std::string& event_name) {
   content::RenderProcessHost* process =
       content::RenderProcessHost::FromID(render_process_id_);
-  if (!process ||
-      !extensions::ExtensionSystem::Get(profile_)->event_router())
+  if (!process || !extensions::ExtensionSystem::Get(profile_)->event_router())
     return;
 
   extensions::ExtensionSystem::Get(profile_)->event_router()->
@@ -524,8 +486,7 @@
     bool lazy) {
   content::RenderProcessHost* process =
       content::RenderProcessHost::FromID(render_process_id_);
-  if (!process ||
-      !extensions::ExtensionSystem::Get(profile_)->event_router())
+  if (!process || !extensions::ExtensionSystem::Get(profile_)->event_router())
     return;
 
   extensions::ExtensionSystem::Get(profile_)->event_router()->
@@ -539,8 +500,7 @@
     bool lazy) {
   content::RenderProcessHost* process =
       content::RenderProcessHost::FromID(render_process_id_);
-  if (!process ||
-      !extensions::ExtensionSystem::Get(profile_)->event_router())
+  if (!process || !extensions::ExtensionSystem::Get(profile_)->event_router())
     return;
 
   extensions::ExtensionSystem::Get(profile_)->event_router()->
@@ -566,12 +526,8 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
   ExtensionFunctionDispatcher::DispatchOnIOThread(
-      extension_info_map_.get(),
-      profile_,
-      render_process_id_,
-      weak_ptr_factory_.GetWeakPtr(),
-      routing_id,
-      params);
+      extension_info_map_.get(), profile_, render_process_id_,
+      weak_ptr_factory_.GetWeakPtr(), routing_id, params);
 }
 
 void ChromeRenderMessageFilter::OnExtensionShouldSuspendAck(
@@ -591,8 +547,8 @@
 }
 
 void ChromeRenderMessageFilter::OnExtensionGenerateUniqueID(int* unique_id) {
-  static int next_unique_id = 1;
-  *unique_id = next_unique_id++;
+  static int next_unique_id = 0;
+  *unique_id = ++next_unique_id;
 }
 
 void ChromeRenderMessageFilter::OnExtensionResumeRequests(int route_id) {
@@ -617,10 +573,9 @@
   scoped_ptr<ListValue> args(params.arguments.DeepCopy());
   // The activity is recorded as a DOM action on the extension
   // activity log.
-  AddDOMActionToExtensionActivityLog(profile_, extension_id,
-                                     params.url, params.url_title,
-                                     params.api_call, args.Pass(),
-                                     params.call_type);
+  AddDOMActionToExtensionActivityLog(profile_, extension_id, params.url,
+                                     params.url_title, params.api_call,
+                                     args.Pass(), params.call_type);
 }
 
 void ChromeRenderMessageFilter::OnAddEventToExtensionActivityLog(
@@ -637,9 +592,7 @@
 void ChromeRenderMessageFilter::OnAddBlockedCallToExtensionActivityLog(
     const std::string& extension_id,
     const std::string& function_name) {
-  AddBlockedActionToExtensionActivityLog(profile_,
-                                         extension_id,
-                                         function_name);
+  AddBlockedActionToExtensionActivityLog(profile_, extension_id, function_name);
 }
 
 void ChromeRenderMessageFilter::OnAllowDatabase(int render_view_id,
@@ -648,14 +601,13 @@
                                                 const string16& name,
                                                 const string16& display_name,
                                                 bool* allowed) {
-  *allowed = cookie_settings_->IsSettingCookieAllowed(origin_url,
-                                                      top_origin_url);
+  *allowed =
+      cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::Bind(
-          &TabSpecificContentSettings::WebDatabaseAccessed,
-          render_process_id_, render_view_id, origin_url, name, display_name,
-          !*allowed));
+      base::Bind(&TabSpecificContentSettings::WebDatabaseAccessed,
+                 render_process_id_, render_view_id, origin_url, name,
+                 display_name, !*allowed));
 }
 
 void ChromeRenderMessageFilter::OnAllowDOMStorage(int render_view_id,
@@ -663,28 +615,27 @@
                                                   const GURL& top_origin_url,
                                                   bool local,
                                                   bool* allowed) {
-  *allowed = cookie_settings_->IsSettingCookieAllowed(origin_url,
-                                                      top_origin_url);
+  *allowed =
+      cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
   // Record access to DOM storage for potential display in UI.
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::Bind(
-          &TabSpecificContentSettings::DOMStorageAccessed,
-          render_process_id_, render_view_id, origin_url, local, !*allowed));
+      base::Bind(&TabSpecificContentSettings::DOMStorageAccessed,
+                 render_process_id_, render_view_id, origin_url, local,
+                 !*allowed));
 }
 
 void ChromeRenderMessageFilter::OnAllowFileSystem(int render_view_id,
                                                   const GURL& origin_url,
                                                   const GURL& top_origin_url,
                                                   bool* allowed) {
-  *allowed = cookie_settings_->IsSettingCookieAllowed(origin_url,
-                                                      top_origin_url);
+  *allowed =
+      cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
   // Record access to file system for potential display in UI.
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::Bind(
-          &TabSpecificContentSettings::FileSystemAccessed,
-          render_process_id_, render_view_id, origin_url, !*allowed));
+      base::Bind(&TabSpecificContentSettings::FileSystemAccessed,
+                 render_process_id_, render_view_id, origin_url, !*allowed));
 }
 
 void ChromeRenderMessageFilter::OnAllowIndexedDB(int render_view_id,
@@ -692,13 +643,13 @@
                                                  const GURL& top_origin_url,
                                                  const string16& name,
                                                  bool* allowed) {
-  *allowed = cookie_settings_->IsSettingCookieAllowed(origin_url,
-                                                      top_origin_url);
+  *allowed =
+      cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::Bind(
-          &TabSpecificContentSettings::IndexedDBAccessed,
-          render_process_id_, render_view_id, origin_url, name, !*allowed));
+      base::Bind(&TabSpecificContentSettings::IndexedDBAccessed,
+                 render_process_id_, render_view_id, origin_url, name,
+                 !*allowed));
 }
 
 void ChromeRenderMessageFilter::OnCanTriggerClipboardRead(
diff --git a/chrome/browser/renderer_host/chrome_render_view_host_observer.cc b/chrome/browser/renderer_host/chrome_render_view_host_observer.cc
index 172bc13..bda101c 100644
--- a/chrome/browser/renderer_host/chrome_render_view_host_observer.cc
+++ b/chrome/browser/renderer_host/chrome_render_view_host_observer.cc
@@ -5,11 +5,11 @@
 #include "chrome/browser/renderer_host/chrome_render_view_host_observer.h"
 
 #include "base/command_line.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/net/predictor.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_messages.h"
diff --git a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate_browsertest.cc b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate_browsertest.cc
index 615b577..678922b 100644
--- a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate_browsertest.cc
+++ b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate_browsertest.cc
@@ -4,11 +4,11 @@
 
 #include "base/basictypes.h"
 #include "base/files/file_path.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
index 93df87e..d31d01f 100644
--- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
@@ -10,6 +10,7 @@
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/download/download_request_limiter.h"
 #include "chrome/browser/download/download_resource_throttle.h"
@@ -32,7 +33,6 @@
 #include "chrome/browser/ui/auto_login_prompter.h"
 #include "chrome/browser/ui/login/login_prompt.h"
 #include "chrome/browser/ui/sync/one_click_signin_helper.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/mime_types_handler.h"
 #include "chrome/common/extensions/user_script.h"
 #include "chrome/common/render_messages.h"
diff --git a/chrome/browser/renderer_host/pepper/device_id_fetcher.cc b/chrome/browser/renderer_host/pepper/device_id_fetcher.cc
index ed795ee..39380db 100644
--- a/chrome/browser/renderer_host/pepper/device_id_fetcher.cc
+++ b/chrome/browser/renderer_host/pepper/device_id_fetcher.cc
@@ -63,7 +63,7 @@
 }
 
 // static
-void DeviceIDFetcher::RegisterUserPrefs(
+void DeviceIDFetcher::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* prefs) {
   // TODO(wad): Once UI is connected, a final default can be set. At that point
   // change this pref from UNSYNCABLE to SYNCABLE.
@@ -167,7 +167,7 @@
   // First check if the legacy device ID file exists on ChromeOS. If it does, we
   // should just return that.
   base::FilePath id_path = GetLegacyDeviceIDPath(profile_path);
-  if (file_util::PathExists(id_path)) {
+  if (base::PathExists(id_path)) {
     if (file_util::ReadFileToString(id_path, &id) && !id.empty()) {
       RunCallbackOnIOThread(id);
       return;
diff --git a/chrome/browser/renderer_host/pepper/device_id_fetcher.h b/chrome/browser/renderer_host/pepper/device_id_fetcher.h
index 0f440b2..1373bdf 100644
--- a/chrome/browser/renderer_host/pepper/device_id_fetcher.h
+++ b/chrome/browser/renderer_host/pepper/device_id_fetcher.h
@@ -40,7 +40,7 @@
   bool Start(const IDCallback& callback);
 
   // Called to register the |kEnableDRM| and |kDRMSalt| preferences.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* prefs);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* prefs);
 
   // Return the path where the legacy device ID is stored (for ChromeOS only).
   static base::FilePath GetLegacyDeviceIDPath(
diff --git a/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc b/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc
index 8440b56..98870a1 100644
--- a/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc
+++ b/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc
@@ -11,8 +11,12 @@
 #include "base/bind.h"
 #include "base/compiler_specific.h"
 #include "base/logging.h"
+#include "base/memory/ref_counted.h"
 #include "content/public/browser/browser_ppapi_host.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_security_policy.h"
+#include "content/public/browser/render_widget_host.h"
+#include "content/public/browser/render_widget_host_view.h"
 #include "content/public/common/pepper_plugin_info.h"
 #include "ppapi/c/pp_errors.h"
 #include "ppapi/host/dispatch_host_message.h"
@@ -20,6 +24,10 @@
 #include "ppapi/host/ppapi_host.h"
 #include "ppapi/proxy/ppapi_messages.h"
 
+#if defined(USE_AURA)
+#include "ui/aura/root_window.h"
+#endif
+
 using content::BrowserPpapiHost;
 
 namespace chrome {
@@ -29,15 +37,91 @@
     FILE_PATH_LITERAL("plugin.vch");
 }
 
+#if defined (OS_WIN)
+// Helper class to get the UI thread which monitor is showing the
+// window associated with the instance's render view. Since we get
+// called by the IO thread and we cannot block, the first answer is
+// of GetMonitor() may be NULL, but eventually it will contain the
+// right monitor.
+class MonitorFinder : public base::RefCountedThreadSafe<MonitorFinder> {
+ public:
+  MonitorFinder(int process_id, int render_id)
+      : process_id_(process_id),
+        render_id_(render_id),
+        monitor_(NULL),
+        request_sent_(0) {
+    GetMonitor();
+  }
+
+  int64_t GetMonitor() {
+    // We use |request_sent_| as an atomic boolean so that we
+    // never have more than one task posted at a given time. We
+    // do this because we don't know how often our client is going
+    // to call and we can't cache the |monitor_| value.
+    if (InterlockedCompareExchange(&request_sent_, 1, 0) == 0) {
+      content::BrowserThread::PostTask(
+          content::BrowserThread::UI, FROM_HERE,
+          base::Bind(&MonitorFinder::FetchMonitorFromWidget, this));
+    }
+    return reinterpret_cast<int64_t>(monitor_);
+  }
+
+ private:
+  friend class base::RefCountedThreadSafe<MonitorFinder>;
+  ~MonitorFinder() { }
+
+  void FetchMonitorFromWidget() {
+    InterlockedExchange(&request_sent_, 0);
+    content::RenderWidgetHost* rwh =
+        content::RenderWidgetHost::FromID(process_id_, render_id_);
+    if (!rwh)
+      return;
+    content::RenderWidgetHostView* view = rwh->GetView();
+    if (!view)
+      return;
+    gfx::NativeView native_view = view->GetNativeView();
+#if defined(USE_AURA)
+    aura::RootWindow* root = native_view->GetRootWindow();
+    if (!root)
+      return;
+    HWND window = root->GetAcceleratedWidget();
+#else
+    HWND window = native_view;
+#endif
+    HMONITOR monitor = ::MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
+    InterlockedExchangePointer(reinterpret_cast<void* volatile *>(&monitor_),
+                               monitor);
+  }
+
+  const int process_id_;
+  const int render_id_;
+  volatile HMONITOR monitor_;
+  volatile long request_sent_;
+};
+#else
+// TODO(cpu): Support Mac and Linux someday.
+class MonitorFinder : public base::RefCountedThreadSafe<MonitorFinder> {
+ public:
+  MonitorFinder(int, int) { }
+  int64_t GetMonitor() { return 0; }
+
+ private:
+  friend class base::RefCountedThreadSafe<MonitorFinder>;
+  ~MonitorFinder() { }
+};
+#endif
+
 PepperFlashDRMHost::PepperFlashDRMHost(BrowserPpapiHost* host,
                                        PP_Instance instance,
                                        PP_Resource resource)
     : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource),
       weak_factory_(this){
   // Grant permissions to read the flash voucher file.
-  int render_process_id, unused;
+  int render_process_id;
+  int render_view_id;
   bool success =
-      host->GetRenderViewIDsForInstance(instance, &render_process_id, &unused);
+      host->GetRenderViewIDsForInstance(
+          instance, &render_process_id, &render_view_id);
   base::FilePath plugin_dir = host->GetPluginPath().DirName();
   DCHECK(!plugin_dir.empty() && success);
   base::FilePath voucher_file = plugin_dir.Append(
@@ -45,8 +129,8 @@
   content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(
       render_process_id, voucher_file);
 
-  // Init the DeviceIDFetcher.
   fetcher_ = new DeviceIDFetcher(render_process_id);
+  monitor_finder_ = new MonitorFinder(render_process_id, render_view_id);
 }
 
 PepperFlashDRMHost::~PepperFlashDRMHost() {
@@ -76,16 +160,13 @@
 
 int32_t PepperFlashDRMHost::OnHostMsgGetHmonitor(
     ppapi::host::HostMessageContext* context) {
-#if defined(OS_WIN)
-  // TODO(cpu): Get the real HMONITOR. See bug 249135.
-  POINT pt = {1,1};
-  HMONITOR monitor = ::MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
-  int64_t monitor_id = reinterpret_cast<int64_t>(monitor);
-  context->reply_msg = PpapiPluginMsg_FlashDRM_GetHmonitorReply(monitor_id);
-  return PP_OK;
-#else
-  return PP_ERROR_FAILED;
-#endif
+  int64_t monitor_id = monitor_finder_->GetMonitor();
+  if (monitor_id) {
+    context->reply_msg = PpapiPluginMsg_FlashDRM_GetHmonitorReply(monitor_id);
+    return PP_OK;
+  } else {
+    return PP_ERROR_FAILED;
+  }
 }
 
 void PepperFlashDRMHost::GotDeviceID(
diff --git a/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h b/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h
index 0ed607b..a2ef26e 100644
--- a/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h
+++ b/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h
@@ -21,6 +21,7 @@
 }
 
 namespace chrome {
+class MonitorFinder;
 
 class PepperFlashDRMHost : public ppapi::host::ResourceHost {
  public:
@@ -45,6 +46,7 @@
                    const std::string& id);
 
   scoped_refptr<DeviceIDFetcher> fetcher_;
+  scoped_refptr<MonitorFinder> monitor_finder_;
 
   base::WeakPtrFactory<PepperFlashDRMHost> weak_factory_;
 
diff --git a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
index cdc9e9e..2034b13 100644
--- a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
+++ b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
@@ -4,12 +4,12 @@
 
 #include "base/command_line.h"
 #include "base/process_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -357,7 +357,7 @@
 }
 
 // This class's goal is to close the browser window when a renderer process has
-// crashed. It does so by monitoring WebContents for RenderViewGone event and
+// crashed. It does so by monitoring WebContents for RenderProcessGone event and
 // closing the passed in TabStripModel. This is used in the following test case.
 class WindowDestroyer : public content::WebContentsObserver {
  public:
@@ -366,7 +366,7 @@
         tab_strip_model_(model) {
   }
 
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE {
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE {
     // Wait for the window to be destroyed, which will ensure all other
     // RenderViewHost objects are deleted before we return and proceed with
     // the next iteration of notifications.
diff --git a/chrome/browser/renderer_host/web_cache_manager.cc b/chrome/browser/renderer_host/web_cache_manager.cc
index 0136501..660529e 100644
--- a/chrome/browser/renderer_host/web_cache_manager.cc
+++ b/chrome/browser/renderer_host/web_cache_manager.cc
@@ -16,8 +16,8 @@
 #include "base/sys_info.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/render_messages.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/repost_form_warning_browsertest.cc b/chrome/browser/repost_form_warning_browsertest.cc
index eab3f1a..d6f0529 100644
--- a/chrome/browser/repost_form_warning_browsertest.cc
+++ b/chrome/browser/repost_form_warning_browsertest.cc
@@ -3,10 +3,10 @@
 // found in the LICENSE file.
 
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/net/url_fixer_upper.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/resources/chromeos/about_os_credits.html b/chrome/browser/resources/chromeos/about_os_credits.html
index ad7d7ce..97ca9f7 100644
--- a/chrome/browser/resources/chromeos/about_os_credits.html
+++ b/chrome/browser/resources/chromeos/about_os_credits.html
@@ -63,10 +63,10 @@
 
   if (licence.style && licence.style.display == 'block') {
     licence.style.display = 'none';
-    o.innerHTML = 'show license';
+    o.innerHTML = 'show license(s)';
   } else {
     licence.style.display = 'block';
-    o.innerHTML = 'hide license';
+    o.innerHTML = 'hide license(s)';
   }
   return false;
 }
@@ -78,10 +78,11 @@
 <div style="clear:both; overflow:auto;"><!-- Chromium <3s the following projects -->
 <div class="product">
 <span class="title">Linux</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.kernel.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -421,6 +422,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -428,10 +432,11 @@
 
 <div class="product">
 <span class="title">X.Org</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.x.org/">homepage</a></span>
 <div class="licence">
-<pre>The following is the 'standard copyright' agreed upon by most contributors,
+<pre>Gentoo Package Provided Stock License X:
+The following is the 'standard copyright' agreed upon by most contributors,
 and is currently the canonical license preferred by the X.Org Foundation.
 This is a slight variant of the common MIT license form published by the
 Open Source Initiative at http://www.opensource.org/licenses/mit-license.php
@@ -2274,6 +2279,9 @@
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 SUCH DAMAGE.
+
+
+
 </pre>
 </div>
 </div>
@@ -2281,10 +2289,12 @@
 
 <div class="product">
 <span class="title">acl</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://savannah.nongnu.org/projects/acl">homepage</a></span>
 <div class="licence">
-<pre>Most components of the "acl" package are licensed under
+<pre>Source license acl-2.2.51/doc/COPYING:
+
+Most components of the "acl" package are licensed under
 Version 2.1 of the GNU Lesser General Public License (see COPYING.LGPL).
 
 Some components (as annotated in the source) are licensed
@@ -2631,6 +2641,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -2638,10 +2650,11 @@
 
 <div class="product">
 <span class="title">adhd</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.chromium.org">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -2981,6 +2994,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -2988,10 +3004,12 @@
 
 <div class="product">
 <span class="title">alsa-headers</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.alsa-project.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license alsa-driver-1.0.25/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -3331,6 +3349,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -3338,10 +3358,12 @@
 
 <div class="product">
 <span class="title">alsa-lib</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.alsa-project.org/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Source license alsa-lib-1.0.25/COPYING:
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -3845,6 +3867,8 @@
 That's all there is to it!
 
 
+
+
 </pre>
 </div>
 </div>
@@ -3852,10 +3876,12 @@
 
 <div class="product">
 <span class="title">alsa-plugins</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.alsa-project.org/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Source license alsa-plugins-1.0.25/COPYING:
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -4359,6 +4385,8 @@
 That's all there is to it!
 
 
+
+
 </pre>
 </div>
 </div>
@@ -4366,10 +4394,12 @@
 
 <div class="product">
 <span class="title">alsa-utils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.alsa-project.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license alsa-utils-1.0.25/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -4709,6 +4739,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -4716,10 +4748,12 @@
 
 <div class="product">
 <span class="title">argparse</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/argparse/">homepage</a></span>
 <div class="licence">
-<pre>argparse is (c) 2006-2009 Steven J. Bethard &lt;steven.bethard@gmail.com&gt;.
+<pre>Source license argparse-1.2.1/LICENSE.txt:
+
+argparse is (c) 2006-2009 Steven J. Bethard &lt;steven.bethard@gmail.com&gt;.
 
 The argparse module was contributed to Python as of Python 2.7 and thus
 was licensed under the Python license. Same license applies to all files in
@@ -4739,6 +4773,8 @@
 The project repository then had a clean start with some files taken from
 Python 2.7.1, so definitely all files are under Python License now.
 
+
+
 </pre>
 </div>
 </div>
@@ -4746,26 +4782,30 @@
 
 <div class="product">
 <span class="title">ath3k</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.atheros.com/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2010, Atheros Communications, Inc.
+<pre>Gentoo Package Provided Stock License Atheros:
+Copyright (c) 2010, Atheros Communications, Inc.

+

+All rights reserved.

+

+Redistribution. Redistribution and use in binary form, without modification, are permitted provided that the following conditions are

+

+met:

+

+* Redistributions must reproduce the above copyright notice and the following disclaimer in the documentation and/or other materials provided with the distribution. 

+

+* Neither the name of Atheros Communications, Inc. nor the names of its suppliers may be used to endorse or promote products derived from this software without specific prior written permission. 

+

+* No reverse engineering, decompilation, or disassembly of this software is permitted.

+

+Limited patent license. Atheros Communications, Inc. grants a world-wide, royalty-free, non-exclusive license under patents it now or hereafter owns or controls to make, have made, use, import, offer to sell and sell ("Utilize") this software, but solely to the extent that any such patent is necessary to Utilize the software alone, or in combination with an operating system licensed under an approved Open Source license as listed by the Open Source Initiative at http://opensource.org/licenses. The patent license shall not apply to any other combinations which include this software. No hardware per se is licensed hereunder.

+

+DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+

+

 
-All rights reserved.
-
-Redistribution. Redistribution and use in binary form, without modification, are permitted provided that the following conditions are
-
-met:
-
-* Redistributions must reproduce the above copyright notice and the following disclaimer in the documentation and/or other materials provided with the distribution. 
-
-* Neither the name of Atheros Communications, Inc. nor the names of its suppliers may be used to endorse or promote products derived from this software without specific prior written permission. 
-
-* No reverse engineering, decompilation, or disassembly of this software is permitted.
-
-Limited patent license. Atheros Communications, Inc. grants a world-wide, royalty-free, non-exclusive license under patents it now or hereafter owns or controls to make, have made, use, import, offer to sell and sell ("Utilize") this software, but solely to the extent that any such patent is necessary to Utilize the software alone, or in combination with an operating system licensed under an approved Open Source license as listed by the Open Source Initiative at http://opensource.org/licenses. The patent license shall not apply to any other combinations which include this software. No hardware per se is licensed hereunder.
-
-DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 </pre>
@@ -4775,26 +4815,30 @@
 
 <div class="product">
 <span class="title">ath6k</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.atheros.com/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2010, Atheros Communications, Inc.
+<pre>Gentoo Package Provided Stock License Atheros:
+Copyright (c) 2010, Atheros Communications, Inc.

+

+All rights reserved.

+

+Redistribution. Redistribution and use in binary form, without modification, are permitted provided that the following conditions are

+

+met:

+

+* Redistributions must reproduce the above copyright notice and the following disclaimer in the documentation and/or other materials provided with the distribution. 

+

+* Neither the name of Atheros Communications, Inc. nor the names of its suppliers may be used to endorse or promote products derived from this software without specific prior written permission. 

+

+* No reverse engineering, decompilation, or disassembly of this software is permitted.

+

+Limited patent license. Atheros Communications, Inc. grants a world-wide, royalty-free, non-exclusive license under patents it now or hereafter owns or controls to make, have made, use, import, offer to sell and sell ("Utilize") this software, but solely to the extent that any such patent is necessary to Utilize the software alone, or in combination with an operating system licensed under an approved Open Source license as listed by the Open Source Initiative at http://opensource.org/licenses. The patent license shall not apply to any other combinations which include this software. No hardware per se is licensed hereunder.

+

+DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+

+

 
-All rights reserved.
-
-Redistribution. Redistribution and use in binary form, without modification, are permitted provided that the following conditions are
-
-met:
-
-* Redistributions must reproduce the above copyright notice and the following disclaimer in the documentation and/or other materials provided with the distribution. 
-
-* Neither the name of Atheros Communications, Inc. nor the names of its suppliers may be used to endorse or promote products derived from this software without specific prior written permission. 
-
-* No reverse engineering, decompilation, or disassembly of this software is permitted.
-
-Limited patent license. Atheros Communications, Inc. grants a world-wide, royalty-free, non-exclusive license under patents it now or hereafter owns or controls to make, have made, use, import, offer to sell and sell ("Utilize") this software, but solely to the extent that any such patent is necessary to Utilize the software alone, or in combination with an operating system licensed under an approved Open Source license as listed by the Open Source Initiative at http://opensource.org/licenses. The patent license shall not apply to any other combinations which include this software. No hardware per se is licensed hereunder.
-
-DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 </pre>
@@ -4804,10 +4848,12 @@
 
 <div class="product">
 <span class="title">atk</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://projects.gnome.org/accessibility/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LIBRARY GENERAL PUBLIC LICENSE
+<pre>Source license atk-1.32.0/COPYING:
+
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1991 Free Software Foundation, Inc.
@@ -5289,6 +5335,8 @@
   Ty Coon, President of Vice
 
 That's all there is to it!
+
+
 </pre>
 </div>
 </div>
@@ -5296,10 +5344,12 @@
 
 <div class="product">
 <span class="title">attr</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://savannah.nongnu.org/projects/attr">homepage</a></span>
 <div class="licence">
-<pre>Most components of the "attr" package are licensed under
+<pre>Source license attr-2.4.46/doc/COPYING:
+
+Most components of the "attr" package are licensed under
 Version 2.1 of the GNU Lesser General Public License (see COPYING.LGPL).
 
 Some components (as annotated in the source) are licensed
@@ -5646,6 +5696,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -5653,10 +5705,12 @@
 
 <div class="product">
 <span class="title">autoconf</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/autoconf/autoconf.html">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license autoconf-2.13/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -5996,6 +6050,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -6003,10 +6059,11 @@
 
 <div class="product">
 <span class="title">autoconf-wrapper</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gentoo.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -6346,6 +6403,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -6353,10 +6413,12 @@
 
 <div class="product">
 <span class="title">automake</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://sources.redhat.com/automake/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license automake-1.11.1/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -6695,6 +6757,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -6702,10 +6766,11 @@
 
 <div class="product">
 <span class="title">automake-wrapper</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gentoo.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -7045,6 +7110,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -7052,10 +7120,12 @@
 
 <div class="product">
 <span class="title">avfs</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://sourceforge.net/projects/avf">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license avfs-1.0.1/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -7395,6 +7465,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -7402,10 +7474,14 @@
 
 <div class="product">
 <span class="title">baselayout</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://src.chromium.org/">homepage</a></span>
 <div class="licence">
-<pre>Copyright 1996-2007 Gentoo Foundation
+<pre>Source license baselayout-2.0.1/COPYRIGHT:
+
+Copyright 1996-2007 Gentoo Foundation
+
+
 </pre>
 </div>
 </div>
@@ -7413,10 +7489,12 @@
 
 <div class="product">
 <span class="title">bash</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://tiswww.case.edu/php/chet/bash/bashtop.html">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license bash-4.2/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -8090,6 +8168,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -8097,10 +8177,12 @@
 
 <div class="product">
 <span class="title">binutils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://sources.redhat.com/binutils/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license gitdir/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -8440,6 +8522,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -8447,10 +8531,11 @@
 
 <div class="product">
 <span class="title">binutils-config</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gentoo.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -8790,6 +8875,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -8797,10 +8885,12 @@
 
 <div class="product">
 <span class="title">bluez</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.bluez.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license bluez-5.4/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -9140,6 +9230,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -9147,10 +9239,11 @@
 
 <div class="product">
 <span class="title">bsdiff</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.daemonology.net/bsdiff/">homepage</a></span>
 <div class="licence">
-<pre>Copyright 2003-2005 Colin Percival
+<pre>Gentoo Package Provided Stock License BSD-bsdiff:
+Copyright 2003-2005 Colin Percival
 All rights reserved
 
 Redistribution and use in source and binary forms, with or without
@@ -9173,6 +9266,9 @@
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
+
+
+
 </pre>
 </div>
 </div>
@@ -9180,10 +9276,12 @@
 
 <div class="product">
 <span class="title">busybox</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.busybox.net/">homepage</a></span>
 <div class="licence">
-<pre>--- A note on GPL versions
+<pre>Source license busybox-1.21.0/LICENSE:
+
+--- A note on GPL versions
 
 BusyBox is distributed under version 2 of the General Public License (included
 in its entirety, below).  Version 2 is the only version of this license which
@@ -9531,6 +9629,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -9538,10 +9638,12 @@
 
 <div class="product">
 <span class="title">bzip2</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.bzip.org/">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license bzip2-1.0.6/LICENSE:
+
+
 --------------------------------------------------------------------------
 
 This program, "bzip2", the associated library "libbzip2", and all
@@ -9583,6 +9685,8 @@
 bzip2/libbzip2 version 1.0.6 of 6 September 2010
 
 --------------------------------------------------------------------------
+
+
 </pre>
 </div>
 </div>
@@ -9590,10 +9694,11 @@
 
 <div class="product">
 <span class="title">c-ares</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://c-ares.haxx.se/">homepage</a></span>
 <div class="licence">
-<pre>Copyright 1998 by the Massachusetts Institute of Technology.
+<pre>Gentoo Package Provided Stock License MIT-MIT:
+Copyright 1998 by the Massachusetts Institute of Technology.
 
 Permission to use, copy, modify, and distribute this
 software and its documentation for any purpose and without
@@ -9606,6 +9711,9 @@
 M.I.T. makes no representations about the suitability of
 this software for any purpose.  It is provided "as is"
 without express or implied warranty.
+
+
+
 </pre>
 </div>
 </div>
@@ -9613,10 +9721,12 @@
 
 <div class="product">
 <span class="title">cairo</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://cairographics.org/">homepage</a></span>
 <div class="licence">
-<pre>Cairo is free software.
+<pre>Source license cairo-1.12.12/COPYING:
+
+Cairo is free software.
 
 Every source file in the implementation[*] of cairo is available to be
 redistributed and/or modified under the terms of either the GNU Lesser
@@ -9635,19 +9745,2790 @@
 information, (in the opening comment of each file).
 
 [*] The implementation of cairo is contained entirely within the "src"
-and "pixman" directories of the cairo source distribution. There are
-other components of the cairo source distribution (such as the "test"
-and "perf") that are auxiliary to the library itself. None of the
-source code in these directories contributes to a build of the cairo
-library itself, (libcairo.so or cairo.dll or similar).
+directory of the cairo source distribution. There are other components
+of the cairo source distribution (such as the "test", "util", and "perf")
+that are auxiliary to the library itself. None of the source code in these
+directories contributes to a build of the cairo library itself, (libcairo.so
+or cairo.dll or similar).
 
-These auxilary components are also free software, but may be under
+These auxiliary components are also free software, but may be under
 different license terms than cairo itself. For example, most of the
 test cases in the perf and test directories are made available under
 an MIT license to simplify any use of this code for reference purposes
 in using cairo itself. Other files might be available under the GNU
-General Public License (GPL), for example. Again, please see the
-opening comment of each file for copyright and licensing information.
+General Public License (GPL), for example. Again, please see the COPYING
+file under each directory and the opening comment of each file for copyright
+and licensing information.
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">chinese-input</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://www.google.com/inputtools/">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License Apache-2.0:
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+
+APACHE HTTP SERVER SUBCOMPONENTS: 
+
+The Apache HTTP Server includes a number of subcomponents with
+separate copyright notices and license terms. Your use of the source
+code for the these subcomponents is subject to the terms and
+conditions of the following licenses. 
+
+For the mod_mime_magic component:
+
+/*
+ * mod_mime_magic: MIME type lookup via file magic numbers
+ * Copyright (c) 1996-1997 Cisco Systems, Inc.
+ *
+ * This software was submitted by Cisco Systems to the Apache Group in July
+ * 1997.  Future revisions and derivatives of this source code must
+ * acknowledge Cisco Systems as the original contributor of this module.
+ * All other licensing and usage conditions are those of the Apache Group.
+ *
+ * Some of this code is derived from the free version of the file command
+ * originally posted to comp.sources.unix.  Copyright info for that program
+ * is included below as required.
+ * ---------------------------------------------------------------------------
+ * - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone and
+ * Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on any
+ * computer system, and to alter it and redistribute it freely, subject to
+ * the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission.  Since few users ever read sources, credits
+ * must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.  Since few users ever read
+ * sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ * -------------------------------------------------------------------------
+ *
+ */
+
+
+For the  modules\mappers\mod_imap.c component:
+
+  "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
+
+For the  server\util_md5.c component:
+
+/************************************************************************
+ * NCSA HTTPd Server
+ * Software Development Group
+ * National Center for Supercomputing Applications
+ * University of Illinois at Urbana-Champaign
+ * 605 E. Springfield, Champaign, IL 61820
+ * httpd@ncsa.uiuc.edu
+ *
+ * Copyright  (C)  1995, Board of Trustees of the University of Illinois
+ *
+ ************************************************************************
+ *
+ * md5.c: NCSA HTTPd code which uses the md5c.c RSA Code
+ *
+ *  Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc.
+ *  Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon
+ *     University (see Copyright below).
+ *  Portions of Content-MD5 code Copyright (C) 1991 Bell Communications 
+ *     Research, Inc. (Bellcore) (see Copyright below).
+ *  Portions extracted from mpack, John G. Myers - jgm+@cmu.edu
+ *  Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk)
+ *
+ */
+
+
+/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */
+/* (C) Copyright 1993,1994 by Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Carnegie
+ * Mellon University not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  Carnegie Mellon University makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
+ *
+ * Permission to use, copy, modify, and distribute this material
+ * for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice
+ * appear in all copies, and that the name of Bellcore not be
+ * used in advertising or publicity pertaining to this
+ * material without the specific, prior written permission
+ * of an authorized representative of Bellcore.  BELLCORE
+ * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
+ * OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS",
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.  
+ */
+
+For the  srclib\apr\include\apr_md5.h component: 
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+
+For the  srclib\apr\passwd\apr_md5.c component:
+
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+/*
+ * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
+ * MD5 crypt() function, which is licenced as follows:
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * &lt;phk@login.dknet.dk&gt; wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.  Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+For the srclib\apr-util\crypto\apr_md4.c component:
+
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\include\apr_md4.h component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+
+For the srclib\apr-util\test\testdbm.c component:
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * &lt;http://www.apache.org/&gt;.
+ *
+ * This file came from the SDBM package (written by oz@nexus.yorku.ca).
+ * That package was under public domain. This file has been ported to
+ * APR, updated to ANSI C and other, newer idioms, and added to the Apache
+ * codebase under the above copyright and license.
+ */
+
+
+For the srclib\apr-util\test\testmd4.c component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ * rights reserved.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\xml\expat\conftools\install-sh component:
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+
+For the srclib\pcre\install-sh component:
+
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+
+For the pcre component:
+
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Written by: Philip Hazel &lt;ph10@cam.ac.uk&gt;
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2001 University of Cambridge
+
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission. In practice, this means that if you use
+   PCRE in software which you distribute to others, commercially or
+   otherwise, you must put a sentence like this
+
+     Regular expression support is provided by the PCRE library package,
+     which is open source software, written by Philip Hazel, and copyright
+     by the University of Cambridge, England.
+
+   somewhere reasonably visible in your documentation and in any relevant
+   files or online help data or similar. A reference to the ftp site for
+   the source, that is, to
+
+     ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+
+   should also be given in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL),
+   then the terms of that licence shall supersede any condition above with
+   which it is incompatible.
+
+The documentation for PCRE, supplied in the "doc" directory, is distributed
+under the same terms as the software itself.
+
+End PCRE LICENCE
+
+
+For the test\zb.c component:
+
+/*                          ZeusBench V1.01
+			    ===============
+
+This program is Copyright (C) Zeus Technology Limited 1996.
+
+This program may be used and copied freely providing this copyright notice
+is not removed.
+
+This software is provided "as is" and any express or implied waranties, 
+including but not limited to, the implied warranties of merchantability and
+fitness for a particular purpose are disclaimed.  In no event shall 
+Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, 
+exemplary, or consequential damaged (including, but not limited to, 
+procurement of substitute good or services; loss of use, data, or profits;
+or business interruption) however caused and on theory of liability.  Whether
+in contract, strict liability or tort (including negligence or otherwise) 
+arising in any way out of the use of this software, even if advised of the
+possibility of such damage.
+
+     Written by Adam Twiss (adam@zeus.co.uk).  March 1996
+
+Thanks to the following people for their input:
+  Mike Belshe (mbelshe@netscape.com) 
+  Michael Campanella (campanella@stevms.enet.dec.com)
+
+*/
+
+For the expat xml parser component:
+
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+                               and Clark Cooper
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+	
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+	
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====================================================================
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">chromeos-cangjie</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="https://code.google.com/p/google-input-tools/">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License Apache-2.0:
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+
+APACHE HTTP SERVER SUBCOMPONENTS: 
+
+The Apache HTTP Server includes a number of subcomponents with
+separate copyright notices and license terms. Your use of the source
+code for the these subcomponents is subject to the terms and
+conditions of the following licenses. 
+
+For the mod_mime_magic component:
+
+/*
+ * mod_mime_magic: MIME type lookup via file magic numbers
+ * Copyright (c) 1996-1997 Cisco Systems, Inc.
+ *
+ * This software was submitted by Cisco Systems to the Apache Group in July
+ * 1997.  Future revisions and derivatives of this source code must
+ * acknowledge Cisco Systems as the original contributor of this module.
+ * All other licensing and usage conditions are those of the Apache Group.
+ *
+ * Some of this code is derived from the free version of the file command
+ * originally posted to comp.sources.unix.  Copyright info for that program
+ * is included below as required.
+ * ---------------------------------------------------------------------------
+ * - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone and
+ * Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on any
+ * computer system, and to alter it and redistribute it freely, subject to
+ * the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission.  Since few users ever read sources, credits
+ * must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.  Since few users ever read
+ * sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ * -------------------------------------------------------------------------
+ *
+ */
+
+
+For the  modules\mappers\mod_imap.c component:
+
+  "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
+
+For the  server\util_md5.c component:
+
+/************************************************************************
+ * NCSA HTTPd Server
+ * Software Development Group
+ * National Center for Supercomputing Applications
+ * University of Illinois at Urbana-Champaign
+ * 605 E. Springfield, Champaign, IL 61820
+ * httpd@ncsa.uiuc.edu
+ *
+ * Copyright  (C)  1995, Board of Trustees of the University of Illinois
+ *
+ ************************************************************************
+ *
+ * md5.c: NCSA HTTPd code which uses the md5c.c RSA Code
+ *
+ *  Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc.
+ *  Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon
+ *     University (see Copyright below).
+ *  Portions of Content-MD5 code Copyright (C) 1991 Bell Communications 
+ *     Research, Inc. (Bellcore) (see Copyright below).
+ *  Portions extracted from mpack, John G. Myers - jgm+@cmu.edu
+ *  Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk)
+ *
+ */
+
+
+/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */
+/* (C) Copyright 1993,1994 by Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Carnegie
+ * Mellon University not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  Carnegie Mellon University makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
+ *
+ * Permission to use, copy, modify, and distribute this material
+ * for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice
+ * appear in all copies, and that the name of Bellcore not be
+ * used in advertising or publicity pertaining to this
+ * material without the specific, prior written permission
+ * of an authorized representative of Bellcore.  BELLCORE
+ * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
+ * OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS",
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.  
+ */
+
+For the  srclib\apr\include\apr_md5.h component: 
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+
+For the  srclib\apr\passwd\apr_md5.c component:
+
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+/*
+ * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
+ * MD5 crypt() function, which is licenced as follows:
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * &lt;phk@login.dknet.dk&gt; wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.  Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+For the srclib\apr-util\crypto\apr_md4.c component:
+
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\include\apr_md4.h component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+
+For the srclib\apr-util\test\testdbm.c component:
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * &lt;http://www.apache.org/&gt;.
+ *
+ * This file came from the SDBM package (written by oz@nexus.yorku.ca).
+ * That package was under public domain. This file has been ported to
+ * APR, updated to ANSI C and other, newer idioms, and added to the Apache
+ * codebase under the above copyright and license.
+ */
+
+
+For the srclib\apr-util\test\testmd4.c component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ * rights reserved.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\xml\expat\conftools\install-sh component:
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+
+For the srclib\pcre\install-sh component:
+
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+
+For the pcre component:
+
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Written by: Philip Hazel &lt;ph10@cam.ac.uk&gt;
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2001 University of Cambridge
+
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission. In practice, this means that if you use
+   PCRE in software which you distribute to others, commercially or
+   otherwise, you must put a sentence like this
+
+     Regular expression support is provided by the PCRE library package,
+     which is open source software, written by Philip Hazel, and copyright
+     by the University of Cambridge, England.
+
+   somewhere reasonably visible in your documentation and in any relevant
+   files or online help data or similar. A reference to the ftp site for
+   the source, that is, to
+
+     ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+
+   should also be given in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL),
+   then the terms of that licence shall supersede any condition above with
+   which it is incompatible.
+
+The documentation for PCRE, supplied in the "doc" directory, is distributed
+under the same terms as the software itself.
+
+End PCRE LICENCE
+
+
+For the test\zb.c component:
+
+/*                          ZeusBench V1.01
+			    ===============
+
+This program is Copyright (C) Zeus Technology Limited 1996.
+
+This program may be used and copied freely providing this copyright notice
+is not removed.
+
+This software is provided "as is" and any express or implied waranties, 
+including but not limited to, the implied warranties of merchantability and
+fitness for a particular purpose are disclaimed.  In no event shall 
+Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, 
+exemplary, or consequential damaged (including, but not limited to, 
+procurement of substitute good or services; loss of use, data, or profits;
+or business interruption) however caused and on theory of liability.  Whether
+in contract, strict liability or tort (including negligence or otherwise) 
+arising in any way out of the use of this software, even if advised of the
+possibility of such damage.
+
+     Written by Adam Twiss (adam@zeus.co.uk).  March 1996
+
+Thanks to the following people for their input:
+  Mike Belshe (mbelshe@netscape.com) 
+  Michael Campanella (campanella@stevms.enet.dec.com)
+
+*/
+
+For the expat xml parser component:
+
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+                               and Clark Cooper
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+	
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+	
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====================================================================
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">chromeos-pinyin</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="https://code.google.com/p/google-input-tools/">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License Apache-2.0:
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+
+APACHE HTTP SERVER SUBCOMPONENTS: 
+
+The Apache HTTP Server includes a number of subcomponents with
+separate copyright notices and license terms. Your use of the source
+code for the these subcomponents is subject to the terms and
+conditions of the following licenses. 
+
+For the mod_mime_magic component:
+
+/*
+ * mod_mime_magic: MIME type lookup via file magic numbers
+ * Copyright (c) 1996-1997 Cisco Systems, Inc.
+ *
+ * This software was submitted by Cisco Systems to the Apache Group in July
+ * 1997.  Future revisions and derivatives of this source code must
+ * acknowledge Cisco Systems as the original contributor of this module.
+ * All other licensing and usage conditions are those of the Apache Group.
+ *
+ * Some of this code is derived from the free version of the file command
+ * originally posted to comp.sources.unix.  Copyright info for that program
+ * is included below as required.
+ * ---------------------------------------------------------------------------
+ * - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone and
+ * Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on any
+ * computer system, and to alter it and redistribute it freely, subject to
+ * the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission.  Since few users ever read sources, credits
+ * must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.  Since few users ever read
+ * sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ * -------------------------------------------------------------------------
+ *
+ */
+
+
+For the  modules\mappers\mod_imap.c component:
+
+  "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
+
+For the  server\util_md5.c component:
+
+/************************************************************************
+ * NCSA HTTPd Server
+ * Software Development Group
+ * National Center for Supercomputing Applications
+ * University of Illinois at Urbana-Champaign
+ * 605 E. Springfield, Champaign, IL 61820
+ * httpd@ncsa.uiuc.edu
+ *
+ * Copyright  (C)  1995, Board of Trustees of the University of Illinois
+ *
+ ************************************************************************
+ *
+ * md5.c: NCSA HTTPd code which uses the md5c.c RSA Code
+ *
+ *  Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc.
+ *  Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon
+ *     University (see Copyright below).
+ *  Portions of Content-MD5 code Copyright (C) 1991 Bell Communications 
+ *     Research, Inc. (Bellcore) (see Copyright below).
+ *  Portions extracted from mpack, John G. Myers - jgm+@cmu.edu
+ *  Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk)
+ *
+ */
+
+
+/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */
+/* (C) Copyright 1993,1994 by Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Carnegie
+ * Mellon University not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  Carnegie Mellon University makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
+ *
+ * Permission to use, copy, modify, and distribute this material
+ * for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice
+ * appear in all copies, and that the name of Bellcore not be
+ * used in advertising or publicity pertaining to this
+ * material without the specific, prior written permission
+ * of an authorized representative of Bellcore.  BELLCORE
+ * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
+ * OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS",
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.  
+ */
+
+For the  srclib\apr\include\apr_md5.h component: 
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+
+For the  srclib\apr\passwd\apr_md5.c component:
+
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+/*
+ * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
+ * MD5 crypt() function, which is licenced as follows:
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * &lt;phk@login.dknet.dk&gt; wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.  Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+For the srclib\apr-util\crypto\apr_md4.c component:
+
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\include\apr_md4.h component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+
+For the srclib\apr-util\test\testdbm.c component:
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * &lt;http://www.apache.org/&gt;.
+ *
+ * This file came from the SDBM package (written by oz@nexus.yorku.ca).
+ * That package was under public domain. This file has been ported to
+ * APR, updated to ANSI C and other, newer idioms, and added to the Apache
+ * codebase under the above copyright and license.
+ */
+
+
+For the srclib\apr-util\test\testmd4.c component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ * rights reserved.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\xml\expat\conftools\install-sh component:
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+
+For the srclib\pcre\install-sh component:
+
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+
+For the pcre component:
+
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Written by: Philip Hazel &lt;ph10@cam.ac.uk&gt;
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2001 University of Cambridge
+
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission. In practice, this means that if you use
+   PCRE in software which you distribute to others, commercially or
+   otherwise, you must put a sentence like this
+
+     Regular expression support is provided by the PCRE library package,
+     which is open source software, written by Philip Hazel, and copyright
+     by the University of Cambridge, England.
+
+   somewhere reasonably visible in your documentation and in any relevant
+   files or online help data or similar. A reference to the ftp site for
+   the source, that is, to
+
+     ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+
+   should also be given in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL),
+   then the terms of that licence shall supersede any condition above with
+   which it is incompatible.
+
+The documentation for PCRE, supplied in the "doc" directory, is distributed
+under the same terms as the software itself.
+
+End PCRE LICENCE
+
+
+For the test\zb.c component:
+
+/*                          ZeusBench V1.01
+			    ===============
+
+This program is Copyright (C) Zeus Technology Limited 1996.
+
+This program may be used and copied freely providing this copyright notice
+is not removed.
+
+This software is provided "as is" and any express or implied waranties, 
+including but not limited to, the implied warranties of merchantability and
+fitness for a particular purpose are disclaimed.  In no event shall 
+Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, 
+exemplary, or consequential damaged (including, but not limited to, 
+procurement of substitute good or services; loss of use, data, or profits;
+or business interruption) however caused and on theory of liability.  Whether
+in contract, strict liability or tort (including negligence or otherwise) 
+arising in any way out of the use of this software, even if advised of the
+possibility of such damage.
+
+     Written by Adam Twiss (adam@zeus.co.uk).  March 1996
+
+Thanks to the following people for their input:
+  Mike Belshe (mbelshe@netscape.com) 
+  Michael Campanella (campanella@stevms.enet.dec.com)
+
+*/
+
+For the expat xml parser component:
+
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+                               and Clark Cooper
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+	
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+	
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====================================================================
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">chromeos-zhuyin</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="https://code.google.com/p/google-input-tools/">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License Apache-2.0:
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+
+APACHE HTTP SERVER SUBCOMPONENTS: 
+
+The Apache HTTP Server includes a number of subcomponents with
+separate copyright notices and license terms. Your use of the source
+code for the these subcomponents is subject to the terms and
+conditions of the following licenses. 
+
+For the mod_mime_magic component:
+
+/*
+ * mod_mime_magic: MIME type lookup via file magic numbers
+ * Copyright (c) 1996-1997 Cisco Systems, Inc.
+ *
+ * This software was submitted by Cisco Systems to the Apache Group in July
+ * 1997.  Future revisions and derivatives of this source code must
+ * acknowledge Cisco Systems as the original contributor of this module.
+ * All other licensing and usage conditions are those of the Apache Group.
+ *
+ * Some of this code is derived from the free version of the file command
+ * originally posted to comp.sources.unix.  Copyright info for that program
+ * is included below as required.
+ * ---------------------------------------------------------------------------
+ * - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone and
+ * Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on any
+ * computer system, and to alter it and redistribute it freely, subject to
+ * the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission.  Since few users ever read sources, credits
+ * must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.  Since few users ever read
+ * sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ * -------------------------------------------------------------------------
+ *
+ */
+
+
+For the  modules\mappers\mod_imap.c component:
+
+  "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
+
+For the  server\util_md5.c component:
+
+/************************************************************************
+ * NCSA HTTPd Server
+ * Software Development Group
+ * National Center for Supercomputing Applications
+ * University of Illinois at Urbana-Champaign
+ * 605 E. Springfield, Champaign, IL 61820
+ * httpd@ncsa.uiuc.edu
+ *
+ * Copyright  (C)  1995, Board of Trustees of the University of Illinois
+ *
+ ************************************************************************
+ *
+ * md5.c: NCSA HTTPd code which uses the md5c.c RSA Code
+ *
+ *  Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc.
+ *  Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon
+ *     University (see Copyright below).
+ *  Portions of Content-MD5 code Copyright (C) 1991 Bell Communications 
+ *     Research, Inc. (Bellcore) (see Copyright below).
+ *  Portions extracted from mpack, John G. Myers - jgm+@cmu.edu
+ *  Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk)
+ *
+ */
+
+
+/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */
+/* (C) Copyright 1993,1994 by Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Carnegie
+ * Mellon University not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  Carnegie Mellon University makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
+ *
+ * Permission to use, copy, modify, and distribute this material
+ * for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice
+ * appear in all copies, and that the name of Bellcore not be
+ * used in advertising or publicity pertaining to this
+ * material without the specific, prior written permission
+ * of an authorized representative of Bellcore.  BELLCORE
+ * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
+ * OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS",
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.  
+ */
+
+For the  srclib\apr\include\apr_md5.h component: 
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+
+For the  srclib\apr\passwd\apr_md5.c component:
+
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+/*
+ * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
+ * MD5 crypt() function, which is licenced as follows:
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * &lt;phk@login.dknet.dk&gt; wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.  Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+For the srclib\apr-util\crypto\apr_md4.c component:
+
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\include\apr_md4.h component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+
+For the srclib\apr-util\test\testdbm.c component:
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * &lt;http://www.apache.org/&gt;.
+ *
+ * This file came from the SDBM package (written by oz@nexus.yorku.ca).
+ * That package was under public domain. This file has been ported to
+ * APR, updated to ANSI C and other, newer idioms, and added to the Apache
+ * codebase under the above copyright and license.
+ */
+
+
+For the srclib\apr-util\test\testmd4.c component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ * rights reserved.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\xml\expat\conftools\install-sh component:
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+
+For the srclib\pcre\install-sh component:
+
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+
+For the pcre component:
+
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Written by: Philip Hazel &lt;ph10@cam.ac.uk&gt;
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2001 University of Cambridge
+
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission. In practice, this means that if you use
+   PCRE in software which you distribute to others, commercially or
+   otherwise, you must put a sentence like this
+
+     Regular expression support is provided by the PCRE library package,
+     which is open source software, written by Philip Hazel, and copyright
+     by the University of Cambridge, England.
+
+   somewhere reasonably visible in your documentation and in any relevant
+   files or online help data or similar. A reference to the ftp site for
+   the source, that is, to
+
+     ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+
+   should also be given in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL),
+   then the terms of that licence shall supersede any condition above with
+   which it is incompatible.
+
+The documentation for PCRE, supplied in the "doc" directory, is distributed
+under the same terms as the software itself.
+
+End PCRE LICENCE
+
+
+For the test\zb.c component:
+
+/*                          ZeusBench V1.01
+			    ===============
+
+This program is Copyright (C) Zeus Technology Limited 1996.
+
+This program may be used and copied freely providing this copyright notice
+is not removed.
+
+This software is provided "as is" and any express or implied waranties, 
+including but not limited to, the implied warranties of merchantability and
+fitness for a particular purpose are disclaimed.  In no event shall 
+Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, 
+exemplary, or consequential damaged (including, but not limited to, 
+procurement of substitute good or services; loss of use, data, or profits;
+or business interruption) however caused and on theory of liability.  Whether
+in contract, strict liability or tort (including negligence or otherwise) 
+arising in any way out of the use of this software, even if advised of the
+possibility of such damage.
+
+     Written by Adam Twiss (adam@zeus.co.uk).  March 1996
+
+Thanks to the following people for their input:
+  Mike Belshe (mbelshe@netscape.com) 
+  Michael Campanella (campanella@stevms.enet.dec.com)
+
+*/
+
+For the expat xml parser component:
+
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+                               and Clark Cooper
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+	
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+	
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====================================================================
+
+
+
 </pre>
 </div>
 </div>
@@ -9655,10 +12536,11 @@
 
 <div class="product">
 <span class="title">chvt</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -9998,6 +12880,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -10005,10 +12890,12 @@
 
 <div class="product">
 <span class="title">coreutils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/coreutils/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license coreutils-8.20/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -10682,6 +13569,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -10689,10 +13578,12 @@
 
 <div class="product">
 <span class="title">crda</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://wireless.kernel.org/en/developers/Regulatory">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2008, Luis R. Rodriguez &lt;mcgrof@gmail.com&gt;
+<pre>Source license crda-1.1.1/LICENSE:
+
+Copyright (c) 2008, Luis R. Rodriguez &lt;mcgrof@gmail.com&gt;
 Copyright (c) 2008, Johannes Berg &lt;johannes@sipsolutions.net&gt;
 Copyright (c) 2008, Michael Green &lt;Michael.Green@Atheros.com&gt;
 
@@ -10708,6 +13599,8 @@
 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
+
+
 </pre>
 </div>
 </div>
@@ -10715,10 +13608,11 @@
 
 <div class="product">
 <span class="title">croscorefonts</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="">homepage</a></span>
 <div class="licence">
-<pre>                                 Apache License
+<pre>Gentoo Package Provided Stock License Apache-2.0:
+                                 Apache License
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
 
@@ -11396,6 +14290,9 @@
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 ====================================================================
+
+
+
 </pre>
 </div>
 </div>
@@ -11403,10 +14300,11 @@
 
 <div class="product">
 <span class="title">crosextrafonts</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="">homepage</a></span>
 <div class="licence">
-<pre>                                 Apache License
+<pre>Gentoo Package Provided Stock License Apache-2.0:
+                                 Apache License
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
 
@@ -12084,6 +14982,9 @@
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 ====================================================================
+
+
+
 </pre>
 </div>
 </div>
@@ -12091,10 +14992,12 @@
 
 <div class="product">
 <span class="title">ctemplate</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/google-ctemplate/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2005, Google Inc.
+<pre>Source license ctemplate-1.0/COPYING:
+
+Copyright (c) 2005, Google Inc.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -12122,6 +15025,8 @@
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
 </pre>
 </div>
 </div>
@@ -12129,10 +15034,12 @@
 
 <div class="product">
 <span class="title">curl</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://curl.haxx.se/">homepage</a></span>
 <div class="licence">
-<pre>COPYRIGHT AND PERMISSION NOTICE
+<pre>Source license curl-7.23.1/COPYING:
+
+COPYRIGHT AND PERMISSION NOTICE
 
 Copyright (c) 1996 - 2011, Daniel Stenberg, &lt;daniel@haxx.se&gt;.
 
@@ -12153,6 +15060,8 @@
 Except as contained in this notice, the name of a copyright holder shall not
 be used in advertising or otherwise to promote the sale, use or other dealings
 in this Software without prior written authorization of the copyright holder.
+
+
 </pre>
 </div>
 </div>
@@ -12160,10 +15069,12 @@
 
 <div class="product">
 <span class="title">dash</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://gondor.apana.org.au/~herbert/dash/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 1989-1994
+<pre>Source license dash-0.5.5.1/COPYING:
+
+Copyright (c) 1989-1994
 	The Regents of the University of California.  All rights reserved.
 Copyright (c) 1997 Christos Zoulas.  All rights reserved.
 Copyright (c) 1997-2005
@@ -12219,6 +15130,8 @@
 Debian GNU/Linux hello source package as the file COPYING.  If not,
 write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 Boston, MA 02111 USA.
+
+
 </pre>
 </div>
 </div>
@@ -12226,10 +15139,12 @@
 
 <div class="product">
 <span class="title">dbus</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://dbus.freedesktop.org/">homepage</a></span>
 <div class="licence">
-<pre>D-Bus is licensed to you under your choice of the Academic Free
+<pre>Source license dbus-1.6.8/COPYING:
+
+D-Bus is licensed to you under your choice of the Academic Free
 License version 2.1, or the GNU General Public License version 2
 (or, at your option any later version).
 
@@ -12781,6 +15696,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -12788,10 +15705,12 @@
 
 <div class="product">
 <span class="title">dbus-c++</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.freedesktop.org/wiki/Software/dbus-c%2B%2B">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Source license dbus-c++-0.0.2/COPYING:
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -13295,6 +16214,8 @@
 That's all there is to it!
 
 
+
+
 </pre>
 </div>
 </div>
@@ -13302,10 +16223,12 @@
 
 <div class="product">
 <span class="title">dbus-glib</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://dbus.freedesktop.org/">homepage</a></span>
 <div class="licence">
-<pre>The D-Bus glib bindings are licensed to you under your choice of the Academic
+<pre>Source license dbus-glib-0.100/COPYING:
+
+The D-Bus glib bindings are licensed to you under your choice of the Academic
 Free License version 2.1, or the GNU General Public License version 2.  Both
 licenses are included here. Some of the standalone binaries are under the GPL
 only; in particular, but not limted to, tests/decode-gcov.c. Each source code
@@ -13855,6 +16778,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -13862,10 +16787,12 @@
 
 <div class="product">
 <span class="title">ddccontrol</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://ddccontrol.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license ddccontrol-0.4.2/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -14205,6 +17132,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -14212,10 +17141,12 @@
 
 <div class="product">
 <span class="title">ddccontrol-db</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://ddccontrol.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license ddccontrol-db-20061014/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -14555,6 +17486,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -14562,10 +17495,12 @@
 
 <div class="product">
 <span class="title">dejavu</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://dejavu.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
+<pre>Source license dejavu-fonts-ttf-2.33/LICENSE:
+
+Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
 Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
 
 Bitstream Vera Fonts Copyright
@@ -14664,6 +17599,8 @@
 . fr.
 
 $Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $
+
+
 </pre>
 </div>
 </div>
@@ -14671,10 +17608,11 @@
 
 <div class="product">
 <span class="title">dhcpcd</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://roy.marples.name/projects/dhcpcd/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2006-2010 Roy Marples &lt;roy@marples.name&gt;
+<pre>Gentoo Package Provided Stock License BSD-dhcpcd:
+Copyright (c) 2006-2010 Roy Marples &lt;roy@marples.name&gt;
 All rights reserved
 
 Redistribution and use in source and binary forms, with or without
@@ -14697,6 +17635,9 @@
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 SUCH DAMAGE.
+
+
+
 </pre>
 </div>
 </div>
@@ -14704,10 +17645,12 @@
 
 <div class="product">
 <span class="title">diffutils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/diffutils/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license diffutils-3.2/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -15381,6 +18324,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -15388,10 +18333,12 @@
 
 <div class="product">
 <span class="title">dmidecode</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.nongnu.org/dmidecode/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license dmidecode-2.10/LICENSE:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -15731,6 +18678,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -15738,10 +18687,12 @@
 
 <div class="product">
 <span class="title">dosfstools</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.daniel-baumann.ch/software/dosfstools/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license dosfstools-3.0.9/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -16415,6 +19366,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -16422,10 +19375,11 @@
 
 <div class="product">
 <span class="title">droidfonts-cros</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="">homepage</a></span>
 <div class="licence">
-<pre>                                 Apache License
+<pre>Gentoo Package Provided Stock License Apache-2.0:
+                                 Apache License
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
 
@@ -17103,6 +20057,9 @@
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 ====================================================================
+
+
+
 </pre>
 </div>
 </div>
@@ -17110,10 +20067,11 @@
 
 <div class="product">
 <span class="title">dtc</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.t2-project.org/packages/dtc.html">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -17453,6 +20411,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -17460,10 +20421,12 @@
 
 <div class="product">
 <span class="title">e2fsprogs</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://e2fsprogs.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>This package, the EXT2 filesystem utilities, are made available under
+<pre>Source license e2fsprogs-1.42/COPYING:
+
+This package, the EXT2 filesystem utilities, are made available under
 the GNU Public License version 2, with the exception of the lib/ext2fs
 and lib/e2p libraries, which are made available under the GNU Library
 General Public License Version 2, the lib/uuid library which is made
@@ -18312,6 +21275,8 @@
   Ty Coon, President of Vice
 
 That's all there is to it!
+
+
 </pre>
 </div>
 </div>
@@ -18319,10 +21284,12 @@
 
 <div class="product">
 <span class="title">e2fsprogs-libs</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://e2fsprogs.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>This package, the EXT2 filesystem utilities, are made available under
+<pre>Source license e2fsprogs-libs-1.42/COPYING:
+
+This package, the EXT2 filesystem utilities, are made available under
 the GNU Public License version 2, with the exception of the lib/ext2fs
 and lib/e2p libraries, which are made available under the GNU Library
 General Public License Version 2, the lib/uuid library which is made
@@ -19171,6 +22138,8 @@
   Ty Coon, President of Vice
 
 That's all there is to it!
+
+
 </pre>
 </div>
 </div>
@@ -19178,10 +22147,12 @@
 
 <div class="product">
 <span class="title">ecryptfs-utils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="https://launchpad.net/ecryptfs">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license ecryptfs-utils-101/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -19520,6 +22491,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -19527,10 +22500,12 @@
 
 <div class="product">
 <span class="title">eject</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://eject.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license eject/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -19869,6 +22844,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -19876,10 +22853,12 @@
 
 <div class="product">
 <span class="title">elfutils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="https://fedorahosted.org/elfutils/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license elfutils-0.154/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -20553,6 +23532,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -20560,10 +23541,11 @@
 
 <div class="product">
 <span class="title">engine_pkcs11</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.opensc-project.org/engine_pkcs11">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License LGPL-2.1:
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -21067,6 +24049,9 @@
 That's all there is to it!
 
 
+
+
+
 </pre>
 </div>
 </div>
@@ -21074,10 +24059,11 @@
 
 <div class="product">
 <span class="title">eselect-opengl</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gentoo.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -21417,6 +24403,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -21424,10 +24413,11 @@
 
 <div class="product">
 <span class="title">eselect-python</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gentoo.org">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -21767,6 +24757,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -21774,10 +24767,12 @@
 
 <div class="product">
 <span class="title">ethtool</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://sourceforge.net/projects/gkernel/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license ethtool-6/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -22117,6 +25112,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -22124,10 +25121,12 @@
 
 <div class="product">
 <span class="title">exfat-utils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/exfat/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license exfat-utils-0.9.8/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -22801,6 +25800,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -22808,10 +25809,12 @@
 
 <div class="product">
 <span class="title">expat</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://expat.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+<pre>Source license expat-2.1.0/COPYING:
+
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
                                and Clark Cooper
 Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.
 
@@ -22833,6 +25836,8 @@
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
 </pre>
 </div>
 </div>
@@ -22840,10 +25845,12 @@
 
 <div class="product">
 <span class="title">findutils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/findutils/">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license findutils-4.4.2/COPYING:
+
+
 		    GNU GENERAL PUBLIC LICENSE
 		       Version 3, 29 June 2007
 
@@ -23519,6 +26526,55 @@
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
 
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">flashmap</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://flashmap.googlecode.com">homepage</a></span>
+<div class="licence">
+<pre>Source license flashmap-0.3/COPYING:
+
+2010, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+* Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Alternatively, this software may be distributed under the terms of the
+GNU General Public License ("GPL") version 2 as published by the Free
+Software Foundation.
+
+
+
 </pre>
 </div>
 </div>
@@ -23526,10 +26582,12 @@
 
 <div class="product">
 <span class="title">flashrom</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://flashrom.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license flashrom-0.9.4/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -23868,6 +26926,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -23875,10 +26935,12 @@
 
 <div class="product">
 <span class="title">flex</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://flex.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>Flex carries the copyright used for BSD software, slightly modified
+<pre>Source license flex-2.5.35/COPYING:
+
+Flex carries the copyright used for BSD software, slightly modified
 because it originated at the Lawrence Berkeley (not Livermore!) Laboratory,
 which operates under a contract with the Department of Energy:
 
@@ -23920,6 +26982,8 @@
 Note that the "flex.skl" scanner skeleton carries no copyright notice.
 You are free to do whatever you please with scanners generated using flex;
 for them, you are not even bound by the above copyright.
+
+
 </pre>
 </div>
 </div>
@@ -23927,10 +26991,12 @@
 
 <div class="product">
 <span class="title">font-util</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://xorg.freedesktop.org/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+<pre>Source license font-util-1.2.0/COPYING:
+
+Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -24050,6 +27116,8 @@
 Unicode Standard, and to make copies of this file in any form for
 internal or external distribution as long as this notice remains
 attached.
+
+
 </pre>
 </div>
 </div>
@@ -24057,10 +27125,12 @@
 
 <div class="product">
 <span class="title">fontconfig</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://fontconfig.org/">homepage</a></span>
 <div class="licence">
-<pre>fontconfig/COPYING
+<pre>Source license fontconfig-2.7.1/COPYING:
+
+fontconfig/COPYING
 
 Copyright © 2001,2003 Keith Packard
 
@@ -24082,6 +27152,8 @@
 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 PERFORMANCE OF THIS SOFTWARE.
 
+
+
 </pre>
 </div>
 </div>
@@ -24089,10 +27161,11 @@
 
 <div class="product">
 <span class="title">freetype</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.freetype.org/">homepage</a></span>
 <div class="licence">
-<pre>                    The FreeType Project LICENSE
+<pre>Gentoo Package Provided Stock License FTL:
+                    The FreeType Project LICENSE
                     ----------------------------
 
                        Copyright 1996-1999 by
@@ -24251,6 +27324,10 @@
 
 --- end of license.txt ---
 
+
+
+
+Gentoo Package Provided Stock License GPL-2:
 		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
@@ -24591,6 +27668,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -24598,10 +27678,12 @@
 
 <div class="product">
 <span class="title">fuse</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://fuse.sourceforge.net">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license fuse-2.8.6/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -24941,6 +28023,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -24948,10 +28032,12 @@
 
 <div class="product">
 <span class="title">fuse-exfat</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/exfat/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license fuse-exfat-0.9.8/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -25625,6 +28711,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -25632,10 +28720,12 @@
 
 <div class="product">
 <span class="title">gdbm</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/gdbm/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license gdbm-1.9.1/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 3, 29 June 2007
 
  Copyright (C) 2007, 2011 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -26309,6 +29399,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -26316,10 +29408,12 @@
 
 <div class="product">
 <span class="title">gflags</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/google-gflags/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2006, Google Inc.
+<pre>Source license gflags-1.2/COPYING:
+
+Copyright (c) 2006, Google Inc.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -26347,6 +29441,8 @@
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
 </pre>
 </div>
 </div>
@@ -26354,10 +29450,12 @@
 
 <div class="product">
 <span class="title">glew</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://glew.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>The OpenGL Extension Wrangler Library
+<pre>Source license glew-1.5.6/LICENSE.txt:
+
+The OpenGL Extension Wrangler Library
 Copyright (C) 2002-2007, Milan Ikits &lt;milan ikits[]ieee org&gt;
 Copyright (C) 2002-2007, Marcelo E. Magallon &lt;mmagallo[]debian org&gt;
 Copyright (C) 2002, Lev Povalahev
@@ -26430,6 +29528,8 @@
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+
 </pre>
 </div>
 </div>
@@ -26437,10 +29537,12 @@
 
 <div class="product">
 <span class="title">glib</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gtk.org/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LIBRARY GENERAL PUBLIC LICENSE
+<pre>Source license glib-2.32.4/COPYING:
+
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1991 Free Software Foundation, Inc.
@@ -26922,6 +30024,351 @@
   Ty Coon, President of Vice
 
 That's all there is to it!
+
+
+Source license pkg-config-0.26/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    &lt;one line to give the program's name and a brief idea of what it does.&gt;
+    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  &lt;signature of Ty Coon&gt;, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -26929,10 +30376,12 @@
 
 <div class="product">
 <span class="title">glog</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/google-glog/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2008, Google Inc.
+<pre>Source license glog-0.3.2/COPYING:
+
+Copyright (c) 2008, Google Inc.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -26997,6 +30446,8 @@
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
 </pre>
 </div>
 </div>
@@ -27004,10 +30455,12 @@
 
 <div class="product">
 <span class="title">glproto</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.x.org/">homepage</a></span>
 <div class="licence">
-<pre>SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+<pre>Source license glproto-1.4.14/COPYING:
+
+SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a
@@ -27034,6 +30487,8 @@
 shall not be used in advertising or otherwise to promote the sale, use or
 other dealings in this Software without prior written authorization from
 Silicon Graphics, Inc.
+
+
 </pre>
 </div>
 </div>
@@ -27041,10 +30496,11 @@
 
 <div class="product">
 <span class="title">glu</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://cgit.freedesktop.org/mesa/glu/">homepage</a></span>
 <div class="licence">
-<pre>SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+<pre>Gentoo Package Provided Stock License SGI-B-2.0:
+SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 
 Copyright (C) [dates of first publication] Silicon Graphics, Inc. All Rights
 Reserved.
@@ -27071,6 +30527,9 @@
 not be used in advertising or otherwise to promote the sale, use or other
 dealings in this Software without prior written authorization from Silicon
 Graphics, Inc.
+
+
+
 </pre>
 </div>
 </div>
@@ -27078,10 +30537,12 @@
 
 <div class="product">
 <span class="title">gmock</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/googlemock/">homepage</a></span>
 <div class="licence">
-<pre>Copyright 2008, Google Inc.
+<pre>Source license gmock-1.6.0/COPYING:
+
+Copyright 2008, Google Inc.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -27109,6 +30570,8 @@
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
 </pre>
 </div>
 </div>
@@ -27116,694 +30579,11 @@
 
 <div class="product">
 <span class="title">gmp</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://gmplib.org/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    &lt;one line to give the program's name and a brief idea of what it does.&gt;
-    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    &lt;program&gt;  Copyright (C) &lt;year&gt;  &lt;name of author&gt;
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-&lt;http://www.gnu.org/licenses/&gt;.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-&lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
-</pre>
-</div>
-</div>
-
+<pre>Source license gmp-5.0.2/COPYING:
 
-<div class="product">
-<span class="title">grep</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
-<span class="homepage"><a href="http://www.gnu.org/software/grep/">homepage</a></span>
-<div class="licence">
-<pre>
                     GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
@@ -28478,6 +31258,697 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">grep</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://www.gnu.org/software/grep/">homepage</a></span>
+<div class="licence">
+<pre>Source license grep-2.14/COPYING:
+
+
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    &lt;one line to give the program's name and a brief idea of what it does.&gt;
+    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    &lt;program&gt;  Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+&lt;http://www.gnu.org/licenses/&gt;.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+&lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -28485,10 +31956,12 @@
 
 <div class="product">
 <span class="title">gtest</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/googletest/">homepage</a></span>
 <div class="licence">
-<pre>Copyright 2008, Google Inc.
+<pre>Source license gtest-1.6.0/COPYING:
+
+Copyright 2008, Google Inc.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -28516,6 +31989,8 @@
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
 </pre>
 </div>
 </div>
@@ -28523,10 +31998,12 @@
 
 <div class="product">
 <span class="title">gtk+</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gtk.org/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LIBRARY GENERAL PUBLIC LICENSE
+<pre>Source license gtk+-2.20.1/COPYING:
+
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1991 Free Software Foundation, Inc.
@@ -29008,6 +32485,8 @@
   Ty Coon, President of Vice
 
 That's all there is to it!
+
+
 </pre>
 </div>
 </div>
@@ -29015,10 +32494,12 @@
 
 <div class="product">
 <span class="title">gtk-doc-am</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gtk.org/gtk-doc/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license gtk-doc-1.18/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -29692,6 +33173,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -29699,10 +33182,12 @@
 
 <div class="product">
 <span class="title">gzip</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/gzip/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license gzip-1.5/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -30376,6 +33861,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -30383,10 +33870,12 @@
 
 <div class="product">
 <span class="title">hdparm</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://sourceforge.net/projects/hdparm/">homepage</a></span>
 <div class="licence">
-<pre>BSD-Style Open Source License:
+<pre>Source license hdparm-9.20/LICENSE.TXT:
+
+BSD-Style Open Source License:
 
 You may freely use, modify, and redistribute the hdparm program,
 as either binary or source, or both.
@@ -30395,6 +33884,8 @@
 remain in the source code as-is.
 
 Mark Lord (mlord@pobox.com)
+
+
 </pre>
 </div>
 </div>
@@ -30402,10 +33893,11 @@
 
 <div class="product">
 <span class="title">htpdate</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.clevervest.com/htp/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -30745,6 +34237,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -30752,10 +34247,11 @@
 
 <div class="product">
 <span class="title">hwids</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="https://github.com/gentoo/hwids">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -31095,6 +34591,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -31102,10 +34601,12 @@
 
 <div class="product">
 <span class="title">ibus</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/ibus/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Source license ibus-1.4.99.20120314/COPYING:
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -31609,6 +35110,8 @@
 That's all there is to it!
 
 
+
+
 </pre>
 </div>
 </div>
@@ -31616,10 +35119,12 @@
 
 <div class="product">
 <span class="title">ibus-english-m</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://github.com/yusukes/ibus-zinnia">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license yusukes-ibus-zinnia-910d66d/COPYING:
+
+
                                  Apache License
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
@@ -31821,6 +35326,8 @@
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
+
+
 </pre>
 </div>
 </div>
@@ -31828,10 +35335,12 @@
 
 <div class="product">
 <span class="title">ibus-m17n</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/ibus/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license ibus-m17n-1.3.3/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -32170,6 +35679,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -32177,10 +35688,12 @@
 
 <div class="product">
 <span class="title">iniparser</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://ndevilla.free.fr/iniparser/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2000-2007 by Nicolas Devillard.
+<pre>Source license iniparser3.0b/LICENSE:
+
+Copyright (c) 2000-2007 by Nicolas Devillard.
 MIT License
 
 Permission is hereby granted, free of charge, to any person obtaining a
@@ -32201,44 +35714,8 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 
-</pre>
-</div>
-</div>
 
 
-<div class="product">
-<span class="title">input-tools</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
-<span class="homepage"><a href="http://www.google.com/inputtools">homepage</a></span>
-<div class="licence">
-<pre>Copyright 2010, Google Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 </pre>
 </div>
 </div>
@@ -32246,10 +35723,12 @@
 
 <div class="product">
 <span class="title">intltool</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://edge.launchpad.net/intltool/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license intltool-0.41.0/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -32589,355 +36068,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
-</pre>
-</div>
-</div>
 
 
-<div class="product">
-<span class="title">iotools</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
-<span class="homepage"><a href="http://code.google.com/p/iotools/">homepage</a></span>
-<div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    &lt;one line to give the program's name and a brief idea of what it does.&gt;
-    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  &lt;signature of Ty Coon&gt;, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
 </pre>
 </div>
 </div>
@@ -32945,10 +36077,12 @@
 
 <div class="product">
 <span class="title">iptables</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.iptables.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license iptables-1.4.8/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -33287,6 +36421,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -33294,10 +36430,11 @@
 
 <div class="product">
 <span class="title">iputils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.linux-foundation.org/en/Net:Iputils">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 1989 The Regents of the University of California.
+<pre>Gentoo Package Provided Stock License BSD-iputils:
+Copyright (c) 1989 The Regents of the University of California.
 All rights reserved.
 
 This code is derived from software contributed to Berkeley by
@@ -33330,6 +36467,9 @@
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 SUCH DAMAGE.
+
+
+
 </pre>
 </div>
 </div>
@@ -33337,10 +36477,12 @@
 
 <div class="product">
 <span class="title">iw</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://wireless.kernel.org/en/users/Documentation/iw">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2007, 2008	Johannes Berg
+<pre>Source license iw-3.6/COPYING:
+
+Copyright (c) 2007, 2008	Johannes Berg
 Copyright (c) 2007		Andy Lutomirski
 Copyright (c) 2007		Mike Kershaw
 Copyright (c) 2008-2009		Luis R. Rodriguez
@@ -33356,6 +36498,669 @@
 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">iwl1000-ucode</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://intellinuxwireless.org/?p=iwlwifi">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License ipw3945:
+Copyright (c) 2006, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+  following disclaimer in the documentation and/or other materials
+  provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses.  The patent license shall not apply to
+any other combinations which include this software.  No hardware per
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">iwl2000-ucode</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://intellinuxwireless.org/?p=iwlwifi">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License ipw3945:
+Copyright (c) 2006, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+  following disclaimer in the documentation and/or other materials
+  provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses.  The patent license shall not apply to
+any other combinations which include this software.  No hardware per
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">iwl2030-ucode</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://intellinuxwireless.org/?p=iwlwifi">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License ipw3945:
+Copyright (c) 2006, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+  following disclaimer in the documentation and/or other materials
+  provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses.  The patent license shall not apply to
+any other combinations which include this software.  No hardware per
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">iwl3945-ucode</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://intellinuxwireless.org/?p=iwlwifi">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License ipw3945:
+Copyright (c) 2006, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+  following disclaimer in the documentation and/or other materials
+  provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses.  The patent license shall not apply to
+any other combinations which include this software.  No hardware per
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">iwl4965-ucode</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://intellinuxwireless.org/?p=iwlwifi">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License ipw3945:
+Copyright (c) 2006, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+  following disclaimer in the documentation and/or other materials
+  provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses.  The patent license shall not apply to
+any other combinations which include this software.  No hardware per
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">iwl5000-ucode</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://intellinuxwireless.org/?p=iwlwifi">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License ipw3945:
+Copyright (c) 2006, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+  following disclaimer in the documentation and/or other materials
+  provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses.  The patent license shall not apply to
+any other combinations which include this software.  No hardware per
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">iwl6000-ucode</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://intellinuxwireless.org/?p=iwlwifi">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License ipw3945:
+Copyright (c) 2006, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+  following disclaimer in the documentation and/or other materials
+  provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses.  The patent license shall not apply to
+any other combinations which include this software.  No hardware per
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">iwl6005-ucode</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://intellinuxwireless.org/?p=iwlwifi">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License ipw3945:
+Copyright (c) 2006, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+  following disclaimer in the documentation and/or other materials
+  provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses.  The patent license shall not apply to
+any other combinations which include this software.  No hardware per
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">iwl6030-ucode</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://intellinuxwireless.org/?p=iwlwifi">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License ipw3945:
+Copyright (c) 2006, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+  following disclaimer in the documentation and/or other materials
+  provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses.  The patent license shall not apply to
+any other combinations which include this software.  No hardware per
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">iwl6050-ucode</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://intellinuxwireless.org/?p=iwlwifi">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License ipw3945:
+Copyright (c) 2006, Intel Corporation.
+All rights reserved.
+
+Redistribution.  Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+  following disclaimer in the documentation and/or other materials
+  provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its suppliers
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+  is permitted.
+
+Limited patent license.  Intel Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses.  The patent license shall not apply to
+any other combinations which include this software.  No hardware per
+se is licensed hereunder.
+
+DISCLAIMER.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">ja-ipafonts</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://ossipedia.ipa.go.jp/ipafont/">homepage</a></span>
+<div class="licence">
+<pre>Source license IPAMGTTC00303_r1/LICENSE:
+
+--------------------------------------------------

+IPA Font License Agreement v1.0 &lt;Japanese/English&gt;

+--------------------------------------------------

+

+IPAフォントライセンスv1.0

+

+許諾者は、この使用許諾(以下「本契約」といいます。)に定める条件の下で、許諾プログラム(1条に定義するところによります。)を提供します。受領者(1条に定義するところによります。)が、許諾プログラムを使用し、複製し、または頒布する行為、その他、本契約に定める権利の利用を行った場合、受領者は本契約に同意したものと見なします。

+

+

+第1条 用語の定義

+

+本契約において、次の各号に掲げる用語は、当該各号に定めるところによります。

+

+1.「デジタル・フォント・プログラム」とは、フォントを含み、レンダリングしまたは表示するために用いられるコンピュータ・プログラムをいいます。

+2.「許諾プログラム」とは、許諾者が本契約の下で許諾するデジタル・フォント・プログラムをいいます。

+3.「派生プログラム」とは、許諾プログラムの一部または全部を、改変し、加除修正等し、入れ替え、その他翻案したデジタル・フォント・プログラムをいい、許諾プログラムの一部もしくは全部から文字情報を取り出し、またはデジタル・ドキュメント・ファイルからエンベッドされたフォントを取り出し、取り出された文字情報をそのまま、または改変をなして新たなデジタル・フォント・プログラムとして製作されたものを含みます。

+4.「デジタル・コンテンツ」とは、デジタル・データ形式によってエンド・ユーザに提供される制作物のことをいい、動画・静止画等の映像コンテンツおよびテレビ番組等の放送コンテンツ、ならびに文字テキスト、画像、図形等を含んで構成された制作物を含みます。

+5.「デジタル・ドキュメント・ファイル」とは、PDFファイルその他、各種ソフトウェア・プログラムによって製作されたデジタル・コンテンツであって、その中にフォントを表示するために許諾プログラムの全部または一部が埋め込まれた(エンベッドされた)ものをいいます。フォントが「エンベッドされた」とは、当該フォントが埋め込まれた特定の「デジタル・ドキュメント・ファイル」においてのみ表示されるために使用されている状態を指し、その特定の「デジタル・ドキュメント・ファイル」以外でフォントを表示するために使用できるデジタル・フォント・プログラムに含まれている場合と区別されます。

+6.「コンピュータ」とは、本契約においては、サーバを含みます。

+7.「複製その他の利用」とは、複製、譲渡、頒布、貸与、公衆送信、上映、展示、翻案その他の利用をいいます。

+8.「受領者」とは、許諾プログラムを本契約の下で受領した人をいい、受領者から許諾プログラムを受領した人を含みます。

+

+第2条 使用許諾の付与

+

+許諾者は受領者に対し、本契約の条項に従い、すべての国で、許諾プログラムを使用することを許諾します。ただし、許諾プログラムに存在する一切の権利はすべて許諾者が保有しています。本契約は、本契約で明示的に定められている場合を除き、いかなる意味においても、許諾者が保有する許諾プログラムに関する一切の権利および、いかなる商標、商号、もしくはサービス・マークに関する権利をも受領者に移転するものではありません。

+

+1.受領者は本契約に定める条件に従い、許諾プログラムを任意の数のコンピュータにインストールし、当該コンピュータで使用することができます。

+2.受領者はコンピュータにインストールされた許諾プログラムをそのまま、または改変を行ったうえで、印刷物およびデジタル・コンテンツにおいて、文字テキスト表現等として使用することができます。

+3.受領者は前項の定めに従い作成した印刷物およびデジタル・コンテンツにつき、その商用・非商用の別、および放送、通信、各種記録メディアなどの媒体の形式を問わず、複製その他の利用をすることができます。

+4.受領者がデジタル・ドキュメント・ファイルからエンベッドされたフォントを取り出して派生プログラムを作成した場合には、かかる派生プログラムは本契約に定める条件に従う必要があります。

+5.許諾プログラムのエンベッドされたフォントがデジタル・ドキュメント・ファイル内のデジタル・コンテンツをレンダリングするためにのみ使用される場合において、受領者が当該デジタル・ドキュメント・ファイルを複製その他の利用をする場合には、受領者はかかる行為に関しては本契約の下ではいかなる義務をも負いません。

+6.受領者は、3条2項の定めに従い、商用・非商用を問わず、許諾プログラムをそのままの状態で改変することなく複製して第三者への譲渡し、公衆送信し、その他の方法で再配布することができます(以下、「再配布」といいます。)。

+7.受領者は、上記の許諾プログラムについて定められた条件と同様の条件に従って、派生プログラムを作成し、使用し、複製し、再配布することができます。ただし、受領者が派生プログラムを再配布する場合には、3条1項の定めに従うものとします。

+

+第3条 制限

+

+前条により付与された使用許諾は、以下の制限に服します。

+

+1.派生プログラムが前条4項及び7項に基づき再配布される場合には、以下の全ての条件を満たさなければなりません。

+ (1)派生プログラムを再配布する際には、下記もまた、当該派生プログラムと一緒に再配布され、オンラインで提供され、または、郵送費・媒体及び取扱手数料の合計を超えない実費と引き換えに媒体を郵送する方法により提供されなければなりません。

+  (a)派生プログラムの写し; および

+  (b)派生プログラムを作成する過程でフォント開発プログラムによって作成された追加のファイルであって派生プログラムをさらに加工するにあたって利用できるファイルが存在すれば、当該ファイル

+ (2)派生プログラムの受領者が、派生プログラムを、このライセンスの下で最初にリリースされた許諾プログラム(以下、「オリジナル・プログラム」といいます。)に置き換えることができる方法を再配布するものとします。かかる方法は、オリジナル・ファイルからの差分ファイルの提供、または、派生プログラムをオリジナル・プログラムに置き換える方法を示す指示の提供などが考えられます。

+ (3)派生プログラムを、本契約書に定められた条件の下でライセンスしなければなりません。

+ (4)派生プログラムのプログラム名、フォント名またはファイル名として、許諾プログラムが用いているのと同一の名称、またはこれを含む名称を使用してはなりません。

+ (5)本項の要件を満たすためにオンラインで提供し、または媒体を郵送する方法で提供されるものは、その提供を希望するいかなる者によっても提供が可能です。

+2.受領者が前条6項に基づき許諾プログラムを再配布する場合には、以下の全ての条件を満たさなければなりません。

+ (1)許諾プログラムの名称を変更してはなりません。

+ (2)許諾プログラムに加工その他の改変を加えてはなりません。

+ (3)本契約の写しを許諾プログラムに添付しなければなりません。

+3.許諾プログラムは、現状有姿で提供されており、許諾プログラムまたは派生プログラムについて、許諾者は一切の明示または黙示の保証(権利の所在、非侵害、商品性、特定目的への適合性を含むがこれに限られません)を行いません。いかなる場合にも、その原因を問わず、契約上の責任か厳格責任か過失その他の不法行為責任かにかかわらず、また事前に通知されたか否かにかかわらず、許諾者は、許諾プログラムまたは派生プログラムのインストール、使用、複製その他の利用または本契約上の権利の行使によって生じた一切の損害(直接・間接・付随的・特別・拡大・懲罰的または結果的損害)(商品またはサービスの代替品の調達、システム障害から生じた損害、現存するデータまたはプログラムの紛失または破損、逸失利益を含むがこれに限られません)について責任を負いません。

+4.許諾プログラムまたは派生プログラムのインストール、使用、複製その他の利用に関して、許諾者は技術的な質問や問い合わせ等に対する対応その他、いかなるユーザ・サポートをも行う義務を負いません。

+

+第4条 契約の終了

+

+1.本契約の有効期間は、受領者が許諾プログラムを受領した時に開始し、受領者が許諾プログラムを何らかの方法で保持する限り続くものとします。

+2.前項の定めにかかわらず、受領者が本契約に定める各条項に違反したときは、本契約は、何らの催告を要することなく、自動的に終了し、当該受領者はそれ以後、許諾プログラムおよび派生プログラムを一切使用しまたは複製その他の利用をすることができないものとします。ただし、かかる契約の終了は、当該違反した受領者から許諾プログラムまたは派生プログラムの配布を受けた受領者の権利に影響を及ぼすものではありません。

+

+第5条 準拠法

+

+1.IPAは、本契約の変更バージョンまたは新しいバージョンを公表することができます。その場合には、受領者は、許諾プログラムまたは派生プログラムの使用、複製その他の利用または再配布にあたり、本契約または変更後の契約のいずれかを選択することができます。その他、上記に記載されていない条項に関しては日本の著作権法および関連法規に従うものとします。

+2.本契約は、日本法に基づき解釈されます。

+

+

+----------

+

+IPA Font License Agreement v1.0

+

+The Licensor provides the Licensed Program (as defined in Article 1 below) under the terms of this license agreement (“Agreement”).  Any use, reproduction or distribution of the Licensed Program, or any exercise of rights under this Agreement by a Recipient (as defined in Article 1 below) constitutes the Recipient's acceptance of this Agreement. 

+

+Article 1 (Definitions)

+1.“Digital Font Program” shall mean a computer program containing, or used to render or display fonts.

+2.“Licensed Program” shall mean a Digital Font Program licensed by the Licensor under this Agreement.

+3.“Derived Program” shall mean a Digital Font Program created as a result of a modification, addition, deletion, replacement or any other adaptation to or of a part or all of the Licensed Program, and includes a case where a Digital Font Program newly created by retrieving font information from a part or all of the Licensed Program or Embedded Fonts from a Digital Document File with or without modification of the retrieved font information. 

+4.“Digital Content” shall mean products provided to end users in the form of digital data, including video content, motion and/or still pictures, TV programs or other broadcasting content and products consisting of character text, pictures, photographic images, graphic symbols and/or the like.

+5.“Digital Document File” shall mean a PDF file or other Digital Content created by various software programs in which a part or all of the Licensed Program becomes embedded or contained in the file for the display of the font (“Embedded Fonts”).  Embedded Fonts are used only in the display of characters in the particular Digital Document File within which they are embedded, and shall be distinguished from those in any Digital Font Program, which may be used for display of characters outside that particular Digital Document File.

+6.“Computer” shall include a server in this Agreement.

+7.“Reproduction and Other Exploitation” shall mean reproduction, transfer, distribution, lease, public transmission, presentation, exhibition, adaptation and any other exploitation.

+8.“Recipient” shall mean anyone who receives the Licensed Program under this Agreement, including one that receives the Licensed Program from a Recipient.

+

+Article 2 (Grant of License)

+The Licensor grants to the Recipient a license to use the Licensed Program in any and all countries in accordance with each of the provisions set forth in this Agreement. However, any and all rights underlying in the Licensed Program shall be held by the Licensor. In no sense is this Agreement intended to transfer any right relating to the Licensed Program held by the Licensor except as specifically set forth herein or any right relating to any trademark, trade name, or service mark to the Recipient.

+

+1.The Recipient may install the Licensed Program on any number of Computers and use the same in accordance with the provisions set forth in this Agreement.

+2.The Recipient may use the Licensed Program, with or without modification in printed materials or in Digital Content as an expression of character texts or the like.

+3.The Recipient may conduct Reproduction and Other Exploitation of the printed materials and Digital Content created in accordance with the preceding Paragraph, for commercial or non-commercial purposes and in any form of media including but not limited to broadcasting, communication and various recording media.

+4.If any Recipient extracts Embedded Fonts from a Digital Document File to create a Derived Program, such Derived Program shall be subject to the terms of this agreement.

+5.If any Recipient performs Reproduction or Other Exploitation of a Digital Document File in which Embedded Fonts of the Licensed Program are used only for rendering the Digital Content within such Digital Document File then such Recipient shall have no further obligations under this Agreement in relation to such actions.

+6.The Recipient may reproduce the Licensed Program as is without modification and transfer such copies, publicly transmit or otherwise redistribute the Licensed Program to a third party for commercial or non-commercial purposes (“Redistribute”), in accordance with the provisions set forth in Article 3 Paragraph 2.

+7.The Recipient may create, use, reproduce and/or Redistribute a Derived Program under the terms stated above for the Licensed Program: provided, that the Recipient shall follow the provisions set forth in Article 3 Paragraph 1 when Redistributing the Derived Program. 

+

+Article 3 (Restriction)

+The license granted in the preceding Article shall be subject to the following restrictions:

+

+1.If a Derived Program is Redistributed pursuant to Paragraph 4 and 7 of the preceding Article, the following conditions must be met :

+ (1)The following must be also Redistributed together with the Derived Program, or be made available online or by means of mailing mechanisms in exchange for a cost which does not exceed the total costs of postage, storage medium and handling fees:

+  (a)a copy of the Derived Program; and

+  (b)any additional file created by the font developing program in the course of creating the Derived Program that can be used for further modification of the Derived Program, if any. 

+ (2)It is required to also Redistribute means to enable recipients of the Derived Program to replace the Derived Program with the Licensed Program first released under this License (the “Original Program”).  Such means may be to provide a difference file from the Original Program, or instructions setting out a method to replace the Derived Program with the Original Program. 

+ (3)The Recipient must license the Derived Program under the terms and conditions of this Agreement.

+ (4)No one may use or include the name of the Licensed Program as a program name, font name or file name of the Derived Program. 

+ (5)Any material to be made available online or by means of mailing a medium to satisfy the requirements of this paragraph may be provided, verbatim, by any party wishing to do so.

+2.If the Recipient Redistributes the Licensed Program pursuant to Paragraph 6 of the preceding Article, the Recipient shall meet all of the following conditions:

+ (1)The Recipient may not change the name of the Licensed Program.

+ (2)The Recipient may not alter or otherwise modify the Licensed Program.

+ (3)The Recipient must attach a copy of this Agreement to the Licensed Program.

+3.THIS LICENSED PROGRAM IS PROVIDED BY THE LICENSOR “AS IS” AND ANY EXPRESSED OR IMPLIED WARRANTY AS TO THE LICENSED PROGRAM OR ANY DERIVED PROGRAM, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.  IN NO EVENT SHALL THE LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXTENDED, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO; PROCUREMENT OF SUBSTITUTED GOODS OR SERVICE; DAMAGES ARISING FROM SYSTEM FAILURE; LOSS OR CORRUPTION OF EXISTING DATA OR PROGRAM; LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE INSTALLATION, USE, THE REPRODUCTION OR OTHER EXPLOITATION OF THE LICENSED PROGRAM OR ANY DERIVED PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

+4.The Licensor is under no obligation to respond to any technical questions or inquiries, or provide any other user support in connection with the installation, use or the Reproduction and Other Exploitation of the Licensed Program or Derived Programs thereof.

+

+Article 4 (Termination of Agreement)

+1.The term of this Agreement shall begin from the time of receipt of the Licensed Program by the Recipient and shall continue as long as the Recipient retains any such Licensed Program in any way.

+2.Notwithstanding the provision set forth in the preceding Paragraph, in the event of the breach of any of the provisions set forth in this Agreement by the Recipient, this Agreement shall automatically terminate without any notice. In the case of such termination, the Recipient may not use or conduct Reproduction and Other Exploitation of the Licensed Program or a Derived Program: provided that such termination shall not affect any rights of any other Recipient receiving the Licensed Program or the Derived Program from such Recipient who breached this Agreement.

+

+Article 5 (Governing Law)

+1.IPA may publish revised and/or new versions of this License.  In such an event, the Recipient may select either this Agreement or any subsequent version of the Agreement in using, conducting the Reproduction and Other Exploitation of, or Redistributing the Licensed Program or a Derived Program. Other matters not specified above shall be subject to the Copyright Law of Japan and other related laws and regulations of Japan.

+2.This Agreement shall be construed under the laws of Japan.

+

+
+
 </pre>
 </div>
 </div>
@@ -33363,10 +37168,12 @@
 
 <div class="product">
 <span class="title">jsonrpclib</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="https://github.com/joshmarshall/jsonrpclib">homepage</a></span>
 <div class="licence">
-<pre>Licensed under the Apache License, Version 2.0 (the "License");
+<pre>Source license jsonrpclib-0_pre20110820/LICENSE.txt:
+
+Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
@@ -33377,6 +37184,8 @@
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
+
+
 </pre>
 </div>
 </div>
@@ -33384,10 +37193,12 @@
 
 <div class="product">
 <span class="title">kbd</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://freshmeat.net/projects/kbd/">homepage</a></span>
 <div class="licence">
-<pre>The file
+<pre>Source license kbd-1.15.3/COPYING:
+
+The file
 	kbdrate.c
 is Copyright (C) 1992 Rickard E. Faith.
 
@@ -33440,6 +37251,8 @@
 of the GNU General Public License (GPL), version 2, or at your
 option any later version - except possibly for the restrictions
 mentioned in the directory consolefonts.
+
+
 </pre>
 </div>
 </div>
@@ -33447,10 +37260,11 @@
 
 <div class="product">
 <span class="title">keyutils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.kernel.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -33791,6 +37605,10 @@
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
 
+
+
+
+Gentoo Package Provided Stock License LGPL-2.1:
 		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
@@ -34295,6 +38113,9 @@
 That's all there is to it!
 
 
+
+
+
 </pre>
 </div>
 </div>
@@ -34302,10 +38123,12 @@
 
 <div class="product">
 <span class="title">ko-nanumfonts</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://hangeul.naver.com/index.nhn">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2010, NHN Corporation (http://www.nhncorp.com),
+<pre>Source license ko-nanumfonts-3.10.0/LICENSE:
+
+Copyright (c) 2010, NHN Corporation (http://www.nhncorp.com),
 with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver
 NanumGothic, NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver
 NanumBrush, NanumPen, Naver NanumPen
@@ -34407,6 +38230,8 @@
 FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER
 DEALINGS IN THE FONT SOFTWARE.
 
+
+
 </pre>
 </div>
 </div>
@@ -34414,10 +38239,12 @@
 
 <div class="product">
 <span class="title">ladspa-sdk</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.ladspa.org/">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license ladspa_sdk/doc/COPYING:
+
+
                   GNU LESSER GENERAL PUBLIC LICENSE
                        Version 2.1, February 1999
 
@@ -34931,6 +38758,8 @@
 That's all there is to it!
 
 
+
+
 </pre>
 </div>
 </div>
@@ -34938,10 +38767,12 @@
 
 <div class="product">
 <span class="title">laptop-mode-tools</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.samwel.tk/laptop_mode/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license laptop-mode-tools-1.59/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -35281,6 +39112,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -35288,14 +39121,694 @@
 
 <div class="product">
 <span class="title">less</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.greenwoodsoftware.com/less/">homepage</a></span>
 <div class="licence">
-<pre>                          Less License
+<pre>Source license less-441/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    &lt;one line to give the program's name and a brief idea of what it does.&gt;
+    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    &lt;program&gt;  Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+&lt;http://www.gnu.org/licenses/&gt;.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+&lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
+Source license less-441/LICENSE:
+
+                          Less License
                           ------------
 
 Less
-Copyright (C) 1984-2009  Mark Nudelman
+Copyright (C) 1984-2011  Mark Nudelman
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
@@ -35303,20 +39816,64 @@
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
-   notice in the documentation and/or other materials provided with
+   notice in the documentation and/or other materials provided with 
    the distribution.
 
 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 
 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">leveldb</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://code.google.com/p/leveldb/">homepage</a></span>
+<div class="licence">
+<pre>Source license leveldb-0.0.1/LICENSE:
+
+Copyright (c) 2011 The LevelDB Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
 </pre>
 </div>
 </div>
@@ -35324,10 +39881,11 @@
 
 <div class="product">
 <span class="title">libaio</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.kernel.org/pub/linux/kernel/people/andrea/libaio/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LIBRARY GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License LGPL-2:
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1991 Free Software Foundation, Inc.
@@ -35809,29 +40367,9 @@
   Ty Coon, President of Vice
 
 That's all there is to it!
-</pre>
-</div>
-</div>
 
 
-<div class="product">
-<span class="title">libatomic_ops</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
-<span class="homepage"><a href="http://www.hpl.hp.com/research/linux/atomic_ops/">homepage</a></span>
-<div class="licence">
-<pre>&lt;copyright notice&gt;
 
-THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
-OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
-
-Permission is hereby granted to use or copy this program
-for any purpose,  provided the above notices are retained on all copies.
-Permission to modify the code and to distribute modified code is granted,
-provided the above notices are retained, and a notice that the code was
-modified is included with the above copyright notice.
-
-GNU General Public License, version 2 or any later version.
-See GPL-2 or GPL-3 for the full text of these licenses.
 </pre>
 </div>
 </div>
@@ -35839,10 +40377,12 @@
 
 <div class="product">
 <span class="title">libcap</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.friedhoff.org/posixfilecaps.html">homepage</a></span>
 <div class="licence">
-<pre>Unless otherwise *explicitly* stated, the following text describes the
+<pre>Source license libcap-2.17/License:
+
+Unless otherwise *explicitly* stated, the following text describes the
 licensed conditions under which the contents of this libcap release
 may be used and distributed:
 
@@ -35883,518 +40423,6 @@
 DAMAGE.
 -------------------------------------------------------------------------
 
-</pre>
-</div>
-</div>
-
-
-<div class="product">
-<span class="title">libchewing</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
-<span class="homepage"><a href="http://chewing.csie.net/">homepage</a></span>
-<div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
-		       Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
-		  GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-			    NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    &lt;one line to give the library's name and a brief idea of what it does.&gt;
-    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  &lt;signature of Ty Coon&gt;, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
 
 
 </pre>
@@ -36404,10 +40432,12 @@
 
 <div class="product">
 <span class="title">libdivsufsort</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/libdivsufsort/">homepage</a></span>
 <div class="licence">
-<pre>The libdivsufsort copyright is as follows:
+<pre>Source license libdivsufsort-2.0.1/COPYING:
+
+The libdivsufsort copyright is as follows:
 
 Copyright (c) 2003-2008 Yuta Mori All Rights Reserved.
 
@@ -36434,6 +40464,8 @@
 
 See also the libdivsufsort web site:
   http://libdivsufsort.googlecode.com/ for more information.
+
+
 </pre>
 </div>
 </div>
@@ -36441,10 +40473,11 @@
 
 <div class="product">
 <span class="title">libevent</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://monkey.org/~provos/libevent/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2002, 2003 Niels Provos &lt;provos@citi.umich.edu&gt;
+<pre>Gentoo Package Provided Stock License BSD-libevent:
+Copyright (c) 2002, 2003 Niels Provos &lt;provos@citi.umich.edu&gt;
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -36468,6 +40501,9 @@
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
 </pre>
 </div>
 </div>
@@ -36475,10 +40511,12 @@
 
 <div class="product">
 <span class="title">libffi</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://sourceware.org/libffi/">homepage</a></span>
 <div class="licence">
-<pre>libffi - Copyright (c) 1996-2009  Anthony Green, Red Hat, Inc and others.  
+<pre>Source license libffi-3.0.9/LICENSE:
+
+libffi - Copyright (c) 1996-2009  Anthony Green, Red Hat, Inc and others.  
 See source files for details.
 
 Permission is hereby granted, free of charge, to any person obtaining
@@ -36499,6 +40537,8 @@
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
 </pre>
 </div>
 </div>
@@ -36506,10 +40546,12 @@
 
 <div class="product">
 <span class="title">libgcrypt</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnupg.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license libgcrypt-1.4.6/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -36849,6 +40891,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -36856,10 +40900,12 @@
 
 <div class="product">
 <span class="title">libgpg-error</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnupg.org/related_software/libgpg-error">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license libgpg-error-1.10/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -37199,6 +41245,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -37206,10 +41254,12 @@
 
 <div class="product">
 <span class="title">libhangul</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://kldp.net/projects/hangul/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Source license libhangul-0.0.10/COPYING:
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -37713,6 +41763,8 @@
 That's all there is to it!
 
 
+
+
 </pre>
 </div>
 </div>
@@ -37720,10 +41772,12 @@
 
 <div class="product">
 <span class="title">libmnl</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://netfilter.org/projects/libmnl">homepage</a></span>
 <div class="licence">
-<pre>                  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Source license libmnl-1.0.3/COPYING:
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
                        Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -38225,6 +42279,8 @@
   Ty Coon, President of Vice
 
 That's all there is to it!
+
+
 </pre>
 </div>
 </div>
@@ -38232,10 +42288,12 @@
 
 <div class="product">
 <span class="title">libmtp</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://libmtp.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Source license libmtp-0.0.1/COPYING:
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright © 1991, 1999 Free Software Foundation, Inc.
@@ -38739,6 +42797,8 @@
 That's all there is to it!
 
 
+
+
 </pre>
 </div>
 </div>
@@ -38746,10 +42806,12 @@
 
 <div class="product">
 <span class="title">libnetfilter_queue</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.netfilter.org/projects/libnetfilter_queue/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license libnetfilter_queue-1.0.1/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -39088,6 +43150,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -39095,10 +43159,12 @@
 
 <div class="product">
 <span class="title">libnfnetlink</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.netfilter.org/projects/libnfnetlink/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license libnfnetlink-1.0.1/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -39437,6 +43503,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -39444,10 +43512,12 @@
 
 <div class="product">
 <span class="title">libnih</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="https://launchpad.net/libnih">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license libnih-1.0.3/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -39786,6 +43856,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -39793,10 +43865,12 @@
 
 <div class="product">
 <span class="title">libnl</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://people.suug.ch/~tgr/libnl/">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license libnl-1.1/COPYING:
+
+
                   GNU LESSER GENERAL PUBLIC LICENSE
                        Version 2.1, February 1999
 
@@ -40257,6 +44331,8 @@
 DAMAGES.
 
                      END OF TERMS AND CONDITIONS
+
+
 </pre>
 </div>
 </div>
@@ -40264,10 +44340,12 @@
 
 <div class="product">
 <span class="title">libp11</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.opensc-project.org/libp11/">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license libp11-0.2.8/COPYING:
+
+
                   GNU LESSER GENERAL PUBLIC LICENSE
                        Version 2.1, February 1999
 
@@ -40777,6 +44855,8 @@
 That's all there is to it!
 
 
+
+
 </pre>
 </div>
 </div>
@@ -40784,10 +44864,12 @@
 
 <div class="product">
 <span class="title">libpcap</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.tcpdump.org/">homepage</a></span>
 <div class="licence">
-<pre>License: BSD
+<pre>Source license libpcap-1.1.1/LICENSE:
+
+License: BSD
  
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
@@ -40806,6 +44888,8 @@
 THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
 </pre>
 </div>
 </div>
@@ -40813,10 +44897,12 @@
 
 <div class="product">
 <span class="title">libpcre</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.pcre.org/">homepage</a></span>
 <div class="licence">
-<pre>PCRE LICENCE
+<pre>Source license pcre-8.30/LICENCE:
+
+PCRE LICENCE
 ------------
 
 PCRE is a library of functions to support regular expressions whose syntax
@@ -40908,6 +44994,17 @@
 POSSIBILITY OF SUCH DAMAGE.
 
 End
+
+
+Source license pcre-8.30/COPYING:
+
+PCRE LICENCE
+
+Please see the file LICENCE in the PCRE distribution for licensing details.
+
+End
+
+
 </pre>
 </div>
 </div>
@@ -40915,10 +45012,12 @@
 
 <div class="product">
 <span class="title">libpng</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.libpng.org/">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license libpng-1.2.49/LICENSE:
+
+
 This copy of the libpng notices is provided for your convenience.  In case of
 any discrepancy between this copy and the notices in the file png.h that is
 included in the libpng distribution, the latter shall prevail.
@@ -41029,6 +45128,8 @@
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
 March 29, 2012
+
+
 </pre>
 </div>
 </div>
@@ -41036,10 +45137,12 @@
 
 <div class="product">
 <span class="title">libpthread-stubs</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://xorg.freedesktop.org/">homepage</a></span>
 <div class="licence">
-<pre>Permission is hereby granted, free of charge, to any person obtaining a
+<pre>Source license libpthread-stubs-0.1/COPYING:
+
+Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
 to deal in the Software without restriction, including without limitation
 the rights to use, copy, modify, merge, publish, distribute, sublicense,
@@ -41060,6 +45163,8 @@
 institutions shall not be used in advertising or otherwise to promote the
 sale, use or other dealings in this Software without prior written
 authorization from the authors.
+
+
 </pre>
 </div>
 </div>
@@ -41067,10 +45172,12 @@
 
 <div class="product">
 <span class="title">libtool</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/libtool/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license libtool-2.4/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -41409,6 +45516,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -41416,10 +45525,12 @@
 
 <div class="product">
 <span class="title">libusb</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://libusb.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Source license libusb-0.1.12/COPYING:
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -41923,6 +46034,59 @@
 That's all there is to it!
 
 
+
+
+Source license libusb-0.1.12/LICENSE:
+
+libusb is covered by the LGPL:
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the
+Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+----
+
+Alternatively, the files usb.h.in and/or usb.h may be licensed under the
+BSD license:
+
+Copyright (c) 2000-2003 Johannes Erdfelt &lt;johannes@erdfelt.com&gt;
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
 </pre>
 </div>
 </div>
@@ -41930,10 +46094,12 @@
 
 <div class="product">
 <span class="title">libva</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.freedesktop.org/wiki/Software/vaapi">homepage</a></span>
 <div class="licence">
-<pre>    Permission is hereby granted, free of charge, to any person obtaining a
+<pre>Source license libva-1.1.1/COPYING:
+
+    Permission is hereby granted, free of charge, to any person obtaining a
     copy of this software and associated documentation files (the
     "Software"), to deal in the Software without restriction, including
     without limitation the rights to use, copy, modify, merge, publish,
@@ -41952,6 +46118,8 @@
     ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
 </pre>
 </div>
 </div>
@@ -41959,10 +46127,12 @@
 
 <div class="product">
 <span class="title">libva-intel-driver</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.freedesktop.org/wiki/Software/vaapi">homepage</a></span>
 <div class="licence">
-<pre>    Permission is hereby granted, free of charge, to any person obtaining a
+<pre>Source license libva-intel-driver-1.0.20/COPYING:
+
+    Permission is hereby granted, free of charge, to any person obtaining a
     copy of this software and associated documentation files (the
     "Software"), to deal in the Software without restriction, including
     without limitation the rights to use, copy, modify, merge, publish,
@@ -41981,6 +46151,8 @@
     ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
 </pre>
 </div>
 </div>
@@ -41988,10 +46160,12 @@
 
 <div class="product">
 <span class="title">libxcb</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://xcb.freedesktop.org/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett.
+<pre>Source license libxcb-1.8.1/COPYING:
+
+Copyright (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett.
 All Rights Reserved.
 
 Permission is hereby granted, free of charge, to any person
@@ -42021,6 +46195,8 @@
 otherwise to promote the sale, use or other dealings in this
 Software without prior written authorization from the
 authors.
+
+
 </pre>
 </div>
 </div>
@@ -42028,10 +46204,12 @@
 
 <div class="product">
 <span class="title">libxml2</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.xmlsoft.org/">homepage</a></span>
 <div class="licence">
-<pre>Except where otherwise noted in the source code (e.g. the files hash.c,
+<pre>Source license libxml2-2.7.8/Copyright:
+
+Except where otherwise noted in the source code (e.g. the files hash.c,
 list.c and the trio files, which are covered by a similar licence but
 with different Copyright notices) all the files are:
 
@@ -42058,6 +46236,39 @@
 be used in advertising or otherwise to promote the sale, use or other deal-
 ings in this Software without prior written authorization from him.
 
+
+
+Source license libxml2-2.7.8/COPYING:
+
+Except where otherwise noted in the source code (e.g. the files hash.c,
+list.c and the trio files, which are covered by a similar licence but
+with different Copyright notices) all the files are:
+
+ Copyright (C) 1998-2003 Daniel Veillard.  All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is fur-
+nished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Daniel Veillard shall not
+be used in advertising or otherwise to promote the sale, use or other deal-
+ings in this Software without prior written authorization from him.
+
+
+
 </pre>
 </div>
 </div>
@@ -42065,10 +46276,11 @@
 
 <div class="product">
 <span class="title">linux-headers</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.kernel.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -42408,6 +46620,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -42415,10 +46630,12 @@
 
 <div class="product">
 <span class="title">llvm</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://llvm.org/">homepage</a></span>
 <div class="licence">
-<pre>==============================================================================
+<pre>Source license llvm-3.2.src/LICENSE.TXT:
+
+==============================================================================
 LLVM Release License
 ==============================================================================
 University of Illinois/NCSA
@@ -42488,6 +46705,8 @@
 Google Test         llvm/utils/unittest/googletest
 OpenBSD regex       llvm/lib/Support/{reg*, COPYRIGHT.regex}
 pyyaml tests        llvm/test/YAMLParser/{*.data, LICENSE.TXT}
+
+
 </pre>
 </div>
 </div>
@@ -42495,10 +46714,12 @@
 
 <div class="product">
 <span class="title">lohitfonts-cros</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://fedorahosted.org/lohit">homepage</a></span>
 <div class="licence">
-<pre>Copyright 2011 Lohit Fonts Project contributors
+<pre>Source license lohitfonts-cros-2.5.0/LICENSE:
+
+Copyright 2011 Lohit Fonts Project contributors
   &lt;http://fedorahosted.org/lohit&gt;, 
 with Reserved Font Name Lohit.
 
@@ -42593,6 +46814,8 @@
 DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
 OTHER DEALINGS IN THE FONT SOFTWARE.
+
+
 </pre>
 </div>
 </div>
@@ -42600,10 +46823,11 @@
 
 <div class="product">
 <span class="title">lsof</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/">homepage</a></span>
 <div class="licence">
-<pre>ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ#1.9
+<pre>Gentoo Package Provided Stock License lsof:
+ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ#1.9
 
 Copyright 2002 Purdue Research Foundation, West Lafayette,
 Indiana 47907.  All rights reserved.
@@ -42631,6 +46855,9 @@
    not be misrepresented as being the original software.
 
 4. This notice may not be removed or altered.
+
+
+
 </pre>
 </div>
 </div>
@@ -42638,10 +46865,12 @@
 
 <div class="product">
 <span class="title">lvm2</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://sources.redhat.com/lvm2/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license LVM2.2.02.88/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -42981,6 +47210,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -42988,10 +47219,12 @@
 
 <div class="product">
 <span class="title">lzo</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.oberhumer.com/opensource/lzo/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license lzo-2.06/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -43330,6 +47563,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -43337,10 +47572,12 @@
 
 <div class="product">
 <span class="title">m17n-contrib</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.m17n.org/m17n-lib/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Source license m17n-contrib-1.1.10/COPYING:
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -43844,6 +48081,8 @@
 That's all there is to it!
 
 
+
+
 </pre>
 </div>
 </div>
@@ -43851,10 +48090,12 @@
 
 <div class="product">
 <span class="title">m17n-db</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.m17n.org/m17n-lib/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Source license m17n-db-1.6.1/COPYING:
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -44358,6 +48599,8 @@
 That's all there is to it!
 
 
+
+
 </pre>
 </div>
 </div>
@@ -44365,10 +48608,12 @@
 
 <div class="product">
 <span class="title">m17n-lib</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.m17n.org/m17n-lib/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Source license m17n-lib-1.6.1/COPYING:
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -44872,6 +49117,8 @@
 That's all there is to it!
 
 
+
+
 </pre>
 </div>
 </div>
@@ -44879,10 +49126,12 @@
 
 <div class="product">
 <span class="title">m2crypto</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://chandlerproject.org/bin/view/Projects/MeTooCrypto">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.
+<pre>Source license M2Crypto-0.21.1/LICENCE:
+
+Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.
 
 Portions copyright (c) 2004-2006 Open Source Applications Foundation. 
 All rights reserved.
@@ -44908,6 +49157,8 @@
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
 </pre>
 </div>
 </div>
@@ -44915,10 +49166,12 @@
 
 <div class="product">
 <span class="title">make</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/make/make.html">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license make-3.82/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -45592,6 +49845,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -45599,10 +49854,11 @@
 
 <div class="product">
 <span class="title">marvell_sd8787</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.marvell.com/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (C) 2010, Marvell International Ltd.
+<pre>Gentoo Package Provided Stock License Marvell:
+Copyright (C) 2010, Marvell International Ltd.
 
 All Rights Reserved.
 
@@ -45610,6 +49866,9 @@
 Reverse engineering of this file is strictly prohibited.
 Redistribution and use in its original form are permitted.
 
+
+
+
 </pre>
 </div>
 </div>
@@ -45617,10 +49876,12 @@
 
 <div class="product">
 <span class="title">mawk</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://invisible-island.net/mawk/mawk.html">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license mawk-1.3.4-20100625/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -45959,6 +50220,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -45966,10 +50229,12 @@
 
 <div class="product">
 <span class="title">memtester</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://pyropus.ca/software/memtester/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license memtester-4.2.2/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -46309,6 +50574,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -46316,10 +50583,11 @@
 
 <div class="product">
 <span class="title">mesa</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://mesa3d.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>		   GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License LGPL-3:
+		   GNU LESSER GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -46485,6 +50753,10 @@
 permanent authorization for you to choose that version for the
 Library.
 
+
+
+
+Gentoo Package Provided Stock License SGI-B-2.0:
 SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 
 Copyright (C) [dates of first publication] Silicon Graphics, Inc. All Rights
@@ -46512,6 +50784,9 @@
 not be used in advertising or otherwise to promote the sale, use or other
 dealings in this Software without prior written authorization from Silicon
 Graphics, Inc.
+
+
+
 </pre>
 </div>
 </div>
@@ -46519,10 +50794,11 @@
 
 <div class="product">
 <span class="title">mime-types</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gentoo.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -46862,6 +51138,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -46869,10 +51148,12 @@
 
 <div class="product">
 <span class="title">ml-anjalioldlipi</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="https://sites.google.com/site/cibu/anjalioldlipi-font">homepage</a></span>
 <div class="licence">
-<pre>Copyright 2004 Kevin &amp; Siji, 2007-2011 Cibu Johny
+<pre>Source license ml-anjalioldlipi-0.740/LICENSE:
+
+Copyright 2004 Kevin &amp; Siji, 2007-2011 Cibu Johny
 with reserved font name AnjaliOldLipi.
 
 This Font Software is licensed under the SIL Open Font License, Version 1.1.
@@ -46966,6 +51247,8 @@
 DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
 OTHER DEALINGS IN THE FONT SOFTWARE.
+
+
 </pre>
 </div>
 </div>
@@ -46973,10 +51256,11 @@
 
 <div class="product">
 <span class="title">modemmanager-classic-interfaces</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.chromium.org/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License LGPL-2.1:
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -47480,6 +51764,9 @@
 That's all there is to it!
 
 
+
+
+
 </pre>
 </div>
 </div>
@@ -47487,10 +51774,12 @@
 
 <div class="product">
 <span class="title">modemmanager-next</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://mail.gnome.org/archives/networkmanager-list/2008-July/msg00274.html">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license modemmanager-next-0.5.999/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -47830,6 +52119,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -47837,10 +52128,12 @@
 
 <div class="product">
 <span class="title">module-init-tools</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://modules.wiki.kernel.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license module-init-tools-3.16/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -48180,6 +52473,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -48187,10 +52482,12 @@
 
 <div class="product">
 <span class="title">mtdev</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://bitmath.org/code/mtdev/">homepage</a></span>
 <div class="licence">
-<pre>mtdev - Multitouch Protocol Translation Library (MIT license)
+<pre>Source license mtdev-1.1.2/COPYING:
+
+mtdev - Multitouch Protocol Translation Library (MIT license)
 
 Copyright (C) 2010 Henrik Rydberg &lt;rydberg@euromail.se&gt;
 Copyright (C) 2010 Canonical Ltd.
@@ -48213,6 +52510,8 @@
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
+
+
 </pre>
 </div>
 </div>
@@ -48220,10 +52519,12 @@
 
 <div class="product">
 <span class="title">mtools</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://mtools.linux.lu/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license mtools-4.0.15/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -48897,6 +53198,113 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">my-padauk</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;id=padauk">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License OFL-1.1:
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----
+
+PREAMBLE
+
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free
+and open framework in which fonts may be shared and improved in
+partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves.  The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works.  The fonts and derivatives,
+however, cannot be released under any other type of license.  The
+requirement for fonts to remain under this license does not apply to
+any document created using the fonts or their derivatives.
+
+DEFINITIONS
+
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such.  This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components
+as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software
+to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer
+or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in
+Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license.  These can be
+included either as stand-alone text files, human-readable headers or in
+the appropriate machine-readable metadata fields within text or binary
+files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the
+corresponding Copyright Holder.  This restriction only applies to the
+primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license.  The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS",
+WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR
+OTHER RIGHT.  IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR
+CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE
+USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+
+
+
 </pre>
 </div>
 </div>
@@ -48904,10 +53312,11 @@
 
 <div class="product">
 <span class="title">nacl-mozc</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/mozc">homepage</a></span>
 <div class="licence">
-<pre>Copyright 2010, Google Inc.
+<pre>Gentoo Package Provided Stock License BSD-Google:
+Copyright 2010, Google Inc.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -48935,6 +53344,9 @@
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
 </pre>
 </div>
 </div>
@@ -48942,10 +53354,11 @@
 
 <div class="product">
 <span class="title">ncurses</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/ncurses/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 1998-2000,2005 Free Software Foundation, Inc.
+<pre>Gentoo Package Provided Stock License ncurses:
+Copyright (c) 1998-2000,2005 Free Software Foundation, Inc.
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the
@@ -48970,6 +53383,9 @@
 holders shall not be used in advertising or otherwise to promote the
 sale, use or other dealings in this Software without prior written
 authorization.
+
+
+
 </pre>
 </div>
 </div>
@@ -48977,10 +53393,12 @@
 
 <div class="product">
 <span class="title">net-tools</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://net-tools.berlios.de/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license net-tools-1.60_p20110409135728/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -49319,6 +53737,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -49326,10 +53746,11 @@
 
 <div class="product">
 <span class="title">netifaces</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://alastairs-place.net/netifaces/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2007, 2008 Alastair Houghton
+<pre>Gentoo Package Provided Stock License netiface:
+Copyright (c) 2007, 2008 Alastair Houghton
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -49348,6 +53769,9 @@
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
+
+
+
 </pre>
 </div>
 </div>
@@ -49355,10 +53779,11 @@
 
 <div class="product">
 <span class="title">notofonts</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="">homepage</a></span>
 <div class="licence">
-<pre>                                 Apache License
+<pre>Gentoo Package Provided Stock License Apache-2.0:
+                                 Apache License
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
 
@@ -50036,6 +54461,9 @@
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 ====================================================================
+
+
+
 </pre>
 </div>
 </div>
@@ -50043,10 +54471,390 @@
 
 <div class="product">
 <span class="title">nspr</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.mozilla.org/projects/nspr/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License MPL-2.0:
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+    means each individual or legal entity that creates, contributes to
+    the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+    means the combination of the Contributions of others (if any) used
+    by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+    means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+    means Source Code Form to which the initial Contributor has attached
+    the notice in Exhibit A, the Executable Form of such Source Code
+    Form, and Modifications of such Source Code Form, in each case
+    including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+    means
+
+    (a) that the initial Contributor has attached the notice described
+        in Exhibit B to the Covered Software; or
+
+    (b) that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the
+        terms of a Secondary License.
+
+1.6. "Executable Form"
+    means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+    means a work that combines Covered Software with other material, in 
+    a separate file or files, that is not Covered Software.
+
+1.8. "License"
+    means this document.
+
+1.9. "Licensable"
+    means having the right to grant, to the maximum extent possible,
+    whether at the time of the initial grant or subsequently, any and
+    all of the rights conveyed by this License.
+
+1.10. "Modifications"
+    means any of the following:
+
+    (a) any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered
+        Software; or
+
+    (b) any new file in Source Code Form that contains any Covered
+        Software.
+
+1.11. "Patent Claims" of a Contributor
+    means any patent claim(s), including without limitation, method,
+    process, and apparatus claims, in any patent Licensable by such
+    Contributor that would be infringed, but for the grant of the
+    License, by the making, using, selling, offering for sale, having
+    made, import, or transfer of either its Contributions or its
+    Contributor Version.
+
+1.12. "Secondary License"
+    means either the GNU General Public License, Version 2.0, the GNU
+    Lesser General Public License, Version 2.1, the GNU Affero General
+    Public License, Version 3.0, or any later versions of those
+    licenses.
+
+1.13. "Source Code Form"
+    means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+    means an individual or a legal entity exercising rights under this
+    License. For legal entities, "You" includes any entity that
+    controls, is controlled by, or is under common control with You. For
+    purposes of this definition, "control" means (a) the power, direct
+    or indirect, to cause the direction or management of such entity,
+    whether by contract or otherwise, or (b) ownership of more than
+    fifty percent (50%) of the outstanding shares or beneficial
+    ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+    Licensable by such Contributor to use, reproduce, make available,
+    modify, display, perform, distribute, and otherwise exploit its
+    Contributions, either on an unmodified basis, with Modifications, or
+    as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+    for sale, have made, import, and otherwise transfer either its
+    Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+    or
+
+(b) for infringements caused by: (i) Your and any other third party's
+    modifications of Covered Software, or (ii) the combination of its
+    Contributions with other software (except as part of its Contributor
+    Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+    its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+    Form, as described in Section 3.1, and You must inform recipients of
+    the Executable Form how they can obtain a copy of such Source Code
+    Form by reasonable means in a timely manner, at a charge no more
+    than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+    License, or sublicense it under different terms, provided that the
+    license for the Executable Form does not attempt to limit or alter
+    the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+*                                                                      *
+*  6. Disclaimer of Warranty                                           *
+*  -------------------------                                           *
+*                                                                      *
+*  Covered Software is provided under this License on an "as is"       *
+*  basis, without warranty of any kind, either expressed, implied, or  *
+*  statutory, including, without limitation, warranties that the       *
+*  Covered Software is free of defects, merchantable, fit for a        *
+*  particular purpose or non-infringing. The entire risk as to the     *
+*  quality and performance of the Covered Software is with You.        *
+*  Should any Covered Software prove defective in any respect, You     *
+*  (not any Contributor) assume the cost of any necessary servicing,   *
+*  repair, or correction. This disclaimer of warranty constitutes an   *
+*  essential part of this License. No use of any Covered Software is   *
+*  authorized under this License except under this disclaimer.         *
+*                                                                      *
+************************************************************************
+
+************************************************************************
+*                                                                      *
+*  7. Limitation of Liability                                          *
+*  --------------------------                                          *
+*                                                                      *
+*  Under no circumstances and under no legal theory, whether tort      *
+*  (including negligence), contract, or otherwise, shall any           *
+*  Contributor, or anyone who distributes Covered Software as          *
+*  permitted above, be liable to You for any direct, indirect,         *
+*  special, incidental, or consequential damages of any character      *
+*  including, without limitation, damages for lost profits, loss of    *
+*  goodwill, work stoppage, computer failure or malfunction, or any    *
+*  and all other commercial damages or losses, even if such party      *
+*  shall have been informed of the possibility of such damages. This   *
+*  limitation of liability shall not apply to liability for death or   *
+*  personal injury resulting from such party's negligence to the       *
+*  extent applicable law prohibits such limitation. Some               *
+*  jurisdictions do not allow the exclusion or limitation of           *
+*  incidental or consequential damages, so this exclusion and          *
+*  limitation may not apply to You.                                    *
+*                                                                      *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+  This Source Code Form is "Incompatible With Secondary Licenses", as
+  defined by the Mozilla Public License, v. 2.0.
+
+
+
+
+
+Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -50386,6 +55194,518 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
+
+Gentoo Package Provided Stock License LGPL-2.1:
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    &lt;one line to give the library's name and a brief idea of what it does.&gt;
+    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  &lt;signature of Ty Coon&gt;, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+
+
+
 </pre>
 </div>
 </div>
@@ -50393,10 +55713,390 @@
 
 <div class="product">
 <span class="title">nss</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.mozilla.org/projects/security/pki/nss/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License MPL-2.0:
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+    means each individual or legal entity that creates, contributes to
+    the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+    means the combination of the Contributions of others (if any) used
+    by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+    means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+    means Source Code Form to which the initial Contributor has attached
+    the notice in Exhibit A, the Executable Form of such Source Code
+    Form, and Modifications of such Source Code Form, in each case
+    including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+    means
+
+    (a) that the initial Contributor has attached the notice described
+        in Exhibit B to the Covered Software; or
+
+    (b) that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the
+        terms of a Secondary License.
+
+1.6. "Executable Form"
+    means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+    means a work that combines Covered Software with other material, in 
+    a separate file or files, that is not Covered Software.
+
+1.8. "License"
+    means this document.
+
+1.9. "Licensable"
+    means having the right to grant, to the maximum extent possible,
+    whether at the time of the initial grant or subsequently, any and
+    all of the rights conveyed by this License.
+
+1.10. "Modifications"
+    means any of the following:
+
+    (a) any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered
+        Software; or
+
+    (b) any new file in Source Code Form that contains any Covered
+        Software.
+
+1.11. "Patent Claims" of a Contributor
+    means any patent claim(s), including without limitation, method,
+    process, and apparatus claims, in any patent Licensable by such
+    Contributor that would be infringed, but for the grant of the
+    License, by the making, using, selling, offering for sale, having
+    made, import, or transfer of either its Contributions or its
+    Contributor Version.
+
+1.12. "Secondary License"
+    means either the GNU General Public License, Version 2.0, the GNU
+    Lesser General Public License, Version 2.1, the GNU Affero General
+    Public License, Version 3.0, or any later versions of those
+    licenses.
+
+1.13. "Source Code Form"
+    means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+    means an individual or a legal entity exercising rights under this
+    License. For legal entities, "You" includes any entity that
+    controls, is controlled by, or is under common control with You. For
+    purposes of this definition, "control" means (a) the power, direct
+    or indirect, to cause the direction or management of such entity,
+    whether by contract or otherwise, or (b) ownership of more than
+    fifty percent (50%) of the outstanding shares or beneficial
+    ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+    Licensable by such Contributor to use, reproduce, make available,
+    modify, display, perform, distribute, and otherwise exploit its
+    Contributions, either on an unmodified basis, with Modifications, or
+    as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+    for sale, have made, import, and otherwise transfer either its
+    Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+    or
+
+(b) for infringements caused by: (i) Your and any other third party's
+    modifications of Covered Software, or (ii) the combination of its
+    Contributions with other software (except as part of its Contributor
+    Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+    its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+    Form, as described in Section 3.1, and You must inform recipients of
+    the Executable Form how they can obtain a copy of such Source Code
+    Form by reasonable means in a timely manner, at a charge no more
+    than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+    License, or sublicense it under different terms, provided that the
+    license for the Executable Form does not attempt to limit or alter
+    the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+*                                                                      *
+*  6. Disclaimer of Warranty                                           *
+*  -------------------------                                           *
+*                                                                      *
+*  Covered Software is provided under this License on an "as is"       *
+*  basis, without warranty of any kind, either expressed, implied, or  *
+*  statutory, including, without limitation, warranties that the       *
+*  Covered Software is free of defects, merchantable, fit for a        *
+*  particular purpose or non-infringing. The entire risk as to the     *
+*  quality and performance of the Covered Software is with You.        *
+*  Should any Covered Software prove defective in any respect, You     *
+*  (not any Contributor) assume the cost of any necessary servicing,   *
+*  repair, or correction. This disclaimer of warranty constitutes an   *
+*  essential part of this License. No use of any Covered Software is   *
+*  authorized under this License except under this disclaimer.         *
+*                                                                      *
+************************************************************************
+
+************************************************************************
+*                                                                      *
+*  7. Limitation of Liability                                          *
+*  --------------------------                                          *
+*                                                                      *
+*  Under no circumstances and under no legal theory, whether tort      *
+*  (including negligence), contract, or otherwise, shall any           *
+*  Contributor, or anyone who distributes Covered Software as          *
+*  permitted above, be liable to You for any direct, indirect,         *
+*  special, incidental, or consequential damages of any character      *
+*  including, without limitation, damages for lost profits, loss of    *
+*  goodwill, work stoppage, computer failure or malfunction, or any    *
+*  and all other commercial damages or losses, even if such party      *
+*  shall have been informed of the possibility of such damages. This   *
+*  limitation of liability shall not apply to liability for death or   *
+*  personal injury resulting from such party's negligence to the       *
+*  extent applicable law prohibits such limitation. Some               *
+*  jurisdictions do not allow the exclusion or limitation of           *
+*  incidental or consequential damages, so this exclusion and          *
+*  limitation may not apply to You.                                    *
+*                                                                      *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+  This Source Code Form is "Incompatible With Secondary Licenses", as
+  defined by the Mozilla Public License, v. 2.0.
+
+
+
+
+
+Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -50736,6 +56436,518 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
+
+Gentoo Package Provided Stock License LGPL-2.1:
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    &lt;one line to give the library's name and a brief idea of what it does.&gt;
+    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  &lt;signature of Ty Coon&gt;, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+
+
+
 </pre>
 </div>
 </div>
@@ -50743,10 +56955,12 @@
 
 <div class="product">
 <span class="title">ntfs3g</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.tuxera.com/community/ntfs-3g-download/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license ntfs-3g_ntfsprogs-2012.1.15/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -51086,6 +57300,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -51093,10 +57309,11 @@
 
 <div class="product">
 <span class="title">o3d</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/o3d/">homepage</a></span>
 <div class="licence">
-<pre>Copyright 2010, Google Inc.
+<pre>Gentoo Package Provided Stock License BSD-Google:
+Copyright 2010, Google Inc.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -51124,6 +57341,9 @@
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
 </pre>
 </div>
 </div>
@@ -51131,10 +57351,12 @@
 
 <div class="product">
 <span class="title">openssh</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.openssh.org/">homepage</a></span>
 <div class="licence">
-<pre>This file is part of the OpenSSH software.
+<pre>Source license openssh-5.2p1/LICENCE:
+
+This file is part of the OpenSSH software.
 
 The licences which components of this software fall under are as
 follows.  First, we will summarize and say that all components
@@ -51472,6 +57694,8 @@
 
 ------
 $OpenBSD: LICENCE,v 1.19 2004/08/30 09:18:08 markus Exp $
+
+
 </pre>
 </div>
 </div>
@@ -51479,10 +57703,12 @@
 
 <div class="product">
 <span class="title">openssl</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.openssl.org/">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license openssl-1.0.1c/LICENSE:
+
+
   LICENSE ISSUES
   ==============
 
@@ -51609,6 +57835,8 @@
  * [including the GNU Public Licence.]
  */
 
+
+
 </pre>
 </div>
 </div>
@@ -51616,10 +57844,12 @@
 
 <div class="product">
 <span class="title">openvpn</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://openvpn.net/">homepage</a></span>
 <div class="licence">
-<pre>OpenVPN (TM) -- An Open Source VPN daemon
+<pre>Source license openvpn-2.1.12/COPYING:
+
+OpenVPN (TM) -- An Open Source VPN daemon
 
 Copyright (C) 2002-2010 OpenVPN Technologies, Inc. &lt;sales@openvpn.net&gt;
 
@@ -51836,6 +58066,8 @@
   In the Windows binary distribution of OpenVPN, the
   GPL is reproduced below.
 
+
+
 </pre>
 </div>
 </div>
@@ -51843,10 +58075,12 @@
 
 <div class="product">
 <span class="title">pam</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="https://fedorahosted.org/linux-pam/">homepage</a></span>
 <div class="licence">
-<pre>Unless otherwise *explicitly* stated the following text describes the
+<pre>Source license Linux-PAM-1.1.5/Copyright:
+
+Unless otherwise *explicitly* stated the following text describes the
 licensed conditions under which the contents of this Linux-PAM release
 may be distributed:
 
@@ -51887,6 +58121,53 @@
 DAMAGE.
 -------------------------------------------------------------------------
 
+
+
+Source license Linux-PAM-1.1.5/COPYING:
+
+Unless otherwise *explicitly* stated the following text describes the
+licensed conditions under which the contents of this Linux-PAM release
+may be distributed:
+
+-------------------------------------------------------------------------
+Redistribution and use in source and binary forms of Linux-PAM, with
+or without modification, are permitted provided that the following
+conditions are met:
+
+1. Redistributions of source code must retain any existing copyright
+   notice, and this entire permission notice in its entirety,
+   including the disclaimer of warranties.
+
+2. Redistributions in binary form must reproduce all prior and current
+   copyright notices, this list of conditions, and the following
+   disclaimer in the documentation and/or other materials provided
+   with the distribution.
+
+3. The name of any author may not be used to endorse or promote
+   products derived from this software without their specific prior
+   written permission.
+
+ALTERNATIVELY, this product may be distributed under the terms of the
+GNU General Public License, in which case the provisions of the GNU
+GPL are required INSTEAD OF the above restrictions.  (This clause is
+necessary due to a potential conflict between the GNU GPL and the
+restrictions contained in a BSD-style copyright.)
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+-------------------------------------------------------------------------
+
+
+
 </pre>
 </div>
 </div>
@@ -51894,10 +58175,11 @@
 
 <div class="product">
 <span class="title">pam_pwdfile</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://cpbotha.net/pam_pwdfile.html">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -52237,6 +58519,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -52244,10 +58529,11 @@
 
 <div class="product">
 <span class="title">pambase</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gentoo.org/proj/en/base/pam/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -52587,6 +58873,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -52594,10 +58883,12 @@
 
 <div class="product">
 <span class="title">pango</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.pango.org/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LIBRARY GENERAL PUBLIC LICENSE
+<pre>Source license pango-1.28.4/COPYING:
+
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1991 Free Software Foundation, Inc.
@@ -53079,6 +59370,8 @@
   Ty Coon, President of Vice
 
 That's all there is to it!
+
+
 </pre>
 </div>
 </div>
@@ -53086,10 +59379,12 @@
 
 <div class="product">
 <span class="title">parted</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/parted">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license parted-3.1/COPYING:
+
+
 		    GNU GENERAL PUBLIC LICENSE
 		       Version 3, 29 June 2007
 
@@ -53764,6 +60059,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -53771,10 +60068,12 @@
 
 <div class="product">
 <span class="title">pax-utils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://hardened.gentoo.org/pax-utils.xml">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license pax-utils-0.4/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -54114,6 +60413,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -54121,10 +60422,12 @@
 
 <div class="product">
 <span class="title">pciutils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://mj.ucw.cz/sw/pciutils/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license pciutils-3.1.10/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -54463,6 +60766,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -54470,10 +60775,12 @@
 
 <div class="product">
 <span class="title">perf</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://perf.wiki.kernel.org/">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license perf-3.4/COPYING:
+
+
    NOTE! This copyright does *not* cover user programs that use kernel
  services by normal system calls - this is merely considered normal use
  of the kernel, and does *not* fall under the heading of "derived work".
@@ -54829,6 +61136,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -54836,10 +61145,12 @@
 
 <div class="product">
 <span class="title">pkcs11-helper</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.opensc-project.org/pkcs11-helper">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license pkcs11-helper-1.07/COPYING:
+
+
 pkcs11-helper License
 
 	Copyright (c) 2005-2008 Alon Bar-Lev &lt;alon.barlev@gmail.com&gt;
@@ -54956,6 +61267,8 @@
 	Documents produced by doxygen are derivative works derived
 	from the input used in their production; they are not affected by this
 	license.
+
+
 </pre>
 </div>
 </div>
@@ -54963,10 +61276,11 @@
 
 <div class="product">
 <span class="title">ply-image</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.chromium.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -55306,6 +61620,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -55313,10 +61630,12 @@
 
 <div class="product">
 <span class="title">popt</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://rpm5.org/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 1998  Red Hat Software
+<pre>Source license popt-1.16/COPYING:
+
+Copyright (c) 1998  Red Hat Software
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -55338,6 +61657,8 @@
 Except as contained in this notice, the name of the X Consortium shall not be
 used in advertising or otherwise to promote the sale, use or other dealings
 in this Software without prior written authorization from the X Consortium.
+
+
 </pre>
 </div>
 </div>
@@ -55345,10 +61666,12 @@
 
 <div class="product">
 <span class="title">portage</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gentoo.org/proj/en/portage/index.xml">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license portage-2.1.10.11/LICENSE:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -55687,6 +62010,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -55694,10 +62019,11 @@
 
 <div class="product">
 <span class="title">ppp</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.samba.org/ppp">homepage</a></span>
 <div class="licence">
-<pre>/*
+<pre>Gentoo Package Provided Stock License ppp-2.4.4:
+/*
  * if_ppp.h - Point-to-Point Protocol definitions.
  *
  * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
@@ -58508,6 +64834,9 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
+
+
+
 </pre>
 </div>
 </div>
@@ -58515,72 +64844,352 @@
 
 <div class="product">
 <span class="title">procps</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://procps.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>This is the Debian Linux prepackaged version of the /proc file
-system utilities.
+<pre>Source license procps-ng-3.3.4/COPYING:
 
-This package was downloaded from:
-  http://procps.sourceforge.net/
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    &lt;one line to give the program's name and a brief idea of what it does.&gt;
+    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  &lt;signature of Ty Coon&gt;, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
 
 
-Upstream Authors:
-Werner Almesberger &lt;almesber@di.epfl.ch&gt;, Roger Binns, Charles
-Blake &lt;cblake@ucsd.edu&gt;, Brian Edmonds, David Engel &lt;david@ods.com&gt;,
-Larry Greenfield &lt;greenfie@gauss.rutgers.edu&gt;, Michael K. Johnson
-&lt;johnsonm@sunsite.unc.edu&gt;, Branko Lankester &lt;lankeste@fwi.uva.nl&gt;,
-Robert Nation &lt;nation@rocket.sanders.lockheed.com&gt;, Michael Shields
-&lt;mjshield@nyx.cs.du.edu&gt;, Henry Ware &lt;al172@yfn.ysu.edu&gt;, Matt
-Welsh &lt;mdw@sunsite.unc.edu&gt;, Albert D. Cahalan, Jim C. Warner
-&lt;warnerjc@worldnet.att.net&gt;, and Kjetil Torgrim Homme
-&lt;kjetilho@ifi.uio.no&gt;
-
-Copyright:
-  free.c:
-    Copyright 2003 Robert Love
-    Copyright 2004 Albert Cahalan
-  minimal.c:
-    Copyright 1998,2004 Albert Cahalan
-  pgrep.c:
-    Copyright 2000 Kjetil Torgrim Homme &lt;kjetilho@ifi.uio.no&gt;
-  pmap.c:
-    Copyright 2002 by Albert Cahalan
-  pwdx.c:
-    Copyright 2004 Nicholas Miell
-  skill.c:
-    Copyright 1998-2002 by Albert Cahalan
-  slabtop.c:
-    Copyright 2003 Chris Rivera
-  sysctl.c:
-    Copyright 1999 George Staikos
-  tload.c:
-    Copyright 1992 Branko Lankester
-  top.c:
-    Copyright 2002 James C. Warner
-  vmstat.c:
-    Copyright 1994 Henry Ware &lt;al172@yfn.ysu.edu&gt;
-    Copyright 2002 Albert Cahalan
-  ps/display.c, ps/parser.c: 
-    Copyright 1998-2003 by Albert Cahalan
-  ps/global.c, ps/global.c: 
-    Copyright 1998-2002 by Albert Cahalan
-  ps/help.c, ps/sortformat.c:
-    Copyright 1998-2004 by Albert Cahalan
-  ps/output.c: 
-    Copyright 1999-2004 by Albert Cahalan
-
-License:
-The programs sysctl and pgrep copyright by their
-authors and redistributable under the terms of the GNU General
-Public License. On Debian Linux systems, the complete text of
-the GNU General Public License can be found in
-`/usr/share/common-licenses/GPL-2'.
-
-All other software is copyright by their authors and redistributable under 
-the terms of the GNU Library General Public License. On Debian Linux 
-systems, the complete text of the GNU Library General Public License can 
-be found in `/usr/share/common-licenses/LGPL-2'.
 </pre>
 </div>
 </div>
@@ -58588,37 +65197,691 @@
 
 <div class="product">
 <span class="title">protobuf</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/protobuf/">homepage</a></span>
 <div class="licence">
-<pre>Copyright 2010, Google Inc.
-All rights reserved.
+<pre>Gentoo Package Provided Stock License Apache-2.0:
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
 
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
+   1. Definitions.
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+
+APACHE HTTP SERVER SUBCOMPONENTS: 
+
+The Apache HTTP Server includes a number of subcomponents with
+separate copyright notices and license terms. Your use of the source
+code for the these subcomponents is subject to the terms and
+conditions of the following licenses. 
+
+For the mod_mime_magic component:
+
+/*
+ * mod_mime_magic: MIME type lookup via file magic numbers
+ * Copyright (c) 1996-1997 Cisco Systems, Inc.
+ *
+ * This software was submitted by Cisco Systems to the Apache Group in July
+ * 1997.  Future revisions and derivatives of this source code must
+ * acknowledge Cisco Systems as the original contributor of this module.
+ * All other licensing and usage conditions are those of the Apache Group.
+ *
+ * Some of this code is derived from the free version of the file command
+ * originally posted to comp.sources.unix.  Copyright info for that program
+ * is included below as required.
+ * ---------------------------------------------------------------------------
+ * - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone and
+ * Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on any
+ * computer system, and to alter it and redistribute it freely, subject to
+ * the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission.  Since few users ever read sources, credits
+ * must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.  Since few users ever read
+ * sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ * -------------------------------------------------------------------------
+ *
+ */
+
+
+For the  modules\mappers\mod_imap.c component:
+
+  "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
+
+For the  server\util_md5.c component:
+
+/************************************************************************
+ * NCSA HTTPd Server
+ * Software Development Group
+ * National Center for Supercomputing Applications
+ * University of Illinois at Urbana-Champaign
+ * 605 E. Springfield, Champaign, IL 61820
+ * httpd@ncsa.uiuc.edu
+ *
+ * Copyright  (C)  1995, Board of Trustees of the University of Illinois
+ *
+ ************************************************************************
+ *
+ * md5.c: NCSA HTTPd code which uses the md5c.c RSA Code
+ *
+ *  Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc.
+ *  Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon
+ *     University (see Copyright below).
+ *  Portions of Content-MD5 code Copyright (C) 1991 Bell Communications 
+ *     Research, Inc. (Bellcore) (see Copyright below).
+ *  Portions extracted from mpack, John G. Myers - jgm+@cmu.edu
+ *  Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk)
+ *
+ */
+
+
+/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */
+/* (C) Copyright 1993,1994 by Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Carnegie
+ * Mellon University not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  Carnegie Mellon University makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
+ *
+ * Permission to use, copy, modify, and distribute this material
+ * for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice
+ * appear in all copies, and that the name of Bellcore not be
+ * used in advertising or publicity pertaining to this
+ * material without the specific, prior written permission
+ * of an authorized representative of Bellcore.  BELLCORE
+ * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
+ * OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS",
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.  
+ */
+
+For the  srclib\apr\include\apr_md5.h component: 
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+
+For the  srclib\apr\passwd\apr_md5.c component:
+
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+/*
+ * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
+ * MD5 crypt() function, which is licenced as follows:
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * &lt;phk@login.dknet.dk&gt; wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.  Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+For the srclib\apr-util\crypto\apr_md4.c component:
+
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\include\apr_md4.h component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+
+For the srclib\apr-util\test\testdbm.c component:
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * &lt;http://www.apache.org/&gt;.
+ *
+ * This file came from the SDBM package (written by oz@nexus.yorku.ca).
+ * That package was under public domain. This file has been ported to
+ * APR, updated to ANSI C and other, newer idioms, and added to the Apache
+ * codebase under the above copyright and license.
+ */
+
+
+For the srclib\apr-util\test\testmd4.c component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ * rights reserved.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\xml\expat\conftools\install-sh component:
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+
+For the srclib\pcre\install-sh component:
+
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+
+For the pcre component:
+
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Written by: Philip Hazel &lt;ph10@cam.ac.uk&gt;
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2001 University of Cambridge
+
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission. In practice, this means that if you use
+   PCRE in software which you distribute to others, commercially or
+   otherwise, you must put a sentence like this
+
+     Regular expression support is provided by the PCRE library package,
+     which is open source software, written by Philip Hazel, and copyright
+     by the University of Cambridge, England.
+
+   somewhere reasonably visible in your documentation and in any relevant
+   files or online help data or similar. A reference to the ftp site for
+   the source, that is, to
+
+     ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+
+   should also be given in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL),
+   then the terms of that licence shall supersede any condition above with
+   which it is incompatible.
+
+The documentation for PCRE, supplied in the "doc" directory, is distributed
+under the same terms as the software itself.
+
+End PCRE LICENCE
+
+
+For the test\zb.c component:
+
+/*                          ZeusBench V1.01
+			    ===============
+
+This program is Copyright (C) Zeus Technology Limited 1996.
+
+This program may be used and copied freely providing this copyright notice
+is not removed.
+
+This software is provided "as is" and any express or implied waranties, 
+including but not limited to, the implied warranties of merchantability and
+fitness for a particular purpose are disclaimed.  In no event shall 
+Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, 
+exemplary, or consequential damaged (including, but not limited to, 
+procurement of substitute good or services; loss of use, data, or profits;
+or business interruption) however caused and on theory of liability.  Whether
+in contract, strict liability or tort (including negligence or otherwise) 
+arising in any way out of the use of this software, even if advised of the
+possibility of such damage.
+
+     Written by Adam Twiss (adam@zeus.co.uk).  March 1996
+
+Thanks to the following people for their input:
+  Mike Belshe (mbelshe@netscape.com) 
+  Michael Campanella (campanella@stevms.enet.dec.com)
+
+*/
+
+For the expat xml parser component:
+
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+                               and Clark Cooper
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+	
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+	
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====================================================================
+
+
+
 </pre>
 </div>
 </div>
@@ -58626,10 +65889,12 @@
 
 <div class="product">
 <span class="title">pv</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.ivarch.com/programs/pv.shtml">homepage</a></span>
 <div class="licence">
-<pre>This package is free software, and is being distributed under the terms
+<pre>Source license pv-1.3.4/doc/COPYING:
+
+This package is free software, and is being distributed under the terms
 of the Artistic License 2.0.
 
 ----------------------------------------------------------
@@ -58800,6 +66065,8 @@
 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 ----------------------------------------------------------
+
+
 </pre>
 </div>
 </div>
@@ -58807,10 +66074,12 @@
 
 <div class="product">
 <span class="title">python</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.python.org/">homepage</a></span>
 <div class="licence">
-<pre>A. HISTORY OF THE SOFTWARE
+<pre>Source license Python-2.7.3/LICENSE:
+
+A. HISTORY OF THE SOFTWARE
 ==========================
 
 Python was created in the early 1990s by Guido van Rossum at Stichting
@@ -59089,6 +66358,8 @@
 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
 </pre>
 </div>
 </div>
@@ -59096,10 +66367,12 @@
 
 <div class="product">
 <span class="title">python-evdev</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://gvalkov.github.com/python-evdev/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2012 Georgi Valkov. All rights reserved.
+<pre>Source license python-evdev-0.3.1/LICENSE:
+
+Copyright (c) 2012 Georgi Valkov. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -59127,6 +66400,8 @@
 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
 </pre>
 </div>
 </div>
@@ -59134,10 +66409,11 @@
 
 <div class="product">
 <span class="title">python-updater</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gentoo.org/proj/en/Python/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -59477,6 +66753,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -59484,10 +66763,12 @@
 
 <div class="product">
 <span class="title">pyyaml</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://pyyaml.org/wiki/PyYAML">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2006 Kirill Simonov
+<pre>Source license PyYAML-3.09/LICENSE:
+
+Copyright (c) 2006 Kirill Simonov
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
@@ -59506,355 +66787,8 @@
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
-</pre>
-</div>
-</div>
 
 
-<div class="product">
-<span class="title">pyzy</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
-<span class="homepage"><a href="http://code.google.com/p/pyzy/">homepage</a></span>
-<div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    &lt;one line to give the program's name and a brief idea of what it does.&gt;
-    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  &lt;signature of Ty Coon&gt;, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
 </pre>
 </div>
 </div>
@@ -59862,10 +66796,12 @@
 
 <div class="product">
 <span class="title">readline</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license readline-6.2/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -60539,6 +67475,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -60546,10 +67484,11 @@
 
 <div class="product">
 <span class="title">realtek-rt2800-firmware</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://git.kernel.org/?p=linux/kernel/git/firmware/linux-firmware.git">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2007, Ralink Technology Corporation
+<pre>Gentoo Package Provided Stock License ralink-firmware:
+Copyright (c) 2007, Ralink Technology Corporation
 All rights reserved.
 
 Redistribution.  Redistribution and use in binary form, without
@@ -60588,6 +67527,50 @@
 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 DAMAGE.
+
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">rootdev</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://www.chromium.org/">homepage</a></span>
+<div class="licence">
+<pre>Source license rootdev-0.0.1/LICENSE:
+
+// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
 </pre>
 </div>
 </div>
@@ -60595,10 +67578,12 @@
 
 <div class="product">
 <span class="title">rsync</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://rsync.samba.org/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license rsync-3.0.8/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -61272,6 +68257,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -61279,10 +68266,12 @@
 
 <div class="product">
 <span class="title">rsyslog</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.rsyslog.com/">homepage</a></span>
 <div class="licence">
-<pre>                  GNU GENERAL PUBLIC LICENSE
+<pre>Source license rsyslog-5.8.11/COPYING:
+
+                  GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -61957,356 +68946,8 @@
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
 
-</pre>
-</div>
-</div>
 
 
-<div class="product">
-<span class="title">rxvt-unicode</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
-<span class="homepage"><a href="http://software.schmorp.de/pkg/rxvt-unicode.html">homepage</a></span>
-<div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    &lt;one line to give the program's name and a brief idea of what it does.&gt;
-    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year  name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  &lt;signature of Ty Coon&gt;, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
 </pre>
 </div>
 </div>
@@ -62314,10 +68955,12 @@
 
 <div class="product">
 <span class="title">sandbox</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gentoo.org/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license sandbox-2.6/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -62657,6 +69300,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -62664,10 +69309,12 @@
 
 <div class="product">
 <span class="title">sbc</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://git.kernel.org/?p=bluetooth/sbc.git">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license sbc-1.0/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -63007,6 +69654,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -63014,10 +69663,12 @@
 
 <div class="product">
 <span class="title">scons</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.scons.org/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
+<pre>Source license scons-2.0.1/LICENSE.txt:
+
+Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
@@ -63037,6 +69688,8 @@
 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
 </pre>
 </div>
 </div>
@@ -63044,10 +69697,12 @@
 
 <div class="product">
 <span class="title">sed</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://sed.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license sed-4.2.1/COPYING:
+
+
 		    GNU GENERAL PUBLIC LICENSE
 		       Version 3, 29 June 2007
 
@@ -63723,6 +70378,8 @@
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
 
+
+
 </pre>
 </div>
 </div>
@@ -63730,10 +70387,12 @@
 
 <div class="product">
 <span class="title">setproctitle</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/py-setproctitle/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2009-2012, Daniele Varrazzo &lt;daniele.varrazzo@gmail.com&gt;
+<pre>Source license setproctitle-1.1.6/COPYRIGHT:
+
+Copyright (c) 2009-2012, Daniele Varrazzo &lt;daniele.varrazzo@gmail.com&gt;
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -63758,6 +70417,8 @@
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
 </pre>
 </div>
 </div>
@@ -63765,10 +70426,11 @@
 
 <div class="product">
 <span class="title">setuptools</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://pypi.python.org/pypi/distribute">homepage</a></span>
 <div class="licence">
-<pre>PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+<pre>Gentoo Package Provided Stock License PSF-2:
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
 --------------------------------------------
 
 1. This LICENSE AGREEMENT is between the Python Software Foundation
@@ -63814,6 +70476,9 @@
 8. By copying, installing or otherwise using Python, Licensee
 agrees to be bound by the terms and conditions of this License
 Agreement.
+
+
+
 </pre>
 </div>
 </div>
@@ -63821,10 +70486,12 @@
 
 <div class="product">
 <span class="title">shadow</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://shadow.pld.org.pl/">homepage</a></span>
 <div class="licence">
-<pre>NOTE:
+<pre>Source license shadow-4.1.2.2/COPYING:
+
+NOTE:
   This license has been obsoleted by the change to the BSD-style copyright.
   You may continue to use this license if you wish, but you are under no
   obligation to do so.
@@ -63942,6 +70609,8 @@
 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
 				The End
+
+
 </pre>
 </div>
 </div>
@@ -63949,10 +70618,12 @@
 
 <div class="product">
 <span class="title">shared-mime-info</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://freedesktop.org/wiki/Software/shared-mime-info">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license shared-mime-info-0.90/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -64292,6 +70963,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -64299,10 +70972,12 @@
 
 <div class="product">
 <span class="title">sharutils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/sharutils/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license sharutils-4.7/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		      Version 3, 29 June 2007
 
 Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -64941,6 +71616,8 @@
 library. If this is what you want to do, use the GNU Lesser General Public
 License instead of this License. But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -64948,10 +71625,11 @@
 
 <div class="product">
 <span class="title">shflags</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/shflags/">homepage</a></span>
 <div class="licence">
-<pre>		  GNU LESSER GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License LGPL-2.1:
+		  GNU LESSER GENERAL PUBLIC LICENSE
 		       Version 2.1, February 1999
 
  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
@@ -65455,6 +72133,9 @@
 That's all there is to it!
 
 
+
+
+
 </pre>
 </div>
 </div>
@@ -65462,10 +72143,11 @@
 
 <div class="product">
 <span class="title">sil-abyssinica</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://scripts.sil.org/AbyssinicaSIL">homepage</a></span>
 <div class="licence">
-<pre>This Font Software is Copyright (c) 2003-2005, SIL International (http://scripts.sil.org/).
+<pre>Gentoo Package Provided Stock License OFL:
+This Font Software is Copyright (c) 2003-2005, SIL International (http://scripts.sil.org/).
 All Rights Reserved.
 
 "Gentium" is a Reserved Font Name for this Font Software.
@@ -65564,6 +72246,9 @@
 DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
 OTHER DEALINGS IN THE FONT SOFTWARE.
+
+
+
 </pre>
 </div>
 </div>
@@ -65571,10 +72256,12 @@
 
 <div class="product">
 <span class="title">simplejson</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://undefined.org/python/#simplejson">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2006 Bob Ippolito
+<pre>Source license simplejson-2.5.0/LICENSE.txt:
+
+Copyright (c) 2006 Bob Ippolito
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
@@ -65593,6 +72280,8 @@
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
+
+
 </pre>
 </div>
 </div>
@@ -65600,10 +72289,12 @@
 
 <div class="product">
 <span class="title">smartmontools</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://smartmontools.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license smartmontools-5.42/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -65943,6 +72634,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -65950,10 +72643,12 @@
 
 <div class="product">
 <span class="title">speex</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.speex.org">homepage</a></span>
 <div class="licence">
-<pre>Copyright 2002-2008 	Xiph.org Foundation
+<pre>Source license speex-1.2rc1/COPYING:
+
+Copyright 2002-2008 	Xiph.org Foundation
 Copyright 2002-2008 	Jean-Marc Valin
 Copyright 2005-2007	Analog Devices Inc.
 Copyright 2005-2008	Commonwealth Scientific and Industrial Research 
@@ -65988,6 +72683,8 @@
 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
 </pre>
 </div>
 </div>
@@ -65995,15 +72692,46 @@
 
 <div class="product">
 <span class="title">sqlite</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.sqlite.org/">homepage</a></span>
 <div class="licence">
-<pre>The author disclaims copyright to this source code.  In place of
-a legal notice, here is a blessing:
+<pre>Gentoo Package Provided Stock License as-is:
+Note: This license label is deprecated, so don't use it for new packages.
+Unfortunately, "as-is" has been (ab)used also for non-free software and
+you cannot rely on it. Please check the upstream license instead.
 
-   May you do good and not evil.
-   May you find forgiveness for yourself and forgive others.
-   May you share freely, never taking more than you give.
+"as-is" in its originally intended sense is now covered by the OSI-approved
+"HPND" (Historical Permission Notice and Disclaimer).
+
+---------------------------------------------------------------------------
+
+This is a generic place holder for a class of licenses that boil down to do
+no guarantees and all you get is what you have. The language is usually
+similar to:
+
+  Permission to use, copy, modify, and distribute this software and its
+  documentation for any purpose and without fee is hereby granted, provided
+  that the above copyright notice appears in all copies and that both the
+  copyright notice and this permission notice appear in supporting
+  documentation, and that the same name not be used in advertising or
+  publicity pertaining to distribution of the software without specific,
+  written prior permission. We make no representations about the
+  suitability of this software for any purpose. It is provided "as is"
+  without express or implied warranty.
+
+
+You will need to check the license that came with the software for the exact
+specifics. Generally you are free to do most anything you want with "as is"
+software but you should not take this license as legal advice.
+
+Note: Most all license have an "as is" clause. For our purposes this does
+not make all software in this category. This category is for software with
+very little restrictions.
+
+The information in this license about licenses is presented "as is". :-P
+
+
+
 </pre>
 </div>
 </div>
@@ -66011,10 +72739,12 @@
 
 <div class="product">
 <span class="title">stressapptest</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://code.google.com/p/stressapptest/">homepage</a></span>
 <div class="licence">
-<pre>                                 Apache License
+<pre>Source license stressapptest-1.0.4_autoconf/COPYING:
+
+                                 Apache License
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
 
@@ -66215,6 +72945,8 @@
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
+
+
 </pre>
 </div>
 </div>
@@ -66222,10 +72954,12 @@
 
 <div class="product">
 <span class="title">strongswan</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.strongswan.org/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license strongswan-5.0.2/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -66564,6 +73298,58 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
+Source license strongswan-5.0.2/LICENSE:
+
+Except for code in the blowfish, des, md4 and md5 plugins (see below) the
+following terms apply:
+
+For copyright information see the headers of individual source files.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, see &lt;http://www.gnu.org/licenses&gt;.
+
+Linking strongSwan statically or dynamically with other modules is making a
+combined work based on strongSwan. Thus, the terms and conditions of the GNU
+General Public License cover the whole combination.
+
+In addition, as a special exception, the copyright holders of strongSwan give
+you permission to combine strongSwan with free software programs or libraries
+that are released under the GNU LGPL and with code included in the standard
+release of the OpenSSL project's OpenSSL library under the OpenSSL or SSLeay
+licenses (or modified versions of such code, with unchanged license). You may
+copy and distribute such a system following the terms of the GNU GPL for
+strongSwan and the licenses of the other code concerned, provided that you
+include the source code of that other code when and as the GNU GPL requires
+distribution of source code.
+
+Note that people who make modified versions of strongSwan are not obligated to
+grant this special exception for their modified versions; it is their choice
+whether to do so. The GNU General Public License gives permission to release a
+modified version without this exception; this exception also makes it possible
+to release a modified version which carries forward this exception.
+
+
+The DES implementation in the des plugin and the Blowfish implementation in the
+blowfish plugin are under a BSD style license (see source files for details).
+Note that these parts have an advertising clause in it.
+
+The MD4 and MD5 implementations in the md4 and md5 plugins are from RSA Data
+Security Inc., so this package must include the following phrase:
+"derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm".
+
+
+
 </pre>
 </div>
 </div>
@@ -66571,10 +73357,12 @@
 
 <div class="product">
 <span class="title">sudo</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.sudo.ws/">homepage</a></span>
 <div class="licence">
-<pre>Sudo is distributed under the following license:
+<pre>Source license sudo-1.8.6p7/doc/LICENSE:
+
+Sudo is distributed under the following license:
 
    Copyright (c) 1994-1996, 1998-2012
         Todd C. Miller &lt;Todd.Miller@courtesan.com&gt;
@@ -66695,6 +73483,8 @@
 
   Jean-loup Gailly        Mark Adler
   jloup@gzip.org          madler@alumni.caltech.edu
+
+
 </pre>
 </div>
 </div>
@@ -66702,10 +73492,12 @@
 
 <div class="product">
 <span class="title">swig</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.swig.org/">homepage</a></span>
 <div class="licence">
-<pre>SWIG Copyright and Authors
+<pre>Source license swig-2.0.4/COPYRIGHT:
+
+SWIG Copyright and Authors
 --------------------------
 
 Copyright (c) 1995-2011 The SWIG Developers
@@ -66808,6 +73600,34 @@
 Thomas Weidner, Tony Seward, Uwe Steinmann, Vadim Chugunov, Wyss Clemens,
 Zhong Ren.
 
+
+
+Source license swig-2.0.4/LICENSE:
+
+SWIG is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version. See the LICENSE-GPL file for
+the full terms of the GNU General Public license version 3.
+
+Portions of SWIG are also licensed under the terms of the licenses
+in the file LICENSE-UNIVERSITIES. You must observe the terms of
+these licenses, as well as the terms of the GNU General Public License,
+when you distribute SWIG.
+
+The SWIG library and examples, under the Lib and Examples top level 
+directories, are distributed under the following terms:
+
+  You may copy, modify, distribute, and make derivative works based on
+  this software, in source code or object code form, without
+  restriction. If you distribute the software to others, you may do
+  so according to the terms of your choice. This software is offered as
+  is, without warranty of any kind.
+
+See the COPYRIGHT file for a list of contributors to SWIG and their
+copyright notices.
+
+
 </pre>
 </div>
 </div>
@@ -66815,10 +73635,12 @@
 
 <div class="product">
 <span class="title">syslinux</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://syslinux.zytor.com/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license syslinux-3.83/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -67158,6 +73980,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -67165,10 +73989,12 @@
 
 <div class="product">
 <span class="title">tar</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/tar/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license tar-1.26/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -67842,6 +74668,113 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">tibt-jomolhari</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="https://sites.google.com/site/chrisfynn2/home/fonts/jomolhari">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License OFL-1.1:
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----
+
+PREAMBLE
+
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free
+and open framework in which fonts may be shared and improved in
+partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves.  The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works.  The fonts and derivatives,
+however, cannot be released under any other type of license.  The
+requirement for fonts to remain under this license does not apply to
+any document created using the fonts or their derivatives.
+
+DEFINITIONS
+
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such.  This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components
+as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software
+to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer
+or other person who contributed to the Font Software.
+
+PERMISSION &amp; CONDITIONS
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in
+Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license.  These can be
+included either as stand-alone text files, human-readable headers or in
+the appropriate machine-readable metadata fields within text or binary
+files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the
+corresponding Copyright Holder.  This restriction only applies to the
+primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license.  The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS",
+WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR
+OTHER RIGHT.  IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR
+CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE
+USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+
+
+
 </pre>
 </div>
 </div>
@@ -67849,10 +74782,14 @@
 
 <div class="product">
 <span class="title">timezone-data</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.iana.org/time-zones">homepage</a></span>
 <div class="licence">
-<pre>Software is in the public domain.
+<pre>Gentoo Package Provided Stock License public-domain:
+Software is in the public domain.
+
+
+
 </pre>
 </div>
 </div>
@@ -67860,10 +74797,12 @@
 
 <div class="product">
 <span class="title">tlsdate</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="https://github.com/ioerror/tlsdate">homepage</a></span>
 <div class="licence">
-<pre>                    This file contains the license for tlsdate,
+<pre>Source license tlsdate-0.0.5/LICENSE:
+
+                    This file contains the license for tlsdate,
         a free software project to set your system clock securely.
 
         It also lists the licenses for other components used by tlsdate.
@@ -67914,6 +74853,8 @@
   the OpenSSL Toolkit (http://www.openssl.org/)"
 
 ===============================================================================
+
+
 </pre>
 </div>
 </div>
@@ -67921,10 +74862,12 @@
 
 <div class="product">
 <span class="title">trousers</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://trousers.sf.net">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license trousers-0.3.3/LICENSE:
+
+
 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
 
 1. DEFINITIONS
@@ -68011,6 +74954,8 @@
 
 This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
 
+
+
 </pre>
 </div>
 </div>
@@ -68018,10 +74963,12 @@
 
 <div class="product">
 <span class="title">udev</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license udev-171/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -68360,6 +75307,50 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
+</pre>
+</div>
+</div>
+
+
+<div class="product">
+<span class="title">unittest2</span>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
+<span class="homepage"><a href="http://pypi.python.org/pypi/unittest2">homepage</a></span>
+<div class="licence">
+<pre>Gentoo Package Provided Stock License BSD-Google:
+Copyright 2010, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
 </pre>
 </div>
 </div>
@@ -68367,10 +75358,12 @@
 
 <div class="product">
 <span class="title">unrar</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.rarlab.com/rar_add.htm">homepage</a></span>
 <div class="licence">
-<pre> ******    *****   ******   UnRAR - free utility for RAR archives
+<pre>Source license unrar/license.txt:
+
+ ******    *****   ******   UnRAR - free utility for RAR archives
  **   **  **   **  **   **  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ******   *******  ******    License for use and distribution of
  **   **  **   **  **   **   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -68412,6 +75405,8 @@
 
 
                                             Alexander L. Roshal
+
+
 </pre>
 </div>
 </div>
@@ -68419,10 +75414,12 @@
 
 <div class="product">
 <span class="title">upstart</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://upstart.ubuntu.com/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license upstart-1.2/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -68761,6 +75758,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -68768,10 +75767,12 @@
 
 <div class="product">
 <span class="title">ureadahead</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="https://launchpad.net/ureadahead">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license ureadahead-0.100.0/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
@@ -69110,6 +76111,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -69117,10 +76120,12 @@
 
 <div class="product">
 <span class="title">usbutils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://linux-usb.sourceforge.net/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license usbutils-006/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -69460,6 +76465,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -69467,10 +76474,12 @@
 
 <div class="product">
 <span class="title">util-linux</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.kernel.org/pub/linux/utils/util-linux/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license util-linux-2.21.2/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -69810,6 +76819,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -69817,10 +76828,11 @@
 
 <div class="product">
 <span class="title">vim</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.vim.org/">homepage</a></span>
 <div class="licence">
-<pre>License details for VIM Editor:
+<pre>Gentoo Package Provided Stock License vim:
+License details for VIM Editor:
 
 *uganda.txt*    For Vim version 7.2.  Last change: 2008 Jun 21
 
@@ -70109,6 +77121,9 @@
 This address is expected to be valid for a long time.
 
  vim:tw=78:ts=8:ft=help:norl:
+
+
+
 </pre>
 </div>
 </div>
@@ -70116,10 +77131,12 @@
 
 <div class="product">
 <span class="title">wget</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.gnu.org/software/wget/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license wget-1.12/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -70793,6 +77810,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -70800,10 +77819,12 @@
 
 <div class="product">
 <span class="title">which</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.xs4all.nl/~carlo17/which/">homepage</a></span>
 <div class="licence">
-<pre>                    GNU GENERAL PUBLIC LICENSE
+<pre>Source license which-2.20/COPYING:
+
+                    GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
@@ -71477,6 +78498,8 @@
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
 &lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+
+
 </pre>
 </div>
 </div>
@@ -71484,10 +78507,12 @@
 
 <div class="product">
 <span class="title">wireless-regdb</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://wireless.kernel.org/en/developers/Regulatory">homepage</a></span>
 <div class="licence">
-<pre>Copyright (c) 2008, Luis R. Rodriguez &lt;mcgrof@gmail.com&gt;
+<pre>Source license wireless-regdb-2010.11.24/LICENSE:
+
+Copyright (c) 2008, Luis R. Rodriguez &lt;mcgrof@gmail.com&gt;
 Copyright (c) 2008, Johannes Berg &lt;johannes@sipsolutions.net&gt;
 Copyright (c) 2008, Michael Green &lt;Michael.Green@Atheros.com&gt;
 
@@ -71503,6 +78528,8 @@
 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
+
+
 </pre>
 </div>
 </div>
@@ -71510,10 +78537,12 @@
 
 <div class="product">
 <span class="title">wpa_supplicant</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://hostap.epitest.fi/wpa_supplicant/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license wpa_supplicant-0.7.2/COPYING:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -71806,7 +78835,7 @@
 the "copyright" line and a pointer to where the full notice is found.
 
     &lt;one line to give the program's name and a brief idea of what it does.&gt;
-    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+    Copyright (C) 19yy  &lt;name of author&gt;
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -71828,7 +78857,7 @@
 If the program is interactive, make it output a short notice like this
 when it starts in an interactive mode:
 
-    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision version 69, Copyright (C) 19yy name of author
     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     This is free software, and you are welcome to redistribute it
     under certain conditions; type `show c' for details.
@@ -71853,6 +78882,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -71860,10 +78891,12 @@
 
 <div class="product">
 <span class="title">xcb-proto</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://xcb.freedesktop.org/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett.
+<pre>Source license xcb-proto-1.7.1/COPYING:
+
+Copyright (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett.
 All Rights Reserved.
 
 Permission is hereby granted, free of charge, to any person
@@ -71893,6 +78926,8 @@
 otherwise to promote the sale, use or other dealings in this
 Software without prior written authorization from the
 authors.
+
+
 </pre>
 </div>
 </div>
@@ -71900,10 +78935,12 @@
 
 <div class="product">
 <span class="title">xkeyboard-config</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.freedesktop.org/wiki/Software/XKeyboardConfig">homepage</a></span>
 <div class="licence">
-<pre>Copyright 1996 by Joseph Moss
+<pre>Source license xkeyboard-config-2.4.1/COPYING:
+
+Copyright 1996 by Joseph Moss
 Copyright (C) 2002-2007 Free Software Foundation, Inc.
 Copyright (C) Dmitry Golubev &lt;lastguru@mail.ru&gt;, 2003-2004
 Copyright (C) 2004, Gregory Mokhin &lt;mokhin@bog.msu.ru&gt;
@@ -72093,6 +79130,8 @@
 the changes in this header.
 
 This file is distributed without any expressed or implied warranty.
+
+
 </pre>
 </div>
 </div>
@@ -72100,10 +79139,12 @@
 
 <div class="product">
 <span class="title">xl2tpd</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.xelerance.com/services/software/xl2tpd/">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Source license xl2tpd-1.3.0/LICENSE:
+
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -72443,6 +79484,8 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
 </pre>
 </div>
 </div>
@@ -72450,10 +79493,11 @@
 
 <div class="product">
 <span class="title">xxd</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://ftp.uni-erlangen.de/pub/utilities/etc/?order=s">homepage</a></span>
 <div class="licence">
-<pre>		    GNU GENERAL PUBLIC LICENSE
+<pre>Gentoo Package Provided Stock License GPL-2:
+		    GNU GENERAL PUBLIC LICENSE
 		       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
@@ -72793,6 +79837,9 @@
 consider it more useful to permit linking proprietary applications with the
 library.  If this is what you want to do, use the GNU Library General
 Public License instead of this License.
+
+
+
 </pre>
 </div>
 </div>
@@ -72800,10 +79847,12 @@
 
 <div class="product">
 <span class="title">xz-utils</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://tukaani.org/xz/">homepage</a></span>
 <div class="licence">
-<pre>
+<pre>Source license xz-4.999.9beta/COPYING:
+
+
 XZ Utils Licensing
 ==================
 
@@ -72868,6 +79917,8 @@
     If you have questions, don't hesitate to ask the author(s) for more
     information.
 
+
+
 </pre>
 </div>
 </div>
@@ -72875,10 +79926,11 @@
 
 <div class="product">
 <span class="title">zlib</span>
-<a class="show" href="#" onclick="return toggle(this);">show license</a>
+<a class="show" href="#" onclick="return toggle(this);">show license(s)</a>
 <span class="homepage"><a href="http://www.zlib.net/">homepage</a></span>
 <div class="licence">
-<pre>Copyright (C) &lt;year&gt; &lt;copyright holders&gt;
+<pre>Gentoo Package Provided Stock License ZLIB:
+Copyright (C) &lt;year&gt; &lt;copyright holders&gt;
 
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the author(s) be held liable for any damages
@@ -72895,6 +79947,9 @@
 2. Altered source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.
 3. This notice may not be removed or altered from any source distribution.
+
+
+
 </pre>
 </div>
 </div>
diff --git a/chrome/browser/resources/chromeos/image_burner.js b/chrome/browser/resources/chromeos/image_burner.js
index 0a48abe..b3e5aa2 100644
--- a/chrome/browser/resources/chromeos/image_burner.js
+++ b/chrome/browser/resources/chromeos/image_burner.js
@@ -111,15 +111,21 @@
 
   /**
    * Reset to initial state.
-   * @param {number} deviceCount Device count information.
+   * @param {Array} devices Array of device information.
    */
-  gotoInitialState: function(deviceCount) {
-    if (deviceCount == 0)
+  gotoInitialState: function(devices) {
+    if (devices.length == 0) {
       this.changeState(State.StatesEnum.DEVICE_NONE);
-    else if (deviceCount == 1)
-      this.changeState(State.StatesEnum.DEVICE_USB);
-    else
+    } else if (devices.length == 1) {
+      // If a device type is not specified for some reason, we should
+      // default to display a USB device.
+      var initialState = State.StatesEnum.DEVICE_USB;
+      if (devices[0].type == 'sd')
+        initialState = State.StatesEnum.DEVICE_SD;
+      this.changeState(initialState);
+    } else {
       this.changeState(State.StatesEnum.DEVICE_MUL);
+    }
   },
 
   /**
@@ -148,30 +154,20 @@
  * @constructor
  */
 function DeviceSelection() {
-  this.deviceCount = 0;
+  this.selectedDevice = undefined;
+  this.devices = [];
 }
 
 DeviceSelection.prototype = {
   /**
-   * Clears the given selection list.
-   * @param {Array} list Device selection list.
-   */
-  clearSelectList: function(list) {
-    list.innerHtml = '';
-  },
-
-  /**
    * Shows the currently selected device.
-   * @return {number} Selected device count.
    */
   showDeviceSelection: function() {
-    if (this.deviceCount == 0) {
+    if (this.devices.length == 0) {
       this.selectedDevice = undefined;
     } else {
-      var devices = document.getElementsByClassName('selection-element');
-      this.selectDevice(devices[0].devicePath);
+      this.selectDevice(this.devices[0].devicePath);
     }
-    return this.deviceCount;
   },
 
   /**
@@ -196,7 +192,7 @@
    * @param {string} path Device path.
    */
   selectDevice: function(path) {
-    var element = $('radio ' + path);
+    var element = $('radio-' + path);
     element.checked = true;
     element.onclick.apply(element);
   },
@@ -212,7 +208,7 @@
     radioButton.type = 'radio';
     radioButton.name = 'device';
     radioButton.value = device.label;
-    radioButton.id = 'radio ' + device.devicePath;
+    radioButton.id = 'radio-' + device.devicePath;
     radioButton.className = 'float-start';
     var deviceLabelText = document.createElement('p');
     deviceLabelText.textContent = device.label;
@@ -222,8 +218,7 @@
     element.appendChild(radioButton);
     element.appendChild(deviceLabelText);
     element.appendChild(newLine);
-    element.id = 'select ' + device.devicePath;
-    element.devicePath = device.devicePath;
+    element.id = 'select-' + device.devicePath;
     element.className = 'selection-element';
     radioButton.onclick = this.onDeviceSelected.bind(this,
         device.label, device.filePath, device.devicePath);
@@ -233,60 +228,73 @@
   /**
    * Updates the list of selected devices.
    * @param {Array} devices List of devices.
-   * @return {number} Device count.
    */
-  getDevicesCallback: function(devices) {
+  devicesUpdated: function(newDevices) {
+    this.devices = newDevices;
     var selectListDOM = $('device-selection');
-    this.clearSelectList(selectListDOM);
-    this.deviceCount = devices.length;
-    if (devices.length > 0) {
-      for (var i = 0; i < devices.length; i++) {
-        var element = this.createNewDeviceElement(devices[i]);
+    selectListDOM.innerHTML = '';
+    if (this.devices.length > 0) {
+      for (var i = 0; i < this.devices.length; i++) {
+        var element = this.createNewDeviceElement(this.devices[i]);
         selectListDOM.appendChild(element);
       }
-      this.selectDevice(devices[0].devicePath);
+      this.selectDevice(this.devices[0].devicePath);
     } else {
       this.selectedDevice = undefined;
     }
-    return this.deviceCount;
   },
 
   /**
    * Handles device added event.
    * @param {Object} device Device information.
    * @param {boolean} allowSelect True to update the selected device info.
-   * @return {number} Device count.
    */
   deviceAdded: function(device, allowSelect) {
+    this.devices.push(device);
     var selectListDOM = $('device-selection');
     selectListDOM.appendChild(this.createNewDeviceElement(device));
-    this.deviceCount++;
-    if (allowSelect && this.deviceCount == 1)
+    if (allowSelect && this.devices.length == 1)
       this.selectDevice(device.devicePath);
-    return this.deviceCount;
   },
 
   /**
    * Handles device removed event.
-   * @param {string} devicePath Selected device path.
+   * @param {string} devicePath Device path to be removed.
    * @param {boolean} allowSelect True to update the selected device info.
-   * @return {number} Device count.
    */
   deviceRemoved: function(devicePath, allowSelect) {
-    var deviceSelectElement = $('select ' + devicePath);
-    deviceSelectElement.parentNode.removeChild(deviceSelectElement);
-    this.deviceCount--;
-    var devices = document.getElementsByClassName('selection-element');
+    device = this.findDevice(devicePath);
+    if (!device)
+      return;
+    this.devices.splice(this.devices.indexOf(device), 1);
 
+    // Remove device selection element from DOM.
+    var deviceSelectElement = $('select-' + devicePath);
+    deviceSelectElement.parentNode.removeChild(deviceSelectElement);
+
+    // Update selected device element.
     if (allowSelect) {
-      if (devices.length > 0) {
+      if (this.devices.length > 0) {
         if (this.selectedDevice == devicePath)
-          this.selectDevice(devices[0].devicePath);
+          this.selectDevice(this.devices[0].devicePath);
       } else {
         this.selectedDevice = undefined;
       }
     }
-    return this.deviceCount;
+  },
+
+  /**
+   * Finds device with given device path property.
+   * @param {string} devicePath Device path of device to find.
+   * @return {Object} Matching device information or undefined if not found.
+   */
+  findDevice: function(devicePath) {
+    for (var i = 0; i < this.devices.length; ++i) {
+      if (this.devices[i].devicePath == devicePath) {
+        return this.devices[i];
+      }
+    }
+    return undefined;
   }
 };
 
@@ -296,7 +304,7 @@
  */
 function BrowserBridge() {
   this.currentState = new State(localStrings);
-  this.devices = new DeviceSelection();
+  this.deviceSelection = new DeviceSelection();
   // We will use these often so it makes sence making them class members to
   // avoid frequent document.getElementById calls.
   this.progressElement = $('progress-div');
@@ -347,20 +355,20 @@
    */
   deviceAdded: function(device) {
     var inInitialState = this.currentState.isInitialState();
-    var deviceCount = this.devices.deviceAdded(device, inInitialState);
+    this.deviceSelection.deviceAdded(device, inInitialState);
     if (inInitialState)
-      this.currentState.gotoInitialState(deviceCount);
+      this.currentState.gotoInitialState(this.deviceSelection.devices);
   },
 
   /**
    * Handles device removed event.
-   * @param {Object} device Device information.
+   * @param {string} devicePath Device path to be removed.
    */
-  deviceRemoved: function(device) {
+  deviceRemoved: function(devicePath) {
     var inInitialState = this.currentState.isInitialState();
-    var deviceCount = this.devices.deviceRemoved(device, inInitialState);
+    this.deviceSelection.deviceRemoved(devicePath, inInitialState);
     if (inInitialState)
-      this.currentState.gotoInitialState(deviceCount);
+      this.currentState.gotoInitialState(this.deviceSelection.devices);
   },
 
   /**
@@ -368,8 +376,8 @@
    * @param {Array} devices List of devices.
    */
   getDevicesCallback: function(devices) {
-    var deviceCount = this.devices.getDevicesCallback(devices);
-    this.currentState.gotoInitialState(deviceCount);
+    this.deviceSelection.devicesUpdated(devices);
+    this.currentState.gotoInitialState(this.deviceSelection.devices);
     this.sendWebuiInitializedMessage();
   },
 
@@ -406,8 +414,8 @@
 
   reportNetworkDetected: function() {
     if (this.currentState.equals(State.StatesEnum.ERROR_NO_NETWORK)) {
-      var deviceCount = this.devices.showDeviceSelection();
-      this.currentState.gotoInitialState(deviceCount);
+      this.deviceSelection.showDeviceSelection();
+      this.currentState.gotoInitialState(this.deviceSelection.devices);
     }
   },
 
@@ -425,8 +433,8 @@
    * Processes click on 'Retry' button in FAIL state.
    */
   onBurnRetry: function() {
-    var deviceCount = this.devices.showDeviceSelection();
-    this.currentState.gotoInitialState(deviceCount);
+    this.deviceSelection.showDeviceSelection();
+    this.currentState.gotoInitialState(this.deviceSelection.devices);
   }
 };
 
diff --git a/chrome/browser/resources/chromeos/keyboard_overlay_data.js b/chrome/browser/resources/chromeos/keyboard_overlay_data.js
index 235420e..9a86bdc 100644
--- a/chrome/browser/resources/chromeos/keyboard_overlay_data.js
+++ b/chrome/browser/resources/chromeos/keyboard_overlay_data.js
@@ -15803,6 +15803,7 @@
     '8<>SEARCH': 'keyboardOverlayF8',
     '9<>ALT': 'keyboardOverlayActivateLastLauncherItem',
     '9<>CTRL': 'keyboardOverlayActivateLastTab',
+    '9<>CTRL<>SHIFT': 'keyboardOverlayToggleTouchHudProjection',
     '9<>SEARCH': 'keyboardOverlayF9',
     '=<>SEARCH': 'keyboardOverlayF12',
     'ALT<>SEARCH': 'keyboardOverlayToggleCapsLock',
diff --git a/chrome/browser/resources/chromeos/login/header_bar.js b/chrome/browser/resources/chromeos/login/header_bar.js
index 2ec8d33..efeed3d 100644
--- a/chrome/browser/resources/chromeos/login/header_bar.js
+++ b/chrome/browser/resources/chromeos/login/header_bar.js
@@ -45,10 +45,8 @@
       $('cancel-multiple-sign-in-button').addEventListener('click',
           this.handleCancelMultipleSignInClick_);
 
-      if (loadTimeData.getBoolean('enableAppMode') &&
-          document.documentElement.getAttribute('screen') == 'login') {
+      if (document.documentElement.getAttribute('screen') == 'login')
         login.AppsMenuButton.decorate($('show-apps-button'));
-      }
     },
 
     /**
diff --git a/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.js b/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.js
index 6cec377..e8c3928 100644
--- a/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.js
+++ b/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.js
@@ -173,7 +173,7 @@
     },
 
     selectPod: function(podToSelect) {
-      if (this.selectedPod_ == podToSelect) {
+      if ((this.selectedPod_ == podToSelect) && (podToSelect != null)) {
         podToSelect.focusInput();
         return;
       }
@@ -185,12 +185,14 @@
           pod.passwordBlock.hidden = true;
         }
       }
+      if (podToSelect == null)
+        return;
       podToSelect.classList.add('focused');
       podToSelect.passwordBlock.hidden = false;
       podToSelect.passwordElement.value = '';
       podToSelect.focusInput();
       chrome.send('managerSelectedOnLocallyManagedUserCreationFlow',
-          [podToSelect.user.emailAddress]);
+          [podToSelect.user.username]);
 
     },
   };
@@ -485,7 +487,7 @@
       if (null == selectedPod)
         return;
 
-      var managerId = selectedPod.user.emailAddress;
+      var managerId = selectedPod.user.username;
       var managerPassword = selectedPod.passwordElement.value;
       if (managerPassword.empty)
         return;
@@ -697,6 +699,12 @@
 
       this.currentPage_ = visiblePage;
 
+      if (visiblePage == 'manager' || visiblePage == 'intro') {
+        this.managerList_.selectPod(null);
+        if (this.managerList_.pods.length == 1)
+          this.managerList_.selectPod(this.managerList_.pods[0]);
+      }
+
       if (visiblePage == 'username') {
         var imageGrid = this.getScreenElement('image-grid');
         // select some image.
diff --git a/chrome/browser/resources/chromeos/sim_unlock.js b/chrome/browser/resources/chromeos/sim_unlock.js
index 5f15d8f..92033c8 100644
--- a/chrome/browser/resources/chromeos/sim_unlock.js
+++ b/chrome/browser/resources/chromeos/sim_unlock.js
@@ -121,7 +121,7 @@
         case SimUnlock.SIM_LOCKED_NO_PUK_TRIES_LEFT:
           $('locked-puk-no-tries-overlay').hidden = false;
           break;
-        case SimUnlock.SimUnlock.SIM_DISABLED:
+        case SimUnlock.SIM_DISABLED:
           $('sim-disabled-overlay').hidden = false;
           break;
       }
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_directories.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_directories.js
index 6e018eb..ff3de99 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_directories.js
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_directories.js
@@ -5,12 +5,12 @@
 /**
  * Wallpaper file system quota.
  */
-/** #const */ var WallpaperQuota = 1024 * 1024 * 100;
+/** @const */ var WallpaperQuota = 1024 * 1024 * 100;
 
 /**
  * Wallpaper directories enum.
  */
-/** #const */ var WallpaperDirNameEnum = {
+/** @const */ var WallpaperDirNameEnum = {
                   ORIGINAL: 'original',
                   THUMBNAIL: 'thumbnail'
               };
diff --git a/chrome/browser/resources/downloads/downloads.css b/chrome/browser/resources/downloads/downloads.css
index 0da77c3..5cc5578 100644
--- a/chrome/browser/resources/downloads/downloads.css
+++ b/chrome/browser/resources/downloads/downloads.css
@@ -23,7 +23,7 @@
 .header .form {
   -webkit-margin-start: 12px;
   float: left;
-  margin-top: 22px;
+  margin-top: 4px;
 }
 
 #downloads-summary {
diff --git a/chrome/browser/resources/downloads/downloads.html b/chrome/browser/resources/downloads/downloads.html
index 4289f89..c6136d3 100644
--- a/chrome/browser/resources/downloads/downloads.html
+++ b/chrome/browser/resources/downloads/downloads.html
@@ -14,7 +14,7 @@
   <div class="header">
     <a id="search-link" href="">
       <img src="../downloads_section.png"
-          width="67" height="67" class="logo" border="0">
+          width="32" height="32" class="logo" border="0">
     </a>
     <input id="term" type="search" tabindex=1
         i18n-values="placeholder:searchbutton" class="form" autofocus incremental>
diff --git a/chrome/browser/resources/extensions/extension_list.js b/chrome/browser/resources/extensions/extension_list.js
index f689263..78ce406 100644
--- a/chrome/browser/resources/extensions/extension_list.js
+++ b/chrome/browser/resources/extensions/extension_list.js
@@ -125,7 +125,7 @@
 
       // The 'allow in incognito' checkbox.
       var incognito = node.querySelector('.incognito-control input');
-      incognito.disabled = !extension.incognitoCanBeEnabled;
+      incognito.disabled = !extension.incognitoCanBeToggled;
       incognito.checked = extension.enabledIncognito;
       if (!incognito.disabled) {
         incognito.addEventListener('change', function(e) {
diff --git a/chrome/browser/resources/extensions/extensions.html b/chrome/browser/resources/extensions/extensions.html
index d97bc0a..02c5c16 100644
--- a/chrome/browser/resources/extensions/extensions.html
+++ b/chrome/browser/resources/extensions/extensions.html
@@ -160,8 +160,6 @@
               <input type="checkbox">
               <span i18n-content="extensionSettingsAllowFileAccess"></span>
             </label>
-            <a class="options-link" i18n-content="extensionSettingsOptions"
-                href="#" hidden></a>
             <a class="reload-link"
                 i18n-content="extensionSettingsReloadUnpacked"
                 href="#" hidden></a>
@@ -170,6 +168,8 @@
             <a class="restart-link" i18n-content="extensionSettingsRestart"
                 href="#" hidden></a>
           </span>
+          <a class="options-link" i18n-content="extensionSettingsOptions"
+              href="#" hidden></a>
         </div>
         <div class="butter-bar"
             i18n-values=".innerHTML:extensionSettingsIncognitoWarning" hidden>
diff --git a/chrome/browser/resources/extensions/extensions.js b/chrome/browser/resources/extensions/extensions.js
index e2010cd..a0f906e 100644
--- a/chrome/browser/resources/extensions/extensions.js
+++ b/chrome/browser/resources/extensions/extensions.js
@@ -21,42 +21,51 @@
 
   // Implements the DragWrapper handler interface.
   var dragWrapperHandler = {
-    // @inheritdoc
+    /** @override */
     shouldAcceptDrag: function(e) {
       // We can't access filenames during the 'dragenter' event, so we have to
       // wait until 'drop' to decide whether to do something with the file or
       // not.
       // See: http://www.w3.org/TR/2011/WD-html5-20110113/dnd.html#concept-dnd-p
-      return e.dataTransfer.types.indexOf('Files') > -1;
+      return (e.dataTransfer.types &&
+              e.dataTransfer.types.indexOf('Files') > -1);
     },
-    // @inheritdoc
+    /** @override */
     doDragEnter: function() {
       chrome.send('startDrag');
       ExtensionSettings.showOverlay(null);
       ExtensionSettings.showOverlay($('dropTargetOverlay'));
     },
-    // @inheritdoc
+    /** @override */
     doDragLeave: function() {
       ExtensionSettings.showOverlay(null);
       chrome.send('stopDrag');
     },
-    // @inheritdoc
+    /** @override */
     doDragOver: function(e) {
       e.preventDefault();
     },
-    // @inheritdoc
+    /** @override */
     doDrop: function(e) {
       ExtensionSettings.showOverlay(null);
+      if (e.dataTransfer.files.length != 1)
+        return;
 
+      var toSend = null;
+      // Files lack a check if they're a directory, but we can find out through
+      // its item entry.
+      var fileIndex = e.dataTransfer.types.indexOf('Files');
+      if (e.dataTransfer.items[fileIndex].webkitGetAsEntry().isDirectory)
+        toSend = 'installDroppedDirectory';
       // Only process files that look like extensions. Other files should
       // navigate the browser normally.
-      if (!e.dataTransfer.files.length ||
-          !/\.(crx|user\.js)$/.test(e.dataTransfer.files[0].name)) {
-        return;
-      }
+      else if (/\.(crx|user\.js)$/i.test(e.dataTransfer.files[0].name))
+        toSend = 'installDroppedFile';
 
-      chrome.send('installDroppedFile');
-      e.preventDefault();
+      if (toSend) {
+        e.preventDefault();
+        chrome.send(toSend);
+      }
     }
   };
 
diff --git a/chrome/browser/resources/file_manager/css/common.css b/chrome/browser/resources/file_manager/css/common.css
index 03eea6c..2c6e080 100644
--- a/chrome/browser/resources/file_manager/css/common.css
+++ b/chrome/browser/resources/file_manager/css/common.css
@@ -220,7 +220,6 @@
 }
 
 menu.chrome-menu > menuitem[disabled] {
-  background-color: rgb(252, 252, 252);
   color: rgb(153, 153, 153);
 }
 
@@ -246,6 +245,10 @@
   display: none;
 }
 
+menu[showShortcuts] > menuitem[shortcutText][selected]:not([disabled])::after {
+  color: white;
+}
+
 /**
  * Ok/Cancel style buttons
  * Height: 31px (content:21px + border:5px * 2)
@@ -371,6 +374,7 @@
   -webkit-box-orient: vertical;
   background-color: rgb(250, 250, 250);
   border: 1px solid rgb(255, 255, 255);
+  border-radius: 2px;
   box-shadow: 0 1px 4px 0 rgba(0, 0, 0, .5);
   color: rgb(34, 34, 34);
   cursor: default;
diff --git a/chrome/browser/resources/file_manager/css/file_manager.css b/chrome/browser/resources/file_manager/css/file_manager.css
index 184f4f3..e4b8a8a 100644
--- a/chrome/browser/resources/file_manager/css/file_manager.css
+++ b/chrome/browser/resources/file_manager/css/file_manager.css
@@ -177,7 +177,7 @@
   min-width: 100px;
   overflow: hidden;
   position: relative;
-  width: 200px;
+  width: 150px;
 }
 
 .dialog-sidebar-header {
@@ -1377,10 +1377,6 @@
   padding-left: 32px;
 }
 
-menu[showShortcuts] > menuitem[selected]:not([disabled])::after {
-  color: white;
-}
-
 #preview-lines {
   -webkit-box-flex: 1;
   -webkit-margin-end: 10px;
diff --git a/chrome/browser/resources/file_manager/css/gallery.css b/chrome/browser/resources/file_manager/css/gallery.css
index 5d2a20a..1966f07 100644
--- a/chrome/browser/resources/file_manager/css/gallery.css
+++ b/chrome/browser/resources/file_manager/css/gallery.css
@@ -1274,7 +1274,8 @@
 }
 
 .mosaic-tile .img-wrapper[generic-thumbnail],
-.mosaic-tile .img-wrapper:not([generic-thumbnail]) canvas:not(.cached) {
+.mosaic-tile .img-wrapper.animated:not([generic-thumbnail])
+    canvas:not(.cached) {
   -webkit-animation: fadeIn ease-in 1;
   -webkit-animation-duration: 500ms;
   -webkit-animation-fill-mode: forwards;
diff --git a/chrome/browser/resources/file_manager/css/menu.css b/chrome/browser/resources/file_manager/css/menu.css
new file mode 100644
index 0000000..2f32d05
--- /dev/null
+++ b/chrome/browser/resources/file_manager/css/menu.css
@@ -0,0 +1,38 @@
+/* Copyright 2013 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+/* Derived from /ui/webui/resources/css/menu.css. */
+
+menu {
+  position: fixed;
+  white-space: nowrap;
+  z-index: 3;
+}
+
+menu:not(.decorated) {
+  display: none;
+}
+
+menu > * {
+  box-sizing: border-box;
+  display: block;
+  text-align: start;
+  width: 100%;
+}
+
+menu > hr {
+  border: 0;
+  height: 1px;
+}
+
+menu > [hidden] {
+  display: none;
+}
+
+menu > [shortcutText]::after {
+  -webkit-padding-start: 30px;
+  color: #999;
+  content: attr(shortcutText);
+  float: right;
+}
diff --git a/chrome/browser/resources/file_manager/gallery.html b/chrome/browser/resources/file_manager/gallery.html
index dfa6941..9488fb6 100644
--- a/chrome/browser/resources/file_manager/gallery.html
+++ b/chrome/browser/resources/file_manager/gallery.html
@@ -5,8 +5,7 @@
   -->
 <html>
 <head>
-  <link rel="stylesheet" href="chrome://resources/css/dialogs.css">
-  <link rel="stylesheet" href="chrome://resources/css/list.css">
+  <link rel="stylesheet" href="css/list.css">
   <link rel="stylesheet" href="css/common.css">
   <link rel="stylesheet" href="css/file_types.css">
   <link rel="stylesheet" href="css/gallery.css">
diff --git a/chrome/browser/resources/file_manager/js/directory_model.js b/chrome/browser/resources/file_manager/js/directory_model.js
index 7520201..46e6015 100644
--- a/chrome/browser/resources/file_manager/js/directory_model.js
+++ b/chrome/browser/resources/file_manager/js/directory_model.js
@@ -1386,7 +1386,7 @@
 
     } else {
       // Unknown path.
-      this.changeDirectory(thid.getDefaultDirectory());
+      this.changeDirectory(this.getDefaultDirectory());
       return;
     }
 
diff --git a/chrome/browser/resources/file_manager/js/file_grid.js b/chrome/browser/resources/file_manager/js/file_grid.js
index 281c466..bb08940 100644
--- a/chrome/browser/resources/file_manager/js/file_grid.js
+++ b/chrome/browser/resources/file_manager/js/file_grid.js
@@ -17,6 +17,15 @@
 }
 
 /**
+ * Thumbnail quality.
+ * @enum {number}
+ */
+FileGrid.ThumbnailQuality = {
+  LOW: 0,
+  HIGH: 1
+};
+
+/**
  * Inherits from cr.ui.Grid.
  */
 FileGrid.prototype.__proto__ = cr.ui.Grid.prototype;
@@ -58,8 +67,11 @@
     if (!entry || !(entry.toURL() in props))
       continue;
 
-    FileGrid.decorateThumbnailBox(box, entry, this.metadataCache_,
-                                  ThumbnailLoader.FillMode.FIT);
+    FileGrid.decorateThumbnailBox(box,
+                                  entry,
+                                  this.metadataCache_,
+                                  ThumbnailLoader.FillMode.FIT,
+                                  FileGrid.ThumbnailQuality.HIGH);
   }
 };
 
@@ -97,8 +109,11 @@
   li.appendChild(frame);
 
   var box = li.ownerDocument.createElement('div');
-  FileGrid.decorateThumbnailBox(
-      box, entry, metadataCache, ThumbnailLoader.FillMode.AUTO);
+  FileGrid.decorateThumbnailBox(box,
+                                entry,
+                                metadataCache,
+                                ThumbnailLoader.FillMode.AUTO,
+                                FileGrid.ThumbnailQuality.HIGH);
   frame.appendChild(box);
 
   var bottom = li.ownerDocument.createElement('div');
@@ -115,11 +130,12 @@
  * @param {Entry} entry Entry which thumbnail is generating for.
  * @param {MetadataCache} metadataCache To retrieve metadata.
  * @param {ThumbnailLoader.FillMode} fillMode Fill mode.
+ * @param {FileGrid.ThumbnailQuality} quality Thumbnail quality.
  * @param {function(HTMLElement)=} opt_imageLoadCallback Callback called when
  *     the image has been loaded before inserting it into the DOM.
  */
 FileGrid.decorateThumbnailBox = function(
-    box, entry, metadataCache, fillMode, opt_imageLoadCallback) {
+    box, entry, metadataCache, fillMode, quality, opt_imageLoadCallback) {
   box.className = 'img-container';
   if (entry.isDirectory) {
     box.setAttribute('generic-thumbnail', 'folder');
@@ -139,15 +155,28 @@
     metadataTypes += '|media';
   }
 
+  // Drive provides high quality thumbnails via USE_EMBEDDED, however local
+  // images usually provide very tiny thumbnails, therefore USE_EMBEDDE can't
+  // be used to obtain high quality output.
+  var useEmbedded;
+  switch (quality) {
+    case FileGrid.ThumbnailQuality.LOW:
+      useEmbedded = ThumbnailLoader.UseEmbedded.USE_EMBEDDED;
+      break;
+    case FileGrid.ThumbnailQuality.HIGH:
+      useEmbedded = FileType.isOnDrive(imageUrl) ?
+          ThumbnailLoader.UseEmbedded.USE_EMBEDDED :
+          ThumbnailLoader.UseEmbedded.NO_EMBEDDED;
+      break;
+  }
+
   metadataCache.get(imageUrl, metadataTypes,
       function(metadata) {
         new ThumbnailLoader(imageUrl,
                             ThumbnailLoader.LoaderType.IMAGE,
                             metadata,
                             undefined,  // opt_mediaType
-                            FileType.isOnDrive(imageUrl) ?
-                                ThumbnailLoader.UseEmbedded.USE_EMBEDDED :
-                                ThumbnailLoader.UseEmbedded.NO_EMBEDDED).
+                            useEmbedded).
             load(box,
                 fillMode,
                 ThumbnailLoader.OptimizationMode.DISCARD_DETACHED,
diff --git a/chrome/browser/resources/file_manager/js/file_manager.js b/chrome/browser/resources/file_manager/js/file_manager.js
index 07ce252..4a722bf 100644
--- a/chrome/browser/resources/file_manager/js/file_manager.js
+++ b/chrome/browser/resources/file_manager/js/file_manager.js
@@ -293,7 +293,6 @@
   FileManager.MetadataFileWatcher.prototype.onFileInWatchedDirectoryChanged =
       function() {
     FileWatcher.prototype.onFileInWatchedDirectoryChanged.apply(this);
-    this.metadataCache_.resumeRefresh(this.getWatchedDirectoryEntry().toURL());
   };
 
   FileManager.prototype.initPreferences_ = function(callback) {
@@ -663,9 +662,6 @@
     CommandUtil.registerCommand(doc, 'drive-clear-local-cache',
         Commands.driveClearCacheCommand, this);
 
-    CommandUtil.registerCommand(doc, 'drive-reload',
-        Commands.driveReloadCommand, this);
-
     CommandUtil.registerCommand(doc, 'drive-go-to-drive',
         Commands.driveGoToDriveCommand, this);
 
@@ -682,6 +678,9 @@
         Commands.zipSelectionCommand, this, this.directoryModel_);
 
     CommandUtil.registerCommand(doc, 'share', Commands.shareCommand, this);
+    CommandUtil.registerCommand(doc, 'pin', Commands.pinCommand, this);
+    CommandUtil.registerCommand(doc, 'unpin',
+        Commands.unpinCommand, this, this.volumeList_);
 
     CommandUtil.registerCommand(doc, 'search', Commands.searchCommand, this,
         this.dialogDom_.querySelector('#search-box'));
@@ -731,7 +730,7 @@
     CommandUtil.forceDefaultHandler(node, 'paste');
     CommandUtil.forceDefaultHandler(node, 'delete');
     node.addEventListener('keydown', function(e) {
-      if (util.getKeyModifiers(event) + event.keyCode == '191') {
+      if (util.getKeyModifiers(e) + e.keyCode == '191') {
         // If this key event is propagated, this is handled search command,
         // which calls 'preventDefault' mehtod.
         e.stopPropagation();
@@ -1087,6 +1086,9 @@
     this.driveBuyMoreStorageCommand_ =
         this.dialogDom_.querySelector('#drive-buy-more-space');
 
+    this.newFolderCommand_ =
+        this.dialogDom_.querySelector('command#newfolder');
+
     this.defaultActionMenuItem_.addEventListener('activate',
         this.dispatchSelectionAction_.bind(this));
 
@@ -1147,6 +1149,8 @@
 
     this.directoryModel_.start();
 
+    this.pinnedFolderModel_ = new cr.ui.ArrayDataModel([]);
+
     this.selectionHandler_ = new FileSelectionHandler(this);
     this.selectionHandler_.addEventListener('show-preview-panel',
         this.onPreviewPanelVisibilityChanged_.bind(this, true));
@@ -1239,7 +1243,9 @@
     }.bind(this));
 
     this.volumeList_ = this.dialogDom_.querySelector('#volume-list');
-    VolumeList.decorate(this.volumeList_, this.directoryModel_);
+    VolumeList.decorate(this.volumeList_,
+                        this.directoryModel_,
+                        this.pinnedFolderModel_);
   };
 
   /**
@@ -2206,6 +2212,48 @@
   };
 
   /**
+   * Pin the selected folder.
+   */
+  FileManager.prototype.pinSelection = function() {
+    var entries = this.getSelection().entries;
+    var entry = entries[0];
+    // Duplicate entry.
+    if (this.isFolderPinned(entry.fullPath))
+      return;
+
+    this.pinnedFolderModel_.splice(0, 0, entry.fullPath);
+    this.pinnedFolderModel_.sort('name', 'asc');
+  };
+
+  /**
+   * Checkes if the folder is pinned or not.
+   * @param {string} path Path of the folder to be checked.
+   */
+  FileManager.prototype.isFolderPinned = function(path) {
+    for (var i = 0; i < this.pinnedFolderModel_.length; i++) {
+      var pinnedPath = this.pinnedFolderModel_.item(i);
+      if (pinnedPath == path) {
+        return true;
+      }
+    }
+    return false;
+  };
+
+  /**
+   * Unpins the pinned folder.
+   * @param {string} path Path of the pinned folder to be unpinnned.
+   */
+  FileManager.prototype.unpinFolder = function(path) {
+    for (var i = 0; i < this.pinnedFolderModel_.length; i++) {
+      var pinnedPath = this.pinnedFolderModel_.item(i);
+      if (pinnedPath == path) {
+        this.pinnedFolderModel_.splice(i, 1);
+        return;
+      }
+    }
+  };
+
+  /**
    * Blinks the selection. Used to give feedback when copying or cutting the
    * selection.
    */
@@ -2413,6 +2461,8 @@
       this.closeOnUnmount_ = false;
     }
 
+    this.newFolderCommand_.canExecuteChange();
+
     this.updateUnformattedDriveStatus_();
     this.updateTitle_();
     this.updateGearMenu_();
@@ -2640,6 +2690,8 @@
       this.grid_.endBatchUpdates();
     }
 
+    this.newFolderCommand_.canExecuteChange();
+
     this.table_.list.startBatchUpdates();
     this.grid_.startBatchUpdates();
     this.scanInProgress_ = true;
@@ -2672,6 +2724,8 @@
       return;
     }
 
+    this.newFolderCommand_.canExecuteChange();
+
     this.hideSpinnerLater_();
     this.refreshCurrentDirectoryMetadata_();
 
@@ -2736,6 +2790,8 @@
       return;
     }
 
+    this.newFolderCommand_.canExecuteChange();
+
     this.hideSpinnerLater_();
     if (this.scanCompletedTimer_) {
       clearTimeout(this.scanCompletedTimer_);
@@ -3837,6 +3893,5 @@
   FileManager.prototype.setCtrlKeyPressed_ = function(flag) {
     this.ctrlKeyPressed_ = flag;
     this.document_.querySelector('#drive-clear-local-cache').canExecuteChange();
-    this.document_.querySelector('#drive-reload').canExecuteChange();
   };
 })();
diff --git a/chrome/browser/resources/file_manager/js/file_manager_commands.js b/chrome/browser/resources/file_manager/js/file_manager_commands.js
index 5e1e0b7..8e12f9c 100644
--- a/chrome/browser/resources/file_manager/js/file_manager_commands.js
+++ b/chrome/browser/resources/file_manager/js/file_manager_commands.js
@@ -12,7 +12,7 @@
  * @param {Event} event Command event for which to retrieve root to operate on.
  * @param {DirectoryTree|VolumeList} list Directory tree or volume list to
  *     extract root node.
- * @return {DirectoryEntry} Found root.
+ * @return {string} Path of the found root.
  */
 CommandUtil.getCommandRoot = function(event, list) {
   if (list instanceof VolumeList) {
@@ -24,7 +24,7 @@
     var entry = list.selectedItem;
 
     if (entry && PathUtil.isRootPath(entry.fullPath))
-      return entry;
+      return entry.fullPath;
     else
       return null;
   }
@@ -37,7 +37,7 @@
  */
 CommandUtil.getCommandRootType = function(event, directoryTree) {
   var root = CommandUtil.getCommandRoot(event, directoryTree);
-  return root && PathUtil.getRootType(root.fullPath);
+  return root && PathUtil.getRootType(root);
 };
 
 /**
@@ -164,7 +164,7 @@
   execute: function(event, directoryTree, fileManager) {
     var root = CommandUtil.getCommandRoot(event, directoryTree);
     if (root)
-      fileManager.unmountVolume(PathUtil.getRootPath(root.fullPath));
+      fileManager.unmountVolume(PathUtil.getRootPath(root));
   },
   /**
    * @param {Event} event Command event.
@@ -193,7 +193,7 @@
     var root = CommandUtil.getCommandRoot(event, directoryTree);
 
     if (root) {
-      var url = util.makeFilesystemUrl(PathUtil.getRootPath(root.fullPath));
+      var url = util.makeFilesystemUrl(PathUtil.getRootPath(root));
       fileManager.confirm.show(
           loadTimeData.getString('FORMATTING_WARNING'),
           chrome.fileBrowserPrivate.formatDevice.bind(null, url));
@@ -206,8 +206,8 @@
   canExecute: function(event, directoryTree, fileManager, directoryModel) {
     var root = CommandUtil.getCommandRoot(event, directoryTree);
     var removable = root &&
-                    PathUtil.getRootType(root.fullPath) == RootType.REMOVABLE;
-    var isReadOnly = root && directoryModel.isPathReadOnly(root.fullPath);
+                    PathUtil.getRootType(root) == RootType.REMOVABLE;
+    var isReadOnly = root && directoryModel.isPathReadOnly(root);
     event.canExecute = removable && !isReadOnly;
     event.command.setHidden(!removable);
   }
@@ -357,16 +357,6 @@
 };
 
 /**
- * Reload the metadata of the file system from the server
- */
-Commands.driveReloadCommand = {
-  execute: function() {
-    chrome.fileBrowserPrivate.reloadDrive();
-  },
-  canExecute: CommandUtil.canExecuteVisibleOnDriveWithCtrlKeyOnly
-};
-
-/**
  * Opens drive.google.com.
  */
 Commands.driveGoToDriveCommand = {
@@ -553,6 +543,60 @@
 };
 
 /**
+ * Pins the selected folder (single only).
+ */
+Commands.pinCommand = {
+  /**
+   * @param {Event} event Command event.
+   * @param {FileManager} fileManager The file manager instance.
+   */
+  execute: function(event, fileManager) {
+    fileManager.pinSelection();
+  },
+  /**
+   * @param {Event} event Command event.
+   * @param {FileManager} fileManager The file manager instance.
+   */
+  canExecute: function(event, fileManager) {
+    var selection = fileManager.getSelection();
+    var selectionEntries = selection.entries;
+    var onlyOneFolderSelected =
+        selection && selection.directoryCount == 1 && selection.fileCount == 0;
+    event.canExecute = onlyOneFolderSelected &&
+        !fileManager.isFolderPinned(selectionEntries[0].fullPath);
+    event.command.setHidden(!onlyOneFolderSelected);
+  }
+};
+
+/**
+ * Unpin the pinned folder.
+ */
+Commands.unpinCommand = {
+  /**
+   * @param {Event} event Command event.
+   * @param {FileManager} fileManager The file manager instance.
+   * @param {DirectoryTree} directoryTree Target directory tree.
+   */
+  execute: function(event, fileManager, directoryTree) {
+    var path = CommandUtil.getCommandRoot(event, directoryTree);
+
+    if (path)
+      fileManager.unpinFolder(path);
+  },
+  /**
+   * @param {Event} event Command event.
+   * @param {FileManager} fileManager The file manager instance.
+   * @param {DirectoryTree} directoryTree Target directory tree.
+   */
+  canExecute: function(event, fileManager, directoryTree) {
+    var path = CommandUtil.getCommandRoot(event, directoryTree);
+    var isPinned = path && !PathUtil.isRootPath(path);
+    event.canExecute = isPinned;
+    event.command.setHidden(!isPinned);
+  }
+};
+
+/**
  * Zoom in to the Files.app.
  */
 Commands.zoomInCommand = {
diff --git a/chrome/browser/resources/file_manager/js/file_selection.js b/chrome/browser/resources/file_manager/js/file_selection.js
index 5228dca..bf6ce06 100644
--- a/chrome/browser/resources/file_manager/js/file_selection.js
+++ b/chrome/browser/resources/file_manager/js/file_selection.js
@@ -650,7 +650,7 @@
                                 entry,
                                 this.fileManager_.metadataCache_,
                                 ThumbnailLoader.FillMode.FILL,
-                                ThumbnailLoader.OptimizationMode.NEVER_DISCARD,
+                                FileGrid.ThumbnailQuality.LOW,
                                 callback);
   return thumbnail;
 };
@@ -703,7 +703,7 @@
     largeImageBox, img, transform) {
   var width = img.width;
   var height = img.height;
-  var THUMBNAIL_SIZE = 45;
+  var THUMBNAIL_SIZE = 35;
   if (width < THUMBNAIL_SIZE * 2 && height < THUMBNAIL_SIZE * 2)
     return false;
 
diff --git a/chrome/browser/resources/file_manager/js/file_table.js b/chrome/browser/resources/file_manager/js/file_table.js
index 57f870e..cb4923b 100644
--- a/chrome/browser/resources/file_manager/js/file_table.js
+++ b/chrome/browser/resources/file_manager/js/file_table.js
@@ -217,7 +217,7 @@
   cr.ui.Table.decorate(self);
   self.__proto__ = FileTable.prototype;
   self.metadataCache_ = metadataCache;
-  self.collator_ = v8Intl.Collator([], {numeric: true, sensitivity: 'base'});
+  self.collator_ = Intl.Collator([], {numeric: true, sensitivity: 'base'});
 
   var columns = [
     new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'),
@@ -353,11 +353,11 @@
  * @param {boolean} use12hourClock True if 12 hours clock, False if 24 hours.
  */
 FileTable.prototype.setDateTimeFormat = function(use12hourClock) {
-  this.timeFormatter_ = v8Intl.DateTimeFormat(
+  this.timeFormatter_ = Intl.DateTimeFormat(
         [] /* default locale */,
         {hour: 'numeric', minute: 'numeric',
          hour12: use12hourClock});
-  this.dateFormatter_ = v8Intl.DateTimeFormat(
+  this.dateFormatter_ = Intl.DateTimeFormat(
         [] /* default locale */,
         {year: 'numeric', month: 'short', day: 'numeric',
          hour: 'numeric', minute: 'numeric',
diff --git a/chrome/browser/resources/file_manager/js/image_editor/image_util.js b/chrome/browser/resources/file_manager/js/image_editor/image_util.js
index 7ae773a..91543f0 100644
--- a/chrome/browser/resources/file_manager/js/image_editor/image_util.js
+++ b/chrome/browser/resources/file_manager/js/image_editor/image_util.js
@@ -494,11 +494,8 @@
                            opt_metadata.modificationTime &&
                            opt_metadata.modificationTime.getTime();
 
-    this.taskId_ = util.loadImage(this.image_, url, {
-      cache: true,
-      timestamp: modificationTime,
-      priority: 1
-    });
+    // Load the image directly.
+    this.image_.src = url;
   }.bind(this);
 
   // Loads the image. If already loaded, then forces a reload.
@@ -584,8 +581,6 @@
     this.image_.onerror = function() {};
     this.image_.src = '';
   }
-  if (this.taskId_)
-    util.cancelLoadImage(this.taskId_);
   this.generation_++;  // Silence the transform fetcher if it is in progress.
 };
 
diff --git a/chrome/browser/resources/file_manager/js/media/media_util.js b/chrome/browser/resources/file_manager/js/media/media_util.js
index af77c9c..75b344a 100644
--- a/chrome/browser/resources/file_manager/js/media/media_util.js
+++ b/chrome/browser/resources/file_manager/js/media/media_util.js
@@ -74,7 +74,8 @@
 ThumbnailLoader.FillMode = {
   FILL: 0,  // Fill whole box. Image may be cropped.
   FIT: 1,   // Keep aspect ratio, do not crop.
-  AUTO: 2   // Try to fill, but if incompatible aspect ratio, then fit.
+  OVER_FILL: 2,  // Fill whole box with possible stretching.
+  AUTO: 3   // Try to fill, but if incompatible aspect ratio, then fit.
 };
 
 /**
@@ -341,6 +342,7 @@
   var fill;
   switch (fillMode) {
     case ThumbnailLoader.FillMode.FILL:
+    case ThumbnailLoader.FillMode.OVER_FILL:
       fill = true;
       break;
     case ThumbnailLoader.FillMode.FIT:
@@ -368,7 +370,8 @@
         Math.max(fitScaleX, fitScaleY) :
         Math.min(fitScaleX, fitScaleY);
 
-    scale = Math.min(scale, 1);  // Never overscale.
+    if (fillMode != ThumbnailLoader.FillMode.OVER_FILL)
+        scale = Math.min(scale, 1);  // Never overscale.
 
     fractionX = imageWidth * scale / boxWidth;
     fractionY = imageHeight * scale / boxHeight;
diff --git a/chrome/browser/resources/file_manager/js/metadata/metadata_cache.js b/chrome/browser/resources/file_manager/js/metadata/metadata_cache.js
index fb66651..e64fba3 100644
--- a/chrome/browser/resources/file_manager/js/metadata/metadata_cache.js
+++ b/chrome/browser/resources/file_manager/js/metadata/metadata_cache.js
@@ -83,10 +83,6 @@
    * @private
    */
   this.lastBatchStart_ = new Date();
-
-  // Holds the directories known to contain files with stale metadata
-  // as URL to bool map.
-  this.directoriesWithStaleMetadata_ = {};
 }
 
 /**
@@ -581,27 +577,6 @@
 };
 
 /**
- * Ask the Drive service to re-fetch the metadata. Ignores sequential requests.
- * @param {string} url Directory URL.
- */
-MetadataCache.prototype.refreshDirectory = function(url) {
-  // Skip if the current directory is now being refreshed.
-  if (this.directoriesWithStaleMetadata_[url] || !FileType.isOnDrive(url))
-    return;
-
-  this.directoriesWithStaleMetadata_[url] = true;
-  chrome.fileBrowserPrivate.requestDirectoryRefresh(url);
-};
-
-/**
- * Resumes refreshes by resreshDirectory.
- * @param {string} url Directory URL.
- */
-MetadataCache.prototype.resumeRefresh = function(url) {
-  delete this.directoriesWithStaleMetadata_[url];
-};
-
-/**
  * Base class for metadata providers.
  * @constructor
  */
diff --git a/chrome/browser/resources/file_manager/js/path_util.js b/chrome/browser/resources/file_manager/js/path_util.js
index e7f040a..db97d8f 100644
--- a/chrome/browser/resources/file_manager/js/path_util.js
+++ b/chrome/browser/resources/file_manager/js/path_util.js
@@ -259,3 +259,28 @@
 
   return path;
 };
+
+/**
+ * Return the label of the folder to be shown. Eg.
+ *  - '/foo/bar/baz' -> 'baz'
+ *  - '/hoge/fuga/ -> 'fuga'
+ * If the directory is root, returns the root label, which is same as
+ * PathUtil.getRootLabel().
+ *
+ * @param {string} directoryPath The full path of the folder.
+ * @return {string} The label to be shown.
+ */
+PathUtil.getFolderLabel = function(directoryPath) {
+  var label = '';
+  if (PathUtil.isRootPath(directoryPath))
+    label = PathUtil.getRootLabel(directoryPath);
+
+  if (label && label != directoryPath)
+    return label;
+
+  var matches = directoryPath.match(/([^\/]*)[\/]?$/);
+  if (matches[1])
+    return matches[1];
+
+  return directoryPath;
+};
diff --git a/chrome/browser/resources/file_manager/js/photo/mosaic_mode.js b/chrome/browser/resources/file_manager/js/photo/mosaic_mode.js
index 3e6d419..4b29b38 100644
--- a/chrome/browser/resources/file_manager/js/photo/mosaic_mode.js
+++ b/chrome/browser/resources/file_manager/js/photo/mosaic_mode.js
@@ -404,7 +404,9 @@
  * @private
  */
 Mosaic.prototype.onScroll_ = function() {
-  this.loadVisibleTiles_();
+  requestAnimationFrame(function() {
+    this.loadVisibleTiles_();
+  }.bind(this));
 };
 
 /**
@@ -485,7 +487,9 @@
 
   this.layoutModel_.invalidateFromTile_(index);
   this.tiles_[index].init(event.metadata, function() {
+        this.tiles_[index].unload();
         this.tiles_[index].load(
+            Mosaic.Tile.LoadMode.HIGH_DPI,
             this.scheduleLayout.bind(this, Mosaic.LAYOUT_DELAY));
       }.bind(this));
 };
@@ -529,8 +533,8 @@
     // Make the selection visible.
     // If the mosaic is not animated it will start fading in now.
     this.setAttribute('visible', 'normal');
+    this.loadVisibleTiles_();
   }.bind(this), duration);
-
 };
 
 /**
@@ -541,6 +545,15 @@
 };
 
 /**
+ * Checks if the mosaic view is visible.
+ * @return {boolean} True if visible, false otherwise.
+ * @private
+ */
+Mosaic.prototype.isVisible_ = function() {
+  return this.hasAttribute('visible');
+};
+
+/**
  * Loads visible tiles. Ignores consecutive calls. Does not reload already
  * loaded images.
  * @private
@@ -576,20 +589,22 @@
     var tile = this.tiles_[index];
     var imageRect = tile.getImageRect();
     // Unload a thumbnail.
-    if (imageRect && !imageRect.intersects(renderableRect)) {
+    if (imageRect && !imageRect.intersects(renderableRect))
       tile.unload();
-    }
   }
 
   // Load the visible tiles first.
   var allVisibleLoaded = true;
+  // Show high-dpi only when the mosaic view is visible.
+  var loadMode = this.isVisible_() ? Mosaic.Tile.LoadMode.HIGH_DPI :
+      Mosaic.Tile.LoadMode.LOW_DPI;
   for (var index = 0; index < this.tiles_.length; index++) {
     var tile = this.tiles_[index];
     var imageRect = tile.getImageRect();
     // Load a thumbnail.
-    if (!tile.isLoading() && !tile.isLoaded() && imageRect &&
+    if (!tile.isLoading(loadMode) && !tile.isLoaded(loadMode) && imageRect &&
         imageRect.intersects(visibleRect)) {
-      tile.load(function() {});
+      tile.load(loadMode, function() {});
       allVisibleLoaded = false;
     }
   }
@@ -602,7 +617,7 @@
       // Load a thumbnail.
       if (!tile.isLoading() && !tile.isLoaded() && imageRect &&
           imageRect.intersects(renderableRect)) {
-        tile.load(function() {});
+        tile.load(Mosaic.Tile.LoadMode.LOW_DPI, function() {});
       }
     }
   }
@@ -1626,6 +1641,15 @@
 };
 
 /**
+ * Load mode for the tile's image.
+ * @enum {number}
+ */
+Mosaic.Tile.LoadMode = {
+  LOW_DPI: 0,
+  HIGH_DPI: 1
+};
+
+/**
 * Inherit from HTMLDivElement.
 */
 Mosaic.Tile.prototype.__proto__ = HTMLDivElement.prototype;
@@ -1676,17 +1700,47 @@
 };
 
 /**
- * @return {boolean} True if the tile is loaded.
+ * Checks whether the image of specified (or better resolution) has been loaded.
+ *
+ * @param {Mosaic.Tile.LoadMode=} opt_loadMode Loading mode, default: LOW_DPI.
+ * @return {boolean} True if the tile is loaded with the specified dpi or
+ *     better.
  */
-Mosaic.Tile.prototype.isLoaded = function() {
-  return this.imageLoaded_;
+Mosaic.Tile.prototype.isLoaded = function(opt_loadMode) {
+  var loadMode = opt_loadMode || Mosaic.Tile.LoadMode.LOW_DPI;
+  switch (loadMode) {
+    case Mosaic.Tile.LoadMode.LOW_DPI:
+      if (this.imagePreloaded_ || this.imageLoaded_)
+        return true;
+      break;
+    case Mosaic.Tile.LoadMode.HIGH_DPI:
+      if (this.imageLoaded_)
+        return true;
+      break;
+  }
+  return false;
 };
 
 /**
- * @return {boolean} True if the tile is being loaded.
+ * Checks whether the image of specified (or better resolution) is being loaded.
+ *
+ * @param {Mosaic.Tile.LoadMode=} opt_loadMode Loading mode, default: LOW_DPI.
+ * @return {boolean} True if the tile is being loaded with the specified dpi or
+ *     better.
  */
-Mosaic.Tile.prototype.isLoading = function() {
-  return this.imageLoading_;
+Mosaic.Tile.prototype.isLoading = function(opt_loadMode) {
+  var loadMode = opt_loadMode || Mosaic.Tile.LoadMode.LOW_DPI;
+  switch (loadMode) {
+    case Mosaic.Tile.LoadMode.LOW_DPI:
+      if (this.imagePreloading_ || this.imageLoading_)
+        return true;
+      break;
+    case Mosaic.Tile.LoadMode.HIGH_DPI:
+      if (this.imageLoading_)
+        return true;
+      break;
+  }
+  return false;
 };
 
 /**
@@ -1696,6 +1750,8 @@
   this.maxContentHeight_ = 0;
   if (this.thumbnailLoader_) {
     this.thumbnailLoader_.cancel();
+    this.imagePreloaded_ = false;
+    this.imagePreloading_ = false;
     this.imageLoaded_ = false;
     this.imageLoading_ = false;
   }
@@ -1713,19 +1769,32 @@
   this.left_ = null;  // Mark as not laid out.
 
   // Set higher priority for the selected elements to load them first.
-  var priority = this.getAttribute('selected') ? 1 : 2;
+  var priority = this.getAttribute('selected') ? 2 : 3;
 
   // Use embedded thumbnails on Drive, since they have higher resolution.
+  var hidpiEmbedded = FileType.isOnDrive(this.getItem().getUrl());
   this.thumbnailLoader_ = new ThumbnailLoader(
       this.getItem().getUrl(),
       ThumbnailLoader.LoaderType.CANVAS,
       metadata,
       undefined,  // Media type.
-      FileType.isOnDrive(this.getItem().getUrl()) ?
-          ThumbnailLoader.UseEmbedded.USE_EMBEDDED :
-          ThumbnailLoader.UseEmbedded.NO_EMBEDDED,
+      hidpiEmbedded ? ThumbnailLoader.UseEmbedded.USE_EMBEDDED :
+                      ThumbnailLoader.UseEmbedded.NO_EMBEDDED,
       priority);
 
+  // If no hidpi embedde thumbnail available, then use the low resolution
+  // for preloading.
+  if (!hidpiEmbedded) {
+    this.thumbnailPreloader_ = new ThumbnailLoader(
+        this.getItem().getUrl(),
+        ThumbnailLoader.LoaderType.CANVAS,
+        metadata,
+        undefined,  // Media type.
+        ThumbnailLoader.UseEmbedded.USE_EMBEDDED,
+        2);  // Preloaders have always higher priotity, so the preload images
+             // are loaded as soon as possible.
+  }
+
   var setDimensions = function(width, height) {
     if (width > height) {
       if (width > Mosaic.Tile.MAX_CONTENT_SIZE) {
@@ -1758,21 +1827,72 @@
 /**
  * Loads an image into the tile.
  *
+ * The mode argument is a hint. Use low-dpi for faster response, and high-dpi
+ * for better output, but possibly affecting performance.
+ *
+ * If the mode is high-dpi, then a the high-dpi image is loaded, but also
+ * low-dpi image is loaded for preloading (if available).
+ * For the low-dpi mode, only low-dpi image is loaded. If not available, then
+ * the high-dpi image is loaded as a fallback.
+ *
+ * @param {Mosaic.Tile.LoadMode} loadMode Loading mode.
  * @param {function(boolean)} onImageLoaded Callback when image is loaded.
  *     The argument is true for success, false for failure.
  */
-Mosaic.Tile.prototype.load = function(onImageLoaded) {
-  this.imageLoaded_ = false;
-  this.imageLoading_ = true;
-  this.thumbnailLoader_.loadDetachedImage(function(success) {
+Mosaic.Tile.prototype.load = function(loadMode, onImageLoaded) {
+  // Attaches the image to the tile and finalizes loading process for the
+  // specified loader.
+  var finalizeLoader = function(mode, success, loader) {
     if (success && this.wrapper_) {
-      this.thumbnailLoader_.attachImage(this.wrapper_,
-                                        ThumbnailLoader.FillMode.FILL);
+      // Show the fade-in animation only when previously there was no image
+      // attached in this tile.
+      if (!this.imageLoaded_ && !this.imagePreloaded_)
+        this.wrapper_.classList.add('animated');
+      else
+        this.wrapper_.classList.remove('animated');
+      loader.attachImage(this.wrapper_, ThumbnailLoader.FillMode.OVER_FILL);
     }
     onImageLoaded(success);
-    this.imageLoaded_ = true;
-    this.imageLoading_ = false;
-  }.bind(this));
+    switch (mode) {
+      case Mosaic.Tile.LoadMode.LOW_DPI:
+        this.imagePreloading_ = false;
+        this.imagePreloaded_ = true;
+        break;
+      case Mosaic.Tile.LoadMode.HIGH_DPI:
+        this.imageLoading_ = false;
+        this.imageLoaded_ = true;
+        break;
+    }
+  }.bind(this);
+
+  // Always load the low-dpi image first if it is available for the fastest
+  // feedback.
+  if (!this.imagePreloading_ && this.thumbnailPreloader_) {
+    this.imagePreloading_ = true;
+    this.thumbnailPreloader_.loadDetachedImage(function(success) {
+      // Hi-dpi loaded first, ignore this call then.
+      if (this.imageLoaded_)
+        return;
+      finalizeLoader(Mosaic.Tile.LoadMode.LOW_DPI,
+                     success,
+                     this.thumbnailPreloader_);
+    }.bind(this));
+  }
+
+  // Load the high-dpi image only when it is requested, or the low-dpi is not
+  // available.
+  if (!this.imageLoading_ &&
+      (loadMode == Mosaic.Tile.LoadMode.HIGH_DPI || !this.imagePreloading_)) {
+    this.imageLoading_ = true;
+    this.thumbnailLoader_.loadDetachedImage(function(success) {
+      // Cancel preloading, since the hi-dpi image is ready.
+      if (this.thumbnailPreloader_)
+        this.thumbnailPreloader_.cancel();
+      finalizeLoader(Mosaic.Tile.LoadMode.HIGH_DPI,
+                     success,
+                     this.thumbnailLoader_);
+    }.bind(this));
+  }
 };
 
 /**
@@ -1780,7 +1900,11 @@
  */
 Mosaic.Tile.prototype.unload = function() {
   this.thumbnailLoader_.cancel();
+  if (this.thumbnailPreloader_)
+    this.thumbnailPreloader_.cancel();
+  this.imagePreloaded_ = false;
   this.imageLoaded_ = false;
+  this.imagePreloading_ = false;
   this.imageLoading_ = false;
   this.wrapper_.innerText = '';
 };
diff --git a/chrome/browser/resources/file_manager/js/photo/photo_import.js b/chrome/browser/resources/file_manager/js/photo/photo_import.js
index 37f1f07..48a2c1c 100644
--- a/chrome/browser/resources/file_manager/js/photo/photo_import.js
+++ b/chrome/browser/resources/file_manager/js/photo/photo_import.js
@@ -165,7 +165,7 @@
   var onError = this.onError_.bind(
       this, loadTimeData.getString('PHOTO_IMPORT_DESTINATION_ERROR'));
 
-  var dateFormatter = v8Intl.DateTimeFormat(
+  var dateFormatter = Intl.DateTimeFormat(
       [] /* default locale */,
       {year: 'numeric', month: 'short', day: 'numeric'});
 
@@ -247,7 +247,7 @@
  * @private
  */
 PhotoImport.prototype.createGroups_ = function(files, filesystem) {
-  var dateFormatter = v8Intl.DateTimeFormat(
+  var dateFormatter = Intl.DateTimeFormat(
       [] /* default locale */,
       {year: 'numeric', month: 'short', day: 'numeric'});
 
diff --git a/chrome/browser/resources/file_manager/js/volume_list.js b/chrome/browser/resources/file_manager/js/volume_list.js
index 6654e0a..bb77526 100644
--- a/chrome/browser/resources/file_manager/js/volume_list.js
+++ b/chrome/browser/resources/file_manager/js/volume_list.js
@@ -5,6 +5,148 @@
 'use strict';
 
 /**
+ * A volume list model. This model combines the 2 lists.
+ * @param {cr.ui.ArrayDataModel} volumesList The first list of the model.
+ * @param {cr.ui.ArrayDataModel} pinnedList The second list of the model.
+ */
+function VolumeListModel(volumesList, pinnedList) {
+  this.volumesList_ = volumesList;
+  this.pinnedList_ = pinnedList;
+
+  // Generates a combined 'permuted' event from an event of either list.
+  var permutedHandler = function(listNum, e) {
+    var permutedEvent = new Event('permuted');
+    var newPermutation = [];
+    var newLength;
+    if (listNum == 1) {
+      newLength = e.newLength + this.pinnedList_.length;
+      for (var i = 0; i < e.permutation.length; i++) {
+        newPermutation[i] = e.permutation[i];
+      }
+      for (var i = 0; i < this.pinnedList_.length; i++) {
+        newPermutation[i + e.permutation.length] = i + e.newLength;
+      }
+    } else {
+      var volumesLen = this.volumesList_.length;
+      newLength = e.newLength + volumesLen;
+      for (var i = 0; i < volumesLen; i++) {
+        newPermutation[i] = i;
+      }
+      for (var i = 0; i < e.permutation.length; i++) {
+        newPermutation[i + volumesLen] =
+            (e.permutation[i] !== -1) ? (e.permutation[i] + volumesLen) : -1;
+      }
+    }
+
+    permutedEvent.newLength = newLength;
+    permutedEvent.permutation = newPermutation;
+    this.dispatchEvent(permutedEvent);
+  };
+  this.volumesList_.addEventListener('permuted', permutedHandler.bind(this, 1));
+  this.pinnedList_.addEventListener('permuted', permutedHandler.bind(this, 2));
+
+  // Generates a combined 'change' event from an event of either list.
+  var changeHandler = function(listNum, e) {
+    var changeEvent = new Event('change');
+    changeEvent.index =
+        (listNum == 1) ? e.index : (e.index + this.volumesList_.length);
+    this.dispatchEvent(changeEvent);
+  };
+  this.volumesList_.addEventListener('change', changeHandler.bind(this, 1));
+  this.pinnedList_.addEventListener('change', changeHandler.bind(this, 2));
+
+  // Generates a combined 'splice' event from an event of either list.
+  var spliceHandler = function(listNum, e) {
+    var spliceEvent = new Event('splice');
+    spliceEvent.index =
+        (listNum == 1) ? e.index : (e.index + this.volumesList_.length);
+
+    // spliceEvent.removed, spliceEvent.add are not supported yet.
+    spliceEvent.removed = null;
+    spliceEvent.add = null;
+
+    this.dispatchEvent(spliceEvent);
+  };
+  this.volumesList_.addEventListener('splice', spliceHandler.bind(this, 1));
+  this.pinnedList_.addEventListener('splice', spliceHandler.bind(this, 2));
+
+  // Generates a combined 'sorted' event from an event of either list.
+  var sortedHandler = function(listNum, e) {
+    var sortedEvent = new Event('sorted');
+    this.dispatchEvent(sortedEvent);
+  }
+  this.volumesList_.addEventListener('sorted', sortedHandler.bind(this, 1));
+  this.pinnedList_.addEventListener('sorted', sortedHandler.bind(this, 2));
+}
+
+/**
+ * VolumeList inherits cr.EventTarget.
+ */
+VolumeListModel.prototype = {
+  __proto__: cr.EventTarget.prototype,
+  get length() { return this.length_(); }
+};
+
+/**
+ * Returns the item at the given index.
+ * @param {number} index The index of the entry to get.
+ * @return {?string} The path at the given index.
+ */
+VolumeListModel.prototype.item = function(index) {
+  var offset = this.volumesList_.length;
+  if (index < offset) {
+    var entry = this.volumesList_.item(index);
+    return entry ? entry.fullPath : undefined;
+  } else {
+    return this.pinnedList_.item(index - offset);
+  }
+};
+
+/**
+ * Type of the item on the volume list.
+ * @enum {number}
+ */
+VolumeListModel.ItemType = {
+  ROOT: 1,
+  PINNED: 2
+};
+
+/**
+ * Returns the type of the item at the given index.
+ * @param {number} index The index of the entry to get.
+ * @return {VolumeListModel.ItemType} The type of the item.
+ */
+VolumeListModel.prototype.getItemType = function(index) {
+  var offset = this.volumesList_.length;
+  return index < offset ?
+      VolumeListModel.ItemType.ROOT : VolumeListModel.ItemType.PINNED;
+};
+
+/**
+ * Returns the number of items in the model.
+ * @return {number} The length of the model.
+ * @private
+ */
+VolumeListModel.prototype.length_ = function() {
+  return this.volumesList_.length + this.pinnedList_.length;
+};
+
+/**
+ * Returns the first matching item.
+ * @param {Entry} item The entry to find.
+ * @param {number=} opt_fromIndex If provided, then the searching start at
+ *     the {@code opt_fromIndex}.
+ * @return {number} The index of the first found element or -1 if not found.
+ */
+VolumeListModel.prototype.indexOf = function(item, opt_fromIndex) {
+  for (var i = opt_fromIndex || 0; i < this.length; i++) {
+    if (item === this.item(i))
+      return i;
+  }
+  return -1;
+};
+
+/**
  * A volume list.
  */
 function VolumeList() {
@@ -18,16 +160,20 @@
 /**
  * @param {HTMLElement} el Element to be DirectoryItem.
  * @param {DirectoryModel} directoryModel Current DirectoryModel.
+ * @param {cr.ui.ArrayDataModel} pinnedFolderModel Current model of the pinned
+ *     folders.
  */
-VolumeList.decorate = function(el, directoryModel) {
+VolumeList.decorate = function(el, directoryModel, pinnedFolderModel) {
   el.__proto__ = VolumeList.prototype;
-  el.decorate(directoryModel);
+  el.decorate(directoryModel, pinnedFolderModel);
 };
 
 /**
  * @param {DirectoryModel} directoryModel Current DirectoryModel.
+ * @param {cr.ui.ArrayDataModel} pinnedFolderModel Current model of the pinned
+ *     folders.
  */
-VolumeList.prototype.decorate = function(directoryModel) {
+VolumeList.prototype.decorate = function(directoryModel, pinnedFolderModel) {
   cr.ui.List.decorate(this);
   this.__proto__ = VolumeList.prototype;
 
@@ -43,29 +189,34 @@
       'beforeChange', this.onBeforeSelectionChange_.bind(this));
   this.currentVolume_ = null;
 
+
+  this.scrollBar_ = new ScrollBar();
+  this.scrollBar_.initialize(this.parentNode, this);
+
   // Overriding default role 'list' set by cr.ui.List.decorate() to 'listbox'
   // role for better accessibility on ChromeOS.
   this.setAttribute('role', 'listbox');
 
   var self = this;
-  this.itemConstructor = function(entry) {
-    return self.renderRoot_(entry);
+  this.itemConstructor = function(path) {
+    return self.renderRoot_(path);
   };
 
-  //this.rootsList_.selectionModel =
-  //    this.directoryModel_.getRootsListSelectionModel();
-  this.dataModel = this.directoryModel_.getRootsList();
+  this.pinnedItemList_ = pinnedFolderModel;
+
+  this.dataModel =
+      new VolumeListModel(this.directoryModel_.getRootsList(),
+                          this.pinnedItemList_);
 };
 
 /**
  * Creates an element of a volume. This method is called from cr.ui.List
  * internally.
- * @param {DirectoryEntry} entry Entry of the directory to be rendered.
+ * @param {string} path Path of the directory to be rendered.
  * @return {HTMLElement} Rendered element.
  * @private
  */
-VolumeList.prototype.renderRoot_ = function(entry) {
-  var path = entry.fullPath;
+VolumeList.prototype.renderRoot_ = function(path) {
   var li = cr.doc.createElement('li');
   li.className = 'root-item';
   li.setAttribute('role', 'option');
@@ -78,6 +229,7 @@
   li.addEventListener('click', handleClick);
   li.addEventListener(cr.ui.TouchHandler.EventType.TOUCH_START, handleClick);
 
+  var isRoot = PathUtil.isRootPath(path);
   var rootType = PathUtil.getRootType(path);
 
   var iconDiv = cr.doc.createElement('div');
@@ -92,7 +244,7 @@
   var div = cr.doc.createElement('div');
   div.className = 'root-label';
 
-  div.textContent = PathUtil.getRootLabel(path);
+  div.textContent = PathUtil.getFolderLabel(path);
   li.appendChild(div);
 
   if (rootType === RootType.ARCHIVE || rootType === RootType.REMOVABLE) {
@@ -112,8 +264,8 @@
     li.appendChild(eject);
   }
 
-  if (this.contextMenu_ &&
-      rootType != RootType.DRIVE && rootType != RootType.DOWNLOADS)
+  if (this.contextMenu_ && (!isRoot ||
+      rootType != RootType.DRIVE && rootType != RootType.DOWNLOADS))
     cr.ui.contextMenuHandler.setContextMenu(li, this.contextMenu_);
 
   cr.defineProperty(li, 'lead', cr.PropertyKind.BOOL_ATTR);
@@ -122,7 +274,7 @@
   // If the current directory is already set.
   if (this.currentVolume_ == path) {
     setTimeout(function() {
-      this.selectedItem = entry;
+      this.selectedItem = path;
     }.bind(this), 0);
   }
 
@@ -139,10 +291,12 @@
   this.contextMenu_ = menu;
 
   for (var i = 0; i < this.dataModel.length; i++) {
-    var item = this.rootsList_.item(i);
-    var type = PathUtil.getRootType(item.fullPath);
+    var path = this.dataModel.item(i);
+    var itemType = this.dataModel.getItemType(i);
+    var type = PathUtil.getRootType(path);
     // Context menu is set only to archive and removable volumes.
-    if (type == RootType.ARCHIVE || type == RootType.REMOVABLE) {
+    if (itemType == VolumeListModel.ItemType.PINNED ||
+        type == RootType.ARCHIVE || type == RootType.REMOVABLE) {
       cr.ui.contextMenuHandler.setContextMenu(this.getListItemByIndex(i),
                                               this.contextMenu_);
     }
@@ -158,11 +312,11 @@
   if (index < 0 || index > this.dataModel.length - 1)
     return false;
 
-  var newRootDir = this.dataModel.item(index);
-  if (!newRootDir || this.currentVolume_ == newRootDir.fullPath)
+  var newPath = this.dataModel.item(index);
+  if (!newPath || this.currentVolume_ == newPath)
     return false;
 
-  this.currentVolume_ = newRootDir.fullPath;
+  this.currentVolume_ = newPath;
   this.directoryModel_.changeDirectory(this.currentVolume_);
   return true;
 };
@@ -183,6 +337,11 @@
  * @private
  */
 VolumeList.prototype.onSelectionChange_ = function(event) {
+  // This handler is invoked even when the volume list itself changes the
+  // selection. In such case, we shouldn't handle the event.
+  if (this.dontHandleSelectionEvent_)
+    return;
+
   this.selectByIndex(this.selectionModel.selectedIndex);
 };
 
@@ -192,17 +351,44 @@
  * @private
  */
 VolumeList.prototype.onCurrentDirectoryChanged_ = function(event) {
-  var path = event.newDirEntry.fullPath || dm.getCurrentDirPath();
+  var path = event.newDirEntry.fullPath || this.dataModel.getCurrentDirPath();
   var newRootPath = PathUtil.getRootPath(path);
 
   // Sets |this.currentVolume_| in advance to prevent |onSelectionChange_()|
   // from calling |DirectoryModel.ChangeDirectory()| again.
   this.currentVolume_ = newRootPath;
 
+  // Synchronizes the volume list selection with the current directory, after
+  // it is changed outside of the volume list.
+
+  // (1) Select the nearest parent directory (including the pinned directories).
+  var bestMatchIndex = -1;
+  var bestMatchSubStringLen = 0;
   for (var i = 0; i < this.dataModel.length; i++) {
-    var item = this.dataModel.item(i);
-    if (PathUtil.getRootPath(item.fullPath) == newRootPath) {
+    var itemPath = this.dataModel.item(i);
+    if (path.indexOf(itemPath) == 0) {
+      if (bestMatchSubStringLen < itemPath.length) {
+        bestMatchIndex = i;
+        bestMatchSubStringLen = itemPath.length;
+      }
+    }
+  }
+  if (bestMatchIndex != -1) {
+    // Not to invoke the handler of this instance, sets the guard.
+    this.dontHandleSelectionEvent_ = true;
+    this.selectionModel.selectedIndex = bestMatchIndex;
+    this.dontHandleSelectionEvent_ = false;
+    return;
+  }
+
+  // (2) Selects the volume of the current directory.
+  for (var i = 0; i < this.dataModel.length; i++) {
+    var itemPath = this.dataModel.item(i);
+    if (PathUtil.getRootPath(itemPath) == newRootPath) {
+      // Not to invoke the handler of this instance, sets the guard.
+      this.dontHandleSelectionEvent_ = true;
       this.selectionModel.selectedIndex = i;
+      this.dontHandleSelectionEvent_ = false;
       return;
     }
   }
diff --git a/chrome/browser/resources/file_manager/main.html b/chrome/browser/resources/file_manager/main.html
index f483621..6392051 100644
--- a/chrome/browser/resources/file_manager/main.html
+++ b/chrome/browser/resources/file_manager/main.html
@@ -14,11 +14,10 @@
 
     <meta name="google" value="notranslate">
 
-    <link rel="stylesheet" href="chrome://resources/css/menu.css"></link>
-
     <link rel="stylesheet" href="css/list.css"></link>
     <link rel="stylesheet" href="css/table.css"></link>
     <link rel="stylesheet" href="css/tree.css"></link>
+    <link rel="stylesheet" href="css/menu.css"></link>
     <link rel="stylesheet" href="css/combobutton.css"></link>
     <link rel="stylesheet" href="css/file_manager.css"></link>
     <link rel="stylesheet" href="css/file_types.css"></link>
@@ -131,6 +130,8 @@
       <command id="rename" i18n-values="label:RENAME_BUTTON_LABEL"
                shortcut="Enter-Ctrl">
       <command id="delete" shortcut="U+007F">
+      <command id="pin" i18n-values="label:PIN_FOLDER_BUTTON_LABEL">
+      <command id="unpin" i18n-values="label:UNPIN_FOLDER_BUTTON_LABEL">
       <command id="newfolder" i18n-values="label:NEW_FOLDER_BUTTON_LABEL"
                shortcut="U+0045-Ctrl">
       <command id="newwindow" i18n-values="label:NEW_WINDOW_BUTTON_LABEL">
@@ -159,7 +160,6 @@
                i18n-values="label:DRIVE_BUY_MORE_SPACE">
       <command id="drive-clear-local-cache"
                i18n-values="label:DRIVE_CLEAR_LOCAL_CACHE">
-      <command id="drive-reload" i18n-values="label:DRIVE_RELOAD">
       <command id="drive-go-to-drive"
                i18n-values="label:DRIVE_VISIT_DRIVE_GOOGLE_COM">
 
@@ -183,6 +183,7 @@
       <hr id="default-action-separator" visibleif="full-page" hidden>
       <menuitem command="#toggle-pinned" checkable></menuitem>
       <menuitem command="#share"></menuitem>
+      <menuitem command="#pin"></menuitem>
       <hr command="#share">
       <menuitem command="#cut" visibleif="full-page"></menuitem>
       <menuitem command="#copy" visibleif="full-page"></menuitem>
@@ -199,6 +200,7 @@
       <menuitem command="#import-photos"></menuitem>
       <menuitem command="#unmount"></menuitem>
       <menuitem command="#format"></menuitem>
+      <menuitem command="#unpin"></menuitem>
     </menu>
 
     <menu id="gear-menu" class="chrome-menu" showShortcuts>
@@ -212,7 +214,6 @@
                 i18n-content=DRIVE_SHOW_HOSTED_FILES_OPTION></menuitem>
       <hr command="#drive-clear-local-cache">
       <menuitem command="#drive-clear-local-cache"></menuitem>
-      <menuitem command="#drive-reload"></menuitem>
       <hr>
       <div>
         View
diff --git a/chrome/browser/resources/gesture_config.css b/chrome/browser/resources/gesture_config.css
index 4ba9d35..74f6a6f 100644
--- a/chrome/browser/resources/gesture_config.css
+++ b/chrome/browser/resources/gesture_config.css
@@ -7,69 +7,73 @@
   font-size: 12px;
 }
 
-button {
-  background-image: -webkit-linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7);
-  border: 1px solid rgba(0, 0, 0, 0.25);
-  border-radius: 2px;
-  color: #444;
-  float: right;
-  margin-top: 15px;
-  min-height: 2em;
-  min-width: 7em;
-  padding-left: 10px;
-  padding-right: 10px;
+form {
+  width: 700px;
+}
+
+h2 {
+  border-bottom: 1px solid rgb(238, 238, 238);
+  color: rgb(48, 57, 66);
 }
 
 .buttons-pane {
   width: 90%;
 }
 
-form {
-  width: 610px;
+#reset-all-button {
+  float: right;
 }
 
-h2 {
-  border-bottom: 1px solid #eee;
-  color: rgb(48, 57, 66);
-  font-size: 1.3em;
-  font-weight: normal;
+html[dir=rtl] #reset-all-button {
+  float: left;
 }
 
-input {
-  border: solid 1px rgb(170, 207, 228);
-  margin: 2px 0 8px 10px;
-  padding: 4px 2px;
+.input {
   text-align: right;
   width: 110px;
 }
 
+html[dir=rtl] .input {
+  text-align: left;
+}
+
 .row {
   display: table-row;
 }
 
-.row-input {
-  display: table-cell;
-}
-
 .row-label {
-  color: black;
   display: table-cell;
   font-size: 16px;
-  font-weight: normal;
-  padding-top: 4px;
   text-align: right;
   width: 370px;
 }
 
+html[dir=rtl] .row-label {
+  text-align: left;
+}
+
+.row-input {
+  display: table-cell;
+}
+
 .row-units {
   display: table-cell;
-  padding-left: 7px;
-  padding-top: 7px;
   text-align: left;
   width: 100px;
 }
 
+html[dir=rtl] .row-units {
+  text-align: right;
+}
+
+.row-reset {
+  display: table-cell;
+  font-size: 12px;
+  width: 100%;
+}
+
 .section-properties {
+  border-spacing: 8px;
   display: table;
 }
 
diff --git a/chrome/browser/resources/gesture_config.html b/chrome/browser/resources/gesture_config.html
index a1aec14..34a7215 100644
--- a/chrome/browser/resources/gesture_config.html
+++ b/chrome/browser/resources/gesture_config.html
@@ -3,6 +3,8 @@
 <head>
   <meta charset="utf-8">
   <title>Gesture Preferences</title>
+  <link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
+  <link rel="stylesheet" href="chrome://resources/css/widgets.css">
   <link rel="stylesheet" href="gesture_config.css">
   <script src="gesture_config.js"></script>
 </head>
@@ -10,7 +12,7 @@
 <form>
   <div id="gesture-form"></div>
   <div class="buttons-pane">
-    <button id="reset-button">Reset</button>
+    <button id="reset-all-button">Reset All</button>
   </div>
 </form>
 <div id="section-template">
@@ -25,6 +27,7 @@
     <input class="input" type="number" size="20">
   </div>
   <div class="row-units"></div>
+  <button class="row-reset">Reset</button>
 </div>
 </body>
 </html>
diff --git a/chrome/browser/resources/gesture_config.js b/chrome/browser/resources/gesture_config.js
index 9a28531..062cdca 100644
--- a/chrome/browser/resources/gesture_config.js
+++ b/chrome/browser/resources/gesture_config.js
@@ -52,6 +52,7 @@
       var label = row.querySelector('.row-label');
       var input = row.querySelector('.input');
       var units = row.querySelector('.row-units');
+      var reset = row.querySelector('.row-reset');
 
       label.setAttribute('for', field.key);
       label.innerHTML = field.label;
@@ -66,13 +67,16 @@
       if (field.units)
         units.innerHTML = field.units;
 
+      reset.id = field.key + '-reset';
+      gesture_config.updateResetButton(reset, true);
+
       section.querySelector('.section-properties').appendChild(row);
     }
     $('gesture-form').appendChild(section);
   },
 
   /**
-   * Initializes the form by adding 'onChange' listeners to all fields.
+   * Initializes the form by adding appropriate event listeners to elements.
    */
   initForm: function() {
     for (var i = 0; i < this.fields.length; i++) {
@@ -80,6 +84,10 @@
       var config = this;
       $(field.key).onchange = (function(key) {
         config.setPreferenceValue(key, $(key).value);
+        gesture_config.updateResetButton($(key + '-reset'), false);
+      }).bind(null, field.key);
+      $(field.key + '-reset').onclick = (function(key) {
+        config.resetPreferenceValue(key);
       }).bind(null, field.key);
     }
   },
@@ -89,13 +97,13 @@
    */
   loadForm: function() {
     for (var i = 0; i < this.fields.length; i++)
-      this.getPreferenceValue(this.fields[i].key);
+      this.updatePreferenceValue(this.fields[i].key);
   },
 
   /**
-   * Handles processing of "Reset" button.
+   * Handles processing of "Reset All" button.
    * Causes all form values to be updated based on current preference values.
-   * @return {bool} Returns false.
+   * @return {boolean} Returns false.
    */
   onReset: function() {
     for (var i = 0; i < this.fields.length; i++) {
@@ -108,11 +116,11 @@
   /**
    * Requests a preference setting's value.
    * This method is asynchronous; the result is provided by a call to
-   * getPreferenceValueResult.
+   * updatePreferenceValueResult.
    * @param {string} prefName The name of the preference value being requested.
    */
-  getPreferenceValue: function(prefName) {
-    chrome.send('getPreferenceValue', [this.prefix + prefName]);
+  updatePreferenceValue: function(prefName) {
+    chrome.send('updatePreferenceValue', [this.prefix + prefName]);
   },
 
   /**
@@ -127,7 +135,7 @@
 
   /**
    * Resets a preference to its default value and get that callback
-   * to getPreferenceValueResult with the new value of the preference.
+   * to updatePreferenceValueResult with the new value of the preference.
    * @param {string} prefName The name of the requested preference.
    */
   resetPreferenceValue: function(prefName) {
@@ -515,7 +523,7 @@
     var c = WorkspaceCyclerConfig();
     c.buildAll();
 
-    $('reset-button').onclick = function() {
+    $('reset-all-button').onclick = function() {
       g.onReset();
       o.onReset();
       f.onReset();
@@ -524,14 +532,31 @@
     };
   },
 
+/**
+ * Updates the status and label of a preference reset button.
+ * @param {HTMLInputElement} resetButton Reset button for the preference.
+ * @param {boolean} isDefault Whether the preference is set to the default
+ *     value.
+ */
+  updateResetButton: function(resetButton, isDefault) {
+    /** @const */ var TITLE_DEFAULT = 'Default';
+
+    /** @const */ var TITLE_NOT_DEFAULT = 'Reset';
+
+    resetButton.innerHTML = isDefault ? TITLE_DEFAULT : TITLE_NOT_DEFAULT;
+    resetButton.disabled = isDefault;
+  },
+
   /**
-   * Handle callback from call to getPreferenceValue.
+   * Handle callback from call to updatePreferenceValue.
    * @param {string} prefName The name of the requested preference value.
    * @param {value} value The current value associated with prefName.
+   * @param {boolean} isDefault Whether the value is the default value.
    */
-  getPreferenceValueResult: function(prefName, value) {
+  updatePreferenceValueResult: function(prefName, value, isDefault) {
     prefName = prefName.substring(prefName.indexOf('.') + 1);
     $(prefName).value = value;
+    this.updateResetButton($(prefName + '-reset'), isDefault);
   },
 };
 
diff --git a/chrome/browser/resources/google_now/background.js b/chrome/browser/resources/google_now/background.js
index d52d18d..e651a18 100644
--- a/chrome/browser/resources/google_now/background.js
+++ b/chrome/browser/resources/google_now/background.js
@@ -684,7 +684,12 @@
     // TODO(zturner): Get the value of isGeolocationEnabled from the settings
     // api and additionally make sure it is true.
     if (!items.toastState) {
-      showWelcomeToast();
+      if (NOTIFICATION_CARDS_URL) {
+        chrome.identity.getAuthToken({interactive: false}, function(token) {
+          if (!chrome.runtime.lastError && token)
+            showWelcomeToast();
+        });
+      }
     } else if (items.toastState == ToastOptionResponse.CHOSE_YES) {
       startPollingCards();
     }
diff --git a/chrome/browser/resources/google_now/background_test_util.js b/chrome/browser/resources/google_now/background_test_util.js
index f59c34e..b4d2bcc 100644
--- a/chrome/browser/resources/google_now/background_test_util.js
+++ b/chrome/browser/resources/google_now/background_test_util.js
@@ -22,4 +22,63 @@
   onInstalled: emptyListener,
   onStartup: emptyListener
 };
+
 var storage = {};
+
+/**
+ * Syntactic sugar for use with will() on a Mock4JS.Mock.
+ * Creates an action for will() that invokes a callback that the tested code
+ * passes to a mocked function.
+ * @param {SaveMockArguments} savedArgs Arguments that will contain the
+ *     callback once the mocked function is called.
+ * @param {number} callbackParameter Index of the callback parameter in
+ *     |savedArgs|.
+ * @param {...Object} var_args Arguments to pass to the callback.
+ * @return {CallFunctionAction} Action for use in will().
+ */
+function invokeCallback(savedArgs, callbackParameter, var_args) {
+  var callbackArguments = Array.prototype.slice.call(arguments, 2);
+  return callFunction(function() {
+    savedArgs.arguments[callbackParameter].apply(null, callbackArguments);
+  });
+}
+
+/**
+  * Mock4JS matcher object that matches the actual agrument and the expected
+  * value iff their JSON represenations are same.
+  * @param {Object} expectedValue Expected value.
+  * @constructor
+  */
+function MatchJSON(expectedValue) {
+  this.expectedValue_ = expectedValue;
+}
+
+MatchJSON.prototype = {
+  /**
+    * Checks that JSON represenation of the actual and expected arguments are
+    * same.
+    * @param {Object} actualArgument The argument to match.
+    * @return {boolean} Result of the comparison.
+    */
+  argumentMatches: function(actualArgument) {
+    return JSON.stringify(this.expectedValue_) ===
+        JSON.stringify(actualArgument);
+  },
+
+  /**
+    * Describes the matcher.
+    * @return {string} Description of this Mock4JS matcher.
+    */
+  describe: function() {
+    return 'eqJSON(' + JSON.stringify(this.expectedValue_) + ')';
+  }
+};
+
+/**
+  * Builds a MatchJSON agrument matcher for a given expected value.
+  * @param {Object} expectedValue Expected value.
+  * @return {MatchJSON} Resulting Mock4JS matcher.
+  */
+function eqJSON(expectedValue) {
+  return new MatchJSON(expectedValue);
+}
diff --git a/chrome/browser/resources/google_now/background_unittest.gtestjs b/chrome/browser/resources/google_now/background_unittest.gtestjs
index 149c51c..a0a8f00 100644
--- a/chrome/browser/resources/google_now/background_unittest.gtestjs
+++ b/chrome/browser/resources/google_now/background_unittest.gtestjs
@@ -40,3 +40,339 @@
   testTaskPair(RETRY_DISMISS_TASK_NAME, RETRY_DISMISS_TASK_NAME, true);
 });
 
+/**
+ * Mocks global functions and APIs that initialize() depends upon.
+ * @param {Test} fixture Test fixture.
+ */
+function mockInitializeDependencies(fixture) {
+  fixture.makeAndRegisterMockGlobals([
+      'recordEvent',
+      'showWelcomeToast',
+      'startPollingCards']);
+  fixture.makeAndRegisterMockApis(
+      ['storage.get', 'chrome.identity.getAuthToken']);
+}
+
+TEST_F(
+    'GoogleNowBackgroundUnitTest',
+    'Initialize_ToastStateEmpty1',
+    function() {
+      // Tests the case when toast state is empty and NOTIFICATION_CARDS_URL is
+      // not set. In this case, the function should quietly exit after finding
+      // out that NOTIFICATION_CARDS_URL is empty.
+
+      // Setup and expectations.
+      var testToastState = {};
+      NOTIFICATION_CARDS_URL = undefined;
+
+      mockInitializeDependencies(this);
+
+      this.mockGlobals.expects(once()).recordEvent(
+          DiagnosticEvent.EXTENSION_START);
+      var storageGetSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          storage_get(
+              storageGetSavedArgs.match(eq('toastState')),
+              storageGetSavedArgs.match(ANYTHING)).
+          will(invokeCallback(storageGetSavedArgs, 1, testToastState));
+
+      // Invoking the tested function.
+      initialize();
+    });
+
+TEST_F(
+    'GoogleNowBackgroundUnitTest',
+    'Initialize_ToastStateEmpty2',
+    function() {
+      // Tests the case when toast state is empty and NOTIFICATION_CARDS_URL is
+      // set, but getAuthToken fails most likely because the user is not signed
+      // in. In this case, the function should quietly exit after finding out
+      // that getAuthToken fails.
+
+      // Setup and expectations.
+      var testToastState = {};
+      NOTIFICATION_CARDS_URL = 'https://some.server.url.com';
+      var testIdentityToken = undefined;
+
+      mockInitializeDependencies(this);
+
+      this.mockGlobals.expects(once()).recordEvent(
+          DiagnosticEvent.EXTENSION_START);
+      var storageGetSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          storage_get(
+              storageGetSavedArgs.match(eq('toastState')),
+              storageGetSavedArgs.match(ANYTHING)).
+          will(invokeCallback(storageGetSavedArgs, 1, testToastState));
+      var chromeIdentityGetAuthTokenSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          chrome_identity_getAuthToken(
+              chromeIdentityGetAuthTokenSavedArgs.match(
+                  eqJSON({interactive: false})),
+              chromeIdentityGetAuthTokenSavedArgs.match(ANYTHING)).
+          will(invokeCallback(
+              chromeIdentityGetAuthTokenSavedArgs, 1, testIdentityToken));
+
+      // Invoking the tested function.
+      initialize();
+    });
+
+TEST_F(
+    'GoogleNowBackgroundUnitTest',
+    'Initialize_ToastStateEmpty3',
+    function() {
+      // Tests the case when toast state is empty and NOTIFICATION_CARDS_URL is
+      // set, and getAuthToken succeeds. In this case, the function should
+      // invoke showWelcomeToast().
+
+      // Setup and expectations.
+      var testToastState = {};
+      NOTIFICATION_CARDS_URL = 'https://some.server.url.com';
+      var testIdentityToken = 'some identity token';
+
+      mockInitializeDependencies(this);
+
+      this.mockGlobals.expects(once()).recordEvent(
+          DiagnosticEvent.EXTENSION_START);
+      var storageGetSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          storage_get(
+              storageGetSavedArgs.match(eq('toastState')),
+              storageGetSavedArgs.match(ANYTHING)).
+          will(invokeCallback(storageGetSavedArgs, 1, testToastState));
+      var chromeIdentityGetAuthTokenSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          chrome_identity_getAuthToken(
+              chromeIdentityGetAuthTokenSavedArgs.match(
+                  eqJSON({interactive: false})),
+              chromeIdentityGetAuthTokenSavedArgs.match(ANYTHING)).
+          will(invokeCallback(
+              chromeIdentityGetAuthTokenSavedArgs, 1, testIdentityToken));
+      this.mockGlobals.expects(once()).showWelcomeToast();
+
+      // Invoking the tested function.
+      initialize();
+    });
+
+TEST_F('GoogleNowBackgroundUnitTest', 'Initialize_ToastStateYes', function() {
+  // Tests the case when the user has answered "yes" to the toast in the past.
+  // In this case, the function should invoke startPollingCards().
+
+  // Setup and expectations.
+  var testToastState = {toastState: ToastOptionResponse.CHOSE_YES};
+
+  mockInitializeDependencies(this);
+
+  this.mockGlobals.expects(once()).recordEvent(DiagnosticEvent.EXTENSION_START);
+  var storageGetSavedArgs = new SaveMockArguments();
+  this.mockApis.expects(once()).
+      storage_get(
+          storageGetSavedArgs.match(eq('toastState')),
+          storageGetSavedArgs.match(ANYTHING)).
+      will(invokeCallback(storageGetSavedArgs, 1, testToastState));
+  this.mockGlobals.expects(once()).startPollingCards();
+
+  // Invoking the tested function.
+  initialize();
+});
+
+TEST_F('GoogleNowBackgroundUnitTest', 'Initialize_ToastStateNo', function() {
+  // Tests the case when the user has answered "no" to the toast in the past.
+  // In this case, the function should do nothing.
+
+  // Setup and expectations.
+  var testToastState = {toastState: ToastOptionResponse.CHOSE_NO};
+
+  mockInitializeDependencies(this);
+
+  this.mockGlobals.expects(once()).recordEvent(DiagnosticEvent.EXTENSION_START);
+  var storageGetSavedArgs = new SaveMockArguments();
+  this.mockApis.expects(once()).
+      storage_get(
+          storageGetSavedArgs.match(eq('toastState')),
+          storageGetSavedArgs.match(ANYTHING)).
+      will(invokeCallback(storageGetSavedArgs, 1, testToastState));
+
+  // Invoking the tested function.
+  initialize();
+});
+
+/**
+ * Mocks global functions and APIs that onNotificationClicked() depends upon.
+ * @param {Test} fixture Test fixture.
+ */
+function mockOnNotificationClickedDependencies(fixture) {
+  fixture.makeAndRegisterMockApis([
+      'storage.get',
+      'chrome.tabs.create',
+      'chrome.windows.create']);
+}
+
+TEST_F(
+    'GoogleNowBackgroundUnitTest',
+    'OnNotificationClicked_NoData',
+    function() {
+      // Tests the case when there is no data associated with notification id.
+      // In this case, the function should do nothing.
+
+      // Setup and expectations.
+      var testNotificationId = 'TEST_ID';
+      var testNotificationData = {};
+
+      mockOnNotificationClickedDependencies(this);
+      this.makeMockLocalFunctions(['selector']);
+
+      var storageGetSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          storage_get(
+              storageGetSavedArgs.match(eq('notificationsData')),
+              storageGetSavedArgs.match(ANYTHING)).
+          will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
+
+      // Invoking the tested function.
+      onNotificationClicked(
+          testNotificationId, this.mockLocalFunctions.functions().selector);
+    });
+
+TEST_F(
+    'GoogleNowBackgroundUnitTest',
+    'OnNotificationClicked_ActionUrlsNotObject',
+    function() {
+      // Tests the case when the data associated with notification id is not an
+      // object, probably because of a malformed server response.
+      // In this case, the function should do nothing.
+
+      // Setup and expectations.
+      var testActionUrls = 'string, not object';
+      var testNotificationId = 'TEST_ID';
+      var testNotificationData = {
+          notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
+      };
+
+      mockOnNotificationClickedDependencies(this);
+      this.makeMockLocalFunctions(['selector']);
+
+      var storageGetSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          storage_get(
+              storageGetSavedArgs.match(eq('notificationsData')),
+              storageGetSavedArgs.match(ANYTHING)).
+          will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
+
+      // Invoking the tested function.
+      onNotificationClicked(
+          testNotificationId, this.mockLocalFunctions.functions().selector);
+    });
+
+TEST_F(
+    'GoogleNowBackgroundUnitTest',
+    'OnNotificationClicked_UrlNotString',
+    function() {
+      // Tests the case when selector returns a non-string, probably because of
+      // a malformed server response.
+      // In this case, the function should do nothing.
+
+      // Setup and expectations.
+      var testActionUrls = {testField: 'TEST VALUE'};
+      var testNotificationId = 'TEST_ID';
+      var testNotificationData = {
+          notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
+      };
+      var testActionUrl = {};
+
+      mockOnNotificationClickedDependencies(this);
+      this.makeMockLocalFunctions(['selector']);
+
+      var storageGetSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          storage_get(
+              storageGetSavedArgs.match(eq('notificationsData')),
+              storageGetSavedArgs.match(ANYTHING)).
+          will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
+      this.mockLocalFunctions.expects(once()).selector(testActionUrls).will(
+          returnValue(testActionUrl));
+
+      // Invoking the tested function.
+      onNotificationClicked(
+          testNotificationId, this.mockLocalFunctions.functions().selector);
+    });
+
+TEST_F(
+    'GoogleNowBackgroundUnitTest',
+    'OnNotificationClicked_TabCreateSuccess',
+    function() {
+      // Tests the selected URL is OK and crome.tabs.create suceeds.
+
+      // Setup and expectations.
+      var testActionUrls = {testField: 'TEST VALUE'};
+      var testNotificationId = 'TEST_ID';
+      var testNotificationData = {
+          notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
+      };
+      var testActionUrl = 'http://testurl.com';
+      var testCreatedTab = {};
+
+      mockOnNotificationClickedDependencies(this);
+      this.makeMockLocalFunctions(['selector']);
+
+      var storageGetSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          storage_get(
+              storageGetSavedArgs.match(eq('notificationsData')),
+              storageGetSavedArgs.match(ANYTHING)).
+          will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
+      this.mockLocalFunctions.expects(once()).selector(testActionUrls).will(
+          returnValue(testActionUrl));
+      var chromeTabsCreateSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          chrome_tabs_create(
+              chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})),
+              chromeTabsCreateSavedArgs.match(ANYTHING)).
+          will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab));
+
+      // Invoking the tested function.
+      onNotificationClicked(
+          testNotificationId, this.mockLocalFunctions.functions().selector);
+    });
+
+TEST_F(
+    'GoogleNowBackgroundUnitTest',
+    'OnNotificationClicked_TabCreateFail',
+    function() {
+      // Tests the selected URL is OK and crome.tabs.create fails.
+      // In this case, the function should invoke chrome.windows.create as a
+      // second attempt.
+
+      // Setup and expectations.
+      var testActionUrls = {testField: 'TEST VALUE'};
+      var testNotificationId = 'TEST_ID';
+      var testNotificationData = {
+        notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
+      };
+      var testActionUrl = 'http://testurl.com';
+      var testCreatedTab = undefined; // chrome.tabs.create fails
+
+      mockOnNotificationClickedDependencies(this);
+      this.makeMockLocalFunctions(['selector']);
+
+      var storageGetSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          storage_get(
+              storageGetSavedArgs.match(eq('notificationsData')),
+              storageGetSavedArgs.match(ANYTHING)).
+          will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
+      this.mockLocalFunctions.expects(once()).selector(testActionUrls).will(
+          returnValue(testActionUrl));
+      var chromeTabsCreateSavedArgs = new SaveMockArguments();
+      this.mockApis.expects(once()).
+          chrome_tabs_create(
+              chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})),
+              chromeTabsCreateSavedArgs.match(ANYTHING)).
+          will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab));
+      this.mockApis.expects(once()).chrome_windows_create(
+          eqJSON({url: testActionUrl}));
+
+      // Invoking the tested function.
+      onNotificationClicked(
+          testNotificationId, this.mockLocalFunctions.functions().selector);
+    });
diff --git a/chrome/browser/resources/history/history.html b/chrome/browser/resources/history/history.html
index 97eaecf..df5d8ea 100644
--- a/chrome/browser/resources/history/history.html
+++ b/chrome/browser/resources/history/history.html
@@ -31,6 +31,7 @@
 <script src="chrome://resources/js/cr.js"></script>
 <script src="chrome://resources/js/cr/ui.js"></script>
 <script src="chrome://resources/js/cr/ui/command.js"></script>
+<script src="chrome://resources/js/cr/ui/focus_manager.js"></script>
 <script src="chrome://resources/js/cr/ui/menu_item.js"></script>
 <script src="chrome://resources/js/cr/ui/menu.js"></script>
 <if expr="not is_android and not pp_ifdef('ios')">
diff --git a/chrome/browser/resources/history/history.js b/chrome/browser/resources/history/history.js
index f1eac1f..d0c1995 100644
--- a/chrome/browser/resources/history/history.js
+++ b/chrome/browser/resources/history/history.js
@@ -182,7 +182,7 @@
   if (this.starred_) {
     bookmarkSection.classList.add('starred');
     bookmarkSection.addEventListener('click', function f(e) {
-      recordUmaAction('BookmarkStarClicked_HistoryPage');
+      recordUmaAction('HistoryPage_BookmarkStarClicked');
       bookmarkSection.classList.remove('starred');
       chrome.send('removeBookmark', [self.url_]);
       bookmarkSection.removeEventListener('click', f);
@@ -270,7 +270,7 @@
  * Remove this visit from the history.
  */
 Visit.prototype.removeFromHistory = function() {
-  recordUmaAction('EntryMenuRemoveFromHistory_HistoryPage');
+  recordUmaAction('HistoryPage_EntryMenuRemoveFromHistory');
   var self = this;
   this.model_.removeVisitsFromHistory([this], function() {
     removeEntryFromView(self.domNode_);
@@ -338,18 +338,18 @@
   link.target = '_top';
   var integerId = parseInt(this.id_, 10);
   link.addEventListener('click', function() {
-    recordUmaAction('EntryLinkClick_HistoryPage');
+    recordUmaAction('HistoryPage_EntryLinkClick');
     // Record the ID of the entry to signify how many entries are above this
     // link on the page.
     recordUmaHistogram('HistoryPage.ClickPosition', integerId);
   });
   link.addEventListener('contextmenu', function() {
-    recordUmaAction('EntryLinkRightClick_HistoryPage');
+    recordUmaAction('HistoryPage_EntryLinkRightClick');
   });
 
   if (isSearchResult) {
     link.addEventListener('click', function() {
-      recordUmaAction('SearchResultClick_HistoryPage');
+      recordUmaAction('HistoryPage_SearchResultClick');
     });
   }
 
@@ -394,7 +394,7 @@
  * @private
  */
 Visit.prototype.showMoreFromSite_ = function() {
-  recordUmaAction('EntryMenuShowMoreFromSite_HistoryPage');
+  recordUmaAction('HistoryPage_EntryMenuShowMoreFromSite');
   historyView.setSearch(this.getDomainFromURL_(this.url_));
 };
 
@@ -760,15 +760,15 @@
 
   // Add handlers for the page navigation buttons at the bottom.
   $('newest-button').addEventListener('click', function() {
-    recordUmaAction('NewestHistoryClick_HistoryPage');
+    recordUmaAction('HistoryPage_NewestHistoryClick');
     self.setPage(0);
   });
   $('newer-button').addEventListener('click', function() {
-    recordUmaAction('NewerHistoryClick_HistoryPage');
+    recordUmaAction('HistoryPage_NewerHistoryClick');
     self.setPage(self.pageIndex_ - 1);
   });
   $('older-button').addEventListener('click', function() {
-    recordUmaAction('OlderHistoryClick_HistoryPage');
+    recordUmaAction('HistoryPage_OlderHistoryClick');
     self.setPage(self.pageIndex_ + 1);
   });
 
@@ -1486,7 +1486,7 @@
     cr.ui.overlay.setupOverlay($('overlay'));
 
   var doSearch = function(e) {
-    recordUmaAction('Search_HistoryPage');
+    recordUmaAction('HistoryPage_Search');
     historyView.setSearch(searchField.value);
 
     if (isMobileVersion())
@@ -1528,6 +1528,8 @@
   window.addEventListener('resize',
       historyView.positionNotificationBar.bind(historyView));
 
+  cr.ui.FocusManager.disableMouseFocusOnButtons();
+
   if (isMobileVersion()) {
     if (searchField) {
       // Move the search box out of the header.
@@ -1582,7 +1584,7 @@
  * @param {Event} e The click event.
  */
 function openClearBrowsingData(e) {
-  recordUmaAction('InitClearBrowsingData_HistoryPage');
+  recordUmaAction('HistoryPage_InitClearBrowsingData');
   chrome.send('clearBrowsingData');
 }
 
@@ -1628,7 +1630,7 @@
  * Confirms the deletion with the user, and then deletes the selected visits.
  */
 function removeItems() {
-  recordUmaAction('RemoveSelected_HistoryPage');
+  recordUmaAction('HistoryPage_RemoveSelected');
   if (!loadTimeData.getBoolean('allowDeletingHistory'))
     return;
 
@@ -1653,11 +1655,11 @@
     // link on the page.
     recordUmaHistogram('HistoryPage.RemoveEntryPosition', integerId);
     if (entry.parentNode.className == 'search-results')
-      recordUmaAction('SearchResultRemove_HistoryPage');
+      recordUmaAction('HistoryPage_SearchResultRemove');
   }
 
   function onConfirmRemove() {
-    recordUmaAction('ConfirmRemoveSelected_HistoryPage');
+    recordUmaAction('HistoryPage_ConfirmRemoveSelected');
     historyModel.removeVisitsFromHistory(toBeRemoved,
         historyView.reload.bind(historyView));
     $('overlay').removeEventListener('cancelOverlay', onCancelRemove);
@@ -1665,7 +1667,7 @@
   }
 
   function onCancelRemove() {
-    recordUmaAction('CancelRemoveSelected_HistoryPage');
+    recordUmaAction('HistoryPage_CancelRemoveSelected');
     // Return everything to its previous state.
     for (var i = 0; i < disabledItems.length; i++) {
       var checkbox = disabledItems[i];
diff --git a/chrome/browser/resources/image_loader/request.js b/chrome/browser/resources/image_loader/request.js
index 46eadc5..4b84720 100644
--- a/chrome/browser/resources/image_loader/request.js
+++ b/chrome/browser/resources/image_loader/request.js
@@ -278,7 +278,10 @@
  * @private
  */
 Request.prototype.onImageLoad_ = function(callback) {
-  if (ImageLoader.shouldProcess(this.image_.width,
+  // Perform processing if the url is not a data url, or if there are some
+  // operations requested.
+  if (!this.request_.url.match(/^data/) ||
+      ImageLoader.shouldProcess(this.image_.width,
                                 this.image_.height,
                                 this.request_)) {
     ImageLoader.resize(this.image_, this.canvas_, this.request_);
diff --git a/chrome/browser/resources/image_loader/worker.js b/chrome/browser/resources/image_loader/worker.js
index c0c29e2..7dba926 100644
--- a/chrome/browser/resources/image_loader/worker.js
+++ b/chrome/browser/resources/image_loader/worker.js
@@ -90,9 +90,6 @@
   var newIndex = this.pendingRequests_.indexOf(request);
   if (newIndex != -1)
     this.newRequests_.splice(newIndex, 1);
-  var cacheCheckIndex = this.cacheCheckRequests_.indexOf(request);
-  if (cacheCheckIndex != -1)
-    this.cacheCheckRequests_.splice(cacheCheckIndex, 1);
   var pendingIndex = this.pendingRequests_.indexOf(request);
   if (pendingIndex != -1)
     this.pendingRequests_.splice(pendingIndex, 1);
@@ -109,7 +106,7 @@
   this.started_ = true;
 
   // Process tasks added before worker has been started.
-  this.pendingRequests_.concat(this.newRequests_);
+  this.pendingRequests_ = this.newRequests_;
   this.sortPendingRequests_();
   this.newRequests_ = [];
 
diff --git a/chrome/browser/resources/inspect/OWNERS b/chrome/browser/resources/inspect/OWNERS
new file mode 100644
index 0000000..2abc7be
--- /dev/null
+++ b/chrome/browser/resources/inspect/OWNERS
@@ -0,0 +1 @@
+pfeldman@chromium.org
diff --git a/chrome/browser/resources/local_ntp/instant_iframe_validation.js b/chrome/browser/resources/local_ntp/instant_iframe_validation.js
index 5e4447d..3e4c128 100644
--- a/chrome/browser/resources/local_ntp/instant_iframe_validation.js
+++ b/chrome/browser/resources/local_ntp/instant_iframe_validation.js
@@ -13,7 +13,7 @@
  * @param {number} color A 6-digit hex RGB color code as a number.
  * @return {?string} A CSS representation of the color or null if invalid.
  */
-function convertColor(color) {
+function convertToHexColor(color) {
   // Color must be a number, finite, with no fractional part, in the correct
   // range for an RGB hex color.
   if (isFinite(color) && Math.floor(color) == color &&
@@ -24,3 +24,35 @@
   }
   return null;
 }
+
+
+/**
+ * Validates a RGBA color component. It must be a number between 0 and 255.
+ * @param {number} component An RGBA component.
+ * @return {boolean} True if the component is valid.
+ */
+function isValidRBGAComponent(component) {
+  return isFinite(component) && component >= 0 && component <= 255;
+}
+
+
+/**
+ * Converts an Array of color components into RGBA format "rgba(R,G,B,A)".
+ * @param {Array.<number>} rgbaColor Array of rgba color components.
+ * @return {?string} CSS color in RGBA format or null if invalid.
+ */
+function convertArrayToRGBAColor(rgbaColor) {
+  // Array must contain 4 valid components.
+  if (rgbaColor instanceof Array && rgbaColor.length === 4 &&
+      isValidRBGAComponent(rgbaColor[0]) &&
+      isValidRBGAComponent(rgbaColor[1]) &&
+      isValidRBGAComponent(rgbaColor[2]) &&
+      isValidRBGAComponent(rgbaColor[3])) {
+    return 'rgba(' +
+            rgbaColor[0] + ',' +
+            rgbaColor[1] + ',' +
+            rgbaColor[2] + ',' +
+            rgbaColor[3] / 255 + ')';
+  }
+  return null;
+}
diff --git a/chrome/browser/resources/local_ntp/local_ntp.css b/chrome/browser/resources/local_ntp/local_ntp.css
index bd4f319..7986847 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.css
+++ b/chrome/browser/resources/local_ntp/local_ntp.css
@@ -16,7 +16,9 @@
 }
 
 .non-google-page #ntp-contents {
+  position: absolute;
   top: -webkit-calc(50% - 155px);
+  width: 100%;
 }
 
 body.hide-fakebox-logo #logo,
@@ -43,7 +45,7 @@
   width: 275px;
 }
 
-body.custom-theme #logo {
+body.alternate-logo #logo {
   background-image: url(images/2x/white_google_logo.png);
 }
 
@@ -117,17 +119,6 @@
   text-align: -webkit-center;
 }
 
-.custom-theme .mv-title,
-.custom-theme #mv-msg {
-  color: #fff;
-  text-shadow: black 0 1px 3px;
-}
-
-.custom-theme #mv-notice-links span {
-  color: #fff;
-  text-shadow: rgb(17, 85, 204) 0 1px 3px;
-}
-
 #mv-tiles {
   /* Use GPU compositing if available. */
   -webkit-transform: translate3d(0, 0, 0);
@@ -244,19 +235,12 @@
   width: 16px;
 }
 
-body.custom-theme #mv-notice-x {
-  background: transparent url(images/close_2_white.png);
-}
-
 .mv-x:hover,
-body.custom-theme #mv-notice-x:hover,
-#mv-notice-x:focus,
-body.custom-theme #mv-notice-x:focus {
+#mv-notice-x:focus {
   background: transparent url(images/close_2_hover.png);
 }
 
-.mv-x:active,
-body.custom-theme #mv-notice-x:active {
+.mv-x:active {
   background: transparent url(images/close_2_active.png);
 }
 
@@ -365,4 +349,4 @@
 body.rtl #attribution,body.rtl #recent-tabs {
   left: 8px;
   right: auto;
-}
\ No newline at end of file
+}
diff --git a/chrome/browser/resources/local_ntp/local_ntp.js b/chrome/browser/resources/local_ntp/local_ntp.js
index 6cdd6c5..8dd4c6d 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.js
+++ b/chrome/browser/resources/local_ntp/local_ntp.js
@@ -23,9 +23,9 @@
  * @const
  */
 var CLASSES = {
+  ALTERNATE_LOGO: 'alternate-logo', // Shows white logo if required by theme
   BLACKLIST: 'mv-blacklist', // triggers tile blacklist animation
   BLACKLIST_BUTTON: 'mv-x',
-  CUSTOM_THEME: 'custom-theme',
   DELAYED_HIDE_NOTIFICATION: 'mv-notice-delayed-hide',
   FAKEBOX_DISABLE: 'fakebox-disable', // Makes fakebox non-interactive
   FAKEBOX_FOCUS: 'fakebox-focused', // Applies focus styles to the fakebox
@@ -54,6 +54,7 @@
 var IDS = {
   ATTRIBUTION: 'attribution',
   ATTRIBUTION_TEXT: 'attribution-text',
+  CUSTOM_THEME_STYLE: 'ct-style',
   FAKEBOX: 'fakebox',
   LOGO: 'logo',
   NOTIFICATION: 'mv-notice',
@@ -212,15 +213,6 @@
 
 
 /**
- * Possible background-colors of a non-custom theme. Used to determine whether
- * the homepage should be updated to support custom or non-custom themes.
- * @type {!Array.<string>}
- * @const
- */
-var WHITE = ['rgba(255,255,255,1)', 'rgba(0,0,0,0)'];
-
-
-/**
  * Total tile width. Should be equal to mv-tile's width + 2 * border-width.
  * @private {number}
  * @const
@@ -286,14 +278,6 @@
 
 
 /**
- * The hex color for most visited tile titles when using a custom theme.
- * @type {string}
- * @const
- */
-var MOST_VISITED_THEME_TITLE_COLOR = 'ffffff';
-
-
-/**
  * The font family for most visited tile elements.
  * @type {string}
  * @const
@@ -343,15 +327,67 @@
   var info = ntpApiHandle.themeBackgroundInfo;
   if (!info)
     return;
-  var background = [info.colorRgba,
+
+  var background = [convertToRGBAColor(info.backgroundColorRgba),
                     info.imageUrl,
                     info.imageTiling,
                     info.imageHorizontalAlignment,
                     info.imageVerticalAlignment].join(' ').trim();
   document.body.style.background = background;
-  var isCustom = !!background && WHITE.indexOf(background) == -1;
-  document.body.classList.toggle(CLASSES.CUSTOM_THEME, isCustom);
-  updateAttribution(info.attributionUrl);
+  document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, info.alternateLogo);
+  updateThemeAttribution(info.attributionUrl);
+  setCustomThemeStyle(info);
+  renderTiles();
+}
+
+
+/**
+ * Updates the NTP style according to theme.
+ * @param {Object=} opt_themeInfo The information about the theme. If it is
+ * omitted the style will be reverted to the default.
+ * @private
+ */
+function setCustomThemeStyle(opt_themeInfo) {
+  var customStyleElement = $(IDS.CUSTOM_THEME_STYLE);
+  var head = document.head;
+
+  if (opt_themeInfo && !opt_themeInfo.usingDefaultTheme) {
+    var themeStyle =
+      '#attribution {' +
+      '  color: ' + convertToRGBAColor(opt_themeInfo.textColorLightRgba) + ';' +
+      '}' +
+      '#mv-msg {' +
+      '  color: ' + convertToRGBAColor(opt_themeInfo.textColorRgba) + ';' +
+      '}' +
+      '#mv-notice-links span {' +
+      '  color: ' + convertToRGBAColor(opt_themeInfo.textColorLightRgba) + ';' +
+      '}' +
+      '#mv-notice-x {' +
+      '  -webkit-filter: drop-shadow(0 0 0 ' +
+          convertToRGBAColor(opt_themeInfo.textColorRgba) + ');' +
+      '}' +
+      '.mv-page-ready {' +
+      '  border: 1px solid ' +
+        convertToRGBAColor(opt_themeInfo.sectionBorderColorRgba) + ';' +
+      '}' +
+      '.mv-page-ready:hover, .mv-page-ready:focus {' +
+      '  border-color: ' +
+          convertToRGBAColor(opt_themeInfo.headerColorRgba) + ';' +
+      '}';
+
+    if (customStyleElement) {
+      customStyleElement.textContent = themeStyle;
+    } else {
+      customStyleElement = document.createElement('style');
+      customStyleElement.type = 'text/css';
+      customStyleElement.id = IDS.CUSTOM_THEME_STYLE;
+      customStyleElement.textContent = themeStyle;
+      head.appendChild(customStyleElement);
+    }
+
+  } else if (customStyleElement) {
+    head.removeChild(customStyleElement);
+  }
 }
 
 
@@ -361,9 +397,9 @@
  * @param {string} url The URL of the attribution image, if any.
  * @private
  */
-function updateAttribution(url) {
+function updateThemeAttribution(url) {
   if (!url) {
-    attribution.hidden = true;
+    setAttributionVisibility_(false);
     return;
   }
   var attributionImage = new Image();
@@ -372,16 +408,40 @@
     if (oldAttributionImage)
       removeNode(oldAttributionImage);
     attribution.appendChild(attributionImage);
-    attribution.hidden = false;
+    setAttributionVisibility_(true);
   };
   attributionImage.onerror = function() {
-    attribution.hidden = true;
+    setAttributionVisibility_(false);
   };
   attributionImage.src = url;
 }
 
 
 /**
+ * Sets the visibility of the theme attribution.
+ * @param {boolean} show True to show the attribution.
+ * @private
+ */
+function setAttributionVisibility_(show) {
+  if (attribution) {
+    attribution.style.display = show ? '' : 'none';
+  }
+}
+
+
+ /**
+ * Converts an Array of color components into RGBA format "rgba(R,G,B,A)".
+ * @param {Array.<number>} color Array of rgba color components.
+ * @return {string} CSS color in RGBA format.
+ * @private
+ */
+function convertToRGBAColor(color) {
+  return 'rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',' +
+                    color[3] / 255 + ')';
+}
+
+
+/**
  * Handles a new set of Most Visited page data.
  */
 function onMostVisitedChange() {
@@ -457,18 +517,16 @@
  * @param {string} color The text color for text in the iframe.
  * @param {string} fontFamily The font family for text in the iframe.
  * @param {number} fontSize The font size for text in the iframe.
- * @param {boolean} textShadow True if text should be drawn with a shadow.
  * @param {number} position The position of the iframe in the UI.
  * @return {string} An URL to display the most visited component in an iframe.
  */
 function getMostVisitedIframeUrl(filename, rid, color, fontFamily, fontSize,
-    textShadow, position) {
+    position) {
   return 'chrome-search://most-visited/' + encodeURIComponent(filename) + '?' +
       ['rid=' + encodeURIComponent(rid),
        'c=' + encodeURIComponent(color),
        'f=' + encodeURIComponent(fontFamily),
        'fs=' + encodeURIComponent(fontSize),
-       'ts=' + (textShadow ? '1' : ''),
        'pos=' + encodeURIComponent(position)].join('&');
 }
 
@@ -502,8 +560,6 @@
     // The iframe which renders the page title.
     var titleElement = document.createElement('iframe');
     titleElement.tabIndex = '-1';
-    var usingCustomTheme = document.body.classList.contains(
-        CLASSES.CUSTOM_THEME);
 
     // Why iframes have IDs:
     //
@@ -520,10 +576,9 @@
     // TODO(jered): Find and fix the root (probably Blink) bug.
 
     titleElement.src = getMostVisitedIframeUrl(
-        MOST_VISITED_TITLE_IFRAME, rid,
-        usingCustomTheme ? MOST_VISITED_THEME_TITLE_COLOR : MOST_VISITED_COLOR,
-        MOST_VISITED_FONT_FAMILY, MOST_VISITED_FONT_SIZE, usingCustomTheme,
-        position);
+        MOST_VISITED_TITLE_IFRAME, rid, MOST_VISITED_COLOR,
+        MOST_VISITED_FONT_FAMILY, MOST_VISITED_FONT_SIZE, position);
+
     // Keep this id here. See comment above.
     titleElement.id = 'title-' + rid;
     titleElement.hidden = true;
@@ -539,7 +594,8 @@
     thumbnailElement.tabIndex = '-1';
     thumbnailElement.src = getMostVisitedIframeUrl(
         MOST_VISITED_THUMBNAIL_IFRAME, rid, MOST_VISITED_COLOR,
-        MOST_VISITED_FONT_FAMILY, MOST_VISITED_FONT_SIZE, false, position);
+        MOST_VISITED_FONT_FAMILY, MOST_VISITED_FONT_SIZE, position);
+
     // Keep this id here. See comment above.
     thumbnailElement.id = 'thumb-' + rid;
     thumbnailElement.hidden = true;
@@ -741,11 +797,10 @@
 
 
 /**
- * Restores the NTP (reloads the custom theme, shows the top visible bars,
- * re-enables the fakebox and unhides all NTP elements.)
+ * Restores the NTP (reloads the custom theme, re-enables the fakebox and
+ * unhides the logo.)
  */
 function restoreNtp() {
-  searchboxApiHandle.showBars();
   setFakeboxActive(true);
   setFakeboxAndLogoVisibility(true);
   onThemeChange();
@@ -753,15 +808,6 @@
 
 
 /**
- * Clears the custom theme (if any).
- */
-function clearCustomTheme() {
-  document.body.style.background = '';
-  document.body.classList.remove(CLASSES.CUSTOM_THEME);
-}
-
-
-/**
  * @param {boolean} focus True to focus the fakebox.
  */
 function setFakeboxFocus(focus) {
diff --git a/chrome/browser/resources/local_ntp/most_visited_util.js b/chrome/browser/resources/local_ntp/most_visited_util.js
index 3b9589e..088ea6d 100644
--- a/chrome/browser/resources/local_ntp/most_visited_util.js
+++ b/chrome/browser/resources/local_ntp/most_visited_util.js
@@ -13,7 +13,7 @@
 /**
  * Parses query parameters from Location.
  * @param {string} location The URL to generate the CSS url for.
- * @return {object} Dictionary containing name value pairs for URL
+ * @return {Object} Dictionary containing name value pairs for URL.
  */
 function parseQueryParams(location) {
   var params = Object.create(null);
@@ -44,14 +44,12 @@
  * @return {HTMLAnchorElement} A new link element.
  */
 function createMostVisitedLink(params, href, title, text) {
-  var styles = getMostVisitedStyles(params);
+  var styles = getMostVisitedStyles(params, !!text);
   var link = document.createElement('a');
   link.style.color = styles.color;
   link.style.fontSize = styles.fontSize + 'px';
   if (styles.fontFamily)
     link.style.fontFamily = styles.fontFamily;
-  if (styles.textShadow)
-    link.style.textShadow = styles.textShadow;
   link.href = href;
   if ('pos' in params && isFinite(params.pos))
     link.ping = '/log.html?pos=' + params.pos;
@@ -62,6 +60,10 @@
   link.tabIndex = '-1';
   if (text)
     link.textContent = text;
+  link.addEventListener('mouseover', function() {
+    var ntpApiHandle = chrome.embeddedSearch.newTabPage;
+    ntpApiHandle.logEvent('NewTabPage.NumberOfMouseOvers');
+  });
   return link;
 }
 
@@ -71,25 +73,28 @@
  * - f: font-family
  * - fs: font-size as a number in pixels.
  * - c: A hexadecimal number interpreted as a hex color code.
- * - ts: Truthy iff text should be drawn with a shadow.
  * @param {Object.<string, string>} params URL parameters specifying style.
+ * @param {boolean} isTitle if the style is for the Most Visited Title.
  * @return {Object} Styles suitable for CSS interpolation.
  */
-function getMostVisitedStyles(params) {
+function getMostVisitedStyles(params, isTitle) {
   var styles = {
     color: '#777',
     fontFamily: '',
-    fontSize: 11,
-    textShadow: ''
+    fontSize: 11
   };
+  var apiHandle = chrome.embeddedSearch.newTabPage;
+  var themeInfo = apiHandle.themeBackgroundInfo;
+  if (isTitle && themeInfo && !themeInfo.usingDefaultTheme) {
+    styles.color = convertArrayToRGBAColor(themeInfo.textColorRgba) ||
+        styles.color;
+  } else if ('c' in params) {
+    styles.color = convertToHexColor(parseInt(params.c, 16)) || styles.color;
+  }
   if ('f' in params && /^[-0-9a-zA-Z ,]+$/.test(params.f))
     styles.fontFamily = params.f;
   if ('fs' in params && isFinite(parseInt(params.fs, 10)))
     styles.fontSize = parseInt(params.fs, 10);
-  if ('c' in params)
-    styles.color = convertColor(parseInt(params.c, 16)) || styles.color;
-  if ('ts' in params && params.ts)
-    styles.textShadow = 'black 0 1px 3px';
   return styles;
 }
 
diff --git a/chrome/browser/resources/memory_internals/memory_internals.js b/chrome/browser/resources/memory_internals/memory_internals.js
index c448a6b..c425997 100644
--- a/chrome/browser/resources/memory_internals/memory_internals.js
+++ b/chrome/browser/resources/memory_internals/memory_internals.js
@@ -69,8 +69,7 @@
             break;
           case 'process-memory-v8':
             if (process['v8_alloc'] !== undefined) {
-              value = 'Used : ' + process['v8_used'] + '<br>' +
-                  'Allocated : ' + process['v8_alloc'];
+              value = process['v8_used'] + '<br>/ ' + process['v8_alloc'];
             }
             break;
           }
diff --git a/chrome/browser/resources/memory_internals/snapshot_view.css b/chrome/browser/resources/memory_internals/snapshot_view.css
index 4e57b21..8defc42 100644
--- a/chrome/browser/resources/memory_internals/snapshot_view.css
+++ b/chrome/browser/resources/memory_internals/snapshot_view.css
@@ -36,7 +36,7 @@
 
 #snapshot-view .process-memory {
   border-left: 1px solid rgb(181, 198, 222);
-  width: 16em;
+  width: 13em;
 }
 
 #snapshot-view .process-memory-private {
@@ -47,7 +47,7 @@
 
 #snapshot-view .process-memory-v8 {
   text-align: right;
-  width: 10em;
+  width: 7em;
 }
 
 #snapshot-view #process-template {
diff --git a/chrome/browser/resources/memory_internals/snapshot_view.html b/chrome/browser/resources/memory_internals/snapshot_view.html
index 43d041d..3d2471e 100644
--- a/chrome/browser/resources/memory_internals/snapshot_view.html
+++ b/chrome/browser/resources/memory_internals/snapshot_view.html
@@ -12,7 +12,7 @@
     <th colspan="2" class="process-memory">Memory [KB]
   <tr class="header bottom">
     <th class="process-memory-private">Private
-    <th class="process-memory-v8">V8
+    <th class="process-memory-v8">V8<br>Used / Alloc
   <tr id="process-template">
     <td class="process-id">
     <td class="process-info">
diff --git a/chrome/browser/resources/net_internals/index.html b/chrome/browser/resources/net_internals/index.html
index 6771cb4..a62ff75 100644
--- a/chrome/browser/resources/net_internals/index.html
+++ b/chrome/browser/resources/net_internals/index.html
@@ -12,6 +12,7 @@
     <link rel="stylesheet" href="main.css">
     <link rel="stylesheet" href="status_view.css">
     <link rel="stylesheet" href="events_view.css">
+    <link rel="stylesheet" href="waterfall_view.css">
     <link rel="stylesheet" href="timeline_view.css">
     <link rel="stylesheet" href="logs_view.css">
     <link rel="stylesheet" href="chromeos_view.css">
@@ -41,6 +42,7 @@
       <include src="test_view.html"/>
       <include src="hsts_view.html"/>
       <include src="events_view.html"/>
+      <include src="waterfall_view.html"/>
       <include src="timeline_view.html"/>
       <include src="logs_view.html"/>
       <include src="chromeos_view.html"/>
diff --git a/chrome/browser/resources/net_internals/index.js b/chrome/browser/resources/net_internals/index.js
index 44465fd..49b1c8a 100644
--- a/chrome/browser/resources/net_internals/index.js
+++ b/chrome/browser/resources/net_internals/index.js
@@ -28,6 +28,8 @@
 <include src="source_filter_parser.js"/>
 <include src="source_row.js"/>
 <include src="events_view.js"/>
+<include src="waterfall_view.js"/>
+<include src="waterfall_row.js"/>
 <include src="details_view.js"/>
 <include src="source_entry.js"/>
 <include src="horizontal_scrollbar_view.js"/>
diff --git a/chrome/browser/resources/net_internals/main.js b/chrome/browser/resources/net_internals/main.js
index 8cbd37c..50927d1 100644
--- a/chrome/browser/resources/net_internals/main.js
+++ b/chrome/browser/resources/net_internals/main.js
@@ -185,6 +185,7 @@
       addTab(ImportView);
       addTab(ProxyView);
       addTab(EventsView);
+      addTab(WaterfallView);
       addTab(TimelineView);
       addTab(DnsView);
       addTab(SocketsView);
diff --git a/chrome/browser/resources/net_internals/quic_view.html b/chrome/browser/resources/net_internals/quic_view.html
index b149f20..3f4a4b8 100644
--- a/chrome/browser/resources/net_internals/quic_view.html
+++ b/chrome/browser/resources/net_internals/quic_view.html
@@ -1,6 +1,7 @@
 <div id=quic-view-tab-content class=content-box>
   <ul style='margin-top:0'>
     <li>QUIC Enabled: <span jscontent="!!quic_enabled"></span></li>
+    <li>HTTPS Over QUIC Enabled: <span jscontent="!!quic_enabled_https"></span></li>
     <li>Origin To Force QUIC On: <span jscontent="origin_to_force_quic_on"></span></li>
   </ul>
 
diff --git a/chrome/browser/resources/net_internals/source_entry.js b/chrome/browser/resources/net_internals/source_entry.js
index 99338ba..38c5f89 100644
--- a/chrome/browser/resources/net_internals/source_entry.js
+++ b/chrome/browser/resources/net_internals/source_entry.js
@@ -37,7 +37,7 @@
         this.isInactive_ = true;
       }
 
-      // If we have a net error code, update |this.isError_| if apporpriate.
+      // If we have a net error code, update |this.isError_| if appropriate.
       if (logEntry.params) {
         var netErrorCode = logEntry.params.net_error;
         // Skip both cases where netErrorCode is undefined, and cases where it
@@ -291,6 +291,11 @@
       return this.isError_;
     },
 
+    getStartTime: function() {
+      var startTicks = this.entries_[0].time;
+      return timeutil.convertTimeTicksToTime(startTicks);
+    },
+
     /**
      * Returns time of last event if inactive.  Returns current time otherwise.
      */
@@ -309,8 +314,7 @@
      * last event.
      */
     getDuration: function() {
-      var startTicks = this.entries_[0].time;
-      var startTime = timeutil.convertTimeTicksToTime(startTicks);
+      var startTime = this.getStartTime();
       var endTime = this.getEndTime();
       return endTime - startTime;
     },
diff --git a/chrome/browser/resources/net_internals/waterfall_row.js b/chrome/browser/resources/net_internals/waterfall_row.js
new file mode 100644
index 0000000..d24595a
--- /dev/null
+++ b/chrome/browser/resources/net_internals/waterfall_row.js
@@ -0,0 +1,163 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var WaterfallRow = (function() {
+  'use strict';
+
+  /**
+   * A WaterfallRow represents the row corresponding to a single SourceEntry
+   * displayed by the EventsWaterfallView.
+   *
+   * @constructor
+   */
+
+  // TODO(viona):
+  // -Support nested events.
+  // -Handle updating length when an event is stalled.
+  function WaterfallRow(parentView, sourceEntry, eventList) {
+    this.parentView_ = parentView;
+    this.sourceEntry_ = sourceEntry;
+
+    this.eventTypes_ = eventList;
+    this.description_ = sourceEntry.getDescription();
+
+    this.createRow_();
+  }
+
+  WaterfallRow.prototype = {
+    onSourceUpdated: function() {
+      this.updateRow();
+    },
+
+    updateRow: function() {
+      var scale = this.parentView_.getScaleFactor();
+      // In some cases, the REQUEST_ALIVE event has been received, while the
+      // URL Request to start the job has not been received. In that case, the
+      // description obtained is incorrect. The following fixes that.
+      if (this.description_ == '') {
+        this.urlCell_.innerHTML = '';
+        this.description_ = this.sourceEntry_.getDescription();
+        addTextNode(this.urlCell_, this.description_);
+      }
+
+      this.barCell_.innerHTML = '';
+      var matchingEventPairs = this.findLogEntryPairs_(this.eventTypes_);
+
+      // Creates the spacing in the beginning to show start time.
+      var startTime = this.parentView_.getStartTime();
+      var sourceEntryStartTime = this.sourceEntry_.getStartTime();
+      var delay = sourceEntryStartTime - startTime;
+      var scaledMinTime = delay * scale;
+      this.createNode_(this.barCell_, scaledMinTime, 'padding');
+
+      var currentEnd = sourceEntryStartTime;
+      for (var i = 0; i < matchingEventPairs.length; ++i) {
+        var event = matchingEventPairs[i];
+        var startTicks = event.startEntry.time;
+        var endTicks = event.endEntry.time;
+        event.eventType = event.startEntry.type;
+        event.startTime = timeutil.convertTimeTicksToTime(startTicks);
+        event.endTime = timeutil.convertTimeTicksToTime(endTicks);
+        event.eventDuration = event.endTime - event.startTime;
+
+        // Handles the spaces between events.
+        if (currentEnd < event.startTime) {
+          var eventDuration = event.startTime - currentEnd;
+          var eventWidth = eventDuration * scale;
+          this.createNode_(this.barCell_, eventWidth, this.type_);
+        }
+
+        // Creates event bars.
+        var eventType = eventTypeToCssClass_(EventTypeNames[event.eventType]);
+        var eventWidth = event.eventDuration * scale;
+        this.createNode_(this.barCell_, eventWidth, eventType);
+        currentEnd = event.startTime + event.eventDuration;
+      }
+      // Creates a bar for the part after the last event.
+      if (this.getEndTime() > currentEnd) {
+        var endWidth = (this.getEndTime() - currentEnd) * scale;
+        this.createNode_(this.barCell_, endWidth, this.type_);
+      }
+    },
+
+    getStartTime: function() {
+      return this.sourceEntry_.getStartTime();
+    },
+
+    getEndTime: function() {
+      return this.sourceEntry_.getEndTime();
+    },
+
+    createRow_: function() {
+      // Create a row.
+      var tr = addNode($(WaterfallView.TBODY_ID), 'tr');
+      tr._id = this.sourceEntry_.getSourceId();
+      this.row_ = tr;
+
+      var idCell = addNode(tr, 'td');
+      addTextNode(idCell, this.sourceEntry_.getSourceId());
+
+      var urlCell = addNode(tr, 'td');
+      urlCell.classList.add('waterfall-view-url-cell');
+      addTextNode(urlCell, this.description_);
+      this.urlCell_ = urlCell;
+
+      // Creates the offset for where the color bar appears.
+      var barCell = addNode(tr, 'td');
+      barCell.classList.add('waterfall-view-row');
+      this.barCell_ = barCell;
+
+      this.updateRow();
+
+      var sourceTypeString = this.sourceEntry_.getSourceTypeString();
+      this.type_ = eventTypeToCssClass_(sourceTypeString);
+    },
+
+    // Generates nodes.
+    createNode_: function(parentNode, durationScaled, eventType) {
+      var newNode = addNode(parentNode, 'div');
+      setNodeWidth(newNode, durationScaled);
+      newNode.classList.add('waterfall-view-row-' + eventType);
+      return newNode;
+    },
+
+    /**
+     * Finds pairs of starting and ending events of all types that are in
+     * typeList. Currently does not handle nested events. Can consider adding
+     * starting events to a stack and popping off as their close events are
+     * found. Returns an array of objects containing start/end entry pairs,
+     * in the format {startEntry, endEntry}.
+     */
+    findLogEntryPairs_: function() {
+      var typeList = this.eventTypes_;
+      var matchingEventPairs = [];
+      var startEntries = {};
+      var entries = this.sourceEntry_.getLogEntries();
+      for (var i = 0; i < entries.length; ++i) {
+        var type = entries[i].type;
+        if (typeList.indexOf(type) < 0) {
+          continue;
+        }
+        if (entries[i].phase == EventPhase.PHASE_BEGIN) {
+          startEntries[type] = entries[i];
+        }
+        if (startEntries[type] && entries[i].phase == EventPhase.PHASE_END) {
+          var event = {
+            startEntry: startEntries[type],
+            endEntry: entries[i],
+          };
+          matchingEventPairs.push(event);
+        }
+      }
+      return matchingEventPairs;
+    },
+
+  };
+
+  function eventTypeToCssClass_(rawEventType) {
+    return rawEventType.toLowerCase().replace(/_/g, '-');
+  }
+
+  return WaterfallRow;
+})();
diff --git a/chrome/browser/resources/net_internals/waterfall_view.css b/chrome/browser/resources/net_internals/waterfall_view.css
new file mode 100644
index 0000000..2d1b636
--- /dev/null
+++ b/chrome/browser/resources/net_internals/waterfall_view.css
@@ -0,0 +1,60 @@
+/* Copyright 2013 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+.waterfall-view-url-cell {
+  display: inline-block;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  width: 250px;
+}
+
+.waterfall-view-row {
+  white-space: nowrap;
+}
+
+.waterfall-view-row * {
+  display: inline-block;
+  height: 15px;
+  opacity: 0.5;
+  padding-top: 0;
+}
+
+.waterfall-view-row [class*='http-stream-request'] {
+  background-color: #000;
+}
+
+.waterfall-view-row [class*='http-transaction-read-headers'] {
+  background-color: rgb(255, 0, 0);
+}
+
+.waterfall-view-row [class*='url-request'] {
+  background-color: rgb(0, 0, 255);
+}
+
+.waterfall-view-row [class*='http-stream-job'] {
+  background-color: rgb(0, 255, 0);
+}
+
+.waterfall-view-row [class*='proxy-service'] {
+  background-color: rgb(122, 122, 0);
+}
+
+.waterfall-view-row [class*='socket-pool-connect-job'] {
+  background-color: rgb(0, 122, 122);
+}
+
+.waterfall-view-row [class*='host-resolver-impl'] {
+  background-color: rgb(122, 0, 122);
+}
+
+.waterfall-view-row [class*='socket'] {
+  background-color: rgb(122, 178, 0);
+}
+
+.waterfall-popup {
+  display: block;
+  font-size: 15px;
+}
diff --git a/chrome/browser/resources/net_internals/waterfall_view.html b/chrome/browser/resources/net_internals/waterfall_view.html
new file mode 100644
index 0000000..d605122
--- /dev/null
+++ b/chrome/browser/resources/net_internals/waterfall_view.html
@@ -0,0 +1,20 @@
+<!-- =============== Events Waterfall View ================= -->
+<div id=waterfall-view-tab-content class=content-box>
+  <div>
+    Information:
+    <p>Currently only captures URL Request events. Blue represents URL
+    Requests. Red represents Header Reads. Grey represents Stream Requests.
+    <input id=waterfall-view-time-scale type="button"
+        value="Scale To Fit Window">
+    <table id=waterfall-view-source-list-table>
+      <thead>
+      <tr>
+        <td id=waterfall-view-source-id>ID</td>
+        <td id=waterfall-view-source-header>Source</td>
+      </tr>
+      </thead>
+      <!-- Events Waterfall table body: This is where request rows go into -->
+      <tbody id=waterfall-view-source-list-tbody></tbody>
+    </table>
+  </div>
+</div>
diff --git a/chrome/browser/resources/net_internals/waterfall_view.js b/chrome/browser/resources/net_internals/waterfall_view.js
new file mode 100644
index 0000000..2f1b0ed
--- /dev/null
+++ b/chrome/browser/resources/net_internals/waterfall_view.js
@@ -0,0 +1,143 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/** This view displays the event waterfall. */
+var WaterfallView = (function() {
+  'use strict';
+
+  // We inherit from DivView.
+  var superClass = DivView;
+
+  /**
+   * @constructor
+   */
+  function WaterfallView() {
+    assertFirstConstructorCall(WaterfallView);
+
+    // Call superclass's constructor.
+    superClass.call(this, WaterfallView.MAIN_BOX_ID);
+
+    SourceTracker.getInstance().addSourceEntryObserver(this);
+
+    // For adjusting the range of view.
+    $(WaterfallView.SCALE_ID).addEventListener(
+        'click', this.adjustToWindow_.bind(this), true);
+
+    this.initializeSourceList_();
+  }
+
+  WaterfallView.TAB_ID = 'tab-handle-waterfall';
+  WaterfallView.TAB_NAME = 'Waterfall';
+  WaterfallView.TAB_HASH = '#waterfall';
+
+  // IDs for special HTML elements in events_waterfall_view.html.
+  WaterfallView.MAIN_BOX_ID = 'waterfall-view-tab-content';
+  WaterfallView.TBODY_ID = 'waterfall-view-source-list-tbody';
+  WaterfallView.SCALE_ID = 'waterfall-view-time-scale';
+  WaterfallView.ID_HEADER_ID = 'waterfall-view-source-id';
+  WaterfallView.SOURCE_HEADER_ID = 'waterfall-view-source-header';
+
+  cr.addSingletonGetter(WaterfallView);
+
+  WaterfallView.prototype = {
+    // Inherit the superclass's methods.
+    __proto__: superClass.prototype,
+
+    /**
+     * Creates new WaterfallRows for URL Requests when the sourceEntries are
+     * updated if they do not already exist.
+     * Updates pre-existing WaterfallRows that correspond to updated sources.
+     */
+    onSourceEntriesUpdated: function(sourceEntries) {
+      if (this.startTime_ == null && sourceEntries.length > 0) {
+        var logEntries = sourceEntries[0].getLogEntries();
+        this.startTime_ = timeutil.convertTimeTicksToTime(logEntries[0].time);
+        // Initial scale factor.
+        this.scaleFactor_ = 0.1;
+      }
+      for (var i = 0; i < sourceEntries.length; ++i) {
+        var sourceEntry = sourceEntries[i];
+        var id = sourceEntry.getSourceId();
+        if (sourceEntry.getSourceType() == EventSourceType.URL_REQUEST) {
+          var row = this.sourceIdToRowMap_[id];
+          if (!row) {
+            var importantEventTypes = [
+                EventType.HTTP_STREAM_REQUEST,
+                EventType.HTTP_TRANSACTION_READ_HEADERS
+            ];
+            this.sourceIdToRowMap_[id] =
+                new WaterfallRow(this, sourceEntry, importantEventTypes);
+          } else {
+            row.onSourceUpdated();
+          }
+        }
+      }
+    },
+
+    onAllSourceEntriesDeleted: function() {
+      this.initializeSourceList_();
+    },
+
+    onLoadLogFinish: function(data) {
+      return true;
+    },
+
+    getScaleFactor: function() {
+      return this.scaleFactor_;
+    },
+
+    getStartTime: function() {
+      return this.startTime_;
+    },
+
+    /**
+     * Initializes the list of source entries.  If source entries are already
+     * being displayed, removes them all in the process.
+     */
+    initializeSourceList_: function() {
+      this.sourceIdToRowMap_ = {};
+      $(WaterfallView.TBODY_ID).innerHTML = '';
+      this.startTime_ = null;
+      this.scaleFactor_ = null;
+    },
+
+    /**
+     * Changes width of the bars such that horizontally, everything fits into
+     * the user's current window size.
+     * TODO(viona): Deal with the magic number.
+     */
+    adjustToWindow_: function() {
+      var usedWidth = $(WaterfallView.SOURCE_HEADER_ID).offsetWidth +
+          $(WaterfallView.ID_HEADER_ID).offsetWidth;
+      var availableWidth = ($(WaterfallView.MAIN_BOX_ID).offsetWidth -
+          usedWidth - 50);
+      if (availableWidth <= 0) {
+        availableWidth = 1;
+      }
+      var totalDuration = 0;
+      for (var id in this.sourceIdToRowMap_) {
+        var row = this.sourceIdToRowMap_[id];
+        var rowDuration = row.getEndTime() - this.startTime_;
+        if (totalDuration < rowDuration) {
+          totalDuration = rowDuration;
+        }
+      }
+      var scaleFactor = availableWidth / totalDuration;
+      this.scaleAll_(scaleFactor);
+    },
+
+    /**
+     * Scales all existing rows by scaleFactor.
+     */
+    scaleAll_: function(scaleFactor) {
+      this.scaleFactor_ = scaleFactor;
+      for (var id in this.sourceIdToRowMap_) {
+        var row = this.sourceIdToRowMap_[id];
+        row.updateRow();
+      }
+    },
+  };
+
+  return WaterfallView;
+})();
diff --git a/chrome/browser/resources/ntp4/new_tab.html b/chrome/browser/resources/ntp4/new_tab.html
index 78d921c..5549770 100644
--- a/chrome/browser/resources/ntp4/new_tab.html
+++ b/chrome/browser/resources/ntp4/new_tab.html
@@ -48,6 +48,7 @@
 <script src="../../../../ui/webui/resources/js/cr/ui/context_menu_handler.js"></script>
 <script src="../../../../ui/webui/resources/js/cr/ui/drag_wrapper.js"></script>
 <script src="../../../../ui/webui/resources/js/cr/ui/expandable_bubble.js"></script>
+<script src="../../../../ui/webui/resources/js/cr/ui/focus_manager.js"></script>
 <script src="../../../../ui/webui/resources/js/cr/ui/menu.js"></script>
 <script src="../../../../ui/webui/resources/js/cr/ui/menu_item.js"></script>
 <script src="../../../../ui/webui/resources/js/cr/ui/position_util.js"></script>
diff --git a/chrome/browser/resources/ntp4/new_tab.js b/chrome/browser/resources/ntp4/new_tab.js
index 621e044..daa0eb7 100644
--- a/chrome/browser/resources/ntp4/new_tab.js
+++ b/chrome/browser/resources/ntp4/new_tab.js
@@ -287,6 +287,7 @@
     });
 
     preventDefaultOnPoundLinkClicks();  // From webui/js/util.js.
+    cr.ui.FocusManager.disableMouseFocusOnButtons();
   }
 
   /**
diff --git a/chrome/browser/resources/omnibox_result.html b/chrome/browser/resources/omnibox_result.html
deleted file mode 100644
index a7dfbec..0000000
--- a/chrome/browser/resources/omnibox_result.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src="chrome-search://suggestion/result.js"></script>
-<style>
-body {
-  -webkit-user-select: none;
-  cursor: default;
-  margin: 0;
-  overflow: hidden;
-  position: fixed;
-  width: 100%;
-}
-
-body > div {
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-</style>
-</head>
-<body>
-  <div>
-    <span id="contents"></span>
-    <span id="optional"> &ndash; <span id="title"></span></span>
-  </div>
-</body>
-</html>
diff --git a/chrome/browser/resources/omnibox_result.js b/chrome/browser/resources/omnibox_result.js
deleted file mode 100644
index 1b3107a..0000000
--- a/chrome/browser/resources/omnibox_result.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Click handler for omnibox results.
- */
-
-(function() {
-/**
- * The origin of the embedding page.
- * This string literal must be in double quotes for proper escaping.
- * @type {string}
- * @const
- */
-var EMBEDDER_ORIGIN = "{{ORIGIN}}";
-
-window.addEventListener('click', function(event) {
-  top.postMessage({click: event.button}, EMBEDDER_ORIGIN);
-});
-
-window.addEventListener('contextmenu', function(event) {
-  event.preventDefault();
-});
-})();
diff --git a/chrome/browser/resources/omnibox_result_loader.html b/chrome/browser/resources/omnibox_result_loader.html
deleted file mode 100644
index d342461..0000000
--- a/chrome/browser/resources/omnibox_result_loader.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<script src="chrome-search://suggestion/loader.js"></script>
diff --git a/chrome/browser/resources/omnibox_result_loader.js b/chrome/browser/resources/omnibox_result_loader.js
deleted file mode 100644
index e8e8903..0000000
--- a/chrome/browser/resources/omnibox_result_loader.js
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Orchestrates loading of suggestion content in several
- * chrome-search://suggestion iframes.
- */
-
-(function() {
-<include src="local_ntp/instant_iframe_validation.js">
-
-/**
- * The origin of the embedding page.
- * This string literal must be in double quotes for proper escaping.
- * @type {string}
- * @const
- */
-var EMBEDDER_ORIGIN = "{{ORIGIN}}";
-
-/**
- * Converts an RGB color number to a hex color string if valid.
- * @param {number} color A 6-digit hex RGB color code as a number.
- * @return {?string} A CSS representation of the color or null if invalid.
- */
-function convertColor(color) {
-  // Color must be a number, finite, with no fractional part, in the correct
-  // range for an RGB hex color.
-  if (isFinite(color) && Math.floor(color) == color &&
-      color >= 0 && color <= 0xffffff) {
-    var hexColor = color.toString(16);
-    // Pads with initial zeros and # (e.g. for 'ff' yields '#0000ff').
-    return '#000000'.substr(0, 7 - hexColor.length) + hexColor;
-  }
-  return null;
-}
-
-/**
- * Checks and returns suggestion style.
- * @param {!Object} pageStyle Instant page-specified overrides for suggestion
- *     styles.
- * @return {!Object} Checked styles or defaults.
- */
-function getStyle(pageStyle) {
-  var apiHandle = chrome.embeddedSearch.searchBox;
-  var style = {
-    queryColor: '#000000',
-    urlColor: '#009933',
-    titleColor: '#666666',
-    font: apiHandle.font,
-    fontSize: apiHandle.fontSize,
-    isRtl: apiHandle.rtl
-  };
-  if ('queryColor' in pageStyle)
-    style.queryColor = convertColor(pageStyle.queryColor) || style.queryColor;
-  if ('urlColor' in pageStyle)
-    style.urlColor = convertColor(pageStyle.urlColor) || style.urlColor;
-  if ('titleColor' in pageStyle)
-    style.titleColor = convertColor(pageStyle.titleColor) || style.titleColor;
-  return style;
-}
-
-/**
- * Renders a native history suggestion.
- * @param {!Document} resultDoc The suggestion template document.
- * @param {!Object} suggestion The NativeSuggestion to render.
- * @param {!Object} pageStyle Page-specificed styles.
- */
-function updateResult(resultDoc, suggestion, pageStyle) {
-  var style = getStyle(pageStyle);
-  resultDoc.body.dir = 'auto';
-  resultDoc.body.style.fontSize = style.fontSize + 'px';
-  resultDoc.body.style.fontFamily = style.font;
-  resultDoc.body.style.textAlign = style.isRtl ? 'right' : 'left';
-  var contentsNode = resultDoc.querySelector('#contents');
-  contentsNode.textContent = suggestion.contents;
-  contentsNode.style.color = suggestion.is_search ?
-      style.queryColor : style.urlColor;
-  var optionalNode = resultDoc.querySelector('#optional');
-  optionalNode.hidden = !suggestion.description;
-  if (suggestion.description) {
-    var titleNode = resultDoc.querySelector('#title');
-    titleNode.textContent = suggestion.description;
-    optionalNode.style.color = style.titleColor;
-  }
-}
-
-/**
- * Handles a postMessage from the embedding page requesting to populate history
- * suggestion iframes.
- * @param {!Object} message The message.
- */
-function handleMessage(message) {
-  // Only allow messages from the embedding page, which should be an Instant
-  // search provider or the local omnibox dropdown (and not e.g. a site which
-  // it has iframed.)
-  if (message.origin != EMBEDDER_ORIGIN)
-    return;
-
-  var apiHandle = chrome.embeddedSearch.searchBox;
-  if ('load' in message.data) {
-    for (var iframeId in message.data.load) {
-      var restrictedId = message.data.load[iframeId];
-      var suggestion = apiHandle.getSuggestionData(restrictedId);
-      var iframe = window.parent.frames[iframeId];
-      if (iframe)
-        updateResult(iframe.document, suggestion, message.data.style || {});
-    }
-    message.source.postMessage(
-        {loaded: message.data.requestId}, message.origin);
-  }
-}
-
-window.addEventListener('message', handleMessage, false);
-})();
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html
index d6bfa99..ef02f53 100644
--- a/chrome/browser/resources/options/browser_options.html
+++ b/chrome/browser/resources/options/browser_options.html
@@ -137,22 +137,6 @@
               i18n-content="defaultSearchManageEngines">
           </button>
         </div>
-        <div id="instant-enabled-setting" class="checkbox"
-            guest-visibility="disabled">
-          <span class="controlled-setting-with-label">
-            <input id="instant-enabled-control" type="checkbox"
-                pref="instant_extended.instant_enabled"
-                metric="Options_InstantExtendedEnabled">
-            <span>
-              <!-- The content of the label is inserted by JS -->
-              <label id="instant-enabled-label" for="instant-enabled-control">
-              </label>
-              <span class="controlled-setting-indicator"
-                  pref="instant_extended.instant_enabled">
-              </span>
-            </span>
-          </span>
-        </div>
       </div>
   </section>
   <section id="sync-users-section" guest-visibility="hidden">
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js
index ec737b8..ca5e832 100644
--- a/chrome/browser/resources/options/browser_options.js
+++ b/chrome/browser/resources/options/browser_options.js
@@ -375,6 +375,9 @@
       $('language-button').onclick = showLanguageOptions;
       $('manage-languages').onclick = showLanguageOptions;
 
+      if (!loadTimeData.getBoolean('enableTranslateSettings'))
+        $('manage-languages').hidden = true;
+
       // Downloads section.
       Preferences.getInstance().addEventListener('download.default_directory',
           this.onDefaultDownloadDirectoryChanged_.bind(this));
@@ -692,41 +695,33 @@
     },
 
     /**
-     * Updates the Instant checkbox section.
-     * @param {boolean} visible Is the checkbox visible?
-     * @param {boolean} enabled Is the checkbox enabled?
-     * @param {boolean} checked Is the checkbox checked?
-     * @param {string} checkboxLabel Label to show next to the checkbox.
-     * @private
-     */
-    updateInstantCheckboxState_: function(visible, enabled, checked,
-                                          checkboxLabel) {
-      var checkboxSection = $('instant-enabled-setting');
-      var checkbox = $('instant-enabled-control');
-      if (visible) {
-        $('instant-enabled-setting').style.display = 'block';
-        checkbox.disabled = !enabled;
-        checkbox.checked = checked;
-        $('instant-enabled-label').textContent = checkboxLabel;
-      } else {
-        $('instant-enabled-setting').style.display = 'none';
-      }
-    },
-
-    /**
      * Updates the sync section with the given state.
      * @param {Object} syncData A bunch of data records that describe the status
      *     of the sync system.
      * @private
      */
     updateSyncState_: function(syncData) {
-      if (!syncData.signinAllowed) {
+      if (!syncData.signinAllowed &&
+          (!syncData.supervisedUser || !cr.isChromeOS)) {
         $('sync-section').hidden = true;
         return;
       }
 
       $('sync-section').hidden = false;
 
+      var subSection = $('sync-section').firstChild;
+      while (subSection) {
+        if (subSection.nodeType == Node.ELEMENT_NODE)
+          subSection.hidden = syncData.supervisedUser;
+        subSection = subSection.nextSibling;
+      }
+
+      if (syncData.supervisedUser) {
+        $('account-picture-wrapper').hidden = false;
+        $('sync-general').hidden = false;
+        $('sync-status').hidden = true;
+        return;
+      }
       // If the user gets signed out or if sync gets disabled while the advanced
       // sync settings dialog is visible, say, due to a dashboard clear, close
       // the dialog.
@@ -788,7 +783,7 @@
         if (cr.isChromeOS && syncData.hasError)
           SyncSetupOverlay.doSignOutOnAuthError();
         else
-          SyncSetupOverlay.showErrorUI();
+          SyncSetupOverlay.showSetupUI();
       };
 
       if (syncData.hasError)
@@ -1493,7 +1488,6 @@
     'updateAccountPicture',
     'updateAutoLaunchState',
     'updateDefaultBrowserState',
-    'updateInstantCheckboxState',
     'updateSearchEngines',
     'updateStartupPages',
     'updateSyncState',
diff --git a/chrome/browser/resources/options/chromeos/browser_options.css b/chrome/browser/resources/options/chromeos/browser_options.css
new file mode 100644
index 0000000..e02cae2
--- /dev/null
+++ b/chrome/browser/resources/options/chromeos/browser_options.css
@@ -0,0 +1,7 @@
+/* Copyright 2013 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+#sync-section {
+  min-height: 64px;
+}
diff --git a/chrome/browser/resources/options/chromeos/display_options.js b/chrome/browser/resources/options/chromeos/display_options.js
index 0b0415b..3043bcc 100644
--- a/chrome/browser/resources/options/chromeos/display_options.js
+++ b/chrome/browser/resources/options/chromeos/display_options.js
@@ -552,7 +552,10 @@
       $('selected-display-name').textContent =
           loadTimeData.getString('mirroringDisplay');
       var resolution = $('display-options-resolution-selection');
-      resolution.appendChild(document.createElement('option'));
+      var option = document.createElement('option');
+      option.value = 'default';
+      option.textContent = display.width + 'x' + display.height;
+      resolution.appendChild(option);
       resolution.disabled = true;
     },
 
diff --git a/chrome/browser/resources/options/chromeos/internet_detail.js b/chrome/browser/resources/options/chromeos/internet_detail.js
index 4ff8dac..edf7944 100644
--- a/chrome/browser/resources/options/chromeos/internet_detail.js
+++ b/chrome/browser/resources/options/chromeos/internet_detail.js
@@ -14,13 +14,13 @@
   function Constants() {}
 
   // Network types:
-  Constants.TYPE_UNKNOWN = 0;
-  Constants.TYPE_ETHERNET = 1;
-  Constants.TYPE_WIFI = 2;
-  Constants.TYPE_WIMAX = 3;
-  Constants.TYPE_BLUETOOTH = 4;
-  Constants.TYPE_CELLULAR = 5;
-  Constants.TYPE_VPN = 6;
+  Constants.TYPE_UNKNOWN = 'UNKNOWN';
+  Constants.TYPE_ETHERNET = 'ethernet';
+  Constants.TYPE_WIFI = 'wifi';
+  Constants.TYPE_WIMAX = 'wimax';
+  Constants.TYPE_BLUETOOTH = 'bluetooth';
+  Constants.TYPE_CELLULAR = 'cellular';
+  Constants.TYPE_VPN = 'vpn';
 
   /*
    * Helper function to set hidden attribute for elements matching a selector.
@@ -1129,8 +1129,8 @@
       detailsPage.ethernet = false;
       detailsPage.cellular = false;
       detailsPage.gsm = false;
-      $('inet-service-name').textContent = data.service_name;
-      $('inet-provider-type').textContent = data.provider_type;
+      $('inet-service-name').textContent = data.serviceName;
+      $('inet-provider-type').textContent = data.providerType;
       $('inet-username').textContent = data.username;
       var inetServerHostname = $('inet-server-hostname');
       inetServerHostname.value = data.serverHostname.value;
diff --git a/chrome/browser/resources/options/chromeos/network_list.js b/chrome/browser/resources/options/chromeos/network_list.js
index 982bde7..0a0cff6 100644
--- a/chrome/browser/resources/options/chromeos/network_list.js
+++ b/chrome/browser/resources/options/chromeos/network_list.js
@@ -19,13 +19,13 @@
   function Constants() {}
 
   // Network types:
-  Constants.TYPE_UNKNOWN = 0;
-  Constants.TYPE_ETHERNET = 1;
-  Constants.TYPE_WIFI = 2;
-  Constants.TYPE_WIMAX = 3;
-  Constants.TYPE_BLUETOOTH = 4;
-  Constants.TYPE_CELLULAR = 5;
-  Constants.TYPE_VPN = 6;
+  Constants.TYPE_UNKNOWN = 'UNKNOWN';
+  Constants.TYPE_ETHERNET = 'ethernet';
+  Constants.TYPE_WIFI = 'wifi';
+  Constants.TYPE_WIMAX = 'wimax';
+  Constants.TYPE_BLUETOOTH = 'bluetooth';
+  Constants.TYPE_CELLULAR = 'cellular';
+  Constants.TYPE_VPN = 'vpn';
 
   // Cellular activation states:
   Constants.ACTIVATION_STATE_UNKNOWN = 0;
@@ -721,7 +721,7 @@
     button.appendChild(buttonLabel);
     var callback = null;
     if (typeof command == 'string') {
-      var type = String(data.networkType);
+      var type = data.networkType;
       var path = data.servicePath;
       callback = function() {
         chrome.send('networkCommand',
diff --git a/chrome/browser/resources/options/chromeos/preferred_networks.js b/chrome/browser/resources/options/chromeos/preferred_networks.js
index b60752a..b6b461b 100644
--- a/chrome/browser/resources/options/chromeos/preferred_networks.js
+++ b/chrome/browser/resources/options/chromeos/preferred_networks.js
@@ -125,7 +125,7 @@
       if (item) {
         // Inform the network library that we are forgetting this network.
         chrome.send('networkCommand',
-                    [String(item.networkType),
+                    [item.networkType,
                     item.servicePath,
                     'forget']);
       }
@@ -162,4 +162,3 @@
   };
 
 });
-
diff --git a/chrome/browser/resources/options/content_settings.html b/chrome/browser/resources/options/content_settings.html
index a5178ee..87aa0a0 100644
--- a/chrome/browser/resources/options/content_settings.html
+++ b/chrome/browser/resources/options/content_settings.html
@@ -504,6 +504,58 @@
             i18n-content="manageGalleriesButton"></button>
       </div>
     </section>
+    <section>
+      <h3 i18n-content="multiple-automatic-downloads_header"></h3>
+      <div>
+        <div class="radio">
+          <span class="controlled-setting-with-label">
+            <input id="multiple-automatic-downloads_allow" type="radio"
+                name="multiple-automatic-downloads" value="allow">
+            <span>
+              <label for="multiple-automatic-downloads_allow"
+                  i18n-content="multiple-automatic-downloads_allow">
+              </label>
+              <span class="controlled-setting-indicator"
+                  content-setting="multiple-automatic-downloads" value="allow">
+              </span>
+            </span>
+          </span>
+        </div>
+        <div class="radio">
+          <span class="controlled-setting-with-label">
+            <input id="multiple-automatic-downloads_ask" type="radio"
+                name="multiple-automatic-downloads" value="ask">
+            <span>
+              <label for="multiple-automatic-downloads_ask"
+                  i18n-content="multiple-automatic-downloads_ask">
+              </label>
+              <span class="controlled-setting-indicator"
+                  content-setting="multiple-automatic-downloads" value="ask">
+              </span>
+            </span>
+          </span>
+        </div>
+        <div class="radio">
+          <span class="controlled-setting-with-label">
+            <input id="multiple-automatic-downloads_block" type="radio"
+                name="multiple-automatic-downloads" value="block">
+            <span>
+              <label for="multiple-automatic-downloads_block"
+                  i18n-content="multiple-automatic-downloads_block">
+              </label>
+              <span class="controlled-setting-indicator"
+                  content-setting="multiple-automatic-downloads" value="block">
+              </span>
+            </span>
+          </span>
+        </div>
+        <div class="settings-row">
+          <button class="exceptions-list-button"
+              contentType="multiple-automatic-downloads"
+              i18n-content="manageExceptions"></button>
+        </div>
+      </div>
+    </section>
   </div>
   <div class="action-area">
     <div class="button-strip">
diff --git a/chrome/browser/resources/options/content_settings_exceptions_area.html b/chrome/browser/resources/options/content_settings_exceptions_area.html
index b6eea35..0f6127d 100644
--- a/chrome/browser/resources/options/content_settings_exceptions_area.html
+++ b/chrome/browser/resources/options/content_settings_exceptions_area.html
@@ -104,6 +104,9 @@
         <list mode="otr"></list>
       </div>
     </div>
+    <div contentType="multiple-automatic-downloads">
+      <list mode="normal"></list>
+    </div>
   </div>
   <div class="action-area">
     <div class="hbox stretch">
diff --git a/chrome/browser/resources/options/content_settings_exceptions_area.js b/chrome/browser/resources/options/content_settings_exceptions_area.js
index 7d2e452..fa013b7 100644
--- a/chrome/browser/resources/options/content_settings_exceptions_area.js
+++ b/chrome/browser/resources/options/content_settings_exceptions_area.js
@@ -369,7 +369,12 @@
 
       chrome.send('setException',
                   [this.contentType, this.mode, newPattern, newSetting]);
-    }
+    },
+
+    /** @override */
+    isExtraFocusableControl: function(element) {
+      return element === this.select;
+    },
   };
 
   /**
diff --git a/chrome/browser/resources/options/inline_editable_list.js b/chrome/browser/resources/options/inline_editable_list.js
index f12505b..3b84302 100644
--- a/chrome/browser/resources/options/inline_editable_list.js
+++ b/chrome/browser/resources/options/inline_editable_list.js
@@ -110,6 +110,9 @@
       if (this.editing == editing)
         return;
 
+      if (this.isExtraFocusableControl(document.activeElement))
+        editing = false;
+
       if (editing)
         this.setAttribute('editing', '');
       else
@@ -349,6 +352,17 @@
         }
       }
     },
+
+    /**
+     * Check if the specified element is a focusable form control which is in
+     * the list item and not in |editFields_|.
+     * @param {!Element} element An element.
+     * @return {boolean} Returns true if the element is one of focusable
+     *     controls in this list item.
+     */
+    isExtraFocusableControl: function(element) {
+      return false;
+    },
   };
 
   /**
diff --git a/chrome/browser/resources/options/language_dictionary_overlay.js b/chrome/browser/resources/options/language_dictionary_overlay.js
index c715423..6315299 100644
--- a/chrome/browser/resources/options/language_dictionary_overlay.js
+++ b/chrome/browser/resources/options/language_dictionary_overlay.js
@@ -61,6 +61,12 @@
       this.searchField_.onsearch = function(e) {
         this.wordList_.search(e.currentTarget.value);
       }.bind(this);
+      this.searchField_.onkeydown = function(e) {
+        // Don't propagate enter key events. Otherwise the default button will
+        // activate.
+        if (e.keyIdentifier == 'Enter')
+          e.stopPropagation();
+      };
 
       this.noMatchesLabel_ = getRequiredElement(
           'language-dictionary-overlay-no-matches');
diff --git a/chrome/browser/resources/options/language_options.js b/chrome/browser/resources/options/language_options.js
index 5250ced..c54c76f 100644
--- a/chrome/browser/resources/options/language_options.js
+++ b/chrome/browser/resources/options/language_options.js
@@ -695,8 +695,8 @@
       }
 
       var dontTranslate = div.querySelector('div');
-      var cannnotTranslate = $('cannot-translate-in-this-language');
-      var nodes = [dontTranslate, cannnotTranslate];
+      var cannotTranslate = $('cannot-translate-in-this-language');
+      var nodes = [dontTranslate, cannotTranslate];
 
       var convertedLangCode = this.convertLangCodeForTranslation_(languageCode);
       if (this.translateSupportedLanguages_.indexOf(convertedLangCode) != -1) {
@@ -1224,7 +1224,6 @@
     convertLangCodeForTranslation_: function(languageCode) {
       var tokens = languageCode.split('-');
       var main = tokens[0];
-      var dialect = tokens[1];
 
       // See also: chrome/renderer/translate/translate_helper.cc.
       var synonyms = {
@@ -1237,8 +1236,8 @@
       if (main in synonyms) {
         return synonyms[main];
       } else if (main == 'zh') {
-        // In Translation, general Chinese is not used.
-        assert(dialect);
+        // In Translation, general Chinese is not used, and the sub code is
+        // necessary as a language code for Translate server.
         return languageCode;
       }
 
diff --git a/chrome/browser/resources/options/manage_profile_overlay.js b/chrome/browser/resources/options/manage_profile_overlay.js
index d27a979..f244c08 100644
--- a/chrome/browser/resources/options/manage_profile_overlay.js
+++ b/chrome/browser/resources/options/manage_profile_overlay.js
@@ -346,6 +346,7 @@
       $('manage-profile-overlay-create').hidden = true;
       $('manage-profile-overlay-manage').hidden = false;
       $('manage-profile-overlay-delete').hidden = true;
+      $('manage-profile-name').disabled = profileInfo.isManaged;
       this.hideErrorBubble_('manage');
     },
 
@@ -537,7 +538,7 @@
       if (profileInfo.isManaged) {
         profileInfo.custodianEmail = this.signedInEmail_;
         ManagedUserCreateConfirmOverlay.setProfileInfo(profileInfo);
-        OptionsPage.navigateToPage('managedUserCreateConfirm');
+        OptionsPage.showPageByName('managedUserCreateConfirm', false);
       }
     },
 
diff --git a/chrome/browser/resources/options/managed_user.png b/chrome/browser/resources/options/managed_user.png
deleted file mode 100644
index e84d850..0000000
--- a/chrome/browser/resources/options/managed_user.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/options/managed_user_create_confirm.js b/chrome/browser/resources/options/managed_user_create_confirm.js
index 88e4701..d1538ac 100644
--- a/chrome/browser/resources/options/managed_user_create_confirm.js
+++ b/chrome/browser/resources/options/managed_user_create_confirm.js
@@ -81,6 +81,11 @@
                                   HTMLEscape(info.name),
                                   HTMLEscape(info.custodianEmail));
     },
+
+    /** @override */
+    canShowPage: function() {
+      return this.profileInfo_ != null;
+    },
   };
 
   // Forward public APIs to private implementations.
diff --git a/chrome/browser/resources/options/managed_user_create_confirm.png b/chrome/browser/resources/options/managed_user_create_confirm.png
deleted file mode 100644
index 58c2331..0000000
--- a/chrome/browser/resources/options/managed_user_create_confirm.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/options/managed_user_learn_more.png b/chrome/browser/resources/options/managed_user_learn_more.png
deleted file mode 100644
index 8adc52a..0000000
--- a/chrome/browser/resources/options/managed_user_learn_more.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html
index 68e5770..d78ee8a 100644
--- a/chrome/browser/resources/options/options.html
+++ b/chrome/browser/resources/options/options.html
@@ -17,6 +17,9 @@
 <link rel="stylesheet" href="autofill_edit_overlay.css">
 <link rel="stylesheet" href="autofill_options.css">
 <link rel="stylesheet" href="browser_options.css">
+<if expr="pp_ifdef('chromeos')">
+  <link rel="stylesheet" href="chromeos/browser_options.css">
+</if>
 <link rel="stylesheet" href="clear_browser_data_overlay.css">
 <link rel="stylesheet" href="content_settings.css">
 <link rel="stylesheet" href="cookies_view.css">
diff --git a/chrome/browser/resources/options/options.js b/chrome/browser/resources/options/options.js
index 89ac8c2..fca1a26 100644
--- a/chrome/browser/resources/options/options.js
+++ b/chrome/browser/resources/options/options.js
@@ -228,6 +228,7 @@
                                 CertificateManager.getInstance());
   }
 
+  cr.ui.FocusManager.disableMouseFocusOnButtons();
   OptionsFocusManager.getInstance().initialize();
   Preferences.getInstance().initialize();
   OptionsPage.initialize();
diff --git a/chrome/browser/resources/options/pref_ui.js b/chrome/browser/resources/options/pref_ui.js
index 1970800..0775306 100644
--- a/chrome/browser/resources/options/pref_ui.js
+++ b/chrome/browser/resources/options/pref_ui.js
@@ -478,7 +478,7 @@
     decorate: function() {
       var self = this;
       self.type = 'text';
-      self.dataType = 'text';
+      self.dataType = 'number';
       PrefTextField.prototype.decorate.call(this);
       self.oninput = function() {
         // Note that using <input type="number"> is insufficient to restrict
diff --git a/chrome/browser/resources/options/reset_profile_settings_overlay.css b/chrome/browser/resources/options/reset_profile_settings_overlay.css
index b78ade2..9fa3b8e 100644
--- a/chrome/browser/resources/options/reset_profile_settings_overlay.css
+++ b/chrome/browser/resources/options/reset_profile_settings_overlay.css
@@ -3,7 +3,7 @@
  * found in the LICENSE file. */
 
 #reset-profile-settings-overlay {
-  min-width: 500px;
+  width: 500px;
 }
 
 #reset-profile-settings-throbber {
diff --git a/chrome/browser/resources/options/reset_profile_settings_overlay.html b/chrome/browser/resources/options/reset_profile_settings_overlay.html
index 138ffb8..f0150c6 100644
--- a/chrome/browser/resources/options/reset_profile_settings_overlay.html
+++ b/chrome/browser/resources/options/reset_profile_settings_overlay.html
@@ -1,7 +1,9 @@
 <div id="reset-profile-settings-overlay" class="page" hidden>
   <div class="close-button"></div>
   <h1 i18n-content="resetProfileSettingsOverlay"></h1>
-  <div id="reset-profile-settings-content-area" class="content-area"></div>
+  <div id="reset-profile-settings-content-area" class="content-area">
+    <span i18n-content="resetProfileSettingsExplanation"></span>
+  </div>
   <div class="action-area">
     <div class="hbox stretch">
       <a target="_blank" i18n-content="learnMore"
diff --git a/chrome/browser/resources/options/reset_profile_settings_overlay.js b/chrome/browser/resources/options/reset_profile_settings_overlay.js
index 5cd675f..8216643 100644
--- a/chrome/browser/resources/options/reset_profile_settings_overlay.js
+++ b/chrome/browser/resources/options/reset_profile_settings_overlay.js
@@ -37,6 +37,11 @@
         chrome.send('performResetProfileSettings');
       };
     },
+
+    /** @override */
+    didShowPage: function() {
+      chrome.send('onShowResetProfileDialog');
+    },
   };
 
   /**
diff --git a/chrome/browser/resources/policy.css b/chrome/browser/resources/policy.css
index cdf701d..37ffa55 100644
--- a/chrome/browser/resources/policy.css
+++ b/chrome/browser/resources/policy.css
@@ -22,6 +22,10 @@
   max-width: none;
 }
 
+html[dir='rtl'] body.uber-frame header {
+  right: 23px;
+}
+
 body.uber-frame section {
   max-width: none;
 }
@@ -118,6 +122,10 @@
   display: none;
 }
 
+#main-section {
+  -webkit-padding-start: 0;
+}
+
 section.policy-table-section {
   padding-bottom: 10px;
 }
diff --git a/chrome/browser/resources/policy.html b/chrome/browser/resources/policy.html
index fff1829..3718f4d 100644
--- a/chrome/browser/resources/policy.html
+++ b/chrome/browser/resources/policy.html
@@ -2,6 +2,7 @@
 <html i18n-values="dir:textdirection">
 <head>
 <meta charset="utf-8">
+<meta name="viewport" content="width=device-width, user-scalable=no">
 <title i18n-content="title"></title>
 
 <link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
@@ -79,22 +80,22 @@
     <table>
       <tbody id="policy-template">
         <tr>
-          <td>
+          <td class="scope-column">
             <div class="scope elide"></div>
           </td>
-          <td>
+          <td class="level-column">
             <div class="level elide"></div>
           </td>
-          <td>
+          <td class="name-column">
             <div class="name elide"></div>
           </td>
-          <td>
+          <td class="value-column">
             <div class="value-container">
               <span class="value"></span>
               <button class="toggle-expanded-value link-button"></button>
             </div>
           </td>
-          <td class="status-container">
+          <td class="status-column">
             <div class="status elide"></div>
           </td>
         </tr>
diff --git a/chrome/browser/resources/policy.js b/chrome/browser/resources/policy.js
index 0e1f87d..5f38e21 100644
--- a/chrome/browser/resources/policy.js
+++ b/chrome/browser/resources/policy.js
@@ -1,8 +1,18 @@
 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-
 cr.define('policy', function() {
+
+  /**
+   * A hack to check if we are displaying the mobile version of this page by
+   * checking if the first column is hidden.
+   * @return {boolean} True if this is the mobile version.
+   */
+  var isMobilePage = function() {
+    return document.defaultView.getComputedStyle(document.querySelector(
+        '.scope-column')).display == 'none';
+  }
+
   /**
    * A box that shows the status of cloud policy for a device or user.
    * @constructor
@@ -126,6 +136,16 @@
         status = loadTimeData.getString('ok');
       }
       this.querySelector('.status').textContent = status;
+
+      if (isMobilePage()) {
+        // The number of columns which are hidden by the css file for the mobile
+        // (Android) version of this page.
+        /** @const */ var HIDDEN_COLUMNS_IN_MOBILE_VERSION = 2;
+
+        var expandedValue = this.querySelector('.expanded-value');
+        expandedValue.setAttribute('colspan',
+            expandedValue.colSpan - HIDDEN_COLUMNS_IN_MOBILE_VERSION);
+      }
     },
 
     /**
@@ -479,11 +499,12 @@
       var newTable = window.document.createElement('table');
       var tableHead = window.document.createElement('thead');
       var tableRow = window.document.createElement('tr');
-      var tableHeadings = ['headerScope', 'headerLevel',
-                           'headerName', 'headerValue', 'headerStatus'];
+      var tableHeadings = ['Scope', 'Level', 'Name', 'Value', 'Status'];
       for (var i = 0; i < tableHeadings.length; i++) {
         var tableHeader = window.document.createElement('th');
-        tableHeader.textContent = loadTimeData.getString(tableHeadings[i]);
+        tableHeader.classList.add(tableHeadings[i].toLowerCase() + '-column');
+        tableHeader.textContent = loadTimeData.getString('header' +
+                                                         tableHeadings[i]);
         tableRow.appendChild(tableHeader);
       }
       tableHead.appendChild(tableRow);
diff --git a/chrome/browser/resources/policy_android.css b/chrome/browser/resources/policy_android.css
new file mode 100644
index 0000000..6bf8a0d
--- /dev/null
+++ b/chrome/browser/resources/policy_android.css
@@ -0,0 +1,197 @@
+/* Copyright 2013 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+body.uber-frame {
+  -webkit-margin-start: 0;
+}
+
+body.uber-frame > .page {
+  -webkit-margin-end: 0;
+  -webkit-padding-end: 10px;
+  -webkit-padding-start: 10px;
+  min-width: 0;
+}
+
+#filter-overlay {
+  padding-bottom: 0;
+  position: fixed;
+  z-index: 4;
+}
+
+body.uber-frame header {
+  left: 0;
+  max-width: none;
+  min-width: 0;
+}
+
+body.uber-frame header > h1 {
+  margin-left: 10px;
+}
+
+body.uber-frame section {
+  -webkit-padding-start: 0;
+  max-width: none;
+}
+
+body.uber-frame section > h3 {
+  -webkit-margin-start: 0;
+}
+
+#status-box-container {
+  display: -webkit-flex;
+}
+
+fieldset {
+  border: 1px solid rgb(217, 217, 217);
+  display: inline;
+  margin: 0;
+  padding: 7px;
+}
+
+fieldset + fieldset {
+  -webkit-margin-start: 20px;
+}
+
+div.status-entry {
+  display: -webkit-flex;
+  margin-bottom: .8em;
+}
+
+div.status-entry:last-child {
+  margin-bottom: 0;
+}
+
+div.label {
+  -webkit-margin-end: 1em;
+  white-space: nowrap;
+}
+
+#show-unset-container {
+  float: right;
+  text-align: right;
+}
+
+html[dir='rtl'] #show-unset-container {
+  float: left;
+  text-align: left;
+}
+
+div.reload-policies-button {
+  float: left;
+}
+
+html[dir='rtl'] div.reload-policies-button {
+  float: right;
+}
+
+div.show-unset-checkbox {
+  float: right;
+}
+
+html[dir='rtl'] div.show-unset-checkbox {
+  float: left;
+}
+
+section.reload-show-unset-section {
+  padding-bottom: 30px;
+  padding-top: 15px;
+}
+
+section.status-box-section {
+  clear: both;
+}
+
+div.table-description {
+  color: rgb(100, 100, 100);
+}
+
+div.no-policies-set {
+  clear: both;
+  color: rgb(180, 180, 180);
+  font-size: 125%;
+  margin-bottom: 10px;
+  margin-top: 20px;
+  text-align: center;
+}
+
+table {
+  border-collapse: collapse;
+  margin-bottom: 5px;
+  margin-top: 17px;
+  table-layout: fixed;
+  width: 100%;
+  word-wrap: break-word;
+}
+
+section.empty > table {
+  display: none;
+}
+
+section:not(.empty) > div.no-policies-set {
+  display: none;
+}
+
+body.uber-frame * section.policy-table-section {
+  padding-bottom: 10px;
+}
+
+th,
+td {
+  border: 1px solid rgb(217, 217, 217);
+  padding: 4px;
+}
+
+th {
+  background-color: rgb(240, 240, 240);
+  font-weight: normal;
+}
+
+.scope-column {
+  display: none;
+}
+
+.level-column {
+  display: none;
+}
+
+.name-column {
+  width: 45%;
+}
+
+div.name {
+  word-wrap: break-word;
+}
+
+.status-column {
+  width: 15%;
+}
+
+div.elide,
+span.value {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+button.toggle-expanded-value {
+  padding: 0;
+}
+
+tbody.has-overflowed-value span.value {
+  display: none;
+}
+
+tbody:not(.has-overflowed-value) button.toggle-expanded-value {
+  display: none;
+}
+
+tbody:not(.has-overflowed-value) > tr.expanded-value-container,
+tbody:not(.show-overflowed-value) > tr.expanded-value-container {
+  display: none;
+}
+
+td.expanded-value {
+  white-space: pre;
+  word-wrap: break-word;
+}
diff --git a/chrome/browser/resources/print_preview/settings/page_settings.html b/chrome/browser/resources/print_preview/settings/page_settings.html
index d371f4a..cd98c2f 100644
--- a/chrome/browser/resources/print_preview/settings/page_settings.html
+++ b/chrome/browser/resources/print_preview/settings/page_settings.html
@@ -6,19 +6,17 @@
       <span i18n-content="optionAllPages"></span>
     </label></div>
     <div class="radio">
-      <label class="page-settings-print-pages-div">
-        <input class="page-settings-custom-radio"
-               name="pages"
-               type="radio"
+      <label class="page-settings-print-pages-div"
+             for="page-settings-custom-input">
+        <input class="page-settings-custom-radio" name="pages" type="radio"
                i18n-values="aria-label:printPagesLabel;">
         <div class="page-settings-custom-input-wrapper">
-          <input class="page-settings-custom-input"
-                 type="text"
+          <input class="page-settings-custom-input" type="text"
+                 id="page-settings-custom-input"
                  i18n-values="placeholder:examplePageRangeText">
         </div>
       </label>
-      <span class="page-settings-custom-hint hint suggestion"
-            aria-hidden="true"
+      <span class="page-settings-custom-hint hint suggestion" aria-hidden="true"
             aria-live="polite"></span>
     </div>
   </div>
diff --git a/chrome/browser/resources/print_preview/settings/page_settings.js b/chrome/browser/resources/print_preview/settings/page_settings.js
index 449f5bb..bdd3b0c 100644
--- a/chrome/browser/resources/print_preview/settings/page_settings.js
+++ b/chrome/browser/resources/print_preview/settings/page_settings.js
@@ -97,6 +97,8 @@
       this.tracker.add(
           this.customInput_, 'blur', this.onCustomInputBlur_.bind(this));
       this.tracker.add(
+          this.customInput_, 'focus', this.onCustomInputFocus_.bind(this));
+      this.tracker.add(
           this.customInput_, 'keyup', this.onCustomInputKeyUp_.bind(this));
       this.tracker.add(
           this.pageRangeTicketItem_,
@@ -158,7 +160,6 @@
      */
     onCustomRadioClick_: function() {
       this.customInput_.focus();
-      this.pageRangeTicketItem_.updateValue(this.customInput_.value);
     },
 
     /**
@@ -169,11 +170,19 @@
     onCustomInputBlur_: function() {
       if (this.customInput_.value == '') {
         this.allRadio_.checked = true;
-        this.customRadio_.checked = false;
       }
     },
 
     /**
+     * Called when the custom input is focused.
+     * @private
+     */
+    onCustomInputFocus_: function() {
+      this.customRadio_.checked = true;
+      this.pageRangeTicketItem_.updateValue(this.customInput_.value);
+    },
+
+    /**
      * Called when a key is pressed on the custom input.
      * @param {Event} event Contains the key that was pressed.
      * @private
@@ -185,7 +194,6 @@
       if (event.keyIdentifier == 'Enter') {
         this.pageRangeTicketItem_.updateValue(this.customInput_.value);
       } else {
-        this.allRadio_.checked = false;
         this.customRadio_.checked = true;
         this.customInputTimeout_ = setTimeout(
             this.onCustomInputTimeout_.bind(this),
@@ -217,11 +225,9 @@
             this.customInput_.value = pageRangeStr;
           }
           this.customRadio_.checked = true;
-          this.allRadio_.checked = false;
           this.setInvalidStateVisible_(!this.pageRangeTicketItem_.isValid());
         } else {
           this.allRadio_.checked = true;
-          this.customRadio_.checked = false;
           this.setInvalidStateVisible_(false);
         }
         fadeInOption(this.getElement());
diff --git a/chrome/browser/resources/sync_file_system_internals/file_metadata.js b/chrome/browser/resources/sync_file_system_internals/file_metadata.js
index efc2196..afcc459 100644
--- a/chrome/browser/resources/sync_file_system_internals/file_metadata.js
+++ b/chrome/browser/resources/sync_file_system_internals/file_metadata.js
@@ -81,8 +81,8 @@
   // Only draw the header if it hasn't been drawn yet
   if (header.children.length === 0) {
     var tr = document.createElement('tr');
-    tr.appendChild(createElementFromText('td', 'Status'));
     tr.appendChild(createElementFromText('td', 'Type'));
+    tr.appendChild(createElementFromText('td', 'Status'));
     tr.appendChild(createElementFromText('td', 'Title'));
     tr.appendChild(createElementFromText('td', 'Details'));
     header.appendChild(tr);
@@ -94,27 +94,53 @@
   for (var i = 0; i < fileMetadataMap.length; i++) {
     var metadatEntry = fileMetadataMap[i];
     var tr = document.createElement('tr');
+    tr.appendChild(createFileIconCell(metadatEntry.type));
     tr.appendChild(createElementFromText('td', metadatEntry.status));
-    tr.appendChild(createElementFromText('td', metadatEntry.type));
     tr.appendChild(createElementFromText('td', metadatEntry.title));
-    tr.appendChild(createElementFromText('td', metadatEntry.details));
+    tr.appendChild(createElementFromDictionary('td', metadatEntry.details));
     itemContainer.appendChild(tr);
   }
 }
 
+/**
+ * @param {string} file type string.
+ * @return {HTMLElement} TD with file or folder icon depending on type.
+ */
+function createFileIconCell(type) {
+  var td = createElementFromText('td', type);
+  td.setAttribute('class', type.toLowerCase() + '-icon');
+  return td;
+}
+
 // TODO(calvinlo): Move to helper file so it doesn't need to be duplicated.
 /**
- * Creates an element named |elementName| containing the content |text|.
+ * Creates an element with |tagName| containing the content |text|.
  * @param {string} elementName Name of the new element to be created.
  * @param {string} text Text to be contained in the new element.
  * @return {HTMLElement} The newly created HTML element.
  */
-function createElementFromText(elementName, text) {
-  var element = document.createElement(elementName);
+function createElementFromText(tagName, text) {
+  var element = document.createElement(tagName);
   element.appendChild(document.createTextNode(text));
   return element;
 }
 
+/**
+ * Creates an element with |tagName| containing the content |dict|.
+ * @param {string} elementName Name of the new element to be created.
+ * @param {Object.<string, string>} dict Dictionary to be contained in the new
+ * element.
+ * @return {HTMLElement} The newly created HTML element.
+ */
+function createElementFromDictionary(tagName, dict) {
+  var element = document.createElement(tagName);
+  for (var key in dict) {
+    element.appendChild(document.createTextNode(key + ': ' + dict[key]));
+    element.appendChild(document.createElement('br'));
+  }
+  return element;
+}
+
 function main() {
   getExtensions();
   $('refresh-metadata-button').addEventListener('click', getExtensions);
diff --git a/chrome/browser/resources/sync_file_system_internals/main.css b/chrome/browser/resources/sync_file_system_internals/main.css
index 090c730..a5a141c 100644
--- a/chrome/browser/resources/sync_file_system_internals/main.css
+++ b/chrome/browser/resources/sync_file_system_internals/main.css
@@ -20,6 +20,7 @@
   padding-left: 0.5em;
   padding-right: 0.5em;
   text-align: left;
+  vertical-align: top;
 }
 
 thead tr {
@@ -38,3 +39,17 @@
 .log-event.error {
   background: rgb(255, 220, 220);
 }
+
+.file-icon {
+  background-image: url('chrome://syncfs-internals/file.png');
+  background-position: 0 2px;
+  background-repeat: no-repeat;
+  padding-left: 18px;
+}
+
+.folder-icon {
+  background-image: url('chrome://syncfs-internals/folder_closed.png');
+  background-position: 0 2px;
+  background-repeat: no-repeat;
+  padding-left: 18px;
+}
diff --git a/chrome/browser/resources/sync_file_system_internals/sync_service.js b/chrome/browser/resources/sync_file_system_internals/sync_service.js
index 6a8e732..4a208eb 100644
--- a/chrome/browser/resources/sync_file_system_internals/sync_service.js
+++ b/chrome/browser/resources/sync_file_system_internals/sync_service.js
@@ -57,16 +57,19 @@
   return element;
 }
 
+// Keeps track of the last log event seen so it's not reprinted.
+var lastLogEventId = -1;
+
 /**
  * Request debug log.
  */
 function getLog() {
-  chrome.send('getLog');
+  chrome.send('getLog', [lastLogEventId]);
 }
 
 /**
  * Handles callback from getUpdateLog.
- * @param {Array} list List of dictionaries containing 'time' and 'logEvent'.
+ * @param {Array} list List of dictionaries containing 'id', 'time', 'logEvent'.
  */
 SyncService.onGetLog = function(logEntries) {
   var itemContainer = $('log-entries');
@@ -79,6 +82,8 @@
     tr.appendChild(createElementFromText('td', logEntry.logEvent,
                                          {class: 'log-event' + error}));
     itemContainer.appendChild(tr);
+
+    lastLogEventId = logEntry.id;
   }
 }
 
diff --git a/chrome/browser/resources/sync_file_system_internals_resources.grd b/chrome/browser/resources/sync_file_system_internals_resources.grd
index a49596f..a01fdc6 100644
--- a/chrome/browser/resources/sync_file_system_internals_resources.grd
+++ b/chrome/browser/resources/sync_file_system_internals_resources.grd
@@ -14,6 +14,6 @@
       <include name="IDR_SYNC_FILE_SYSTEM_INTERNALS_FILE_METADATA_JS" file="sync_file_system_internals/file_metadata.js" type="BINDATA" />
       <include name="IDR_SYNC_FILE_SYSTEM_INTERNALS_MAIN_HTML" file="sync_file_system_internals/main.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_SYNC_FILE_SYSTEM_INTERNALS_SYNC_SERVICE_JS" file="sync_file_system_internals/sync_service.js" type="BINDATA" />
-      </includes>
+    </includes>
   </release>
 </grit>
diff --git a/chrome/browser/resources/sync_setup_overlay.css b/chrome/browser/resources/sync_setup_overlay.css
index 805c7f5..4430bb6 100644
--- a/chrome/browser/resources/sync_setup_overlay.css
+++ b/chrome/browser/resources/sync_setup_overlay.css
@@ -105,7 +105,6 @@
   margin: 0;
 }
 
-#passphrase-encryption-message,
 #encryption-section-message {
   color: gray;
   margin-bottom: 5px;
diff --git a/chrome/browser/resources/sync_setup_overlay.html b/chrome/browser/resources/sync_setup_overlay.html
index f0bdfd3..246ff77 100644
--- a/chrome/browser/resources/sync_setup_overlay.html
+++ b/chrome/browser/resources/sync_setup_overlay.html
@@ -109,30 +109,6 @@
             <div id="error-text" i18n-content="syncZeroDataTypesError"
                 class="sync-configuration-error reset-hidden" hidden></div>
           </div>
-          <div id="customize-sync-encryption">
-            <hr>
-            <h4 i18n-content="encryptedDataTypesTitle"></h4>
-            <div class="sync-customize-section-container">
-              <div id="passphrase-encryption-message"
-                  i18n-content="passphraseEncryptionMessage"></div>
-              <div class="radio">
-                <label>
-                  <input id="encrypt-sensitive-option" name="encrypt"
-                      type="radio" value="sensitive">
-                  <span i18n-content="encryptSensitiveOption"></span>
-                </label>
-              </div>
-              <div class="radio">
-                <label>
-                  <input id="encrypt-all-option" name="encrypt" type="radio"
-                      value="all">
-                  <span i18n-content="encryptAllOption"></span>
-                </label>
-              </div>
-            </div>
-            <hr>
-            <h4 i18n-content="passphraseSectionTitle"></h4>
-          </div>
           <div id="customize-sync-encryption-new">
             <hr>
             <h4 i18n-content="encryptionSectionTitle"></h4>
@@ -160,24 +136,6 @@
           </div>
           <div id="sync-custom-passphrase-container"
               class="sync-customize-section-container">
-            <div id="sync-custom-passphrase-options">
-              <div class="radio">
-                <label>
-                  <input id="google-option" name="option" type="radio"
-                      value="google">
-                  <span i18n-content="googleOption"></span>
-                </label>
-              </div>
-              <div class="radio">
-                <label>
-                  <input id="explicit-option" name="option" type="radio"
-                      value="explicit">
-                  <span i18n-content="explicitOption"></span>
-                </label>
-                <a i18n-values="href:encryptionHelpURL" target="_blank"
-                    i18n-content="learnMore"></a>
-              </div>
-            </div>
             <div id="sync-custom-passphrase"
                 class="reset-hidden" hidden>
               <div id="sync-passphrase-message">
diff --git a/chrome/browser/resources/sync_setup_overlay.js b/chrome/browser/resources/sync_setup_overlay.js
index ed234f3..ef4f619 100644
--- a/chrome/browser/resources/sync_setup_overlay.js
+++ b/chrome/browser/resources/sync_setup_overlay.js
@@ -11,12 +11,6 @@
   // True if the synced account uses 'encrypt everything'.
   var useEncryptEverything_ = false;
 
-  // True if the support for keystore encryption is enabled. Controls whether
-  // the new unified encryption UI is displayed instead of the old encryption
-  // ui (where passphrase and encrypted types could be set independently of
-  // each other).
-  var keystoreEncryptionEnabled_ = false;
-
   // An object used as a cache of the arguments passed in while initially
   // displaying the advanced sync settings dialog. Used to switch between the
   // options in the main drop-down menu. Reset when the dialog is closed.
@@ -66,9 +60,6 @@
       OptionsPage.prototype.initializePage.call(this);
 
       var self = this;
-      $('google-option').onchange = $('explicit-option').onchange = function() {
-        self.onPassphraseRadioChanged_();
-      };
       $('basic-encryption-option').onchange =
           $('full-encryption-option').onchange = function() {
         self.onEncryptionRadioChanged_();
@@ -114,38 +105,6 @@
       chrome.send('SyncSetupDidClosePage');
     },
 
-    getEncryptionRadioCheckedValue_: function() {
-      var f = $('choose-data-types-form');
-      for (var i = 0; i < f.encrypt.length; ++i) {
-        if (f.encrypt[i].checked)
-          return f.encrypt[i].value;
-      }
-
-      return undefined;
-    },
-
-    getPassphraseRadioCheckedValue_: function() {
-      var f = $('choose-data-types-form');
-      for (var i = 0; i < f.option.length; ++i) {
-        if (f.option[i].checked) {
-          return f.option[i].value;
-        }
-      }
-
-      return undefined;
-    },
-
-    disableEncryptionRadioGroup_: function() {
-      var f = $('choose-data-types-form');
-      for (var i = 0; i < f.encrypt.length; ++i)
-        f.encrypt[i].disabled = true;
-    },
-
-    onPassphraseRadioChanged_: function() {
-      var visible = this.getPassphraseRadioCheckedValue_() == 'explicit';
-      $('sync-custom-passphrase').hidden = !visible;
-    },
-
     onEncryptionRadioChanged_: function() {
       var visible = $('full-encryption-option').checked;
       $('sync-custom-passphrase').hidden = !visible;
@@ -229,10 +188,8 @@
       mismatchError.hidden = true;
 
       var f = $('choose-data-types-form');
-      if ((this.getPassphraseRadioCheckedValue_() != 'explicit' ||
-           $('google-option').disabled) &&
-          (!$('full-encryption-option').checked ||
-           $('basic-encryption-option').disabled)) {
+      if (!$('full-encryption-option').checked ||
+           $('basic-encryption-option').disabled) {
         return true;
       }
 
@@ -262,12 +219,7 @@
         return;
       }
 
-      var encryptAllData = this.getEncryptionRadioCheckedValue_() == 'all';
-      if (!encryptAllData &&
-          $('full-encryption-option').checked &&
-          this.keystoreEncryptionEnabled_) {
-        encryptAllData = true;
-      }
+      var encryptAllData = $('full-encryption-option').checked;
 
       var usePassphrase;
       var customPassphrase;
@@ -284,10 +236,8 @@
         // the passphrase and finish configuration. If the user has enabled
         // encrypted datatypes, the PSS will prompt again specifying that the
         // passphrase failed.
-      } else if ((!$('google-option').disabled &&
-                  this.getPassphraseRadioCheckedValue_() == 'explicit') ||
-                 (!$('basic-encryption-option').disabled &&
-                  $('full-encryption-option').checked)) {
+      } else if (!$('basic-encryption-option').disabled &&
+                  $('full-encryption-option').checked) {
         // The user is setting a custom passphrase for the first time.
         if (!this.checkPassphraseMatch_())
           return;
@@ -464,13 +414,6 @@
     },
 
     setEncryptionRadios_: function(args) {
-      if (args.encryptAllData) {
-        $('encrypt-all-option').checked = true;
-        this.disableEncryptionRadioGroup_();
-      } else {
-        $('encrypt-sensitive-option').checked = true;
-      }
-
       if (!args.encryptAllData && !args.usePassphrase) {
         $('basic-encryption-option').checked = true;
       } else {
@@ -480,23 +423,9 @@
       }
     },
 
-    setPassphraseRadios_: function(args) {
-      if (args.usePassphrase) {
-        $('explicit-option').checked = true;
-
-        // The passphrase, once set, cannot be unset, but we show a reset link.
-        $('explicit-option').disabled = true;
-        $('google-option').disabled = true;
-        $('sync-custom-passphrase').hidden = true;
-      } else {
-        $('google-option').checked = true;
-      }
-    },
-
     setCheckboxesAndErrors_: function(args) {
       this.setChooseDataTypesCheckboxes_(args);
       this.setEncryptionRadios_(args);
-      this.setPassphraseRadios_(args);
     },
 
     showConfigure_: function(args) {
@@ -512,7 +441,7 @@
       // between its drop-down menu items as follows:
       // "Sync everything": Show encryption and passphrase sections, and disable
       // and check all data type checkboxes.
-      // "Sync everything": Hide encryption and passphrase sections, and disable
+      // "Sync nothing": Hide encryption and passphrase sections, and disable
       // and uncheck all data type checkboxes.
       // "Choose what to sync": Show encryption and passphrase sections, enable
       // data type checkboxes, and restore their checked state to the last time
@@ -547,7 +476,6 @@
         // Determine whether to display the 'OK, sync everything' confirmation
         // dialog or the advanced sync settings dialog.
         this.usePassphrase_ = args.usePassphrase;
-        this.keystoreEncryptionEnabled_ = args.keystoreEncryptionEnabled;
         if (args.showSyncEverythingPage == false || this.usePassphrase_ ||
             args.syncAllDataTypes == false || args.showPassphrase) {
           var index = args.syncAllDataTypes ?
@@ -580,17 +508,8 @@
       // The default state is to sync everything.
       this.setDataTypeCheckboxes_(DataTypeSelection.SYNC_EVERYTHING);
 
-      // Encrypt passwords is the default, but don't set it if the previously
-      // synced account is already set to encrypt everything.
-      if (!this.useEncryptEverything_)
-        $('encrypt-sensitive-option').checked = true;
-
-      // If the account is not synced with a custom passphrase, reset the
-      // passphrase radio when switching to the 'Sync everything' page.
-      if (!this.usePassphrase_) {
-        $('google-option').checked = true;
+      if (!this.usePassphrase_)
         $('sync-custom-passphrase').hidden = true;
-      }
 
       if (!this.useEncryptEverything_ && !this.usePassphrase_)
         $('basic-encryption-option').checked = true;
@@ -613,7 +532,6 @@
       this.setDataTypeCheckboxesEnabled_(false);
 
       // Hide the encryption section.
-      $('customize-sync-encryption').hidden = true;
       $('customize-sync-encryption-new').hidden = true;
       $('sync-custom-passphrase-container').hidden = true;
       $('sync-existing-passphrase-container').hidden = true;
@@ -672,17 +590,9 @@
       $('customize-sync-preferences').hidden = false;
 
       $('sync-custom-passphrase-container').hidden = false;
-
-      if (this.keystoreEncryptionEnabled_) {
-        $('customize-sync-encryption').hidden = true;
-        $('sync-custom-passphrase-options').hidden = true;
-        $('sync-new-encryption-section-container').hidden = false;
-        $('customize-sync-encryption-new').hidden = false;
-      } else {
-        $('customize-sync-encryption').hidden = false;
-        $('sync-custom-passphrase-options').hidden = false;
-        $('customize-sync-encryption-new').hidden = true;
-      }
+      $('sync-custom-passphrase').hidden = true;
+      $('sync-new-encryption-section-container').hidden = false;
+      $('customize-sync-encryption-new').hidden = false;
 
       $('sync-existing-passphrase-container').hidden = true;
 
@@ -812,14 +722,6 @@
     },
 
     /**
-     * Steps into the appropriate Sync Setup error UI.
-     * @private
-     */
-    showErrorUI_: function() {
-      chrome.send('SyncSetupShowErrorUI');
-    },
-
-    /**
      * Determines the appropriate page to show in the Sync Setup UI based on
      * the state of the Sync backend. Does nothing if the user is not signed in.
      * @private
@@ -851,10 +753,6 @@
     SyncSetupOverlay.getInstance().closeOverlay_();
   };
 
-  SyncSetupOverlay.showErrorUI = function() {
-    SyncSetupOverlay.getInstance().showErrorUI_();
-  };
-
   SyncSetupOverlay.showSetupUI = function() {
     SyncSetupOverlay.getInstance().showSetupUI_();
   };
diff --git a/chrome/browser/resources/translate_internals/prefs.html b/chrome/browser/resources/translate_internals/prefs.html
index e04030d..f39b242 100644
--- a/chrome/browser/resources/translate_internals/prefs.html
+++ b/chrome/browser/resources/translate_internals/prefs.html
@@ -25,6 +25,12 @@
     <p id="prefs-supported-languages-last-updated">Last updated: <span></span></p>
     <ul id="prefs-supported-languages-languages"></ul>
   </section>
+<if expr="not pp_ifdef('ios')">
+  <section id="prefs-cld-version">
+    <h2>CLD Version</h2>
+    <p i18n-content="cld-version"></p>
+  </section>
+</if>
 </div>
 <div>
   <section id="prefs-dump">
diff --git a/chrome/browser/resources/uber/uber.html b/chrome/browser/resources/uber/uber.html
index c863984..0750dfc 100644
--- a/chrome/browser/resources/uber/uber.html
+++ b/chrome/browser/resources/uber/uber.html
@@ -10,6 +10,7 @@
 <link rel="stylesheet" href="uber.css">
 
 <script src="chrome://resources/js/cr.js"></script>
+<script src="chrome://resources/js/cr/ui/focus_manager.js"></script>
 <script src="chrome://resources/js/load_time_data.js"></script>
 <script src="chrome://resources/js/util.js"></script>
 
diff --git a/chrome/browser/resources/uber/uber_frame.html b/chrome/browser/resources/uber/uber_frame.html
index d9362b2..21ce88e 100644
--- a/chrome/browser/resources/uber/uber_frame.html
+++ b/chrome/browser/resources/uber/uber_frame.html
@@ -7,6 +7,7 @@
 <link rel="stylesheet" href="uber_frame.css">
 
 <script src="chrome://resources/js/cr.js"></script>
+<script src="chrome://resources/js/cr/ui/focus_manager.js"></script>
 <script src="chrome://resources/js/load_time_data.js"></script>
 <script src="chrome://uber-frame/uber_frame.js"></script>
 </head>
diff --git a/chrome/browser/resources/uber/uber_frame.js b/chrome/browser/resources/uber/uber_frame.js
index cd0fbc3..8c5bb3b 100644
--- a/chrome/browser/resources/uber/uber_frame.js
+++ b/chrome/browser/resources/uber/uber_frame.js
@@ -26,6 +26,7 @@
     uber.invokeMethodOnParent('navigationControlsLoaded');
 
     document.documentElement.addEventListener('mousewheel', onMouseWheel);
+    cr.ui.FocusManager.disableMouseFocusOnButtons();
   }
 
   /**
diff --git a/chrome/browser/resources/webstore_app/OWNERS b/chrome/browser/resources/webstore_app/OWNERS
index d693d64..ed96b84 100644
--- a/chrome/browser/resources/webstore_app/OWNERS
+++ b/chrome/browser/resources/webstore_app/OWNERS
@@ -1,7 +1,6 @@
 # Extensions / Apps team members.
 asargent@chromium.org
 bolms@chromium.org
-erikkay@chromium.org
 finnur@chromium.org
 jstritar@chromium.org
 miket@chromium.org
diff --git a/chrome/browser/rlz/rlz.cc b/chrome/browser/rlz/rlz.cc
index fc4e7ba..adc4160 100644
--- a/chrome/browser/rlz/rlz.cc
+++ b/chrome/browser/rlz/rlz.cc
@@ -18,13 +18,13 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
@@ -278,10 +278,6 @@
     // the user performs a first search.
     registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
                    content::NotificationService::AllSources());
-    // If instant is enabled we'll start searching as soon as the user starts
-    // typing in the omnibox (which triggers INSTANT_CONTROLLER_UPDATED).
-    registrar_.Add(this, chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED,
-                   content::NotificationService::AllSources());
 
     // Register for notifications from navigations, to see if the user has used
     // the home page.
@@ -386,12 +382,9 @@
                          const content::NotificationDetails& details) {
   switch (type) {
     case chrome::NOTIFICATION_OMNIBOX_OPENED_URL:
-    case chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED:
       RecordFirstSearch(CHROME_OMNIBOX);
       registrar_.Remove(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
                         content::NotificationService::AllSources());
-      registrar_.Remove(this, chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED,
-                        content::NotificationService::AllSources());
       break;
     case content::NOTIFICATION_NAV_ENTRY_PENDING: {
       const NavigationEntry* entry =
diff --git a/chrome/browser/rlz/rlz_unittest.cc b/chrome/browser/rlz/rlz_unittest.cc
index 9bdf98b..50ae360 100644
--- a/chrome/browser/rlz/rlz_unittest.cc
+++ b/chrome/browser/rlz/rlz_unittest.cc
@@ -11,10 +11,10 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/omnibox/omnibox_log.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/env_vars.h"
 #include "chrome/installer/util/browser_distribution.h"
 #include "chrome/installer/util/google_update_constants.h"
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
index 3a696b5..432aea5 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -180,12 +180,6 @@
   typedef SafeBrowsingUIManager::UnsafeResource UnsafeResource;
 
   virtual void SetUp() {
-    // Set custom profile object so that we can mock calls to IsOffTheRecord.
-    // This needs to happen before we call the parent SetUp() function.  We use
-    // a nice mock because other parts of the code are calling IsOffTheRecord.
-    mock_profile_ = new NiceMock<MockTestingProfile>();
-    browser_context_.reset(mock_profile_);
-
     ChromeRenderViewHostTestHarness::SetUp();
 
     // Inject service classes.
@@ -221,6 +215,14 @@
     ChromeRenderViewHostTestHarness::TearDown();
   }
 
+  virtual content::BrowserContext* CreateBrowserContext() OVERRIDE {
+    // Set custom profile object so that we can mock calls to IsOffTheRecord.
+    // This needs to happen before we call the parent SetUp() function.  We use
+    // a nice mock because other parts of the code are calling IsOffTheRecord.
+    mock_profile_ = new NiceMock<MockTestingProfile>();
+    return mock_profile_;
+  }
+
   void OnPhishingDetectionDone(const std::string& verdict_str) {
     csd_host_->OnPhishingDetectionDone(verdict_str);
   }
diff --git a/chrome/browser/safe_browsing/database_manager.cc b/chrome/browser/safe_browsing/database_manager.cc
index f3e7dec..47b238d 100644
--- a/chrome/browser/safe_browsing/database_manager.cc
+++ b/chrome/browser/safe_browsing/database_manager.cc
@@ -17,6 +17,7 @@
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/metrics/metrics_service.h"
 #include "chrome/browser/prerender/prerender_field_trial.h"
 #include "chrome/browser/safe_browsing/client_side_detection_service.h"
@@ -27,7 +28,6 @@
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/safe_browsing/ui_manager.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/startup_metric_utils.h"
diff --git a/chrome/browser/safe_browsing/download_feedback.cc b/chrome/browser/safe_browsing/download_feedback.cc
index 6748d2d..b23a313 100644
--- a/chrome/browser/safe_browsing/download_feedback.cc
+++ b/chrome/browser/safe_browsing/download_feedback.cc
@@ -108,10 +108,10 @@
     uploader_.reset();
   }
 
-  base::FileUtilProxy::Delete(file_task_runner_.get(),
-                              file_path_,
-                              false,
-                              base::FileUtilProxy::StatusCallback());
+  base::FileUtilProxy::DeleteFile(file_task_runner_.get(),
+                                  file_path_,
+                                  false,
+                                  base::FileUtilProxy::StatusCallback());
 }
 
 void DownloadFeedbackImpl::Start(const base::Closure& finish_callback) {
diff --git a/chrome/browser/safe_browsing/download_feedback_service.cc b/chrome/browser/safe_browsing/download_feedback_service.cc
index 8c189aa..5465ef6 100644
--- a/chrome/browser/safe_browsing/download_feedback_service.cc
+++ b/chrome/browser/safe_browsing/download_feedback_service.cc
@@ -177,10 +177,10 @@
   if (service) {
     service->BeginFeedback(ping_request, ping_response, path);
   } else {
-    base::FileUtilProxy::Delete(file_task_runner.get(),
-                                path,
-                                false,
-                                base::FileUtilProxy::StatusCallback());
+    base::FileUtilProxy::DeleteFile(file_task_runner.get(),
+                                    path,
+                                    false,
+                                    base::FileUtilProxy::StatusCallback());
   }
 }
 
diff --git a/chrome/browser/safe_browsing/download_feedback_service_unittest.cc b/chrome/browser/safe_browsing/download_feedback_service_unittest.cc
index a912a3f..167e622 100644
--- a/chrome/browser/safe_browsing/download_feedback_service_unittest.cc
+++ b/chrome/browser/safe_browsing/download_feedback_service_unittest.cc
@@ -229,7 +229,7 @@
 
   // File should still exist since our FakeDownloadFeedback does not delete it.
   base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(file_util::PathExists(file_path));
+  EXPECT_TRUE(base::PathExists(file_path));
 }
 
 TEST_F(DownloadFeedbackServiceTest, MultiplePendingFeedbackComplete) {
@@ -296,9 +296,9 @@
   base::RunLoop().RunUntilIdle();
   // These files should still exist since the FakeDownloadFeedback does not
   // delete them.
-  EXPECT_TRUE(file_util::PathExists(file_path[0]));
-  EXPECT_TRUE(file_util::PathExists(file_path[1]));
-  EXPECT_TRUE(file_util::PathExists(file_path[2]));
+  EXPECT_TRUE(base::PathExists(file_path[0]));
+  EXPECT_TRUE(base::PathExists(file_path[1]));
+  EXPECT_TRUE(base::PathExists(file_path[2]));
 }
 
 TEST_F(DownloadFeedbackServiceTest, MultiFeedbackWithIncomplete) {
@@ -361,17 +361,17 @@
   EXPECT_EQ(2U, num_feedbacks());
 
   // File should still exist since the FileUtilProxy task hasn't run yet.
-  EXPECT_TRUE(file_util::PathExists(file_path[2]));
+  EXPECT_TRUE(base::PathExists(file_path[2]));
 
   base::RunLoop().RunUntilIdle();
   // File should be deleted since the AcquireFileCallback ran after the service
   // was deleted.
-  EXPECT_FALSE(file_util::PathExists(file_path[2]));
+  EXPECT_FALSE(base::PathExists(file_path[2]));
 
   // These files should still exist since the FakeDownloadFeedback does not
   // delete them.
-  EXPECT_TRUE(file_util::PathExists(file_path[0]));
-  EXPECT_TRUE(file_util::PathExists(file_path[1]));
+  EXPECT_TRUE(base::PathExists(file_path[0]));
+  EXPECT_TRUE(base::PathExists(file_path[1]));
 }
 
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_feedback_unittest.cc b/chrome/browser/safe_browsing/download_feedback_unittest.cc
index 0054a69..3edc8bd 100644
--- a/chrome/browser/safe_browsing/download_feedback_unittest.cc
+++ b/chrome/browser/safe_browsing/download_feedback_unittest.cc
@@ -192,14 +192,14 @@
             uploader()->metadata_);
   EXPECT_EQ(kTestFeedbackURL, uploader()->base_url_.spec());
 
-  EXPECT_TRUE(file_util::PathExists(upload_file_path_));
+  EXPECT_TRUE(base::PathExists(upload_file_path_));
 
   EXPECT_FALSE(feedback_finish_called_);
   uploader()->finish_callback_.Run(
       TwoPhaseUploader::STATE_SUCCESS, net::OK, 0, "");
   EXPECT_TRUE(feedback_finish_called_);
   base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(file_util::PathExists(upload_file_path_));
+  EXPECT_FALSE(base::PathExists(upload_file_path_));
 }
 
 TEST_F(DownloadFeedbackTest, CancelUpload) {
@@ -230,13 +230,13 @@
   ASSERT_TRUE(uploader());
   EXPECT_FALSE(feedback_finish_called_);
   EXPECT_TRUE(uploader()->start_called_);
-  EXPECT_TRUE(file_util::PathExists(upload_file_path_));
+  EXPECT_TRUE(base::PathExists(upload_file_path_));
 
   delete feedback;
   EXPECT_FALSE(feedback_finish_called_);
 
   base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(file_util::PathExists(upload_file_path_));
+  EXPECT_FALSE(base::PathExists(upload_file_path_));
 }
 
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
index 1862107..b8dae7b 100644
--- a/chrome/browser/safe_browsing/download_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
@@ -18,6 +18,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "base/path_service.h"
+#include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/safe_browsing/database_manager.h"
@@ -26,8 +27,9 @@
 #include "chrome/browser/safe_browsing/signature_util.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/safe_browsing/csd.pb.h"
+#include "content/public/browser/render_process_host.h"
 #include "content/public/test/mock_download_item.h"
-#include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "net/cert/x509_certificate.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "net/url_request/url_fetcher_delegate.h"
@@ -47,6 +49,7 @@
 using ::testing::SaveArg;
 using ::testing::StrictMock;
 using ::testing::_;
+using base::MessageLoop;
 using content::BrowserThread;
 namespace safe_browsing {
 namespace {
@@ -148,22 +151,23 @@
 
 class DownloadProtectionServiceTest : public testing::Test {
  protected:
+  DownloadProtectionServiceTest()
+      : test_browser_thread_bundle_(
+            content::TestBrowserThreadBundle::IO_MAINLOOP) {
+  }
   virtual void SetUp() {
+    content::RenderProcessHost::SetRunRendererInProcess(true);
     CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kSbEnableDownloadFeedback);
-    ui_thread_.reset(new content::TestBrowserThread(BrowserThread::UI,
-                                                    &msg_loop_));
     // Start real threads for the IO and File threads so that the DCHECKs
     // to test that we're on the correct thread work.
-    io_thread_.reset(new content::TestBrowserThread(BrowserThread::IO));
-    ASSERT_TRUE(io_thread_->Start());
     sb_service_ = new StrictMock<FakeSafeBrowsingService>();
     sb_service_->Initialize();
     signature_util_ = new StrictMock<MockSignatureUtil>();
     download_service_ = sb_service_->download_protection_service();
     download_service_->signature_util_ = signature_util_;
     download_service_->SetEnabled(true);
-    msg_loop_.RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
     has_result_ = false;
 
     base::FilePath source_path;
@@ -182,8 +186,7 @@
     // tasks currently running.
     FlushThreadMessageLoops();
     sb_service_ = NULL;
-    io_thread_.reset();
-    ui_thread_.reset();
+    content::RenderProcessHost::SetRunRendererInProcess(false);
   }
 
   bool RequestContainsResource(const ClientDownloadRequest& request,
@@ -219,7 +222,7 @@
   void FlushThreadMessageLoops() {
     BrowserThread::GetBlockingPool()->FlushForTesting();
     FlushMessageLoop(BrowserThread::IO);
-    msg_loop_.RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 
   // Proxy for private method.
@@ -277,7 +280,7 @@
         FROM_HERE,
         base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask,
                    base::Unretained(this), thread));
-    msg_loop_.Run();
+    MessageLoop::current()->Run();
   }
 
  public:
@@ -285,7 +288,7 @@
       DownloadProtectionService::DownloadCheckResult result) {
     result_ = result;
     has_result_ = true;
-    msg_loop_.Quit();
+    MessageLoop::current()->Quit();
   }
 
   void SyncCheckDoneCallback(
@@ -313,11 +316,9 @@
   scoped_refptr<FakeSafeBrowsingService> sb_service_;
   scoped_refptr<MockSignatureUtil> signature_util_;
   DownloadProtectionService* download_service_;
-  base::MessageLoop msg_loop_;
   DownloadProtectionService::DownloadCheckResult result_;
   bool has_result_;
-  scoped_ptr<content::TestBrowserThread> io_thread_;
-  scoped_ptr<content::TestBrowserThread> ui_thread_;
+  content::TestBrowserThreadBundle test_browser_thread_bundle_;
   base::FilePath testdata_path_;
 };
 
@@ -338,7 +339,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
   Mock::VerifyAndClearExpectations(&item);
 
@@ -353,7 +354,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
 }
 
@@ -384,7 +385,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
 
   // Check that the referrer is matched against the whitelist.
@@ -394,7 +395,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
 }
 
@@ -432,7 +433,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
 }
 
@@ -474,7 +475,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
 
   // Invalid response should be safe too.
@@ -488,7 +489,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
   std::string feedback_ping;
   std::string feedback_response;
@@ -506,7 +507,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
       item, &feedback_ping, &feedback_response));
 #if defined(OS_WIN)
@@ -526,7 +527,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
 #if defined(OS_WIN)
   EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON));
   EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
@@ -551,7 +552,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
 #if defined(OS_WIN)
   EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST));
   EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
@@ -599,7 +600,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
 #if defined(OS_WIN)
   EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
 #else
@@ -653,7 +654,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
   Mock::VerifyAndClearExpectations(sb_service_.get());
   Mock::VerifyAndClearExpectations(signature_util_.get());
@@ -672,7 +673,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
   Mock::VerifyAndClearExpectations(signature_util_.get());
 
@@ -688,7 +689,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
 #if defined(OS_WIN)
   EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
 #else
@@ -728,7 +729,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
   Mock::VerifyAndClearExpectations(sb_service_.get());
   Mock::VerifyAndClearExpectations(signature_util_.get());
@@ -776,7 +777,7 @@
       &item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
 }
 
@@ -816,7 +817,7 @@
 
 #if !defined(OS_WIN)
   // SendRequest is not called.  Wait for FinishRequest to call our callback.
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
   EXPECT_EQ(NULL, fetcher);
 #else
@@ -851,7 +852,7 @@
       FROM_HERE,
       base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
                  base::Unretained(this), fetcher));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
 #endif
 }
 
@@ -892,7 +893,7 @@
 
 #if !defined(OS_WIN)
   // SendRequest is not called.  Wait for FinishRequest to call our callback.
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
   EXPECT_EQ(NULL, fetcher);
 #else
@@ -922,7 +923,7 @@
       FROM_HERE,
       base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
                  base::Unretained(this), fetcher));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
 #endif
 }
 
@@ -948,7 +949,7 @@
       item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
   Mock::VerifyAndClearExpectations(sb_service_.get());
 
@@ -960,7 +961,7 @@
       item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
   Mock::VerifyAndClearExpectations(sb_service_.get());
 
@@ -973,7 +974,7 @@
       item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
   Mock::VerifyAndClearExpectations(sb_service_.get());
 
@@ -987,7 +988,7 @@
       item,
       base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
                  base::Unretained(this)));
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
 }
 
@@ -1026,7 +1027,7 @@
 
   // The request should time out because the HTTP request hasn't returned
   // anything yet.
-  msg_loop_.Run();
+  MessageLoop::current()->Run();
   EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
 }
 
diff --git a/chrome/browser/safe_browsing/malware_details_history.cc b/chrome/browser/safe_browsing/malware_details_history.cc
index 498d7fe..6c0910f 100644
--- a/chrome/browser/safe_browsing/malware_details_history.cc
+++ b/chrome/browser/safe_browsing/malware_details_history.cc
@@ -8,10 +8,10 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/malware_details.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.cc b/chrome/browser/safe_browsing/safe_browsing_database.cc
index ce2483c..dd1802f 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_database.cc
@@ -1486,7 +1486,7 @@
   // TODO(shess): Track failure to delete?
   base::FilePath bloom_filter_filename =
       BloomFilterForFilename(browse_filename_);
-  base::Delete(bloom_filter_filename, false);
+  base::DeleteFile(bloom_filter_filename, false);
 
   const base::TimeTicks before = base::TimeTicks::Now();
   browse_prefix_set_.reset(safe_browsing::PrefixSet::LoadFile(
@@ -1522,24 +1522,24 @@
 
   base::FilePath bloom_filter_filename =
       BloomFilterForFilename(browse_filename_);
-  const bool r5 = base::Delete(bloom_filter_filename, false);
+  const bool r5 = base::DeleteFile(bloom_filter_filename, false);
   if (!r5)
     RecordFailure(FAILURE_DATABASE_FILTER_DELETE);
 
-  const bool r6 = base::Delete(browse_prefix_set_filename_, false);
+  const bool r6 = base::DeleteFile(browse_prefix_set_filename_, false);
   if (!r6)
     RecordFailure(FAILURE_BROWSE_PREFIX_SET_DELETE);
 
-  const bool r7 = base::Delete(extension_blacklist_filename_, false);
+  const bool r7 = base::DeleteFile(extension_blacklist_filename_, false);
   if (!r7)
     RecordFailure(FAILURE_EXTENSION_BLACKLIST_DELETE);
 
-  const bool r8 = base::Delete(side_effect_free_whitelist_filename_,
+  const bool r8 = base::DeleteFile(side_effect_free_whitelist_filename_,
                                     false);
   if (!r8)
     RecordFailure(FAILURE_SIDE_EFFECT_FREE_WHITELIST_DELETE);
 
-  const bool r9 = base::Delete(
+  const bool r9 = base::DeleteFile(
       side_effect_free_whitelist_prefix_set_filename_,
       false);
   if (!r9)
diff --git a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
index 3b61ce7..315d684 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
@@ -1126,7 +1126,7 @@
     database_->UpdateFinished(true);
 
     // Database file still exists until the corruption handler has run.
-    EXPECT_TRUE(file_util::PathExists(database_filename_));
+    EXPECT_TRUE(base::PathExists(database_filename_));
 
     // Flush through the corruption-handler task.
     VLOG(1) << "Expect failed check on: SafeBrowsing database reset";
@@ -1134,13 +1134,13 @@
   }
 
   // Database file should not exist.
-  EXPECT_FALSE(file_util::PathExists(database_filename_));
+  EXPECT_FALSE(base::PathExists(database_filename_));
 
   // Run the update again successfully.
   EXPECT_TRUE(database_->UpdateStarted(&lists));
   database_->InsertChunks(safe_browsing_util::kMalwareList, chunks);
   database_->UpdateFinished(true);
-  EXPECT_TRUE(file_util::PathExists(database_filename_));
+  EXPECT_TRUE(base::PathExists(database_filename_));
 
   database_.reset();
 }
@@ -1647,7 +1647,7 @@
 
   // After re-creating the database, it should have a filter read from
   // a file, so it should find the same results.
-  ASSERT_TRUE(file_util::PathExists(filter_file));
+  ASSERT_TRUE(base::PathExists(filter_file));
   database_.reset(new SafeBrowsingDatabaseNew);
   database_->Init(database_filename_);
   EXPECT_TRUE(database_->ContainsBrowseUrl(
@@ -1658,8 +1658,8 @@
       &matching_list, &prefix_hits, &full_hashes, now));
 
   // If there is no filter file, the database cannot find malware urls.
-  base::Delete(filter_file, false);
-  ASSERT_FALSE(file_util::PathExists(filter_file));
+  base::DeleteFile(filter_file, false);
+  ASSERT_FALSE(base::PathExists(filter_file));
   database_.reset(new SafeBrowsingDatabaseNew);
   database_->Init(database_filename_);
   EXPECT_FALSE(database_->ContainsBrowseUrl(
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index d522b47..5ae4201 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -18,6 +18,7 @@
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/metrics/metrics_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -30,7 +31,6 @@
 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
 #include "chrome/browser/safe_browsing/ui_manager.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
index 17522f6..20543d5 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -19,6 +19,7 @@
 #include "base/test/thread_test_helper.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prerender/prerender_manager.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -31,7 +32,6 @@
 #include "chrome/browser/safe_browsing/ui_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -895,7 +895,7 @@
   virtual bool SetUpUserDataDirectory() OVERRIDE {
     base::FilePath cookie_path(
         SafeBrowsingService::GetCookieFilePathForTesting());
-    EXPECT_FALSE(file_util::PathExists(cookie_path));
+    EXPECT_FALSE(base::PathExists(cookie_path));
 
     base::FilePath test_dir;
     if (!PathService::Get(chrome::DIR_TEST_DATA, &test_dir)) {
@@ -908,7 +908,7 @@
     // expires in 2038.
     base::FilePath initial_cookies = test_dir.AppendASCII("safe_browsing")
         .AppendASCII("Safe Browsing Cookies");
-    if (!file_util::CopyFile(initial_cookies, cookie_path)) {
+    if (!base::CopyFile(initial_cookies, cookie_path)) {
       EXPECT_TRUE(false);
       return false;
     }
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file.cc b/chrome/browser/safe_browsing/safe_browsing_store_file.cc
index 234716c..628907c 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_file.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store_file.cc
@@ -179,14 +179,14 @@
     const base::FilePath& current_filename) {
   const base::FilePath original_filename(
       current_filename.DirName().AppendASCII("Safe Browsing"));
-  if (file_util::PathExists(original_filename)) {
+  if (base::PathExists(original_filename)) {
     int64 size = 0;
     if (file_util::GetFileSize(original_filename, &size)) {
       UMA_HISTOGRAM_COUNTS("SB2.OldDatabaseKilobytes",
                            static_cast<int>(size / 1024));
     }
 
-    if (base::Delete(original_filename, false)) {
+    if (base::DeleteFile(original_filename, false)) {
       RecordFormatEvent(FORMAT_EVENT_DELETED_ORIGINAL);
     } else {
       RecordFormatEvent(FORMAT_EVENT_DELETED_ORIGINAL_FAILED);
@@ -196,7 +196,7 @@
     // the weeds.
     const base::FilePath journal_filename(
         current_filename.DirName().AppendASCII("Safe Browsing-journal"));
-    base::Delete(journal_filename, false);
+    base::DeleteFile(journal_filename, false);
   }
 }
 
@@ -406,7 +406,7 @@
   if (empty_) {
     // If the file exists but cannot be opened, try to delete it (not
     // deleting directly, the bloom filter needs to be deleted, too).
-    if (file_util::PathExists(filename_))
+    if (base::PathExists(filename_))
       return OnCorruptDatabase();
 
     new_file_.swap(new_file);
@@ -654,8 +654,8 @@
 
   // Close the file handle and swizzle the file into place.
   new_file_.reset();
-  if (!base::Delete(filename_, false) &&
-      file_util::PathExists(filename_))
+  if (!base::DeleteFile(filename_, false) &&
+      base::PathExists(filename_))
     return false;
 
   const base::FilePath new_filename = TemporaryFileForFilename(filename_);
@@ -735,15 +735,15 @@
 
 // static
 bool SafeBrowsingStoreFile::DeleteStore(const base::FilePath& basename) {
-  if (!base::Delete(basename, false) &&
-      file_util::PathExists(basename)) {
+  if (!base::DeleteFile(basename, false) &&
+      base::PathExists(basename)) {
     NOTREACHED();
     return false;
   }
 
   const base::FilePath new_filename = TemporaryFileForFilename(basename);
-  if (!base::Delete(new_filename, false) &&
-      file_util::PathExists(new_filename)) {
+  if (!base::DeleteFile(new_filename, false) &&
+      base::PathExists(new_filename)) {
     NOTREACHED();
     return false;
   }
@@ -753,8 +753,8 @@
   // also removed.
   const base::FilePath journal_filename(
       basename.value() + FILE_PATH_LITERAL("-journal"));
-  if (file_util::PathExists(journal_filename))
-    base::Delete(journal_filename, false);
+  if (base::PathExists(journal_filename))
+    base::DeleteFile(journal_filename, false);
 
   return true;
 }
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
index 89eec6f..3470736 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
@@ -57,24 +57,24 @@
   const base::FilePath temp_file =
       SafeBrowsingStoreFile::TemporaryFileForFilename(filename_);
 
-  EXPECT_FALSE(file_util::PathExists(filename_));
-  EXPECT_FALSE(file_util::PathExists(temp_file));
+  EXPECT_FALSE(base::PathExists(filename_));
+  EXPECT_FALSE(base::PathExists(temp_file));
 
   // Starting a transaction creates a temporary file.
   EXPECT_TRUE(store_->BeginUpdate());
-  EXPECT_TRUE(file_util::PathExists(temp_file));
+  EXPECT_TRUE(base::PathExists(temp_file));
 
   // Pull the rug out from under the existing store, simulating a
   // crash.
   store_.reset(new SafeBrowsingStoreFile());
   store_->Init(filename_, base::Closure());
-  EXPECT_FALSE(file_util::PathExists(filename_));
-  EXPECT_TRUE(file_util::PathExists(temp_file));
+  EXPECT_FALSE(base::PathExists(filename_));
+  EXPECT_TRUE(base::PathExists(temp_file));
 
   // Make sure the temporary file is deleted.
   EXPECT_TRUE(store_->Delete());
-  EXPECT_FALSE(file_util::PathExists(filename_));
-  EXPECT_FALSE(file_util::PathExists(temp_file));
+  EXPECT_FALSE(base::PathExists(filename_));
+  EXPECT_FALSE(base::PathExists(temp_file));
 }
 
 // Test basic corruption-handling.
@@ -133,7 +133,7 @@
 
 TEST_F(SafeBrowsingStoreFileTest, CheckValidity) {
   // Empty store is valid.
-  EXPECT_FALSE(file_util::PathExists(filename_));
+  EXPECT_FALSE(base::PathExists(filename_));
   ASSERT_TRUE(store_->BeginUpdate());
   EXPECT_FALSE(corruption_detected_);
   EXPECT_TRUE(store_->CheckValidity());
@@ -141,9 +141,9 @@
   EXPECT_TRUE(store_->CancelUpdate());
 
   // A store with some data is valid.
-  EXPECT_FALSE(file_util::PathExists(filename_));
+  EXPECT_FALSE(base::PathExists(filename_));
   SafeBrowsingStoreTestStorePrefix(store_.get());
-  EXPECT_TRUE(file_util::PathExists(filename_));
+  EXPECT_TRUE(base::PathExists(filename_));
   ASSERT_TRUE(store_->BeginUpdate());
   EXPECT_FALSE(corruption_detected_);
   EXPECT_TRUE(store_->CheckValidity());
@@ -154,7 +154,7 @@
 // Corrupt the payload.
 TEST_F(SafeBrowsingStoreFileTest, CheckValidityPayload) {
   SafeBrowsingStoreTestStorePrefix(store_.get());
-  EXPECT_TRUE(file_util::PathExists(filename_));
+  EXPECT_TRUE(base::PathExists(filename_));
 
   // 37 is the most random prime number.  It's also past the header,
   // as corrupting the header would fail BeginUpdate() in which case
@@ -176,7 +176,7 @@
 // Corrupt the checksum.
 TEST_F(SafeBrowsingStoreFileTest, CheckValidityChecksum) {
   SafeBrowsingStoreTestStorePrefix(store_.get());
-  EXPECT_TRUE(file_util::PathExists(filename_));
+  EXPECT_TRUE(base::PathExists(filename_));
 
   // An offset from the end of the file which is in the checksum.
   const int kOffset = -static_cast<int>(sizeof(base::MD5Digest));
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.cc b/chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.cc
index acb34b2..48f5e80 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.cc
@@ -320,7 +320,7 @@
 void SafeBrowsingStoreTestDelete(SafeBrowsingStore* store,
                                  const base::FilePath& filename) {
   // Delete should work if the file wasn't there in the first place.
-  EXPECT_FALSE(file_util::PathExists(filename));
+  EXPECT_FALSE(base::PathExists(filename));
   EXPECT_TRUE(store->Delete());
 
   // Create a store file.
@@ -345,7 +345,7 @@
                                   &add_prefixes_result,
                                   &add_full_hashes_result));
 
-  EXPECT_TRUE(file_util::PathExists(filename));
+  EXPECT_TRUE(base::PathExists(filename));
   EXPECT_TRUE(store->Delete());
-  EXPECT_FALSE(file_util::PathExists(filename));
+  EXPECT_FALSE(base::PathExists(filename));
 }
diff --git a/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc b/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc
index b6cb350..0d10195 100644
--- a/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_tab_observer.cc
@@ -6,8 +6,8 @@
 
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/render_messages.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_test.cc b/chrome/browser/safe_browsing/safe_browsing_test.cc
index fe2e14e..5d0d488 100644
--- a/chrome/browser/safe_browsing/safe_browsing_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_test.cc
@@ -31,13 +31,13 @@
 #include "base/threading/thread.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/database_manager.h"
 #include "chrome/browser/safe_browsing/local_safebrowsing_test_server.h"
 #include "chrome/browser/safe_browsing/protocol_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/safe_browsing/sandboxed_zip_analyzer.cc b/chrome/browser/safe_browsing/sandboxed_zip_analyzer.cc
index 6e97585..5d3c512 100644
--- a/chrome/browser/safe_browsing/sandboxed_zip_analyzer.cc
+++ b/chrome/browser/safe_browsing/sandboxed_zip_analyzer.cc
@@ -14,7 +14,7 @@
 #include "chrome/common/safe_browsing/zip_analyzer.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_data.h"
-#include "content/public/browser/resource_dispatcher_host.h"
+#include "content/public/browser/render_process_host.h"
 #include "content/public/common/content_switches.h"
 #include "ipc/ipc_message_macros.h"
 #include "ipc/ipc_platform_file.h"
@@ -65,29 +65,11 @@
     return;
   }
 
-  // TODO(asargent) we shouldn't need to do this branch here - instead
-  // UtilityProcessHost should handle it for us. (http://crbug.com/19192)
-  bool use_utility_process = content::ResourceDispatcherHost::Get() &&
-      !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess);
-  if (use_utility_process) {
-    BrowserThread::PostTask(
-        BrowserThread::IO, FROM_HERE,
-        base::Bind(
-            &SandboxedZipAnalyzer::StartProcessOnIOThread, this));
-    // The file will be closed on the IO thread once it has been handed
-    // off to the child process.
-  } else {
-    zip_analyzer::Results results;
-    zip_analyzer::AnalyzeZipFile(zip_platform_file_, &results);
-    base::ClosePlatformFile(zip_platform_file_);
-    if (!BrowserThread::PostTask(
-            BrowserThread::IO, FROM_HERE,
-            base::Bind(
-                &SandboxedZipAnalyzer::OnAnalyzeZipFileFinished, this,
-                results))) {
-      NOTREACHED();
-    }
-  }
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::Bind(&SandboxedZipAnalyzer::StartProcessOnIOThread, this));
+  // The file will be closed on the IO thread once it has been handed
+  // off to the child process.
 }
 
 bool SandboxedZipAnalyzer::OnMessageReceived(const IPC::Message& message) {
@@ -126,14 +108,19 @@
 
 void SandboxedZipAnalyzer::OnUtilityProcessStarted() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  if (utility_process_host_->GetData().handle == base::kNullProcessHandle) {
+  base::ProcessHandle utility_process =
+      content::RenderProcessHost::run_renderer_in_process() ?
+          base::GetCurrentProcessHandle() :
+          utility_process_host_->GetData().handle;
+
+  if (utility_process == base::kNullProcessHandle) {
     DLOG(ERROR) << "Child process handle is null";
   }
   utility_process_host_->Send(
       new ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection(
           IPC::GetFileHandleForProcess(
               zip_platform_file_,
-              utility_process_host_->GetData().handle,
+              utility_process,
               true /* close_source_handle */)));
 }
 
diff --git a/chrome/browser/search/iframe_source_unittest.cc b/chrome/browser/search/iframe_source_unittest.cc
index ceb80f4..d4a5484 100644
--- a/chrome/browser/search/iframe_source_unittest.cc
+++ b/chrome/browser/search/iframe_source_unittest.cc
@@ -183,17 +183,15 @@
 }
 
 TEST_F(IframeSourceTest, SendResource) {
-  SendResource(IDR_OMNIBOX_RESULT_LOADER_HTML);
+  SendResource(IDR_MOST_VISITED_TITLE_HTML);
   EXPECT_FALSE(response_string().empty());
 }
 
 TEST_F(IframeSourceTest, SendJSWithOrigin) {
-  SendJSWithOrigin(IDR_OMNIBOX_RESULT_LOADER_JS, kInstantRendererPID, 0);
+  SendJSWithOrigin(IDR_MOST_VISITED_TITLE_JS, kInstantRendererPID, 0);
   EXPECT_FALSE(response_string().empty());
-  EXPECT_NE(std::string::npos, response_string().find(kInstantOrigin));
-  SendJSWithOrigin(IDR_OMNIBOX_RESULT_LOADER_JS, kNonInstantRendererPID, 0);
+  SendJSWithOrigin(IDR_MOST_VISITED_TITLE_JS, kNonInstantRendererPID, 0);
   EXPECT_FALSE(response_string().empty());
-  EXPECT_NE(std::string::npos, response_string().find(kNonInstantOrigin));
-  SendJSWithOrigin(IDR_OMNIBOX_RESULT_LOADER_JS, kInvalidRendererPID, 0);
+  SendJSWithOrigin(IDR_MOST_VISITED_TITLE_JS, kInvalidRendererPID, 0);
   EXPECT_TRUE(response_string().empty());
 }
diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc
index 7718bc1..b1c842d 100644
--- a/chrome/browser/search/instant_service.cc
+++ b/chrome/browser/search/instant_service.cc
@@ -8,6 +8,7 @@
 
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/profiles/profile.h"
@@ -17,14 +18,12 @@
 #include "chrome/browser/search/local_ntp_source.h"
 #include "chrome/browser/search/most_visited_iframe_source.h"
 #include "chrome/browser/search/search.h"
-#include "chrome/browser/search/suggestion_iframe_source.h"
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/ui/webui/favicon_source.h"
 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h"
 #include "chrome/browser/ui/webui/theme_source.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
@@ -39,6 +38,22 @@
 
 using content::BrowserThread;
 
+namespace {
+
+const int kSectionBorderAlphaTransparency = 80;
+
+// Converts SkColor to RGBAColor
+RGBAColor SkColorToRGBAColor(const SkColor& sKColor) {
+  RGBAColor color;
+  color.r = SkColorGetR(sKColor);
+  color.g = SkColorGetG(sKColor);
+  color.b = SkColorGetB(sKColor);
+  color.a = SkColorGetA(sKColor);
+  return color;
+}
+
+}  // namespace
+
 InstantService::InstantService(Profile* profile)
     : profile_(profile),
       weak_ptr_factory_(this) {
@@ -79,7 +94,6 @@
   content::URLDataSource::Add(profile, new FaviconSource(
       profile, FaviconSource::FAVICON));
   content::URLDataSource::Add(profile, new LocalNtpSource());
-  content::URLDataSource::Add(profile, new SuggestionIframeSource());
   content::URLDataSource::Add(profile, new MostVisitedIframeSource());
 }
 
@@ -233,16 +247,51 @@
   // Get theme information from theme service.
   theme_info_.reset(new ThemeBackgroundInfo());
 
-  // Set theme background color.
+  // Get if the current theme is the default theme.
+  theme_info_->using_default_theme = theme_service->UsingDefaultTheme();
+
+  // Get theme colors.
   SkColor background_color =
       theme_service->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND);
-  if (gfx::IsInvertedColorScheme())
-    background_color = color_utils::InvertColor(background_color);
+  SkColor text_color =
+      theme_service->GetColor(ThemeProperties::COLOR_NTP_TEXT);
+  SkColor link_color =
+      theme_service->GetColor(ThemeProperties::COLOR_NTP_LINK);
+  SkColor text_color_light =
+      theme_service->GetColor(ThemeProperties::COLOR_NTP_TEXT_LIGHT);
+  SkColor header_color =
+      theme_service->GetColor(ThemeProperties::COLOR_NTP_HEADER);
+  // Generate section border color from the header color.
+  SkColor section_border_color =
+      SkColorSetARGB(kSectionBorderAlphaTransparency,
+                     SkColorGetR(header_color),
+                     SkColorGetG(header_color),
+                     SkColorGetB(header_color));
 
-  theme_info_->color_r = SkColorGetR(background_color);
-  theme_info_->color_g = SkColorGetG(background_color);
-  theme_info_->color_b = SkColorGetB(background_color);
-  theme_info_->color_a = SkColorGetA(background_color);
+  // Invert colors if needed.
+  if (gfx::IsInvertedColorScheme()) {
+    background_color = color_utils::InvertColor(background_color);
+    text_color = color_utils::InvertColor(text_color);
+    link_color = color_utils::InvertColor(link_color);
+    text_color_light = color_utils::InvertColor(text_color_light);
+    header_color = color_utils::InvertColor(header_color);
+    section_border_color = color_utils::InvertColor(section_border_color);
+  }
+
+  // Set colors.
+  theme_info_->background_color = SkColorToRGBAColor(background_color);
+  theme_info_->text_color = SkColorToRGBAColor(text_color);
+  theme_info_->link_color = SkColorToRGBAColor(link_color);
+  theme_info_->text_color_light = SkColorToRGBAColor(text_color_light);
+  theme_info_->header_color = SkColorToRGBAColor(header_color);
+  theme_info_->section_border_color = SkColorToRGBAColor(section_border_color);
+
+  // Set logo for the theme. By default, use alternate logo.
+  theme_info_->logo_alternate = true;
+  int logo_alternate = 0;
+  if (theme_service->GetDisplayProperty(
+      ThemeProperties::NTP_LOGO_ALTERNATE, &logo_alternate))
+    theme_info_->logo_alternate = logo_alternate == 1;
 
   if (theme_service->HasCustomImage(IDR_THEME_NTP_BACKGROUND)) {
     // Set theme id for theme background image url.
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc
index 3281a64..84f6381 100644
--- a/chrome/browser/search/local_ntp_source.cc
+++ b/chrome/browser/search/local_ntp_source.cc
@@ -151,8 +151,7 @@
 }
 
 std::string LocalNtpSource::GetContentSecurityPolicyFrameSrc() const {
-  // Allow embedding of suggestion and most visited iframes.
-  return base::StringPrintf("frame-src %s %s;",
-                            chrome::kChromeSearchSuggestionUrl,
+  // Allow embedding of most visited iframes.
+  return base::StringPrintf("frame-src %s;",
                             chrome::kChromeSearchMostVisitedUrl);
 }
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc
index 30cf8be..2e62b2d 100644
--- a/chrome/browser/search/search.cc
+++ b/chrome/browser/search/search.cc
@@ -21,8 +21,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_instant_controller.h"
 #include "chrome/browser/ui/browser_iterator.h"
-#include "chrome/browser/ui/search/search_model.h"
-#include "chrome/browser/ui/search/search_tab_helper.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -58,13 +56,6 @@
 const int kStalePageTimeoutDefault = 3 * 3600;  // 3 hours.
 const int kStalePageTimeoutDisabled = 0;
 
-// Unless "allow_instant:1" is present, users cannot opt into Instant, nor will
-// the "instant" flag below have any effect.
-const char kAllowInstantSearchResultsFlagName[] = "allow_instant";
-
-// Sets the default state for the Instant checkbox.
-const char kInstantSearchResultsFlagName[] = "instant";
-
 const char kUseRemoteNTPOnStartupFlagName[] = "use_remote_ntp_on_startup";
 const char kShowNtpFlagName[] = "show_ntp";
 const char kRecentTabsOnNTPFlagName[] = "show_recent_tabs";
@@ -171,6 +162,9 @@
 
 // Returns true if |url| can be used as an Instant URL for |profile|.
 bool IsInstantURL(const GURL& url, Profile* profile) {
+  if (!IsInstantExtendedAPIEnabled())
+    return false;
+
   if (!url.is_valid())
     return false;
 
@@ -178,8 +172,7 @@
   if (!template_url)
     return false;
 
-  const bool extended_api_enabled = IsInstantExtendedAPIEnabled();
-  if (extended_api_enabled && !IsSuitableURLForInstant(url, template_url))
+  if (!IsSuitableURLForInstant(url, template_url))
     return false;
 
   const TemplateURLRef& instant_url_ref = template_url->instant_url_ref();
@@ -187,12 +180,12 @@
       TemplateURLRefToGURL(instant_url_ref, kDisableStartMargin, false);
   return instant_url.is_valid() &&
       (MatchesOriginAndPath(url, instant_url) ||
-       (extended_api_enabled && MatchesAnySearchURL(url, template_url)));
+       MatchesAnySearchURL(url, template_url));
 }
 
 string16 GetSearchTermsImpl(const content::WebContents* contents,
                             const content::NavigationEntry* entry) {
-  if (!contents || !IsQueryExtractionEnabled())
+  if (!IsQueryExtractionEnabled())
     return string16();
 
   // For security reasons, don't extract search terms if the page is not being
@@ -291,15 +284,6 @@
   if (!entry)
     return string16();
 
-  // Return immediately if the page does not support Instant.
-  const SearchTabHelper* search_tab_helper =
-      SearchTabHelper::FromWebContents(contents);
-  if (search_tab_helper) {
-    const SearchModel* search_model = search_tab_helper->model();
-    if (search_model && search_model->instant_support() == INSTANT_SUPPORT_NO)
-      return string16();
-  }
-
   return GetSearchTermsImpl(contents, entry);
 }
 
@@ -325,40 +309,11 @@
     return false;
 
   Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
-  bool is_instant_url = IsInstantURL(entry->GetVirtualURL(), profile);
-  bool is_local_ntp = entry->GetVirtualURL() == GetLocalInstantURL(profile);
-  if (!IsInstantExtendedAPIEnabled() ||
-      !IsRenderedInInstantProcess(contents, profile) ||
-      !(is_instant_url || is_local_ntp)) {
-    return false;
-  }
-
-  bool has_search_terms = !GetSearchTermsImpl(contents, entry).empty();
-  bool is_online_ntp = is_instant_url && !has_search_terms;
-  return is_online_ntp || is_local_ntp;
-}
-
-void RegisterInstantUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
-  // This default is overridden by SetInstantExtendedPrefDefault().
-  registry->RegisterBooleanPref(
-      prefs::kSearchInstantEnabled,
-      true,
-      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
-}
-
-void SetInstantExtendedPrefDefault(Profile* profile) {
-  FieldTrialFlags flags;
-  if (GetFieldTrialInfo(
-          base::FieldTrialList::FindFullName(kInstantExtendedFieldTrialName),
-          &flags, NULL)) {
-    bool pref_default = GetBoolValueForFlagWithDefault(
-        kInstantSearchResultsFlagName, true, flags);
-    if (profile && profile->GetPrefs()) {
-      profile->GetPrefs()->SetDefaultPrefValue(
-          prefs::kSearchInstantEnabled,
-          Value::CreateBooleanValue(pref_default));
-    }
-  }
+  return IsInstantExtendedAPIEnabled() &&
+         IsRenderedInInstantProcess(contents, profile) &&
+         (IsInstantURL(entry->GetVirtualURL(), profile) ||
+          entry->GetVirtualURL() == GetLocalInstantURL(profile)) &&
+         GetSearchTermsImpl(contents, entry).empty();
 }
 
 bool IsSuggestPrefEnabled(Profile* profile) {
@@ -366,91 +321,24 @@
          profile->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled);
 }
 
-bool IsInstantPrefEnabled(Profile* profile) {
-  return profile && !profile->IsOffTheRecord() && profile->GetPrefs() &&
-         profile->GetPrefs()->GetBoolean(prefs::kSearchInstantEnabled);
-}
-
-bool IsInstantCheckboxVisible() {
-  FieldTrialFlags flags;
-  if (GetFieldTrialInfo(
-          base::FieldTrialList::FindFullName(kInstantExtendedFieldTrialName),
-          &flags, NULL)) {
-    return GetBoolValueForFlagWithDefault(
-        kAllowInstantSearchResultsFlagName, false, flags);
-  }
-  return false;
-}
-
-bool IsInstantCheckboxEnabled(Profile* profile) {
-  RecordInstantExtendedOptInState();
-  return IsInstantExtendedAPIEnabled() &&
-         DefaultSearchProviderSupportsInstant(profile) &&
-         IsSuggestPrefEnabled(profile);
-}
-
-bool IsInstantCheckboxChecked(Profile* profile) {
-  // NOTE: This is a global bool, not profile-specific. So, the histogram will
-  // record the value of whichever profile happens to get here first. There's
-  // no point doing a per-profile bool, because UMA uploads don't carry
-  // profile-specific information anyway.
-  static bool recorded = false;
-  if (!recorded) {
-    recorded = true;
-    UMA_HISTOGRAM_BOOLEAN("InstantExtended.PrefValue",
-                          IsInstantPrefEnabled(profile));
-  }
-
-  return IsInstantCheckboxVisible() &&
-         IsInstantCheckboxEnabled(profile) &&
-         IsInstantPrefEnabled(profile);
-}
-
-string16 GetInstantCheckboxLabel(Profile* profile) {
-  if (!IsInstantExtendedAPIEnabled())
-    return l10n_util::GetStringUTF16(IDS_INSTANT_CHECKBOX_NO_EXTENDED_API);
-
-  if (!DefaultSearchProviderSupportsInstant(profile)) {
-    const TemplateURL* provider = GetDefaultSearchProviderTemplateURL(profile);
-    if (!provider) {
-      return l10n_util::GetStringUTF16(
-          IDS_INSTANT_CHECKBOX_NO_DEFAULT_SEARCH_PROVIDER);
-    }
-
-    if (provider->short_name().empty()) {
-      return l10n_util::GetStringUTF16(
-          IDS_INSTANT_CHECKBOX_UNKNOWN_DEFAULT_SEARCH_PROVIDER);
-    }
-
-    return l10n_util::GetStringFUTF16(
-        IDS_INSTANT_CHECKBOX_NON_INSTANT_DEFAULT_SEARCH_PROVIDER,
-        provider->short_name());
-  }
-
-  if (!IsSuggestPrefEnabled(profile))
-    return l10n_util::GetStringUTF16(IDS_INSTANT_CHECKBOX_PREDICTION_DISABLED);
-
-  DCHECK(IsInstantCheckboxEnabled(profile));
-  return l10n_util::GetStringUTF16(IDS_INSTANT_CHECKBOX_ENABLED);
-}
-
 GURL GetInstantURL(Profile* profile, int start_margin) {
-  if (!IsInstantCheckboxEnabled(profile))
-    return GURL();
-
-  // In non-extended mode, the checkbox must be checked.
-  const bool extended_api_enabled = IsInstantExtendedAPIEnabled();
-  if (!extended_api_enabled && !IsInstantCheckboxChecked(profile))
+  if (!IsInstantExtendedAPIEnabled() || !IsSuggestPrefEnabled(profile))
     return GURL();
 
   TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
+  if (!template_url)
+    return GURL();
+
   GURL instant_url =
       TemplateURLRefToGURL(template_url->instant_url_ref(), start_margin, true);
+  if (!instant_url.is_valid() ||
+      !template_url->HasSearchTermsReplacementKey(instant_url))
+    return GURL();
 
   // Extended mode requires HTTPS.  Force it unless the base URL was overridden
   // on the command line, in which case we allow HTTP (see comments on
   // IsSuitableURLForInstant()).
-  if (!extended_api_enabled || instant_url.SchemeIsSecure() ||
+  if (instant_url.SchemeIsSecure() ||
       google_util::StartsWithCommandLineGoogleBaseURL(instant_url))
     return instant_url;
   GURL::Replacements replacements;
@@ -471,10 +359,6 @@
   return GURL(chrome::kChromeSearchLocalNtpUrl);
 }
 
-bool IsInstantEnabled(Profile* profile) {
-  return GetInstantURL(profile, kDisableStartMargin).is_valid();
-}
-
 bool ShouldPreferRemoteNTPOnStartup() {
   // Check the command-line/about:flags setting first, which should have
   // precedence and allows the trial to not be reported (if it's never queried).
@@ -496,6 +380,10 @@
   return false;
 }
 
+bool ShouldPreloadInstantNTP(Profile* profile) {
+  return !GetInstantURL(profile, kDisableStartMargin).is_empty();
+}
+
 bool ShouldShowInstantNTP() {
   FieldTrialFlags flags;
   if (GetFieldTrialInfo(
@@ -656,19 +544,6 @@
   return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags);
 }
 
-bool DefaultSearchProviderSupportsInstant(Profile* profile) {
-  TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
-  if (!template_url)
-    return false;
-
-  GURL instant_url = TemplateURLRefToGURL(template_url->instant_url_ref(),
-                                          kDisableStartMargin, false);
-  // Extended mode instant requires a search terms replacement key.
-  return instant_url.is_valid() &&
-         (!IsInstantExtendedAPIEnabled() ||
-          template_url->HasSearchTermsReplacementKey(instant_url));
-}
-
 void ResetInstantExtendedOptInStateGateForTest() {
   instant_extended_opt_in_state_gate = false;
 }
diff --git a/chrome/browser/search/search.h b/chrome/browser/search/search.h
index 313f164..dfc202e 100644
--- a/chrome/browser/search/search.h
+++ b/chrome/browser/search/search.h
@@ -86,28 +86,6 @@
 bool NavEntryIsInstantNTP(const content::WebContents* contents,
                           const content::NavigationEntry* nav_entry);
 
-// Registers Instant-related user preferences. Called at startup.
-void RegisterInstantUserPrefs(user_prefs::PrefRegistrySyncable* registry);
-
-// Sets the default value of prefs::kSearchInstantEnabled based on field trials.
-void SetInstantExtendedPrefDefault(Profile* profile);
-
-// Returns whether the Instant checkbox in chrome://settings/ should be shown.
-bool IsInstantCheckboxVisible();
-
-// Returns whether the Instant checkbox in chrome://settings/ should be enabled
-// (i.e., toggleable). This returns true iff prefs::kSearchSuggestEnabled is
-// true and the default search engine has a valid Instant URL in its template.
-bool IsInstantCheckboxEnabled(Profile* profile);
-
-// Returns whether the Instant checkbox in chrome://settings/ should be checked
-// (i.e., with a tick mark). This returns true iff IsInstantCheckboxEnabled()
-// and the pref indicated by GetInstantPrefName() is set to true.
-bool IsInstantCheckboxChecked(Profile* profile);
-
-// Returns the label for the Instant checkbox in chrome://settings/.
-string16 GetInstantCheckboxLabel(Profile* profile);
-
 // Returns the Instant URL of the default search engine. Returns an empty GURL
 // if the engine doesn't have an Instant URL, or if it shouldn't be used (say
 // because it doesn't satisfy the requirements for extended mode or if Instant
@@ -124,18 +102,13 @@
 // to the JS that Google-specific New Tab Page elements should be rendered.
 GURL GetLocalInstantURL(Profile* profile);
 
-// Instant (loading a remote server page and talking to it using the searchbox
-// API) is considered enabled if there's a valid Instant URL that can be used,
-// so this simply returns whether GetInstantURL() is a valid URL.
-// NOTE: This method expands the default search engine's instant_url template,
-// so it shouldn't be called from SearchTermsData or other such code that would
-// lead to an infinite recursion.
-bool IsInstantEnabled(Profile* profile);
-
 // Returns true if 'use_remote_ntp_on_startup' flag is enabled in field trials
 // to always show the remote NTP on browser startup.
 bool ShouldPreferRemoteNTPOnStartup();
 
+// Returns true if the Instant NTP should be preloaded before it is shown.
+bool ShouldPreloadInstantNTP(Profile* profile);
+
 // Returns true if the Instant NTP should be shown and false if not.
 bool ShouldShowInstantNTP();
 
@@ -215,10 +188,6 @@
                                     bool default_value,
                                     const FieldTrialFlags& flags);
 
-// Returns whether the default search provider has a valid Instant URL in its
-// template. Exposed for testing only.
-bool DefaultSearchProviderSupportsInstant(Profile* profile);
-
 // Let tests reset the gate that prevents metrics from being sent more than
 // once.
 void ResetInstantExtendedOptInStateGateForTest();
diff --git a/chrome/browser/search/search_terms_tracker.cc b/chrome/browser/search/search_terms_tracker.cc
new file mode 100644
index 0000000..a0d9d2f
--- /dev/null
+++ b/chrome/browser/search/search_terms_tracker.cc
@@ -0,0 +1,130 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/search/search_terms_tracker.h"
+
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/browser/web_contents.h"
+
+namespace chrome {
+
+SearchTermsTracker::SearchTermsTracker() {
+  registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
+                 content::NotificationService::AllSources());
+  registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED,
+                 content::NotificationService::AllSources());
+  registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
+                 content::NotificationService::AllSources());
+}
+
+SearchTermsTracker::~SearchTermsTracker() {
+}
+
+bool SearchTermsTracker::GetSearchTerms(
+    const content::WebContents* contents,
+    base::string16* search_terms,
+    int* navigation_index) const {
+  if (contents) {
+    TabState::const_iterator it = tabs_.find(contents);
+    if (it != tabs_.end() && !it->second.search_terms.empty()) {
+      if (search_terms)
+        *search_terms = it->second.search_terms;
+      if (navigation_index)
+        *navigation_index = it->second.srp_navigation_index;
+      return true;
+    }
+  }
+  return false;
+}
+
+void SearchTermsTracker::Observe(
+    int type,
+    const content::NotificationSource& source,
+    const content::NotificationDetails& details) {
+  switch (type) {
+    case content::NOTIFICATION_NAV_ENTRY_COMMITTED:
+    case content::NOTIFICATION_NAV_ENTRY_CHANGED: {
+      content::NavigationController* controller =
+          content::Source<content::NavigationController>(source).ptr();
+      TabData search;
+      if (FindMostRecentSearch(controller, &search))
+        tabs_[controller->GetWebContents()] = search;
+      else
+        RemoveTabData(controller->GetWebContents());
+      break;
+    }
+
+    case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
+      RemoveTabData(content::Source<content::WebContents>(source).ptr());
+      break;
+    }
+
+    default:
+      NOTREACHED();
+      return;
+  }
+}
+
+bool SearchTermsTracker::FindMostRecentSearch(
+    const content::NavigationController* controller,
+    SearchTermsTracker::TabData* tab_data) {
+  Profile* profile =
+      Profile::FromBrowserContext(controller->GetBrowserContext());
+  DCHECK(profile);
+  if (!profile)
+    return false;
+
+  TemplateURL* template_url =
+      TemplateURLServiceFactory::GetForProfile(profile)->
+          GetDefaultSearchProvider();
+
+  for (int i = controller->GetCurrentEntryIndex(); i >= 0; --i) {
+    content::NavigationEntry* entry = controller->GetEntryAtIndex(i);
+    if (entry->GetPageType() == content::PAGE_TYPE_NORMAL) {
+      if (template_url->IsSearchURL(entry->GetURL())) {
+        // This entry is a search results page. Extract the terms only if this
+        // isn't the last (i.e. most recent/current) entry as we don't want to
+        // record the search terms when we're on an SRP.
+        if (i != controller->GetCurrentEntryIndex()) {
+          tab_data->srp_navigation_index = i;
+          template_url->ExtractSearchTermsFromURL(entry->GetURL(),
+                                                  &tab_data->search_terms);
+          return true;
+        }
+
+        // We've found an SRP - stop searching (even if we did not record the
+        // search terms, as anything before this entry will be unrelated).
+        break;
+      }
+    }
+
+    // Do not consider any navigations that precede a non-web-triggerable
+    // navigation as they are not related to those terms.
+    if (!content::PageTransitionIsWebTriggerable(
+            entry->GetTransitionType())) {
+      break;
+    }
+  }
+
+  return false;
+}
+
+void SearchTermsTracker::RemoveTabData(
+    const content::WebContents* contents) {
+  TabState::iterator it = tabs_.find(contents);
+  if (it != tabs_.end()) {
+    tabs_.erase(it);
+  }
+}
+
+}  // namespace chrome
diff --git a/chrome/browser/search/search_terms_tracker.h b/chrome/browser/search/search_terms_tracker.h
new file mode 100644
index 0000000..b253f99
--- /dev/null
+++ b/chrome/browser/search/search_terms_tracker.h
@@ -0,0 +1,72 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SEARCH_SEARCH_TERMS_TRACKER_H_
+#define CHROME_BROWSER_SEARCH_SEARCH_TERMS_TRACKER_H_
+
+#include <map>
+
+#include "base/strings/string16.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+
+namespace content {
+class NavigationController;
+class WebContents;
+}
+
+namespace chrome {
+
+// Observes navigation events (and WebContents destructions) to keep track of
+// search terms associated with a WebContents. Essentially, as long as there are
+// only web-triggerable navigations following a search results page, this class
+// will consider the search terms from that SRP as the "current" search terms.
+// Any other type of navigation will invalidate the search terms. The search
+// terms are being tracked so they can be displayed in the location bar for
+// related navigations that occur after a search.
+class SearchTermsTracker : public content::NotificationObserver {
+ public:
+  SearchTermsTracker();
+  virtual ~SearchTermsTracker();
+
+  // Returns the current search terms and navigation index of the corresponding
+  // search results page for the specified WebContents. This function will
+  // return true if there are valid search terms for |contents|. |search_terms|
+  // and/or |navigation_index| can be NULL if not needed.
+  bool GetSearchTerms(const content::WebContents* contents,
+                      base::string16* search_terms,
+                      int* navigation_index) const;
+
+  // content::NotificationObserver
+  virtual void Observe(int type,
+                       const content::NotificationSource& source,
+                       const content::NotificationDetails& details) OVERRIDE;
+
+ private:
+  struct TabData {
+    TabData() : srp_navigation_index(-1) {}
+    base::string16 search_terms;
+    int srp_navigation_index;
+  };
+
+  // Keeps information about the specified WebContents.
+  typedef std::map<const content::WebContents*, TabData> TabState;
+
+  // Searches for the most recent search and, if found, fills |tab_data| with
+  // information about that search and returns true.
+  bool FindMostRecentSearch(const content::NavigationController* controller,
+                            TabData* tab_data);
+
+  // Removes the TabData entry associated to the specified |contents|.
+  void RemoveTabData(const content::WebContents* contents);
+
+  content::NotificationRegistrar registrar_;
+  TabState tabs_;
+
+  DISALLOW_COPY_AND_ASSIGN(SearchTermsTracker);
+};
+
+}  // namespace chrome
+
+#endif  // CHROME_BROWSER_SEARCH_SEARCH_TERMS_TRACKER_H_
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc
index 91c6cfc..ff99325 100644
--- a/chrome/browser/search/search_unittest.cc
+++ b/chrome/browser/search/search_unittest.cc
@@ -369,7 +369,6 @@
 
   // Enable Instant. Still no Instant URL because "strk" is missing.
   EnableInstantExtendedAPIForTesting();
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchInstantEnabled, true);
   SetDefaultInstantTemplateUrl(false);
   EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin));
 
@@ -385,11 +384,6 @@
   EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"),
             GetInstantURL(profile(), kDisableStartMargin));
 
-  // Disable Instant. No difference, because suggest is still enabled.
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchInstantEnabled, false);
-  EXPECT_EQ(GURL("https://foo.com/instant?foo=foo#foo=foo&strk"),
-            GetInstantURL(profile(), kDisableStartMargin));
-
   // Disable suggest. No Instant URL.
   profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, false);
   EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin));
@@ -411,140 +405,8 @@
             GetInstantURL(profile(), 10));
 }
 
-TEST_F(SearchTest, DefaultSearchProviderSupportsInstant) {
-  // Enable Instant.
-  EnableInstantExtendedAPIForTesting();
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchInstantEnabled, true);
-  SetDefaultInstantTemplateUrl(false);
-
-  // No default search provider support yet.
-  EXPECT_FALSE(DefaultSearchProviderSupportsInstant(profile()));
-
-  // Set an Instant URL with a valid search terms replacement key.
-  SetDefaultInstantTemplateUrl(true);
-
-  // Default search provider should now support instant.
-  EXPECT_TRUE(DefaultSearchProviderSupportsInstant(profile()));
-  // Enable suggest. No difference.
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
-  EXPECT_TRUE(DefaultSearchProviderSupportsInstant(profile()));
-
-  // Disable Instant. No difference.
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchInstantEnabled, false);
-  EXPECT_TRUE(DefaultSearchProviderSupportsInstant(profile()));
-
-  // Disable suggest. No Instant URL.
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, false);
-  EXPECT_EQ(GURL(), GetInstantURL(profile(), kDisableStartMargin));
-  // Even with suggest disabled, the default search provider still supports
-  // instant.
-  EXPECT_TRUE(DefaultSearchProviderSupportsInstant(profile()));
-
-  // Set an Instant URL with no valid search terms replacement key.
-  SetDefaultInstantTemplateUrl(false);
-
-  EXPECT_FALSE(DefaultSearchProviderSupportsInstant(profile()));
-}
-
-TEST_F(SearchTest, IsInstantCheckboxEnabledExtendedEnabledWithInstant) {
-  // Enable instant extended.
-  EnableInstantExtendedAPIForTesting();
-
-  // Enable Instant.
-  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended",
-                                                     "Group1 allow_instant:1"));
-  ASSERT_TRUE(IsInstantCheckboxVisible());
-
-  // Enable suggest.
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
-
-  // Set an Instant URL with a valid search terms replacement key.
-  SetDefaultInstantTemplateUrl(true);
-
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchInstantEnabled, true);
-
-  EXPECT_TRUE(IsInstantCheckboxVisible());
-  EXPECT_TRUE(IsInstantCheckboxEnabled(profile()));
-  EXPECT_TRUE(IsInstantCheckboxChecked(profile()));
-
-  // Set an Instant URL with no valid search terms replacement key.
-  SetDefaultInstantTemplateUrl(false);
-
-  // For extended instant, the checkbox should now be disabled.
-  EXPECT_FALSE(IsInstantCheckboxEnabled(profile()));
-
-  // Disable suggest.
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, false);
-
-  EXPECT_TRUE(IsInstantCheckboxVisible());
-  EXPECT_FALSE(IsInstantCheckboxEnabled(profile()));
-  EXPECT_FALSE(IsInstantCheckboxChecked(profile()));
-
-  // Set an Instant URL with a search terms replacement key.
-  SetDefaultInstantTemplateUrl(true);
-
-  // Should still be disabled, since suggest is still off.
-  EXPECT_FALSE(IsInstantCheckboxEnabled(profile()));
-
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
-
-  // Now that suggest is back on and the instant url is good, the checkbox
-  // should be enabled and checked again.
-  EXPECT_TRUE(IsInstantCheckboxVisible());
-  EXPECT_TRUE(IsInstantCheckboxEnabled(profile()));
-  EXPECT_TRUE(IsInstantCheckboxChecked(profile()));
-}
-
-TEST_F(SearchTest, IsInstantCheckboxEnabledExtendedEnabledWithoutInstant) {
-  // Enable instant extended.
-  EnableInstantExtendedAPIForTesting();
-
-  // Leave Instant disallowed.
-  ASSERT_FALSE(IsInstantCheckboxVisible());
-
-  // Enable suggest.
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
-
-  // Set an Instant URL with a valid search terms replacement key.
-  SetDefaultInstantTemplateUrl(true);
-
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchInstantEnabled, true);
-
-  EXPECT_FALSE(IsInstantCheckboxVisible());
-  EXPECT_TRUE(IsInstantCheckboxEnabled(profile()));
-  EXPECT_FALSE(IsInstantCheckboxChecked(profile()));
-
-  // Set an Instant URL with no valid search terms replacement key.
-  SetDefaultInstantTemplateUrl(false);
-
-  // For extended instant, the checkbox should now be disabled.
-  EXPECT_FALSE(IsInstantCheckboxEnabled(profile()));
-
-  // Disable suggest.
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, false);
-
-  EXPECT_FALSE(IsInstantCheckboxVisible());
-  EXPECT_FALSE(IsInstantCheckboxEnabled(profile()));
-  EXPECT_FALSE(IsInstantCheckboxChecked(profile()));
-
-  // Set an Instant URL with a search terms replacement key.
-  SetDefaultInstantTemplateUrl(true);
-
-  // Should still be disabled, since suggest is still off.
-  EXPECT_FALSE(IsInstantCheckboxEnabled(profile()));
-
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true);
-
-  // Now that suggest is back on and the instant url is good, the checkbox
-  // should be enabled and checked again, but still invisible.
-  EXPECT_FALSE(IsInstantCheckboxVisible());
-  EXPECT_TRUE(IsInstantCheckboxEnabled(profile()));
-  EXPECT_FALSE(IsInstantCheckboxChecked(profile()));
-}
-
 TEST_F(SearchTest, CommandLineOverrides) {
   EnableInstantExtendedAPIForTesting();
-  profile()->GetPrefs()->SetBoolean(prefs::kSearchInstantEnabled, true);
 
   // GetLocalInstantURL() should default to the non-Google local NTP.
   SetSearchProvider(false);
diff --git a/chrome/browser/search/suggestion_iframe_source.cc b/chrome/browser/search/suggestion_iframe_source.cc
deleted file mode 100644
index 07b9ce6..0000000
--- a/chrome/browser/search/suggestion_iframe_source.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/search/suggestion_iframe_source.h"
-
-#include "chrome/common/url_constants.h"
-#include "grit/browser_resources.h"
-
-namespace {
-
-const char kLoaderHtmlPath[] = "/loader.html";
-const char kLoaderJSPath[] = "/loader.js";
-const char kResultHtmlPath[] = "/result.html";
-const char kResultJSPath[] = "/result.js";
-
-}  // namespace
-
-SuggestionIframeSource::SuggestionIframeSource() {
-}
-
-SuggestionIframeSource::~SuggestionIframeSource() {
-}
-
-std::string SuggestionIframeSource::GetSource() const {
-  return chrome::kChromeSearchSuggestionHost;
-}
-
-void SuggestionIframeSource::StartDataRequest(
-    const std::string& path,
-    int render_process_id,
-    int render_view_id,
-    const content::URLDataSource::GotDataCallback& callback) {
-  // path has no leading '/' and includes any query string. Since we don't
-  // expect a query string for requests to this source, just add back the '/'.
-  std::string full_path = "/" + path;
-  if (full_path == kLoaderHtmlPath) {
-    SendResource(IDR_OMNIBOX_RESULT_LOADER_HTML, callback);
-  } else if (full_path == kLoaderJSPath) {
-    SendJSWithOrigin(IDR_OMNIBOX_RESULT_LOADER_JS, render_process_id,
-                     render_view_id, callback);
-  } else if (full_path == kResultHtmlPath) {
-    SendResource(IDR_OMNIBOX_RESULT_HTML, callback);
-  } else if (full_path == kResultJSPath) {
-    SendJSWithOrigin(IDR_OMNIBOX_RESULT_JS, render_process_id, render_view_id,
-                     callback);
-  } else {
-    callback.Run(NULL);
-  }
-}
-
-bool SuggestionIframeSource::ServesPath(const std::string& path) const {
-  return path == kLoaderHtmlPath || path == kLoaderJSPath ||
-         path == kResultHtmlPath || path == kResultJSPath;
-}
diff --git a/chrome/browser/search/suggestion_iframe_source.h b/chrome/browser/search/suggestion_iframe_source.h
deleted file mode 100644
index ef25980..0000000
--- a/chrome/browser/search/suggestion_iframe_source.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_SEARCH_SUGGESTION_IFRAME_SOURCE_H_
-#define CHROME_BROWSER_SEARCH_SUGGESTION_IFRAME_SOURCE_H_
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "chrome/browser/search/iframe_source.h"
-
-// Serves HTML for displaying suggestions using iframes, e.g.
-// chrome-search://suggestion/loader.html
-class SuggestionIframeSource : public IframeSource {
- public:
-  SuggestionIframeSource();
-  virtual ~SuggestionIframeSource();
-
- protected:
-  // Overridden from IframeSource:
-  virtual std::string GetSource() const OVERRIDE;
-  virtual void StartDataRequest(
-      const std::string& path,
-      int render_process_id,
-      int render_view_id,
-      const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
-  virtual bool ServesPath(const std::string& path) const OVERRIDE;
-
-  DISALLOW_COPY_AND_ASSIGN(SuggestionIframeSource);
-};
-
-#endif  // CHROME_BROWSER_SEARCH_SUGGESTION_IFRAME_SOURCE_H_
diff --git a/chrome/browser/search_engines/prepopulated_engines.json b/chrome/browser/search_engines/prepopulated_engines.json
index 5b16823..8e30f34 100644
--- a/chrome/browser/search_engines/prepopulated_engines.json
+++ b/chrome/browser/search_engines/prepopulated_engines.json
@@ -850,6 +850,8 @@
       "search_url": "{google:baseURL}search?q={searchTerms}&{google:RLZ}{google:originalQueryForSuggestion}{google:assistedQueryStats}{google:searchFieldtrialParameter}{google:searchClient}{google:sourceId}{google:instantExtendedEnabledParameter}{google:omniboxStartMarginParameter}ie={inputEncoding}",
       "suggest_url": "{google:baseSuggestURL}search?{google:searchFieldtrialParameter}client={google:suggestClient}&q={searchTerms}&{google:cursorPosition}{google:zeroPrefixUrl}sugkey={google:suggestAPIKeyParameter}",
       "instant_url": "{google:baseURL}webhp?sourceid=chrome-instant&{google:RLZ}{google:instantEnabledParameter}{google:instantExtendedEnabledParameter}{google:ntpIsThemedParameter}{google:omniboxStartMarginParameter}ie={inputEncoding}",
+      "image_url": "{google:baseURL}searchbyimage/upload",
+      "image_url_post_params": "image_content={google:imageThumbnail},image_url={google:imageURL},sbisrc={google:imageSearchSource}",
       "alternate_urls": [
         "{google:baseURL}#q={searchTerms}",
         "{google:baseURL}search#q={searchTerms}",
diff --git a/chrome/browser/search_engines/prepopulated_engines_schema.json b/chrome/browser/search_engines/prepopulated_engines_schema.json
index b07c4e3..893e565 100644
--- a/chrome/browser/search_engines/prepopulated_engines_schema.json
+++ b/chrome/browser/search_engines/prepopulated_engines_schema.json
@@ -26,8 +26,26 @@
     { "field": "suggest_url", "type": "string", "optional": true },
     // If omitted, this engine does not support instant.
     { "field": "instant_url", "type": "string", "optional": true },
+    // If omitted, this engine does not support image search.
+    { "field": "image_url", "type": "string", "optional": true },
+    // The followings are post parameters for the corresponding search URL.
+    // If omitted, a GET request will be sent when using the corresponding
+    // search URL. Otherwise, a POST request will be sent.
+    // The string of post parameters consists of comma-separated name/value
+    // pairs, e.g.:
+    // "name1=value1,name2={template1},...".
+    // In each name/value pair, the equal sign('=') must be delimiter between
+    // name and value. In above example, the "value1" is the constant value for
+    // "name1", which is not replaceable. The {template1} is a replaceable value
+    // for name2, the actual value will be replaced with real search terms data.
+    { "field": "search_url_post_params", "type": "string", "optional": true },
+    { "field": "suggest_url_post_params", "type": "string", "optional": true },
+    { "field": "instant_url_post_params", "type": "string", "optional": true },
+    { "field": "image_url_post_params", "type": "string", "optional": true },
     // A list of URL patterns that can be used, in addition to |search_url|,
     // to extract search terms from a URL.
+    // If "search_url_post_params" is not empty, then all alternate URLs are
+    // sent using POST with using same post parameters as the search URL.
     {
       "field": "alternate_urls",
       "type": "array",
diff --git a/chrome/browser/search_engines/search_provider_install_data.cc b/chrome/browser/search_engines/search_provider_install_data.cc
index 7cf3a7e..a491db7 100644
--- a/chrome/browser/search_engines/search_provider_install_data.cc
+++ b/chrome/browser/search_engines/search_provider_install_data.cc
@@ -13,6 +13,7 @@
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequenced_task_runner_helpers.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_url_tracker.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/search_host_to_urls_map.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/util.h"
 #include "chrome/browser/webdata/web_data_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
diff --git a/chrome/browser/search_engines/search_provider_install_data_unittest.cc b/chrome/browser/search_engines/search_provider_install_data_unittest.cc
index a17e1e1..446d2fa 100644
--- a/chrome/browser/search_engines/search_provider_install_data_unittest.cc
+++ b/chrome/browser/search_engines/search_provider_install_data_unittest.cc
@@ -9,12 +9,12 @@
 #include "base/memory/ref_counted.h"
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/search_engines/search_provider_install_data.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_test_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_pref_service_syncable.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/search_engines/template_url.cc b/chrome/browser/search_engines/template_url.cc
index 1ccf6dc..ecd139b 100644
--- a/chrome/browser/search_engines/template_url.cc
+++ b/chrome/browser/search_engines/template_url.cc
@@ -13,6 +13,7 @@
 #include "base/logging.h"
 #include "base/metrics/field_trial.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -20,6 +21,7 @@
 #include "chrome/browser/search_engines/search_terms_data.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/common/chrome_version_info.h"
 #include "chrome/common/url_constants.h"
 #include "extensions/common/constants.h"
 #include "google_apis/google_api_keys.h"
@@ -83,6 +85,13 @@
 const char kGoogleUnescapedSearchTermsParameterFull[] =
     "{google:unescapedSearchTerms}";
 
+const char kGoogleImageSearchSource[] = "google:imageSearchSource";
+const char kGoogleImageSearchSourceFull[] = "{google:imageSearchSource}";
+const char kGoogleImageThumbnailParameter[] = "google:imageThumbnail";
+const char kGoogleImageThumbnailParameterFull[] = "{google:imageThumbnail}";
+const char kGoogleImageURLParameter[] = "google:imageURL";
+const char kGoogleImageURLParameterFull[] = "{google:imageURL}";
+
 // Display value for kSearchTermsParameter.
 const char kDisplaySearchTerms[] = "%s";
 
@@ -148,6 +157,27 @@
   return std::string();
 }
 
+// Returns the string to use for replacements of type
+// GOOGLE_IMAGE_SEARCH_SOURCE.
+std::string GetGoogleImageSearchSource() {
+  chrome::VersionInfo version_info;
+  if (version_info.is_valid()) {
+    std::string version(version_info.Name() + " " + version_info.Version());
+    if (version_info.IsOfficialBuild())
+      version += " (Official)";
+    version += " " + version_info.OSType();
+    std::string modifier(version_info.GetVersionStringModifier());
+    if (!modifier.empty())
+      version += " " + modifier;
+  }
+  return "unknown";
+}
+
+bool IsTemplateParameterString(const std::string& param) {
+  return (param.length() > 2) && (*(param.begin()) == kStartParameter) &&
+      (*(param.rbegin()) == kEndParameter);
+}
+
 }  // namespace
 
 
@@ -201,11 +231,44 @@
     case SEARCH:  return owner_->url();
     case SUGGEST: return owner_->suggestions_url();
     case INSTANT: return owner_->instant_url();
+    case IMAGE:   return owner_->image_url();
     case INDEXED: return owner_->GetURL(index_in_owner_);
     default:      NOTREACHED(); return std::string();  // NOLINT
   }
 }
 
+std::string TemplateURLRef::GetPostParamsString() const {
+  switch (type_) {
+    case INDEXED:
+    case SEARCH:  return owner_->search_url_post_params();
+    case SUGGEST: return owner_->suggestions_url_post_params();
+    case INSTANT: return owner_->instant_url_post_params();
+    case IMAGE:   return owner_->image_url_post_params();
+    default:      NOTREACHED(); return std::string();  // NOLINT
+  }
+}
+
+bool TemplateURLRef::UsesPOSTMethodUsingTermsData(
+    const SearchTermsData* search_terms_data) const {
+  if (search_terms_data)
+    ParseIfNecessaryUsingTermsData(*search_terms_data);
+  else
+    ParseIfNecessary();
+  return !post_params_.empty();
+}
+
+bool TemplateURLRef::EncodeFormData(const std::vector<PostParam>& post_params,
+                                    std::string* post_data) const {
+  // TODO(jnd): implement this function once we have form encoding utility in
+  // Chrome side.
+  if (!post_params.empty()) {
+    if (!post_data)
+      return false;
+    *post_data = "not implemented yet!";
+  }
+  return true;
+}
+
 bool TemplateURLRef::SupportsReplacement() const {
   UIThreadSearchTermsData search_terms_data(owner_->profile());
   return SupportsReplacementUsingTermsData(search_terms_data);
@@ -218,19 +281,23 @@
 }
 
 std::string TemplateURLRef::ReplaceSearchTerms(
-    const SearchTermsArgs& search_terms_args) const {
+    const SearchTermsArgs& search_terms_args,
+    std::string* post_data) const {
   UIThreadSearchTermsData search_terms_data(owner_->profile());
-  return ReplaceSearchTermsUsingTermsData(search_terms_args, search_terms_data);
+  return ReplaceSearchTermsUsingTermsData(search_terms_args, search_terms_data,
+                                          post_data);
 }
 
 std::string TemplateURLRef::ReplaceSearchTermsUsingTermsData(
     const SearchTermsArgs& search_terms_args,
-    const SearchTermsData& search_terms_data) const {
+    const SearchTermsData& search_terms_data,
+    std::string* post_data) const {
   ParseIfNecessaryUsingTermsData(search_terms_data);
   if (!valid_)
     return std::string();
 
-  std::string url(HandleReplacements(search_terms_args, search_terms_data));
+  std::string url(HandleReplacements(search_terms_args, search_terms_data,
+                                     post_data));
 
   // If the user specified additional query params on the command line, add
   // them.
@@ -361,8 +428,9 @@
 
   // Fill-in the replacements. We don't care about search terms in the pattern,
   // so we use the empty string.
-  GURL pattern(ReplaceSearchTermsUsingTermsData(SearchTermsArgs(string16()),
-                                                search_terms_data));
+  // Currently we assume the search term only shows in URL, not in post params.
+  GURL pattern(ReplaceSearchTermsUsingTermsData(
+      SearchTermsArgs(string16()), search_terms_data, NULL));
   // Host, path and port must match.
   if (url.port() != pattern.port() ||
       url.host() != host_ ||
@@ -411,6 +479,7 @@
   path_.clear();
   search_term_key_.clear();
   replacements_.clear();
+  post_params_.clear();
 }
 
 bool TemplateURLRef::ParseParameter(size_t start,
@@ -491,6 +560,14 @@
 #endif
   } else if (parameter == kGoogleUnescapedSearchTermsParameter) {
     replacements->push_back(Replacement(GOOGLE_UNESCAPED_SEARCH_TERMS, start));
+  } else if (parameter == kGoogleImageSearchSource) {
+    url->insert(start, GetGoogleImageSearchSource());
+  } else if (parameter == kGoogleImageThumbnailParameter) {
+    replacements->push_back(
+        Replacement(TemplateURLRef::GOOGLE_IMAGE_THUMBNAIL, start));
+  } else if (parameter == kGoogleImageURLParameter) {
+    replacements->push_back(Replacement(TemplateURLRef::GOOGLE_IMAGE_URL,
+                                        start));
   } else if (!prepopulated_) {
     // If it's a prepopulated URL, we know that it's safe to remove unknown
     // parameters, so just ignore this and return true below. Otherwise it could
@@ -503,6 +580,7 @@
 
 std::string TemplateURLRef::ParseURL(const std::string& url,
                                      Replacements* replacements,
+                                     PostParams* post_params,
                                      bool* valid) const {
   *valid = false;
   std::string parsed_url = url;
@@ -531,6 +609,39 @@
       }
     }
   }
+
+  // Handles the post parameters.
+  const std::string& post_params_string = GetPostParamsString();
+  if (!post_params_string.empty()) {
+    typedef std::vector<std::string> Strings;
+    Strings param_list;
+    base::SplitString(post_params_string, ',', &param_list);
+
+    for (Strings::const_iterator iterator = param_list.begin();
+         iterator != param_list.end(); ++iterator) {
+      Strings parts;
+      // The '=' delimiter is required and the name must be not empty.
+      base::SplitString(*iterator, '=', &parts);
+      if ((parts.size() != 2U) || parts[0].empty())
+        return std::string();
+
+      std::string& value = parts[1];
+      size_t replacements_size = replacements->size();
+      if (IsTemplateParameterString(value))
+        ParseParameter(0, value.length() - 1, &value, replacements);
+      post_params->push_back(std::make_pair(parts[0], value));
+      // If there was a replacement added, points its index to last added
+      // PostParam.
+      if (replacements->size() > replacements_size) {
+        DCHECK_EQ(replacements_size + 1, replacements->size());
+        Replacement* r = &replacements->back();
+        r->is_post_param = true;
+        r->index = post_params->size() - 1;
+      }
+    }
+    DCHECK(!post_params->empty());
+  }
+
   *valid = true;
   return parsed_url;
 }
@@ -543,8 +654,9 @@
 void TemplateURLRef::ParseIfNecessaryUsingTermsData(
     const SearchTermsData& search_terms_data) const {
   if (!parsed_) {
+    InvalidateCachedValues();
     parsed_ = true;
-    parsed_url_ = ParseURL(GetURL(), &replacements_, &valid_);
+    parsed_url_ = ParseURL(GetURL(), &replacements_, &post_params_, &valid_);
     supports_replacements_ = false;
     if (valid_) {
       bool has_only_one_search_term = false;
@@ -598,11 +710,29 @@
   path_ = url.path();
 }
 
+void TemplateURLRef::HandleReplacement(const std::string& name,
+                                       const std::string& value,
+                                       const Replacement& replacement,
+                                       std::string* url) const {
+  size_t pos = replacement.index;
+  if (replacement.is_post_param) {
+    DCHECK_LT(pos, post_params_.size());
+    DCHECK(!post_params_[pos].first.empty());
+    post_params_[pos].second = value;
+  } else {
+    url->insert(pos, name.empty() ? value : (name + "=" + value + "&"));
+  }
+}
+
 std::string TemplateURLRef::HandleReplacements(
     const SearchTermsArgs& search_terms_args,
-    const SearchTermsData& search_terms_data) const {
-  if (replacements_.empty())
+    const SearchTermsData& search_terms_data,
+    std::string* post_data) const {
+  if (replacements_.empty()) {
+    if (!post_params_.empty())
+      EncodeFormData(post_params_, post_data);
     return parsed_url_;
+  }
 
   // Determine if the search terms are in the query or before. We're escaping
   // space as '+' in the former case and as '%20' in the latter case.
@@ -621,7 +751,7 @@
   string16 encoded_terms;
   string16 encoded_original_query;
   owner_->EncodeSearchTerms(search_terms_args, is_in_query, &input_encoding,
-      &encoded_terms, &encoded_original_query);
+                            &encoded_terms, &encoded_original_query);
 
   std::string url = parsed_url_;
 
@@ -631,10 +761,11 @@
        i != replacements_.rend(); ++i) {
     switch (i->type) {
       case ENCODING:
-        url.insert(i->index, input_encoding);
+        HandleReplacement(std::string(), input_encoding, *i, &url);
         break;
 
       case GOOGLE_ASSISTED_QUERY_STATS:
+        DCHECK(!i->is_post_param);
         if (!search_terms_args.assisted_query_stats.empty()) {
           // Get the base URL without substituting AQS to avoid infinite
           // recursion.  We need the URL to find out if it meets all
@@ -643,72 +774,94 @@
           SearchTermsArgs search_terms_args_without_aqs(search_terms_args);
           search_terms_args_without_aqs.assisted_query_stats.clear();
           GURL base_url(ReplaceSearchTermsUsingTermsData(
-              search_terms_args_without_aqs, search_terms_data));
+              search_terms_args_without_aqs, search_terms_data, NULL));
           if (base_url.SchemeIs(chrome::kHttpsScheme)) {
-            url.insert(i->index,
-                       "aqs=" + search_terms_args.assisted_query_stats + "&");
+            HandleReplacement(
+                "aqs", search_terms_args.assisted_query_stats, *i, &url);
           }
         }
         break;
 
       case GOOGLE_BASE_URL:
-        url.insert(i->index, search_terms_data.GoogleBaseURLValue());
+        DCHECK(!i->is_post_param);
+        HandleReplacement(
+            std::string(), search_terms_data.GoogleBaseURLValue(), *i, &url);
         break;
 
       case GOOGLE_BASE_SUGGEST_URL:
-        url.insert(i->index, search_terms_data.GoogleBaseSuggestURLValue());
+        DCHECK(!i->is_post_param);
+        HandleReplacement(
+            std::string(), search_terms_data.GoogleBaseSuggestURLValue(), *i,
+            &url);
         break;
 
       case GOOGLE_CURSOR_POSITION:
+        DCHECK(!i->is_post_param);
         if (search_terms_args.cursor_position != string16::npos)
-          url.insert(i->index,
-                     base::StringPrintf("cp=%" PRIuS "&",
-                                        search_terms_args.cursor_position));
+          HandleReplacement(
+              "cp",
+              base::StringPrintf("%" PRIuS, search_terms_args.cursor_position),
+              *i,
+              &url);
         break;
 
       case GOOGLE_INSTANT_ENABLED:
-        url.insert(i->index, search_terms_data.InstantEnabledParam());
+        DCHECK(!i->is_post_param);
+        HandleReplacement(
+            std::string(), search_terms_data.InstantEnabledParam(), *i, &url);
         break;
 
       case GOOGLE_INSTANT_EXTENDED_ENABLED:
-        url.insert(i->index, search_terms_data.InstantExtendedEnabledParam());
+        DCHECK(!i->is_post_param);
+        HandleReplacement(
+            std::string(), search_terms_data.InstantExtendedEnabledParam(), *i,
+            &url);
         break;
 
       case GOOGLE_NTP_IS_THEMED:
-        url.insert(i->index, search_terms_data.NTPIsThemedParam());
+        DCHECK(!i->is_post_param);
+        HandleReplacement(
+            std::string(), search_terms_data.NTPIsThemedParam(), *i, &url);
         break;
 
       case GOOGLE_OMNIBOX_START_MARGIN:
+        DCHECK(!i->is_post_param);
         if (search_terms_args.omnibox_start_margin >= 0) {
-          url.insert(i->index, "es_sm=" +
-              base::IntToString(search_terms_args.omnibox_start_margin) + "&");
+          HandleReplacement(
+              "es_sm",
+              base::IntToString(search_terms_args.omnibox_start_margin),
+              *i,
+              &url);
         }
         break;
 
       case GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION:
+        DCHECK(!i->is_post_param);
         if (search_terms_args.accepted_suggestion >= 0 ||
             !search_terms_args.assisted_query_stats.empty()) {
-          url.insert(i->index, "oq=" + UTF16ToUTF8(encoded_original_query) +
-                               "&");
+          HandleReplacement(
+              "oq", UTF16ToUTF8(encoded_original_query), *i, &url);
         }
         break;
 
       case GOOGLE_RLZ: {
+        DCHECK(!i->is_post_param);
         // On platforms that don't have RLZ, we still want this branch
         // to happen so that we replace the RLZ template with the
         // empty string.  (If we don't handle this case, we hit a
         // NOTREACHED below.)
         string16 rlz_string = search_terms_data.GetRlzParameterValue();
         if (!rlz_string.empty()) {
-          url.insert(i->index, "rlz=" + UTF16ToUTF8(rlz_string) + "&");
+          HandleReplacement("rlz", UTF16ToUTF8(rlz_string), *i, &url);
         }
         break;
       }
 
       case GOOGLE_SEARCH_CLIENT: {
+        DCHECK(!i->is_post_param);
         std::string client = search_terms_data.GetSearchClient();
         if (!client.empty())
-          url.insert(i->index, "client=" + client + "&");
+          HandleReplacement("client", client, *i, &url);
         break;
       }
 
@@ -719,7 +872,8 @@
         break;
 
       case GOOGLE_SUGGEST_CLIENT:
-        url.insert(i->index, search_terms_data.GetSuggestClient());
+        HandleReplacement(
+            std::string(), search_terms_data.GetSuggestClient(), *i, &url);
         break;
 
       case GOOGLE_UNESCAPED_SEARCH_TERMS: {
@@ -728,27 +882,40 @@
                               input_encoding.c_str(),
                               base::OnStringConversionError::SKIP,
                               &unescaped_terms);
-        url.insert(i->index, std::string(unescaped_terms.begin(),
-                                         unescaped_terms.end()));
+        HandleReplacement(std::string(), unescaped_terms, *i, &url);
         break;
       }
 
       case GOOGLE_ZERO_PREFIX_URL:
+        DCHECK(!i->is_post_param);
         if (!search_terms_args.zero_prefix_url.empty()) {
           const std::string& escaped_zero_prefix_url =
               net::EscapeQueryParamValue(search_terms_args.zero_prefix_url,
                                          true);
-          url.insert(i->index, "url=" + escaped_zero_prefix_url + "&");
+          HandleReplacement("url", escaped_zero_prefix_url, *i, &url);
         }
 
         break;
 
       case LANGUAGE:
-        url.insert(i->index, search_terms_data.GetApplicationLocale());
+        HandleReplacement(
+            std::string(), search_terms_data.GetApplicationLocale(), *i, &url);
         break;
 
       case SEARCH_TERMS:
-        url.insert(i->index, UTF16ToUTF8(encoded_terms));
+        HandleReplacement(std::string(), UTF16ToUTF8(encoded_terms), *i, &url);
+        break;
+
+      case GOOGLE_IMAGE_THUMBNAIL:
+        HandleReplacement(
+            std::string(), search_terms_args.image_thumbnail_content, *i, &url);
+        break;
+
+      case GOOGLE_IMAGE_URL:
+        if (search_terms_args.image_url.is_valid()) {
+          HandleReplacement(
+              std::string(), search_terms_args.image_url.spec(), *i, &url);
+        }
         break;
 
       default:
@@ -757,6 +924,9 @@
     }
   }
 
+  if (!post_params_.empty())
+    EncodeFormData(post_params_, post_data);
+
   return url;
 }
 
@@ -803,7 +973,8 @@
       suggestions_url_ref_(this,
                            TemplateURLRef::SUGGEST),
       instant_url_ref_(this,
-                       TemplateURLRef::INSTANT) {
+                       TemplateURLRef::INSTANT),
+      image_url_ref_(this, TemplateURLRef::IMAGE) {
   SetPrepopulateId(data_.prepopulate_id);
 
   if (data_.search_terms_replacement_key ==
diff --git a/chrome/browser/search_engines/template_url.h b/chrome/browser/search_engines/template_url.h
index 3eb9f4d..4b5b2d2 100644
--- a/chrome/browser/search_engines/template_url.h
+++ b/chrome/browser/search_engines/template_url.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_H_
 
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/gtest_prod_util.h"
@@ -47,6 +48,7 @@
     SEARCH,
     SUGGEST,
     INSTANT,
+    IMAGE,
     INDEXED
   };
 
@@ -94,6 +96,14 @@
     // indeed TemplateURL know whether a TemplateURL is the default search
     // engine, callers instead must set this manually.
     bool append_extra_query_params;
+
+    // The raw content of an image thumbnail that will be used as a query for
+    // search-by-image frontend.
+    std::string image_thumbnail_content;
+
+    // When searching for an image, the URL of the original image. Callers
+    // should leave this empty for images specified via data: URLs.
+    GURL image_url;
   };
 
   TemplateURLRef(TemplateURL* owner, Type type);
@@ -103,7 +113,11 @@
   // Returns the raw URL. None of the parameters will have been replaced.
   std::string GetURL() const;
 
-  // Returns true if this URL supports replacement.
+  // Returns the raw string of the post params. Please see comments in
+  // prepopulated_engines_schema.json for the format.
+  std::string GetPostParamsString() const;
+
+  // Returns true if this URL supports search term replacement.
   bool SupportsReplacement() const;
 
   // Like SupportsReplacement but usable on threads other than the UI thread.
@@ -115,15 +129,27 @@
   //
   // If this TemplateURLRef does not support replacement (SupportsReplacement
   // returns false), an empty string is returned.
+  // If this TemplateURLRef uses POST, and |post_data| is not NULL, the
+  // |post_params_| will be replaced, encoded in "multipart/form-data" format
+  // and stored into |post_data|.
   std::string ReplaceSearchTerms(
-      const SearchTermsArgs& search_terms_args) const;
+      const SearchTermsArgs& search_terms_args,
+      std::string* post_data) const;
+  // TODO(jnd): remove the following ReplaceSearchTerms definition which does
+  // not have |post_data| parameter once all reference callers pass |post_data|
+  // parameter.
+  std::string ReplaceSearchTerms(
+      const SearchTermsArgs& search_terms_args) const {
+    return ReplaceSearchTerms(search_terms_args, NULL);
+  }
 
   // Just like ReplaceSearchTerms except that it takes SearchTermsData to supply
   // the data for some search terms. Most of the time ReplaceSearchTerms should
   // be called.
   std::string ReplaceSearchTermsUsingTermsData(
       const SearchTermsArgs& search_terms_args,
-      const SearchTermsData& search_terms_data) const;
+      const SearchTermsData& search_terms_data,
+      std::string* post_data) const;
 
   // Returns true if the TemplateURLRef is valid. An invalid TemplateURLRef is
   // one that contains unknown terms, or invalid characters.
@@ -171,6 +197,13 @@
       url_parse::Parsed::ComponentType* search_term_component,
       url_parse::Component* search_terms_position) const;
 
+  // Whether the URL uses POST (as opposed to GET).
+  bool UsesPOSTMethodUsingTermsData(
+      const SearchTermsData* search_terms_data) const;
+  bool UsesPOSTMethod() const {
+    return UsesPOSTMethodUsingTermsData(NULL);
+  }
+
  private:
   friend class TemplateURL;
   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, SetPrepopulatedAndParse);
@@ -181,6 +214,7 @@
   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNoKnownParameters);
   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLTwoParameters);
   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNestedParameter);
+  FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, URLRefTestImageURLWithPOST);
 
   // Enumeration of the known types.
   enum ReplacementType {
@@ -189,6 +223,9 @@
     GOOGLE_BASE_URL,
     GOOGLE_BASE_SUGGEST_URL,
     GOOGLE_CURSOR_POSITION,
+    GOOGLE_IMAGE_SEARCH_SOURCE,
+    GOOGLE_IMAGE_THUMBNAIL,
+    GOOGLE_IMAGE_URL,
     GOOGLE_INSTANT_ENABLED,
     GOOGLE_INSTANT_EXTENDED_ENABLED,
     GOOGLE_NTP_IS_THEMED,
@@ -207,13 +244,20 @@
   // Used to identify an element of the raw url that can be replaced.
   struct Replacement {
     Replacement(ReplacementType type, size_t index)
-        : type(type), index(index) {}
+        : type(type), index(index), is_post_param(false) {}
     ReplacementType type;
     size_t index;
+    // Indicates the location in where the replacement is replaced. If
+    // |is_post_param| is false, |index| indicates the byte position in
+    // |parsed_url_|. Otherwise, |index| is the index of |post_params_|.
+    bool is_post_param;
   };
 
   // The list of elements to replace.
   typedef std::vector<struct Replacement> Replacements;
+  // Type to store <key, value> pairs for POST URLs.
+  typedef std::pair<std::string, std::string> PostParam;
+  typedef std::vector<PostParam> PostParams;
 
   // TemplateURLRef internally caches values to make replacement quick. This
   // method invalidates any cached values.
@@ -237,9 +281,13 @@
   // successful, valid is set to true, and the parsed url is returned. For all
   // known parameters that are encountered an entry is added to replacements.
   // If there is an error parsing the url, valid is set to false, and an empty
-  // string is returned.
+  // string is returned.  If the URL has the POST parameters, they will be
+  // parsed into |post_params| which will be further replaced with real search
+  // terms data and encoded in "multipart/form-data" format to generate the
+  // POST data.
   std::string ParseURL(const std::string& url,
                        Replacements* replacements,
+                       PostParams* post_params,
                        bool* valid) const;
 
   // If the url has not yet been parsed, ParseURL is invoked.
@@ -255,12 +303,28 @@
   void ParseHostAndSearchTermKey(
       const SearchTermsData& search_terms_data) const;
 
+  // Encode post parameters in "multipart/form-data" format and store it
+  // inside |post_data|. Returns false if errors are encountered during
+  // encoding. This method is called each time ReplaceSearchTerms gets called.
+  bool EncodeFormData(const PostParams& post_params,
+                      std::string* post_data) const;
+
+  // Handles a replacement by using real term data. If the replacement
+  // belongs to a PostParam, the PostParam will be replaced by the term data.
+  // Otherwise, the term data will be inserted at the place that the
+  // replacement points to.
+  void HandleReplacement(const std::string& name,
+                         const std::string& value,
+                         const Replacement& replacement,
+                         std::string* url) const;
+
   // Replaces all replacements in |parsed_url_| with their actual values and
   // returns the result.  This is the main functionality of
   // ReplaceSearchTermsUsingTermsData().
   std::string HandleReplacements(
       const SearchTermsArgs& search_terms_args,
-      const SearchTermsData& search_terms_data) const;
+      const SearchTermsData& search_terms_data,
+      std::string* post_data) const;
 
   // The TemplateURL that contains us.  This should outlive us.
   TemplateURL* const owner_;
@@ -282,7 +346,7 @@
   // replacements_ giving the index of the terms to replace.
   mutable std::string parsed_url_;
 
-  // Do we support replacement?
+  // Do we support search term replacement?
   mutable bool supports_replacements_;
 
   // The replaceable parts of url (parsed_url_). These are ordered by index
@@ -296,6 +360,8 @@
   mutable std::string search_term_key_;
   mutable url_parse::Parsed::ComponentType search_term_key_location_;
 
+  mutable PostParams post_params_;
+
   // Whether the contained URL is a pre-populated URL.
   bool prepopulated_;
 
@@ -329,6 +395,14 @@
   // Optional additional raw URLs.
   std::string suggestions_url;
   std::string instant_url;
+  std::string image_url;
+
+  // The following post_params are comma-separated lists used to specify the
+  // post parameters for the corresponding URL.
+  std::string search_url_post_params;
+  std::string suggestions_url_post_params;
+  std::string instant_url_post_params;
+  std::string image_url_post_params;
 
   // Optional favicon for the TemplateURL.
   GURL favicon_url;
@@ -438,6 +512,19 @@
   const std::string& url() const { return data_.url(); }
   const std::string& suggestions_url() const { return data_.suggestions_url; }
   const std::string& instant_url() const { return data_.instant_url; }
+  const std::string& image_url() const { return data_.image_url; }
+  const std::string& search_url_post_params() const {
+    return data_.search_url_post_params;
+  }
+  const std::string& suggestions_url_post_params() const {
+    return data_.suggestions_url_post_params;
+  }
+  const std::string& instant_url_post_params() const {
+    return data_.instant_url_post_params;
+  }
+  const std::string& image_url_post_params() const {
+    return data_.image_url_post_params;
+  }
   const std::vector<std::string>& alternate_urls() const {
     return data_.alternate_urls;
   }
@@ -479,6 +566,7 @@
     return suggestions_url_ref_;
   }
   const TemplateURLRef& instant_url_ref() const { return instant_url_ref_; }
+  const TemplateURLRef& image_url_ref() const { return image_url_ref_; }
 
   // Returns true if |url| supports replacement.
   bool SupportsReplacement() const;
@@ -599,6 +687,7 @@
   TemplateURLRef url_ref_;
   TemplateURLRef suggestions_url_ref_;
   TemplateURLRef instant_url_ref_;
+  TemplateURLRef image_url_ref_;
 
   // TODO(sky): Add date last parsed OSD file.
 
diff --git a/chrome/browser/search_engines/template_url_fetcher.cc b/chrome/browser/search_engines/template_url_fetcher.cc
index 3b7b5a2..b20e59e 100644
--- a/chrome/browser/search_engines/template_url_fetcher.cc
+++ b/chrome/browser/search_engines/template_url_fetcher.cc
@@ -8,13 +8,13 @@
 
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_fetcher_callbacks.h"
 #include "chrome/browser/search_engines/template_url_parser.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/search_engines/template_url_fetcher_unittest.cc b/chrome/browser/search_engines/template_url_fetcher_unittest.cc
index 9120251..d97e662 100644
--- a/chrome/browser/search_engines/template_url_fetcher_unittest.cc
+++ b/chrome/browser/search_engines/template_url_fetcher_unittest.cc
@@ -145,8 +145,8 @@
     base::FilePath osdd_full_path;
     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &osdd_full_path));
     osdd_full_path = osdd_full_path.AppendASCII(osdd_file_name);
-    ASSERT_TRUE(file_util::PathExists(osdd_full_path));
-    ASSERT_FALSE(file_util::DirectoryExists(osdd_full_path));
+    ASSERT_TRUE(base::PathExists(osdd_full_path));
+    ASSERT_FALSE(base::DirectoryExists(osdd_full_path));
   }
 
   // Start the fetch.
diff --git a/chrome/browser/search_engines/template_url_parser_unittest.cc b/chrome/browser/search_engines/template_url_parser_unittest.cc
index ae11ecb..3905a3a 100644
--- a/chrome/browser/search_engines/template_url_parser_unittest.cc
+++ b/chrome/browser/search_engines/template_url_parser_unittest.cc
@@ -77,7 +77,7 @@
 void TemplateURLParserTest::SetUp() {
   ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &full_path_));
   full_path_ = full_path_.AppendASCII("osdd");
-  if (!file_util::PathExists(full_path_)) {
+  if (!base::PathExists(full_path_)) {
     LOG(ERROR) <<
         "This test can't be run without some non-redistributable data";
     full_path_ = base::FilePath();
@@ -95,7 +95,7 @@
   ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &full_path));
   full_path = full_path.AppendASCII("osdd");
   full_path = full_path.AppendASCII(file_name);
-  ASSERT_TRUE(file_util::PathExists(full_path));
+  ASSERT_TRUE(base::PathExists(full_path));
 
   std::string contents;
   ASSERT_TRUE(file_util::ReadFileToString(full_path, &contents));
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data.cc b/chrome/browser/search_engines/template_url_prepopulate_data.cc
index aa3032e..31c7505 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data.cc
+++ b/chrome/browser/search_engines/template_url_prepopulate_data.cc
@@ -1089,7 +1089,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       prefs::kCountryIDAtInstall,
       kCountryIDUnknown,
@@ -1121,6 +1121,11 @@
     const base::StringPiece& search_url,
     const base::StringPiece& suggest_url,
     const base::StringPiece& instant_url,
+    const base::StringPiece& image_url,
+    const base::StringPiece& search_url_post_params,
+    const base::StringPiece& suggest_url_post_params,
+    const base::StringPiece& instant_url_post_params,
+    const base::StringPiece& image_url_post_params,
     const base::StringPiece& favicon_url,
     const base::StringPiece& encoding,
     const ListValue& alternate_urls,
@@ -1134,6 +1139,11 @@
   data.SetURL(search_url.as_string());
   data.suggestions_url = suggest_url.as_string();
   data.instant_url = instant_url.as_string();
+  data.image_url = image_url.as_string();
+  data.search_url_post_params = search_url_post_params.as_string();
+  data.suggestions_url_post_params = suggest_url_post_params.as_string();
+  data.instant_url_post_params = instant_url_post_params.as_string();
+  data.image_url_post_params = image_url_post_params.as_string();
   data.favicon_url = GURL(favicon_url.as_string());
   data.show_in_default_list = true;
   data.safe_for_autoreplace = true;
@@ -1182,17 +1192,30 @@
       // These fields are optional.
       std::string suggest_url;
       std::string instant_url;
+      std::string image_url;
+      std::string search_url_post_params;
+      std::string suggest_url_post_params;
+      std::string instant_url_post_params;
+      std::string image_url_post_params;
       ListValue empty_list;
       const ListValue* alternate_urls = &empty_list;
       std::string search_terms_replacement_key;
       engine->GetString("suggest_url", &suggest_url);
       engine->GetString("instant_url", &instant_url);
+      engine->GetString("image_url", &image_url);
+      engine->GetString("search_url_post_params", &search_url_post_params);
+      engine->GetString("suggest_url_post_params", &suggest_url_post_params);
+      engine->GetString("instant_url_post_params", &instant_url_post_params);
+      engine->GetString("image_url_post_params", &image_url_post_params);
       engine->GetList("alternate_urls", &alternate_urls);
       engine->GetString("search_terms_replacement_key",
           &search_terms_replacement_key);
       t_urls->push_back(MakePrepopulatedTemplateURL(profile, name, keyword,
-          search_url, suggest_url, instant_url, favicon_url, encoding,
-          *alternate_urls, search_terms_replacement_key, id));
+          search_url, suggest_url, instant_url, image_url,
+          search_url_post_params, suggest_url_post_params,
+          instant_url_post_params, image_url_post_params,
+          favicon_url, encoding, *alternate_urls, search_terms_replacement_key,
+          id));
     }
   }
 }
@@ -1220,8 +1243,10 @@
 
   return MakePrepopulatedTemplateURL(profile, WideToUTF16(engine.name),
       WideToUTF16(engine.keyword), engine.search_url, engine.suggest_url,
-      engine.instant_url, engine.favicon_url, engine.encoding, alternate_urls,
-      engine.search_terms_replacement_key, engine.id);
+      engine.instant_url, engine.image_url, engine.search_url_post_params,
+      engine.suggest_url_post_params, engine.instant_url_post_params,
+      engine.image_url_post_params, engine.favicon_url, engine.encoding,
+      alternate_urls, engine.search_terms_replacement_key, engine.id);
 }
 
 void GetPrepopulatedEngines(Profile* profile,
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data.h b/chrome/browser/search_engines/template_url_prepopulate_data.h
index 7eebf8d..cfd614b 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data.h
+++ b/chrome/browser/search_engines/template_url_prepopulate_data.h
@@ -39,7 +39,7 @@
 
 #endif
 
-void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
 // Returns the current version of the prepopulate data, so callers can know when
 // they need to re-merge. If the prepopulate data comes from the preferences
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc b/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc
index 1c1245b..140d700 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc
+++ b/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc
@@ -224,6 +224,8 @@
   EXPECT_EQ(ASCIIToUTF16("Google"), t_urls[default_index]->short_name());
   EXPECT_FALSE(t_urls[default_index]->suggestions_url().empty());
   EXPECT_FALSE(t_urls[default_index]->instant_url().empty());
+  EXPECT_FALSE(t_urls[default_index]->image_url().empty());
+  EXPECT_FALSE(t_urls[default_index]->image_url_post_params().empty());
   EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
       TemplateURLPrepopulateData::GetEngineType(t_urls[default_index]->url()));
 }
@@ -254,6 +256,8 @@
   EXPECT_EQ(ASCIIToUTF16("Google"), t_urls[default_index]->short_name());
   EXPECT_FALSE(t_urls[default_index]->suggestions_url().empty());
   EXPECT_FALSE(t_urls[default_index]->instant_url().empty());
+  EXPECT_FALSE(t_urls[default_index]->image_url().empty());
+  EXPECT_FALSE(t_urls[default_index]->image_url_post_params().empty());
   // Expect at least 2 alternate_urls.
   // This caught a bug with static initialization of arrays, so leave this in.
   EXPECT_GT(t_urls[default_index]->alternate_urls().size(), 1u);
diff --git a/chrome/browser/search_engines/template_url_scraper_unittest.cc b/chrome/browser/search_engines/template_url_scraper_unittest.cc
index 6d9b011..aa70734 100644
--- a/chrome/browser/search_engines/template_url_scraper_unittest.cc
+++ b/chrome/browser/search_engines/template_url_scraper_unittest.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_registrar.h"
diff --git a/chrome/browser/search_engines/template_url_service.cc b/chrome/browser/search_engines/template_url_service.cc
index b809632..e897739 100644
--- a/chrome/browser/search_engines/template_url_service.cc
+++ b/chrome/browser/search_engines/template_url_service.cc
@@ -19,6 +19,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_url_tracker.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/history_service.h"
@@ -33,7 +34,6 @@
 #include "chrome/browser/search_engines/template_url_service_observer.h"
 #include "chrome/browser/search_engines/util.h"
 #include "chrome/browser/webdata/web_data_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/env_vars.h"
 #include "chrome/common/pref_names.h"
@@ -281,7 +281,7 @@
       models_associated_(false),
       processing_syncer_changes_(false),
       pending_synced_default_search_(false),
-      dsp_change_origin_(DSP_CHANGE_NOT_SYNC) {
+      dsp_change_origin_(DSP_CHANGE_OTHER) {
   DCHECK(profile_);
   Init(NULL, 0);
 }
@@ -301,7 +301,7 @@
       models_associated_(false),
       processing_syncer_changes_(false),
       pending_synced_default_search_(false),
-      dsp_change_origin_(DSP_CHANGE_NOT_SYNC) {
+      dsp_change_origin_(DSP_CHANGE_OTHER) {
   Init(initializers, count);
 }
 
@@ -377,9 +377,12 @@
   if (!search_ref.SupportsReplacementUsingTermsData(search_terms_data))
     return GURL(t_url->url());
 
+  // TODO(jnd): Adds additional parameters to get post data when the search URL
+  // has post parameters.
   return GURL(search_ref.ReplaceSearchTermsUsingTermsData(
       TemplateURLRef::SearchTermsArgs(ASCIIToUTF16(kReplacementTerm)),
-      search_terms_data));
+      search_terms_data,
+      NULL));
 }
 
 bool TemplateURLService::CanReplaceKeyword(
@@ -718,6 +721,8 @@
   STLDeleteContainerPointers(extensions, entries_to_process.end());
   entries_to_process.erase(extensions, entries_to_process.end());
   // Setup search engines and a default one.
+  base::AutoReset<DefaultSearchChangeOrigin> change_origin(
+      &dsp_change_origin_, DSP_CHANGE_PROFILE_RESET);
   AddTemplateURLsAndSetupDefaultEngine(&entries_to_process,
                                        default_search_provider);
 
@@ -1998,9 +2003,10 @@
       base::AutoReset<DefaultSearchChangeOrigin> change_origin(
           &dsp_change_origin_, DSP_CHANGE_SYNC_NOT_MANAGED);
       pending_synced_default_search_ = false;
+      SetDefaultSearchProviderNoNotify(synced_default);
+    } else {
+      SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider());
     }
-    SetDefaultSearchProviderNoNotify(synced_default ? synced_default :
-        FindNewDefaultSearchProvider());
   }
   NotifyObservers();
 }
diff --git a/chrome/browser/search_engines/template_url_service.h b/chrome/browser/search_engines/template_url_service.h
index 724f771..31d6186 100644
--- a/chrome/browser/search_engines/template_url_service.h
+++ b/chrome/browser/search_engines/template_url_service.h
@@ -381,7 +381,11 @@
     // certain changes were intentionally from the system, or possibly some
     // unintentional change from when we were Syncing.
     DSP_CHANGE_SYNC_UNINTENTIONAL,
-    DSP_CHANGE_NOT_SYNC,
+    // All non-sync changes save PROFILE_RESET; we can't reorder the list for
+    // clarity as this would screw up stat collection.
+    DSP_CHANGE_OTHER,
+    // Changed through "Profile Reset" feature.
+    DSP_CHANGE_PROFILE_RESET,
     // Boundary value.
     DSP_CHANGE_MAX,
   };
diff --git a/chrome/browser/search_engines/template_url_service_android.cc b/chrome/browser/search_engines/template_url_service_android.cc
index 1081a03..e03325d 100644
--- a/chrome/browser/search_engines/template_url_service_android.cc
+++ b/chrome/browser/search_engines/template_url_service_android.cc
@@ -9,12 +9,12 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "jni/TemplateUrlService_jni.h"
 
diff --git a/chrome/browser/search_engines/template_url_service_factory.cc b/chrome/browser/search_engines/template_url_service_factory.cc
index 30391fe..915e275 100644
--- a/chrome/browser/search_engines/template_url_service_factory.cc
+++ b/chrome/browser/search_engines/template_url_service_factory.cc
@@ -47,7 +47,7 @@
   return BuildInstanceFor(static_cast<Profile*>(profile));
 }
 
-void TemplateURLServiceFactory::RegisterUserPrefs(
+void TemplateURLServiceFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterStringPref(prefs::kSyncedDefaultSearchProviderGUID,
                                std::string(),
diff --git a/chrome/browser/search_engines/template_url_service_factory.h b/chrome/browser/search_engines/template_url_service_factory.h
index db46263..9a44782 100644
--- a/chrome/browser/search_engines/template_url_service_factory.h
+++ b/chrome/browser/search_engines/template_url_service_factory.h
@@ -31,7 +31,7 @@
   // BrowserContextKeyedServiceFactory:
   virtual BrowserContextKeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const OVERRIDE;
diff --git a/chrome/browser/search_engines/template_url_service_sync_unittest.cc b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
index 0e0c549..9b8461b 100644
--- a/chrome/browser/search_engines/template_url_service_sync_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
@@ -7,13 +7,13 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/search_engines/search_terms_data.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/search_engines/template_url_service_test_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/testing_pref_service_syncable.h"
diff --git a/chrome/browser/search_engines/template_url_service_test_util.cc b/chrome/browser/search_engines/template_url_service_test_util.cc
index 34894ab..b5e4a07 100644
--- a/chrome/browser/search_engines/template_url_service_test_util.cc
+++ b/chrome/browser/search_engines/template_url_service_test_util.cc
@@ -9,12 +9,12 @@
 #include "base/path_service.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/thread.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_url_tracker.h"
 #include "chrome/browser/search_engines/search_terms_data.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/webdata/web_data_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/automation/value_conversion_util.h"
 #include "chrome/test/base/testing_pref_service_syncable.h"
diff --git a/chrome/browser/search_engines/template_url_unittest.cc b/chrome/browser/search_engines/template_url_unittest.cc
index 2f8b6c4..23601f2 100644
--- a/chrome/browser/search_engines/template_url_unittest.cc
+++ b/chrome/browser/search_engines/template_url_unittest.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/search_engines/search_terms_data.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/common/chrome_version_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if defined(ENABLE_RLZ)
@@ -44,7 +45,6 @@
   return google_base_url_;
 }
 
-
 // TemplateURLTest ------------------------------------------------------------
 
 class TemplateURLTest : public testing::Test {
@@ -166,6 +166,100 @@
   EXPECT_EQ("http://fooxxutf-8ya/", result.spec());
 }
 
+TEST_F(TemplateURLTest, URLRefTestImageURLWithPOST) {
+  const char kInvalidPostParamsString[] =
+      "unknown_template={UnknownTemplate},bad_value=bad{value},"
+      "{google:sbiSource}";
+  // List all accpectable parameter format in valid_post_params_string. it is
+  // expected like: "name0=,name1=value1,name2={template1}"
+  const char kValidPostParamsString[] =
+      "image_content={google:imageThumbnail},image_url={google:imageURL},"
+      "sbisrc={google:imageSearchSource},language={language},empty_param=,"
+      "constant_param=constant";
+  const char KImageSearchURL[] = "http://foo.com/sbi";
+
+  TemplateURLData data;
+  data.image_url = KImageSearchURL;
+
+  // Try to parse invalid post parameters.
+  data.image_url_post_params = kInvalidPostParamsString;
+  TemplateURL url_bad(NULL, data);
+  ASSERT_FALSE(url_bad.image_url_ref().IsValid());
+  const TemplateURLRef::PostParams& bad_post_params =
+      url_bad.image_url_ref().post_params_;
+  ASSERT_EQ(2U, bad_post_params.size());
+  EXPECT_EQ("unknown_template", bad_post_params[0].first);
+  EXPECT_EQ("{UnknownTemplate}", bad_post_params[0].second);
+  EXPECT_EQ("bad_value", bad_post_params[1].first);
+  EXPECT_EQ("bad{value}", bad_post_params[1].second);
+
+  // Try to parse valid post parameters.
+  data.image_url_post_params = kValidPostParamsString;
+  TemplateURL url(NULL, data);
+  ASSERT_TRUE(url.image_url_ref().IsValid());
+  ASSERT_FALSE(url.image_url_ref().SupportsReplacement());
+
+  // Check term replacement.
+  TemplateURLRef::SearchTermsArgs search_args(ASCIIToUTF16("X"));
+  search_args.image_thumbnail_content = "dummy-image-thumbnail";
+  search_args.image_url = GURL("http://dummyimage.com/dummy.jpg");
+  // Replacement operation with no post_data buffer should still return
+  // the parsed URL.
+  GURL result(url.image_url_ref().ReplaceSearchTerms(search_args));
+  ASSERT_TRUE(result.is_valid());
+  EXPECT_EQ(KImageSearchURL, result.spec());
+  std::string post_data;
+  TestSearchTermsData search_terms_data("http://X");
+  result = GURL(url.image_url_ref().ReplaceSearchTermsUsingTermsData(
+      search_args, search_terms_data, &post_data));
+  ASSERT_TRUE(result.is_valid());
+  EXPECT_EQ(KImageSearchURL, result.spec());
+  ASSERT_FALSE(post_data.empty());
+
+  // Check parsed result of post parameters.
+  const TemplateURLRef::Replacements& replacements =
+      url.image_url_ref().replacements_;
+  const TemplateURLRef::PostParams& post_params =
+      url.image_url_ref().post_params_;
+  EXPECT_EQ(6U, post_params.size());
+  for (TemplateURLRef::PostParams::const_iterator i = post_params.begin();
+       i != post_params.end(); ++i) {
+    TemplateURLRef::Replacements::const_iterator j = replacements.begin();
+    for (; j != replacements.end(); ++j) {
+      if (j->is_post_param && j->index ==
+          static_cast<size_t>(i - post_params.begin())) {
+        switch (j->type) {
+          case TemplateURLRef::GOOGLE_IMAGE_THUMBNAIL:
+            EXPECT_EQ("image_content", i->first);
+            EXPECT_EQ(search_args.image_thumbnail_content, i->second);
+            break;
+          case TemplateURLRef::GOOGLE_IMAGE_URL:
+            EXPECT_EQ("image_url", i->first);
+            EXPECT_EQ(search_args.image_url.spec(), i->second);
+            break;
+          case TemplateURLRef::LANGUAGE:
+            EXPECT_EQ("language", i->first);
+            EXPECT_EQ("en", i->second);
+            break;
+          default:
+            ADD_FAILURE();  // Should never go here.
+        }
+        break;
+      }
+    }
+    if (j != replacements.end())
+      continue;
+    if (i->first == "empty_param") {
+      EXPECT_TRUE(i->second.empty());
+    } else if (i->first == "sbisrc") {
+      EXPECT_EQ("unknown", i->second);
+    } else {
+      EXPECT_EQ("constant_param", i->first);
+      EXPECT_EQ("constant", i->second);
+    }
+  }
+}
+
 // Test that setting the prepopulate ID from TemplateURL causes the stored
 // TemplateURLRef to handle parsing the URL parameters differently.
 TEST_F(TemplateURLTest, SetPrepopulatedAndParse) {
@@ -175,14 +269,15 @@
   TemplateURLRef::Replacements replacements;
   bool valid = false;
   EXPECT_EQ("http://foo{fhqwhgads}bar", url.url_ref().ParseURL(
-      "http://foo{fhqwhgads}bar", &replacements, &valid));
+      "http://foo{fhqwhgads}bar", &replacements, NULL, &valid));
   EXPECT_TRUE(replacements.empty());
   EXPECT_TRUE(valid);
 
   data.prepopulate_id = 123;
   TemplateURL url2(NULL, data);
   EXPECT_EQ("http://foobar", url2.url_ref().ParseURL("http://foo{fhqwhgads}bar",
-                                                     &replacements, &valid));
+                                                     &replacements, NULL,
+                                                     &valid));
   EXPECT_TRUE(replacements.empty());
   EXPECT_TRUE(valid);
 }
@@ -232,7 +327,7 @@
     EXPECT_TRUE(url.url_ref().IsValid());
     ASSERT_TRUE(url.url_ref().SupportsReplacement());
     GURL result(url.url_ref().ReplaceSearchTermsUsingTermsData(
-        TemplateURLRef::SearchTermsArgs(value.terms), search_terms_data));
+        TemplateURLRef::SearchTermsArgs(value.terms), search_terms_data, NULL));
     ASSERT_TRUE(result.is_valid());
     EXPECT_EQ(value.output, result.spec());
   }
@@ -668,7 +763,7 @@
   TemplateURLRef::Replacements replacements;
   bool valid = false;
   EXPECT_EQ(std::string(),
-            url.url_ref().ParseURL(std::string(), &replacements, &valid));
+            url.url_ref().ParseURL(std::string(), &replacements, NULL, &valid));
   EXPECT_TRUE(replacements.empty());
   EXPECT_TRUE(valid);
 }
@@ -679,7 +774,8 @@
   TemplateURL url(NULL, data);
   TemplateURLRef::Replacements replacements;
   bool valid = false;
-  EXPECT_EQ(std::string(), url.url_ref().ParseURL("{", &replacements, &valid));
+  EXPECT_EQ(std::string(), url.url_ref().ParseURL("{", &replacements, NULL,
+                                                  &valid));
   EXPECT_TRUE(replacements.empty());
   EXPECT_FALSE(valid);
 }
@@ -690,7 +786,7 @@
   TemplateURL url(NULL, data);
   TemplateURLRef::Replacements replacements;
   bool valid = false;
-  EXPECT_EQ("{}", url.url_ref().ParseURL("{}", &replacements, &valid));
+  EXPECT_EQ("{}", url.url_ref().ParseURL("{}", &replacements, NULL, &valid));
   EXPECT_TRUE(replacements.empty());
   EXPECT_TRUE(valid);
 }
@@ -702,7 +798,8 @@
   TemplateURLRef::Replacements replacements;
   bool valid = false;
   EXPECT_EQ("{}{}",
-            url.url_ref().ParseURL("{}{{searchTerms}}", &replacements, &valid));
+            url.url_ref().ParseURL("{}{{searchTerms}}", &replacements, NULL,
+                                   &valid));
   ASSERT_EQ(1U, replacements.size());
   EXPECT_EQ(3U, replacements[0].index);
   EXPECT_EQ(TemplateURLRef::SEARCH_TERMS, replacements[0].type);
@@ -716,7 +813,8 @@
   TemplateURLRef::Replacements replacements;
   bool valid = false;
   EXPECT_EQ("{",
-            url.url_ref().ParseURL("{{searchTerms}", &replacements, &valid));
+            url.url_ref().ParseURL("{{searchTerms}", &replacements, NULL,
+                                   &valid));
   ASSERT_EQ(1U, replacements.size());
   EXPECT_EQ(1U, replacements[0].index);
   EXPECT_EQ(TemplateURLRef::SEARCH_TERMS, replacements[0].type);
diff --git a/chrome/browser/service/service_process_control.cc b/chrome/browser/service/service_process_control.cc
index 3c16d4f..7c17a1f 100644
--- a/chrome/browser/service/service_process_control.cc
+++ b/chrome/browser/service/service_process_control.cc
@@ -13,8 +13,8 @@
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/upgrade_detector.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/service_messages.h"
 #include "chrome/common/service_process_util.h"
diff --git a/chrome/browser/sessions/persistent_tab_restore_service_browsertest.cc b/chrome/browser/sessions/persistent_tab_restore_service_browsertest.cc
index fc55379..84c63a2 100644
--- a/chrome/browser/sessions/persistent_tab_restore_service_browsertest.cc
+++ b/chrome/browser/sessions/persistent_tab_restore_service_browsertest.cc
@@ -8,6 +8,7 @@
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_service.h"
 #include "chrome/browser/sessions/session_service_factory.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/sessions/tab_restore_service_factory.h"
 #include "chrome/browser/sessions/tab_restore_service_observer.h"
 #include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/chrome_render_view_test.h"
diff --git a/chrome/browser/sessions/session_backend.cc b/chrome/browser/sessions/session_backend.cc
index 90e6a38..018b679 100644
--- a/chrome/browser/sessions/session_backend.cc
+++ b/chrome/browser/sessions/session_backend.cc
@@ -47,7 +47,7 @@
         buffer_position_(0),
         available_count_(0) {
     file_.reset(new net::FileStream(NULL));
-    if (file_util::PathExists(path))
+    if (base::PathExists(path))
       file_->OpenSync(path,
                       base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ);
   }
@@ -265,7 +265,7 @@
 
 void SessionBackend::DeleteLastSession() {
   Init();
-  base::Delete(GetLastSessionPath(), false);
+  base::DeleteFile(GetLastSessionPath(), false);
 }
 
 void SessionBackend::MoveCurrentSessionToLastSession() {
@@ -274,9 +274,9 @@
 
   const base::FilePath current_session_path = GetCurrentSessionPath();
   const base::FilePath last_session_path = GetLastSessionPath();
-  if (file_util::PathExists(last_session_path))
-    base::Delete(last_session_path, false);
-  if (file_util::PathExists(current_session_path)) {
+  if (base::PathExists(last_session_path))
+    base::DeleteFile(last_session_path, false);
+  if (base::PathExists(current_session_path)) {
     int64 file_size;
     if (file_util::GetFileSize(current_session_path, &file_size)) {
       if (type_ == BaseSessionService::TAB_RESTORE) {
@@ -290,8 +290,8 @@
     last_session_valid_ = base::Move(current_session_path, last_session_path);
   }
 
-  if (file_util::PathExists(current_session_path))
-    base::Delete(current_session_path, false);
+  if (base::PathExists(current_session_path))
+    base::DeleteFile(current_session_path, false);
 
   // Create and open the file for the current session.
   ResetFile();
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc
index e9d9e2a..0f2868a 100644
--- a/chrome/browser/sessions/session_restore.cc
+++ b/chrome/browser/sessions/session_restore.cc
@@ -20,6 +20,7 @@
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/performance_monitor/startup_timer.h"
 #include "chrome/browser/profiles/profile.h"
@@ -35,7 +36,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
 #include "chrome/common/cancelable_task_tracker.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/browser/dom_storage_context.h"
 #include "content/public/browser/navigation_controller.h"
@@ -1044,19 +1044,14 @@
 
     // Set up the file access rights for the selected navigation entry.
     const int id = web_contents->GetRenderProcessHost()->GetID();
-    const int read_file_permissions =
-        base::PLATFORM_FILE_OPEN |
-        base::PLATFORM_FILE_READ |
-        base::PLATFORM_FILE_EXCLUSIVE_READ |
-        base::PLATFORM_FILE_ASYNC;
     const content::PageState& page_state =
         tab.navigations.at(selected_index).page_state();
     const std::vector<base::FilePath>& file_paths =
         page_state.GetReferencedFiles();
     for (std::vector<base::FilePath>::const_iterator file = file_paths.begin();
          file != file_paths.end(); ++file) {
-      content::ChildProcessSecurityPolicy::GetInstance()->
-          GrantPermissionsForFile(id, *file, read_file_permissions);
+      content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(id,
+                                                                        *file);
     }
 
     if (schedule_load)
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc
index a5b0e8e..6626bfe 100644
--- a/chrome/browser/sessions/session_restore_browsertest.cc
+++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -7,6 +7,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/first_run/first_run.h"
 #include "chrome/browser/profiles/profile.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc
index 4727415..1521552 100644
--- a/chrome/browser/sessions/session_service.cc
+++ b/chrome/browser/sessions/session_service.cc
@@ -16,6 +16,7 @@
 #include "base/metrics/histogram.h"
 #include "base/pickle.h"
 #include "base/threading/thread.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/profiles/profile.h"
@@ -31,7 +32,6 @@
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/startup_metric_utils.h"
 #include "content/public/browser/navigation_details.h"
diff --git a/chrome/browser/sessions/session_service_unittest.cc b/chrome/browser/sessions/session_service_unittest.cc
index 4ed982b..2511d85 100644
--- a/chrome/browser/sessions/session_service_unittest.cc
+++ b/chrome/browser/sessions/session_service_unittest.cc
@@ -13,12 +13,12 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/sessions/session_backend.h"
 #include "chrome/browser/sessions/session_service.h"
 #include "chrome/browser/sessions/session_service_test_helper.h"
 #include "chrome/browser/sessions/session_types.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/testing_profile.h"
@@ -858,7 +858,7 @@
   // Forces closing the file.
   helper_.set_service(NULL);
 
-  ASSERT_TRUE(file_util::CopyFile(v1_file_path, dest_file_path));
+  ASSERT_TRUE(base::CopyFile(v1_file_path, dest_file_path));
 
   SessionService* session_service = new SessionService(path_);
   helper_.set_service(session_service);
diff --git a/chrome/browser/sessions/session_tab_helper.cc b/chrome/browser/sessions/session_tab_helper.cc
index 2314afd..da4115b 100644
--- a/chrome/browser/sessions/session_tab_helper.cc
+++ b/chrome/browser/sessions/session_tab_helper.cc
@@ -4,10 +4,10 @@
 
 #include "chrome/browser/sessions/session_tab_helper.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_service.h"
 #include "chrome/browser/sessions/session_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_messages.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_view_host.h"
diff --git a/chrome/browser/sessions/tab_restore_browsertest.cc b/chrome/browser/sessions/tab_restore_browsertest.cc
index 1dfa94b..31f8310 100644
--- a/chrome/browser/sessions/tab_restore_browsertest.cc
+++ b/chrome/browser/sessions/tab_restore_browsertest.cc
@@ -8,13 +8,13 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/test_timeouts.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/find_bar/find_notification_details.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/shell_integration.cc b/chrome/browser/shell_integration.cc
index 4551315..505d87b 100644
--- a/chrome/browser/shell_integration.cc
+++ b/chrome/browser/shell_integration.cc
@@ -79,7 +79,7 @@
   if (!user_data_dir.empty()) {
     // Make sure user_data_dir is an absolute path.
     user_data_dir = base::MakeAbsoluteFilePath(user_data_dir);
-    if (!user_data_dir.empty() && file_util::PathExists(user_data_dir))
+    if (!user_data_dir.empty() && base::PathExists(user_data_dir))
       new_cmd_line.AppendSwitchPath(switches::kUserDataDir, user_data_dir);
   }
 
diff --git a/chrome/browser/shell_integration_linux.cc b/chrome/browser/shell_integration_linux.cc
index 8ef3320..64bb162 100644
--- a/chrome/browser/shell_integration_linux.cc
+++ b/chrome/browser/shell_integration_linux.cc
@@ -29,6 +29,7 @@
 #include "base/process_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_tokenizer.h"
+#include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
@@ -170,7 +171,7 @@
 void DeleteShortcutOnDesktop(const base::FilePath& shortcut_filename) {
   base::FilePath desktop_path;
   if (PathService::Get(base::DIR_USER_DESKTOP, &desktop_path))
-    base::Delete(desktop_path.Append(shortcut_filename), false);
+    base::DeleteFile(desktop_path.Append(shortcut_filename), false);
 }
 
 // Creates a shortcut with |shortcut_filename| and |contents| in the system
@@ -551,7 +552,7 @@
   // Determine whether there is a shortcut on desktop.
   if (!desktop_path.empty()) {
     locations.on_desktop =
-        file_util::PathExists(desktop_path.Append(shortcut_filename));
+        base::PathExists(desktop_path.Append(shortcut_filename));
   }
 
   // Determine whether there is a shortcut in the applications directory.
@@ -604,7 +605,7 @@
        i != search_paths.end(); ++i) {
     base::FilePath path = i->Append("applications").Append(desktop_filename);
     VLOG(1) << "Looking for desktop file in " << path.value();
-    if (file_util::PathExists(path)) {
+    if (base::PathExists(path)) {
       VLOG(1) << "Found desktop file at " << path.value();
       return file_util::ReadFileToString(path, output);
     }
@@ -626,7 +627,7 @@
   base::FilePath filepath = desktop_path.Append(filename);
   base::FilePath alternative_filepath(filepath.value() + ".desktop");
   for (size_t i = 1; i < 100; ++i) {
-    if (file_util::PathExists(base::FilePath(alternative_filepath))) {
+    if (base::PathExists(base::FilePath(alternative_filepath))) {
       alternative_filepath = base::FilePath(
           filepath.value() + "_" + base::IntToString(i) + ".desktop");
     } else {
@@ -648,6 +649,9 @@
       .append("-")
       .append(profile_path.BaseName().value());
   file_util::ReplaceIllegalCharactersInPath(&filename, '_');
+  // Spaces in filenames break xdg-desktop-menu
+  // (see https://bugs.freedesktop.org/show_bug.cgi?id=66605).
+  ReplaceChars(filename, " ", "_", &filename);
   return base::FilePath(filename.append(".desktop"));
 }
 
diff --git a/chrome/browser/shell_integration_unittest.cc b/chrome/browser/shell_integration_unittest.cc
index 2d524a4..3789d2b 100644
--- a/chrome/browser/shell_integration_unittest.cc
+++ b/chrome/browser/shell_integration_unittest.cc
@@ -72,9 +72,9 @@
 }  // namespace
 
 TEST(ShellIntegrationTest, GetExistingShortcutLocations) {
-  base::FilePath kProfilePath("Default");
+  base::FilePath kProfilePath("Profile 1");
   const char kExtensionId[] = "test_extension";
-  const char kTemplateFilename[] = "chrome-test_extension-Default.desktop";
+  const char kTemplateFilename[] = "chrome-test_extension-Profile_1.desktop";
   base::FilePath kTemplateFilepath(kTemplateFilename);
   const char kNoDisplayDesktopFile[] = "[Desktop Entry]\nNoDisplay=true";
 
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc
index c30dc78..eb37324 100644
--- a/chrome/browser/shell_integration_win.cc
+++ b/chrome/browser/shell_integration_win.cc
@@ -530,7 +530,7 @@
 
     shortcut = shortcut.Append(shortcut_name).Append(shortcut_name +
                                                      installer::kLnkExt);
-    if (file_util::PathExists(shortcut))
+    if (base::PathExists(shortcut))
       return shortcut;
   }
 
diff --git a/chrome/browser/signin/DEPS b/chrome/browser/signin/DEPS
index 05965ba..2eaadea 100644
--- a/chrome/browser/signin/DEPS
+++ b/chrome/browser/signin/DEPS
@@ -8,6 +8,7 @@
   "+chrome/browser/signin",
 
   # TODO(joi): Get this list to zero.
+  "!chrome/browser/chrome_notification_types.h",
   "!chrome/browser/policy/cloud/user_policy_signin_service.h",
   "!chrome/browser/policy/cloud/user_policy_signin_service_factory.h",
   "!chrome/browser/profiles/profile.h",
@@ -32,7 +33,6 @@
   "!chrome/browser/ui/webui/signin_internals_ui.h",
   "!chrome/browser/webdata/token_web_data.h",
   "!chrome/browser/webdata/web_data_service_factory.h",
-  "!chrome/common/chrome_notification_types.h",
   "!chrome/common/chrome_switches.h",
   "!chrome/common/chrome_version_info.h",
   "!chrome/common/pref_names.h",
diff --git a/chrome/browser/signin/about_signin_internals_factory.cc b/chrome/browser/signin/about_signin_internals_factory.cc
index 4ff1c09..6b9f924 100644
--- a/chrome/browser/signin/about_signin_internals_factory.cc
+++ b/chrome/browser/signin/about_signin_internals_factory.cc
@@ -37,7 +37,7 @@
   return Singleton<AboutSigninInternalsFactory>::get();
 }
 
-void AboutSigninInternalsFactory::RegisterUserPrefs(
+void AboutSigninInternalsFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* user_prefs) {
   // SigninManager information for about:signin-internals.
   for (int i = UNTIMED_FIELDS_BEGIN; i < UNTIMED_FIELDS_END; ++i) {
diff --git a/chrome/browser/signin/about_signin_internals_factory.h b/chrome/browser/signin/about_signin_internals_factory.h
index c362aac..59e6a7e 100644
--- a/chrome/browser/signin/about_signin_internals_factory.h
+++ b/chrome/browser/signin/about_signin_internals_factory.h
@@ -23,7 +23,7 @@
   static AboutSigninInternalsFactory* GetInstance();
 
   // Implementation of BrowserContextKeyedServiceFactory.
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
 
  private:
diff --git a/chrome/browser/signin/android_profile_oauth2_token_service.cc b/chrome/browser/signin/android_profile_oauth2_token_service.cc
index c013185..8516a87 100644
--- a/chrome/browser/signin/android_profile_oauth2_token_service.cc
+++ b/chrome/browser/signin/android_profile_oauth2_token_service.cc
@@ -4,11 +4,41 @@
 
 #include "chrome/browser/signin/android_profile_oauth2_token_service.h"
 
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
 #include "base/bind.h"
+#include "base/logging.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/sync/profile_sync_service_android.h"
 #include "content/public/browser/browser_thread.h"
+#include "jni/AndroidProfileOAuth2TokenServiceHelper_jni.h"
 #include "net/url_request/url_request_context_getter.h"
 
+using base::android::AttachCurrentThread;
+using base::android::CheckException;
+using base::android::ConvertJavaStringToUTF8;
+using base::android::ConvertUTF8ToJavaString;
+using base::android::ScopedJavaLocalRef;
+using content::BrowserThread;
+
+namespace {
+
+std::string CombineScopes(const OAuth2TokenService::ScopeSet& scopes) {
+  // The Android AccountManager supports multiple scopes separated by a space:
+  // https://code.google.com/p/google-api-java-client/wiki/OAuth2#Android
+  std::string scope;
+  for (OAuth2TokenService::ScopeSet::const_iterator it = scopes.begin();
+       it != scopes.end(); ++it) {
+    if (!scope.empty())
+      scope += " ";
+    scope += *it;
+  }
+  return scope;
+}
+
+}  // namespace
+
 AndroidProfileOAuth2TokenService::AndroidProfileOAuth2TokenService(
     net::URLRequestContextGetter* getter)
     : ProfileOAuth2TokenService(getter) {
@@ -21,42 +51,91 @@
     AndroidProfileOAuth2TokenService::StartRequest(
         const OAuth2TokenService::ScopeSet& scopes,
         OAuth2TokenService::Consumer* consumer) {
+  const std::string& sync_username =
+      SigninManagerFactory::GetForProfile(profile())->
+          GetAuthenticatedUsername();
+  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK(!sync_username.empty());
+  return StartRequestForUsername(sync_username, scopes, consumer);
+}
+
+scoped_ptr<OAuth2TokenService::Request>
+    AndroidProfileOAuth2TokenService::StartRequestForUsername(
+        const std::string& username,
+        const OAuth2TokenService::ScopeSet& scopes,
+        OAuth2TokenService::Consumer* consumer) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 
-  if (HasCacheEntry(scopes))
-    return StartCacheLookupRequest(scopes, consumer);
-
   scoped_ptr<RequestImpl> request(new RequestImpl(consumer));
-  DCHECK_EQ(scopes.size(), 1U);
-  std::vector<std::string> scope_list(scopes.begin(), scopes.end());
-  ProfileSyncServiceAndroid* sync_service =
-      ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid();
-  sync_service->FetchOAuth2Token(
-      scope_list.front(),
-      base::Bind(&RequestImpl::InformConsumer,
-                 request->AsWeakPtr()));
+  FetchOAuth2Token(
+      username,
+      CombineScopes(scopes),
+      base::Bind(&RequestImpl::InformConsumer, request->AsWeakPtr()));
   return request.PassAs<Request>();
 }
 
+bool AndroidProfileOAuth2TokenService::RefreshTokenIsAvailable() {
+  SigninManagerBase* signin_manager =
+      SigninManagerFactory::GetForProfile(profile());
+  return !signin_manager->GetAuthenticatedUsername().empty();
+}
+
 void AndroidProfileOAuth2TokenService::InvalidateToken(
     const ScopeSet& scopes,
     const std::string& invalid_token) {
   OAuth2TokenService::InvalidateToken(scopes, invalid_token);
 
-  DCHECK_EQ(scopes.size(), 1U);
-  std::vector<std::string> scope_list(scopes.begin(), scopes.end());
-  ProfileSyncServiceAndroid* sync_service =
-      ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid();
-  sync_service->InvalidateOAuth2Token(
-      scope_list.front(),
-      invalid_token);
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jstring> j_invalid_token =
+      ConvertUTF8ToJavaString(env, invalid_token);
+  Java_AndroidProfileOAuth2TokenServiceHelper_invalidateOAuth2AuthToken(
+      env, base::android::GetApplicationContext(),
+      j_invalid_token.obj());
 }
 
-bool AndroidProfileOAuth2TokenService::ShouldCacheForRefreshToken(
-    TokenService *token_service,
-    const std::string& refresh_token) {
-  // The parent class skips caching if the TokenService login token is stale,
-  // but on Android the user is always logged in to exactly one profile, so
-  // this concept doesn't exist and we can simply always cache.
-  return true;
+void AndroidProfileOAuth2TokenService::FetchOAuth2Token(
+    const std::string& username,
+    const std::string& scope,
+    const FetchOAuth2TokenCallback& callback) {
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jstring> j_username =
+      ConvertUTF8ToJavaString(env, username);
+  ScopedJavaLocalRef<jstring> j_scope =
+      ConvertUTF8ToJavaString(env, scope);
+
+  // Allocate a copy of the callback on the heap, because the callback
+  // needs to be passed through JNI as an int.
+  // It will be passed back to OAuth2TokenFetched(), where it will be freed.
+  scoped_ptr<FetchOAuth2TokenCallback> heap_callback(
+      new FetchOAuth2TokenCallback(callback));
+
+  // Call into Java to get a new token.
+  Java_AndroidProfileOAuth2TokenServiceHelper_getOAuth2AuthToken(
+      env, base::android::GetApplicationContext(),
+      j_username.obj(),
+      j_scope.obj(),
+      reinterpret_cast<int>(heap_callback.release()));
+}
+
+// Called from Java when fetching of an OAuth2 token is finished. The
+// |authToken| param is only valid when |result| is true.
+void OAuth2TokenFetched(JNIEnv* env, jclass clazz,
+    jstring authToken,
+    jboolean result,
+    jint nativeCallback) {
+  std::string token = ConvertJavaStringToUTF8(env, authToken);
+  scoped_ptr<AndroidProfileOAuth2TokenService::FetchOAuth2TokenCallback>
+      heap_callback(
+          reinterpret_cast<
+              AndroidProfileOAuth2TokenService::FetchOAuth2TokenCallback*>(
+                  nativeCallback));
+  GoogleServiceAuthError err(result ?
+                             GoogleServiceAuthError::NONE :
+                             GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
+  heap_callback->Run(err, token, base::Time());
+}
+
+// static
+bool AndroidProfileOAuth2TokenService::Register(JNIEnv* env) {
+  return RegisterNativesImpl(env);
 }
diff --git a/chrome/browser/signin/android_profile_oauth2_token_service.h b/chrome/browser/signin/android_profile_oauth2_token_service.h
index 14556c0..22c805b 100644
--- a/chrome/browser/signin/android_profile_oauth2_token_service.h
+++ b/chrome/browser/signin/android_profile_oauth2_token_service.h
@@ -5,9 +5,15 @@
 #ifndef CHROME_BROWSER_SIGNIN_ANDROID_PROFILE_OAUTH2_TOKEN_SERVICE_H_
 #define CHROME_BROWSER_SIGNIN_ANDROID_PROFILE_OAUTH2_TOKEN_SERVICE_H_
 
+#include <jni.h>
 #include <string>
 
+#include "base/android/jni_helper.h"
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
 #include "chrome/browser/signin/profile_oauth2_token_service.h"
+#include "google_apis/gaia/google_service_auth_error.h"
 
 namespace net {
 class URLRequestContextGetter;
@@ -15,6 +21,7 @@
 
 class TokenService;
 
+
 // A specialization of ProfileOAuth2TokenService that will be returned by
 // ProfileOAuth2TokenServiceFactory for OS_ANDROID.  This instance uses
 // native Android features to lookup OAuth2 tokens.
@@ -25,24 +32,49 @@
 // request from other thread, please use ProfileOAuth2TokenServiceRequest.
 class AndroidProfileOAuth2TokenService : public ProfileOAuth2TokenService {
  public:
+
+  // Callback from FetchOAuth2Token.
+  // Arguments:
+  // - the error, or NONE if the token fetch was successful.
+  // - the OAuth2 access token.
+  // - the expiry time of the token (may be null, indicating that the expiry
+  //   time is unknown.
+  typedef base::Callback<void(
+      const GoogleServiceAuthError&, const std::string&, const base::Time&)>
+          FetchOAuth2TokenCallback;
+
   // Start the OAuth2 access token for the given scopes using
   // ProfileSyncServiceAndroid.
   virtual scoped_ptr<OAuth2TokenService::Request> StartRequest(
       const OAuth2TokenService::ScopeSet& scopes,
       OAuth2TokenService::Consumer* consumer) OVERRIDE;
 
+  // StartRequest() fetches a token for the currently signed-in account; this
+  // version uses the account corresponding to |username|. This allows fetching
+  // tokens before a user is signed-in (e.g. during the sign-in flow).
+  scoped_ptr<OAuth2TokenService::Request> StartRequestForUsername(
+      const std::string& username,
+      const OAuth2TokenService::ScopeSet& scopes,
+      OAuth2TokenService::Consumer* consumer);
+
+  virtual bool RefreshTokenIsAvailable() OVERRIDE;
   virtual void InvalidateToken(const ScopeSet& scopes,
                                const std::string& invalid_token) OVERRIDE;
 
+  // Registers the AndroidProfileOAuth2TokenService's native methods through
+  // JNI.
+  static bool Register(JNIEnv* env);
+
  protected:
   friend class ProfileOAuth2TokenServiceFactory;
   explicit AndroidProfileOAuth2TokenService(
       net::URLRequestContextGetter* getter);
   virtual ~AndroidProfileOAuth2TokenService();
 
-  // Takes injected TokenService for testing.
-  bool ShouldCacheForRefreshToken(TokenService *token_service,
-                                  const std::string& refresh_token);
+  // virtual for testing.
+  virtual void FetchOAuth2Token(const std::string& username,
+                                const std::string& scope,
+                                const FetchOAuth2TokenCallback& callback);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AndroidProfileOAuth2TokenService);
diff --git a/chrome/browser/signin/fake_signin_manager.cc b/chrome/browser/signin/fake_signin_manager.cc
index 43d5306..51d4e91 100644
--- a/chrome/browser/signin/fake_signin_manager.cc
+++ b/chrome/browser/signin/fake_signin_manager.cc
@@ -6,12 +6,12 @@
 
 #include "base/callback_helpers.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/chrome_signin_manager_delegate.h"
 #include "chrome/browser/signin/signin_global_error.h"
 #include "chrome/browser/ui/global_error/global_error_service.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/signin/oauth2_token_service.cc b/chrome/browser/signin/oauth2_token_service.cc
index 8564175..c372cd7 100644
--- a/chrome/browser/signin/oauth2_token_service.cc
+++ b/chrome/browser/signin/oauth2_token_service.cc
@@ -294,6 +294,14 @@
       pending_fetchers_.begin(), pending_fetchers_.end());
 }
 
+void OAuth2TokenService::AddObserver(Observer* observer) {
+  observer_list_.AddObserver(observer);
+}
+
+void OAuth2TokenService::RemoveObserver(Observer* observer) {
+  observer_list_.RemoveObserver(observer);
+}
+
 bool OAuth2TokenService::RefreshTokenIsAvailable() {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   return !GetRefreshToken().empty();
@@ -457,6 +465,27 @@
   token_cache_.clear();
 }
 
+void OAuth2TokenService::FireRefreshTokenAvailable(
+    const std::string& account_id) {
+  FOR_EACH_OBSERVER(Observer, observer_list_,
+                    OnRefreshTokenAvailable(account_id));
+}
+
+void OAuth2TokenService::FireRefreshTokenRevoked(
+    const std::string& account_id,
+    const GoogleServiceAuthError& error) {
+  FOR_EACH_OBSERVER(Observer, observer_list_,
+                    OnRefreshTokenRevoked(account_id, error));
+}
+
+void OAuth2TokenService::FireRefreshTokensLoaded() {
+  FOR_EACH_OBSERVER(Observer, observer_list_, OnRefreshTokensLoaded());
+}
+
+void OAuth2TokenService::FireRefreshTokensCleared() {
+  FOR_EACH_OBSERVER(Observer, observer_list_, OnRefreshTokensCleared());
+}
+
 int OAuth2TokenService::cache_size_for_testing() const {
   return token_cache_.size();
 }
diff --git a/chrome/browser/signin/oauth2_token_service.h b/chrome/browser/signin/oauth2_token_service.h
index 150e6ca..f961505 100644
--- a/chrome/browser/signin/oauth2_token_service.h
+++ b/chrome/browser/signin/oauth2_token_service.h
@@ -13,7 +13,9 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
 #include "base/time/time.h"
+#include "google_apis/gaia/google_service_auth_error.h"
 
 namespace base {
 class Time;
@@ -72,12 +74,40 @@
                                    const GoogleServiceAuthError& error) = 0;
   };
 
+  // Classes that want to listen for token availability should implement this
+  // interface and register with the AddObserver() call.
+  // TODO(rogerta): may get rid of |error| argument for OnRefreshTokenRevoked()
+  // once we stop supporting ClientLogin.  Need to evaluate if its still useful.
+  class Observer {
+   public:
+    // Called whenever a new login-scoped refresh token is available for
+    // account |account_id|. Once available, access tokens can be retrieved for
+    // this account.  This is called during initial startup for each token
+    // loaded.
+    virtual void OnRefreshTokenAvailable(const std::string& account_id) {}
+    // Called whenever the login-scoped refresh token becomes unavailable for
+    // account |account_id|.
+    virtual void OnRefreshTokenRevoked(const std::string& account_id,
+                                       const GoogleServiceAuthError& error) {}
+    // Called after all refresh tokens are loaded during OAuth2TokenService
+    // startup.
+    virtual void OnRefreshTokensLoaded() {}
+    // Called after all refresh tokens are removed from OAuth2TokenService.
+    virtual void OnRefreshTokensCleared() {}
+   protected:
+    virtual ~Observer() {}
+  };
+
   // A set of scopes in OAuth2 authentication.
   typedef std::set<std::string> ScopeSet;
 
   explicit OAuth2TokenService(net::URLRequestContextGetter* getter);
   virtual ~OAuth2TokenService();
 
+  // Add or remove observers of this token service.
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
   // Checks in the cache for a valid access token, and if not found starts
   // a request for an OAuth2 access token using the OAuth2 refresh token
   // maintained by this instance. The caller owns the returned Request.
@@ -89,7 +119,7 @@
 
   // Returns true if a refresh token exists. If false, calls to
   // |StartRequest| will result in a Consumer::OnGetTokenFailure callback.
-  bool RefreshTokenIsAvailable();
+  virtual bool RefreshTokenIsAvailable();
 
   // Mark an OAuth2 access token as invalid. This should be done if the token
   // was received from this class, but was not accepted by the server (e.g.,
@@ -150,6 +180,13 @@
   // Clears the internal token cache.
   void ClearCache();
 
+  // Called by subclasses to notify observers.
+  void FireRefreshTokenAvailable(const std::string& account_id);
+  void FireRefreshTokenRevoked(const std::string& account_id,
+                               const GoogleServiceAuthError& error);
+  void FireRefreshTokensLoaded();
+  void FireRefreshTokensCleared();
+
  private:
   // Class that fetches an OAuth2 access token for a given set of scopes and
   // OAuth2 refresh token.
@@ -191,6 +228,11 @@
   // A map from fetch parameters to a fetcher that is fetching an OAuth2 access
   // token using these parameters.
   std::map<FetchParameters, Fetcher*> pending_fetchers_;
+
+  // List of observers to notify when token availiability changes.
+  // Makes sure list is empty on destruction.
+  ObserverList<Observer, true> observer_list_;
+
   // Maximum number of retries in fetching an OAuth2 access token.
   static int max_fetch_retry_num_;
 
diff --git a/chrome/browser/signin/oauth2_token_service_unittest.cc b/chrome/browser/signin/oauth2_token_service_unittest.cc
index e9e9fca..901258b 100644
--- a/chrome/browser/signin/oauth2_token_service_unittest.cc
+++ b/chrome/browser/signin/oauth2_token_service_unittest.cc
@@ -5,11 +5,11 @@
 #include <string>
 
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/signin/oauth2_token_service.h"
 #include "chrome/browser/signin/oauth2_token_service_test_util.h"
 #include "chrome/browser/signin/token_service_factory.h"
 #include "chrome/browser/signin/token_service_unittest.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "google_apis/gaia/gaia_constants.h"
 #include "google_apis/gaia/google_service_auth_error.h"
diff --git a/chrome/browser/signin/profile_oauth2_token_service.cc b/chrome/browser/signin/profile_oauth2_token_service.cc
index fd6799b..be60548 100644
--- a/chrome/browser/signin/profile_oauth2_token_service.cc
+++ b/chrome/browser/signin/profile_oauth2_token_service.cc
@@ -8,12 +8,15 @@
 #include "base/message_loop.h"
 #include "base/stl_util.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/signin_global_error.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/signin/token_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/ui/global_error/global_error_service.h"
+#include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
@@ -21,6 +24,17 @@
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "net/url_request/url_request_context_getter.h"
 
+namespace {
+
+std::string GetAccountId(Profile* profile) {
+  SigninManagerBase* signin_manager =
+      SigninManagerFactory::GetForProfileIfExists(profile);
+  return signin_manager ? signin_manager->GetAuthenticatedUsername() :
+      std::string();
+}
+
+}  // namespace
+
 ProfileOAuth2TokenService::ProfileOAuth2TokenService(
     net::URLRequestContextGetter* getter)
     : OAuth2TokenService(getter),
@@ -29,6 +43,9 @@
 }
 
 ProfileOAuth2TokenService::~ProfileOAuth2TokenService() {
+  DCHECK(!signin_global_error_.get()) <<
+      "ProfileOAuth2TokenService::Initialize called but not "
+      "ProfileOAuth2TokenService::Shutdown";
 }
 
 void ProfileOAuth2TokenService::Initialize(Profile* profile) {
@@ -38,6 +55,11 @@
   DCHECK(!profile_);
   profile_ = profile;
 
+  signin_global_error_.reset(new SigninGlobalError(profile));
+  GlobalErrorServiceFactory::GetForProfile(profile_)->AddGlobalError(
+      signin_global_error_.get());
+  signin_global_error_->AddProvider(this);
+
   content::Source<TokenService> token_service_source(
       TokenServiceFactory::GetForProfile(profile));
   registrar_.Add(this,
@@ -46,15 +68,19 @@
   registrar_.Add(this,
                  chrome::NOTIFICATION_TOKEN_AVAILABLE,
                  token_service_source);
-  SigninManagerFactory::GetForProfile(profile_)->signin_global_error()->
-      AddProvider(this);
+  registrar_.Add(this,
+                 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED,
+                 token_service_source);
+  registrar_.Add(this,
+                 chrome::NOTIFICATION_TOKEN_LOADING_FINISHED,
+                 token_service_source);
 }
 
 void ProfileOAuth2TokenService::Shutdown() {
-  if (profile_) {
-    SigninManagerFactory::GetForProfile(profile_)->signin_global_error()->
-        RemoveProvider(this);
-  }
+  signin_global_error_->RemoveProvider(this);
+  GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError(
+      signin_global_error_.get());
+  signin_global_error_.reset();
 }
 
 std::string ProfileOAuth2TokenService::GetRefreshToken() {
@@ -75,8 +101,7 @@
 
   if (error.state() != last_auth_error_.state()) {
     last_auth_error_ = error;
-    SigninManagerFactory::GetForProfile(profile_)->signin_global_error()->
-        AuthStatusChanged();
+    signin_global_error_->AuthStatusChanged();
   }
 }
 
@@ -84,19 +109,44 @@
     int type,
     const content::NotificationSource& source,
     const content::NotificationDetails& details) {
-  DCHECK(type == chrome::NOTIFICATION_TOKENS_CLEARED ||
-         type == chrome::NOTIFICATION_TOKEN_AVAILABLE);
-  if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) {
-    TokenService::TokenAvailableDetails* tok_details =
-        content::Details<TokenService::TokenAvailableDetails>(details).ptr();
-    if (tok_details->service() != GaiaConstants::kGaiaOAuth2LoginRefreshToken)
-      return;
+  switch (type) {
+    case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
+      TokenService::TokenAvailableDetails* tok_details =
+          content::Details<TokenService::TokenAvailableDetails>(details).ptr();
+      if (tok_details->service() ==
+          GaiaConstants::kGaiaOAuth2LoginRefreshToken) {
+        ClearCache();
+        UpdateAuthError(GoogleServiceAuthError::AuthErrorNone());
+        FireRefreshTokenAvailable(GetAccountId(profile_));
+      }
+      break;
+    }
+    case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: {
+      TokenService::TokenRequestFailedDetails* tok_details =
+          content::Details<TokenService::TokenRequestFailedDetails>(details)
+              .ptr();
+      if (tok_details->service() == GaiaConstants::kLSOService ||
+          tok_details->service() ==
+              GaiaConstants::kGaiaOAuth2LoginRefreshToken) {
+        ClearCache();
+        UpdateAuthError(tok_details->error());
+        FireRefreshTokenRevoked(GetAccountId(profile_), tok_details->error());
+      }
+      break;
+    }
+    case chrome::NOTIFICATION_TOKENS_CLEARED: {
+      ClearCache();
+      UpdateAuthError(GoogleServiceAuthError::AuthErrorNone());
+      FireRefreshTokensCleared();
+      break;
+    }
+    case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED:
+      FireRefreshTokensLoaded();
+      break;
+    default:
+      NOTREACHED() << "Invalid notification type=" << type;
+      break;
   }
-  // The GaiaConstants::kGaiaOAuth2LoginRefreshToken token is used to create
-  // OAuth2 access tokens. If this token either changes or is cleared, any
-  // available tokens must be invalidated.
-  ClearCache();
-  UpdateAuthError(GoogleServiceAuthError::AuthErrorNone());
 }
 
 GoogleServiceAuthError ProfileOAuth2TokenService::GetAuthStatus() const {
diff --git a/chrome/browser/signin/profile_oauth2_token_service.h b/chrome/browser/signin/profile_oauth2_token_service.h
index b4054a1..d5cbe9f 100644
--- a/chrome/browser/signin/profile_oauth2_token_service.h
+++ b/chrome/browser/signin/profile_oauth2_token_service.h
@@ -21,6 +21,7 @@
 class GoogleServiceAuthError;
 class Profile;
 class TokenService;
+class SigninGlobalError;
 
 // ProfileOAuth2TokenService is a BrowserContextKeyedService that retrieves
 // OAuth2 access tokens for a given set of scopes using the OAuth2 login
@@ -59,11 +60,22 @@
   bool ShouldCacheForRefreshToken(TokenService *token_service,
                                   const std::string& refresh_token);
 
+  SigninGlobalError* signin_global_error() {
+    return signin_global_error_.get();
+  }
+
+  const SigninGlobalError* signin_global_error() const {
+    return signin_global_error_.get();
+  }
+
+  Profile* profile() const { return profile_; }
+
  protected:
   friend class ProfileOAuth2TokenServiceFactory;
   explicit ProfileOAuth2TokenService(net::URLRequestContextGetter* getter);
   virtual ~ProfileOAuth2TokenService();
 
+  // OAuth2TokenService overrides.
   virtual std::string GetRefreshToken() OVERRIDE;
 
   // Updates the internal cache of the result from the most-recently-completed
@@ -89,6 +101,12 @@
   // The profile with which this instance was initialized, or NULL.
   Profile* profile_;
 
+  // Used to show auth errors in the wrench menu. The SigninGlobalError is
+  // different than most GlobalErrors in that its lifetime is controlled by
+  // ProfileOAuth2TokenService (so we can expose a reference for use in the
+  // wrench menu).
+  scoped_ptr<SigninGlobalError> signin_global_error_;
+
   // The auth status from the most-recently-completed request.
   GoogleServiceAuthError last_auth_error_;
 
diff --git a/chrome/browser/signin/profile_oauth2_token_service_factory.cc b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
index 97687dc..92c88e6 100644
--- a/chrome/browser/signin/profile_oauth2_token_service_factory.cc
+++ b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
@@ -6,31 +6,36 @@
 
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/profile_oauth2_token_service.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/signin/token_service_factory.h"
+#include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
 
-#if defined(OS_ANDROID)
-#include "chrome/browser/signin/android_profile_oauth2_token_service.h"
-#endif
-
 ProfileOAuth2TokenServiceFactory::ProfileOAuth2TokenServiceFactory()
     : BrowserContextKeyedServiceFactory(
         "ProfileOAuth2TokenService",
         BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(SigninManagerFactory::GetInstance());
+  DependsOn(GlobalErrorServiceFactory::GetInstance());
   DependsOn(TokenServiceFactory::GetInstance());
 }
 
 ProfileOAuth2TokenServiceFactory::~ProfileOAuth2TokenServiceFactory() {
 }
 
+#if defined(OS_ANDROID)
+// static
+AndroidProfileOAuth2TokenService*
+    ProfileOAuth2TokenServiceFactory::GetForProfile(Profile* profile) {
+  return static_cast<AndroidProfileOAuth2TokenService*>(
+      GetInstance()->GetServiceForBrowserContext(profile, true));
+}
+#else
 // static
 ProfileOAuth2TokenService* ProfileOAuth2TokenServiceFactory::GetForProfile(
     Profile* profile) {
   return static_cast<ProfileOAuth2TokenService*>(
       GetInstance()->GetServiceForBrowserContext(profile, true));
 }
+#endif  // defined(OS_ANDROID)
 
 // static
 ProfileOAuth2TokenServiceFactory*
diff --git a/chrome/browser/signin/profile_oauth2_token_service_factory.h b/chrome/browser/signin/profile_oauth2_token_service_factory.h
index 9051758..7ecef37 100644
--- a/chrome/browser/signin/profile_oauth2_token_service_factory.h
+++ b/chrome/browser/signin/profile_oauth2_token_service_factory.h
@@ -8,6 +8,10 @@
 #include "base/memory/singleton.h"
 #include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
 
+#if defined(OS_ANDROID)
+#include "chrome/browser/signin/android_profile_oauth2_token_service.h"
+#endif
+
 class ProfileOAuth2TokenService;
 class Profile;
 
@@ -22,7 +26,11 @@
   // cannot have a ProfileOAuth2TokenService (for example, if |profile| is
   // incognito).  On Android, returns the AndroidProfileOAuth2TokenService
   // specialization.
+#if defined(OS_ANDROID)
+  static AndroidProfileOAuth2TokenService* GetForProfile(Profile* profile);
+#else
   static ProfileOAuth2TokenService* GetForProfile(Profile* profile);
+#endif
 
   // Returns an instance of the ProfileOAuth2TokenServiceFactory singleton.
   static ProfileOAuth2TokenServiceFactory* GetInstance();
diff --git a/chrome/browser/signin/profile_oauth2_token_service_request_unittest.cc b/chrome/browser/signin/profile_oauth2_token_service_request_unittest.cc
index 0ed2903..adcf700 100644
--- a/chrome/browser/signin/profile_oauth2_token_service_request_unittest.cc
+++ b/chrome/browser/signin/profile_oauth2_token_service_request_unittest.cc
@@ -159,7 +159,9 @@
 
 static BrowserContextKeyedService* CreateOAuth2TokenService(
     content::BrowserContext* profile) {
-  return new MockProfileOAuth2TokenService();
+  MockProfileOAuth2TokenService* mock = new MockProfileOAuth2TokenService();
+  mock->Initialize(static_cast<Profile*>(profile));
+  return mock;
 }
 
 class ProfileOAuth2TokenServiceRequestTest : public testing::Test {
diff --git a/chrome/browser/signin/profile_oauth2_token_service_unittest.cc b/chrome/browser/signin/profile_oauth2_token_service_unittest.cc
index 036a1c6..8170bfe 100644
--- a/chrome/browser/signin/profile_oauth2_token_service_unittest.cc
+++ b/chrome/browser/signin/profile_oauth2_token_service_unittest.cc
@@ -15,9 +15,15 @@
 
 using content::BrowserThread;
 
-class ProfileOAuth2TokenServiceTest : public TokenServiceTestHarness {
+class ProfileOAuth2TokenServiceTest : public TokenServiceTestHarness,
+                                      public OAuth2TokenService::Observer {
  public:
-  ProfileOAuth2TokenServiceTest() {}
+  ProfileOAuth2TokenServiceTest()
+      : token_available_count_(0),
+        token_revoked_count_(0),
+        tokens_loaded_count_(0),
+        tokens_cleared_count_(0) {
+  }
 
   virtual void SetUp() OVERRIDE {
     TokenServiceTestHarness::SetUp();
@@ -27,25 +33,146 @@
     profile_->CreateRequestContext();
     oauth2_service_ = ProfileOAuth2TokenServiceFactory::GetForProfile(
         profile_.get());
+
+    oauth2_service_->AddObserver(this);
   }
 
   virtual void TearDown() OVERRIDE {
+    oauth2_service_->RemoveObserver(this);
     TokenServiceTestHarness::TearDown();
   }
 
+  // OAuth2TokenService::Observer implementation.
+  virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE {
+    ++token_available_count_;
+  }
+  virtual void OnRefreshTokenRevoked(
+      const std::string& account_id,
+      const GoogleServiceAuthError& error) OVERRIDE {
+    ++token_revoked_count_;
+  }
+  virtual void OnRefreshTokensLoaded() OVERRIDE {
+    ++tokens_loaded_count_;
+  }
+  virtual void OnRefreshTokensCleared() OVERRIDE {
+    ++tokens_cleared_count_;
+  }
+
+  void ResetObserverCounts() {
+    token_available_count_ = 0;
+    token_revoked_count_ = 0;
+    tokens_loaded_count_ = 0;
+    tokens_cleared_count_ = 0;
+  }
+
+  void ExpectNoNotifications() {
+    EXPECT_EQ(0, token_available_count_);
+    EXPECT_EQ(0, token_revoked_count_);
+    EXPECT_EQ(0, tokens_loaded_count_);
+    EXPECT_EQ(0, tokens_cleared_count_);
+    ResetObserverCounts();
+  }
+
+  void ExpectOneTokenAvailableNotification() {
+    EXPECT_EQ(1, token_available_count_);
+    EXPECT_EQ(0, token_revoked_count_);
+    EXPECT_EQ(0, tokens_loaded_count_);
+    EXPECT_EQ(0, tokens_cleared_count_);
+    ResetObserverCounts();
+  }
+
+  void ExpectOneTokenRevokedNotification() {
+    EXPECT_EQ(0, token_available_count_);
+    EXPECT_EQ(1, token_revoked_count_);
+    EXPECT_EQ(0, tokens_loaded_count_);
+    EXPECT_EQ(0, tokens_cleared_count_);
+    ResetObserverCounts();
+  }
+
+  void ExpectOneTokensLoadedNotification() {
+    EXPECT_EQ(0, token_available_count_);
+    EXPECT_EQ(0, token_revoked_count_);
+    EXPECT_EQ(1, tokens_loaded_count_);
+    EXPECT_EQ(0, tokens_cleared_count_);
+    ResetObserverCounts();
+  }
+
+  void ExpectOneTokensClearedNotification() {
+    EXPECT_EQ(0, token_available_count_);
+    EXPECT_EQ(0, token_revoked_count_);
+    EXPECT_EQ(0, tokens_loaded_count_);
+    EXPECT_EQ(1, tokens_cleared_count_);
+    ResetObserverCounts();
+  }
+
  protected:
   scoped_ptr<content::TestBrowserThread> io_thread_;
   net::TestURLFetcherFactory factory_;
   ProfileOAuth2TokenService* oauth2_service_;
   TestingOAuth2TokenServiceConsumer consumer_;
+  int token_available_count_;
+  int token_revoked_count_;
+  int tokens_loaded_count_;
+  int tokens_cleared_count_;
 };
 
+TEST_F(ProfileOAuth2TokenServiceTest, Notifications) {
+  EXPECT_EQ(0, oauth2_service_->cache_size_for_testing());
+  service_->IssueAuthTokenForTest(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
+                                  "refreshToken");
+  ExpectOneTokenAvailableNotification();
+
+  service_->EraseTokensFromDB();
+  service_->ResetCredentialsInMemory();
+  ExpectOneTokensClearedNotification();
+}
+
+// Until the TokenService class is removed, problems fetching the LSO token
+// should translate to problems fetching the oauth2 refresh token.
+TEST_F(ProfileOAuth2TokenServiceTest, LsoNotification) {
+  EXPECT_EQ(0, oauth2_service_->cache_size_for_testing());
+
+  // Get a valid token.
+  service_->IssueAuthTokenForTest(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
+                                  "refreshToken");
+  ExpectOneTokenAvailableNotification();
+
+  service_->OnIssueAuthTokenFailure(
+      GaiaConstants::kLSOService,
+      GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
+  ExpectOneTokenRevokedNotification();
+}
+
+// Until the TokenService class is removed, finish token loading in TokenService
+// should translate to finish token loading in ProfileOAuth2TokenService.
+TEST_F(ProfileOAuth2TokenServiceTest, TokensLoaded) {
+  EXPECT_EQ(0, oauth2_service_->cache_size_for_testing());
+  service_->LoadTokensFromDB();
+  WaitForDBLoadCompletion();
+  ExpectOneTokensLoadedNotification();
+}
+
+TEST_F(ProfileOAuth2TokenServiceTest, UnknownNotificationsAreNoops) {
+  EXPECT_EQ(0, oauth2_service_->cache_size_for_testing());
+  service_->IssueAuthTokenForTest("foo", "toto");
+  ExpectNoNotifications();
+
+  // Get a valid token.
+  service_->IssueAuthTokenForTest(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
+                                  "refreshToken");
+  ExpectOneTokenAvailableNotification();
+
+  service_->IssueAuthTokenForTest("bar", "baz");
+  ExpectNoNotifications();
+}
+
 TEST_F(ProfileOAuth2TokenServiceTest, TokenServiceUpdateClearsCache) {
   EXPECT_EQ(0, oauth2_service_->cache_size_for_testing());
   std::set<std::string> scope_list;
   scope_list.insert("scope");
   service_->IssueAuthTokenForTest(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
                                   "refreshToken");
+  ExpectOneTokenAvailableNotification();
   scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest(
       scope_list, &consumer_));
   message_loop_.RunUntilIdle();
@@ -61,10 +188,14 @@
   // Signs out and signs in
   service_->IssueAuthTokenForTest(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
                                   "");
+  ExpectOneTokenAvailableNotification();
   service_->EraseTokensFromDB();
+  ExpectOneTokensClearedNotification();
+
   EXPECT_EQ(0, oauth2_service_->cache_size_for_testing());
   service_->IssueAuthTokenForTest(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
                                   "refreshToken");
+  ExpectOneTokenAvailableNotification();
 
   request = oauth2_service_->StartRequest(scope_list, &consumer_);
   message_loop_.RunUntilIdle();
@@ -86,11 +217,13 @@
 
   service_->IssueAuthTokenForTest(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
                                   "T1");
+  ExpectOneTokenAvailableNotification();
   EXPECT_TRUE(oauth2_service_->ShouldCacheForRefreshToken(service_, "T1"));
   EXPECT_FALSE(oauth2_service_->ShouldCacheForRefreshToken(service_, "T2"));
 
   service_->IssueAuthTokenForTest(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
                                   "T2");
+  ExpectOneTokenAvailableNotification();
   EXPECT_TRUE(oauth2_service_->ShouldCacheForRefreshToken(service_, "T2"));
   EXPECT_FALSE(oauth2_service_->ShouldCacheForRefreshToken(NULL, "T2"));
 }
diff --git a/chrome/browser/signin/signin_global_error.cc b/chrome/browser/signin/signin_global_error.cc
index 4418eba..4281626 100644
--- a/chrome/browser/signin/signin_global_error.cc
+++ b/chrome/browser/signin/signin_global_error.cc
@@ -5,24 +5,27 @@
 #include "chrome/browser/signin/signin_global_error.h"
 
 #include "base/logging.h"
+#include "base/prefs/pref_service.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/profile_oauth2_token_service.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/global_error/global_error_service.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
-SigninGlobalError::SigninGlobalError(SigninManagerBase* manager,
-                                     Profile* profile)
-    : auth_error_(GoogleServiceAuthError::AuthErrorNone()),
-      signin_manager_(manager),
-      profile_(profile) {
+SigninGlobalError::SigninGlobalError(Profile* profile)
+    : auth_error_(GoogleServiceAuthError::AuthErrorNone()), profile_(profile) {
 }
 
 SigninGlobalError::~SigninGlobalError() {
@@ -84,7 +87,12 @@
 }
 
 string16 SigninGlobalError::MenuItemLabel() {
-  if (signin_manager_->GetAuthenticatedUsername().empty() ||
+  std::string username;
+  SigninManagerBase* signin_manager =
+      SigninManagerFactory::GetForProfileIfExists(profile_);
+  if (signin_manager)
+    username = signin_manager->GetAuthenticatedUsername();
+  if (username.empty() ||
       auth_error_.state() == GoogleServiceAuthError::NONE ||
       auth_error_.state() == GoogleServiceAuthError::CONNECTION_FAILED) {
     // If the user isn't signed in, or there's no auth error worth elevating to
@@ -128,9 +136,14 @@
 
 std::vector<string16> SigninGlobalError::GetBubbleViewMessages() {
   std::vector<string16> messages;
+
   // If the user isn't signed in, no need to display an error bubble.
-  if (signin_manager_->GetAuthenticatedUsername().empty()) {
-    return messages;
+  SigninManagerBase* signin_manager =
+      SigninManagerFactory::GetForProfileIfExists(profile_);
+  if (signin_manager) {
+    std::string username = signin_manager->GetAuthenticatedUsername();
+    if (username.empty())
+      return messages;
   }
 
   switch (auth_error_.state()) {
@@ -190,3 +203,9 @@
 void SigninGlobalError::BubbleViewCancelButtonPressed(Browser* browser) {
   NOTREACHED();
 }
+
+// static
+SigninGlobalError* SigninGlobalError::GetForProfile(Profile* profile) {
+  return ProfileOAuth2TokenServiceFactory::GetForProfile(profile)->
+      signin_global_error();
+}
diff --git a/chrome/browser/signin/signin_global_error.h b/chrome/browser/signin/signin_global_error.h
index 8242115..1667031 100644
--- a/chrome/browser/signin/signin_global_error.h
+++ b/chrome/browser/signin/signin_global_error.h
@@ -12,7 +12,6 @@
 #include "google_apis/gaia/google_service_auth_error.h"
 
 class Profile;
-class SigninManagerBase;
 
 // Shows auth errors on the wrench menu using a bubble view and a
 // menu item. Services that wish to expose auth errors to the user should
@@ -31,7 +30,7 @@
     virtual GoogleServiceAuthError GetAuthStatus() const = 0;
   };
 
-  SigninGlobalError(SigninManagerBase* signin_manager, Profile* profile);
+  SigninGlobalError(Profile* profile);
   virtual ~SigninGlobalError();
 
   // Adds a provider which the SigninGlobalError object will start querying for
@@ -61,6 +60,9 @@
   virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
   virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
 
+  // Returns the SigninGlobalError instance for the given profile.
+  static SigninGlobalError* GetForProfile(Profile* profile);
+
  private:
   std::set<const AuthStatusProvider*> provider_set_;
 
@@ -68,9 +70,6 @@
   // NONE if AuthStatusChanged() has never been invoked).
   GoogleServiceAuthError auth_error_;
 
-  // The SigninManager that owns this object.
-  SigninManagerBase* signin_manager_;
-
   // The Profile this object belongs to.
   Profile* profile_;
 };
diff --git a/chrome/browser/signin/signin_global_error_unittest.cc b/chrome/browser/signin/signin_global_error_unittest.cc
index e0aeba0..ade065e 100644
--- a/chrome/browser/signin/signin_global_error_unittest.cc
+++ b/chrome/browser/signin/signin_global_error_unittest.cc
@@ -10,11 +10,11 @@
 #include "chrome/browser/signin/fake_signin_manager.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
-#include "chrome/browser/signin/token_service_factory.h"
 #include "chrome/browser/ui/global_error/global_error_service.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 class SigninGlobalErrorTest : public testing::Test {
@@ -27,11 +27,12 @@
         SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse(
             profile_.get(), FakeSigninManagerBase::Build));
     profile_->GetPrefs()->SetString(
-          prefs::kGoogleServicesUsername, "testuser@test.com");
+        prefs::kGoogleServicesUsername, "testuser@test.com");
     manager->Initialize(profile_.get(), NULL);
-    global_error_ = manager->signin_global_error();
+    global_error_ = SigninGlobalError::GetForProfile(profile_.get());
   }
 
+  content::TestBrowserThreadBundle thread_bundle_;
   scoped_ptr<TestingProfile> profile_;
   SigninGlobalError* global_error_;
 };
diff --git a/chrome/browser/signin/signin_manager.cc b/chrome/browser/signin/signin_manager.cc
index 4ca5da1..d0629e5 100644
--- a/chrome/browser/signin/signin_manager.cc
+++ b/chrome/browser/signin/signin_manager.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_io_data.h"
 #include "chrome/browser/signin/about_signin_internals.h"
 #include "chrome/browser/signin/about_signin_internals_factory.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/signin/token_service_factory.h"
 #include "chrome/browser/ui/global_error/global_error_service.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
@@ -606,10 +606,29 @@
   }
 }
 
-
 void SigninManager::CompletePendingSignin() {
   DCHECK(!possibly_invalid_username_.empty());
-  SetAuthenticatedUsername(possibly_invalid_username_);
+  OnSignedIn(possibly_invalid_username_);
+
+  TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
+  token_service->UpdateCredentials(last_result_);
+  DCHECK(token_service->AreCredentialsValid());
+  token_service->StartFetchingTokens();
+
+  // If we have oauth2 tokens, tell token service about them so it does not
+  // need to fetch them again.
+  if (!temp_oauth_login_tokens_.refresh_token.empty()) {
+    token_service->UpdateCredentialsWithOAuth2(temp_oauth_login_tokens_);
+    temp_oauth_login_tokens_ = ClientOAuthResult();
+  }
+}
+
+void SigninManager::OnExternalSigninCompleted(const std::string& username) {
+  OnSignedIn(username);
+}
+
+void SigninManager::OnSignedIn(const std::string& username) {
+  SetAuthenticatedUsername(username);
   possibly_invalid_username_.clear();
   profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
                                   GetAuthenticatedUsername());
@@ -623,18 +642,6 @@
 
   password_.clear();  // Don't need it anymore.
   DisableOneClickSignIn(profile_);  // Don't ever offer again.
-
-  TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
-  token_service->UpdateCredentials(last_result_);
-  DCHECK(token_service->AreCredentialsValid());
-  token_service->StartFetchingTokens();
-
-  // If we have oauth2 tokens, tell token service about them so it does not
-  // need to fetch them again.
-  if (!temp_oauth_login_tokens_.refresh_token.empty()) {
-    token_service->UpdateCredentialsWithOAuth2(temp_oauth_login_tokens_);
-    temp_oauth_login_tokens_ = ClientOAuthResult();
-  }
 }
 
 void SigninManager::OnGetUserInfoFailure(const GoogleServiceAuthError& error) {
diff --git a/chrome/browser/signin/signin_manager.h b/chrome/browser/signin/signin_manager.h
index 4ae4c2f..1e84e0a 100644
--- a/chrome/browser/signin/signin_manager.h
+++ b/chrome/browser/signin/signin_manager.h
@@ -124,6 +124,10 @@
   // Invoked from an OAuthTokenFetchedCallback to complete user signin.
   virtual void CompletePendingSignin();
 
+  // Invoked from SigninManagerAndroid to indicate that the sign-in process
+  // has completed for |username|.
+  void OnExternalSigninCompleted(const std::string& username);
+
   // Returns true if there's a signin in progress.
   virtual bool AuthInProgress() const OVERRIDE;
 
@@ -229,6 +233,10 @@
   void OnGaiaCookiesFetched(
       const std::string session_index, const net::CookieList& cookie_list);
 
+  // Persists |username| as the currently signed-in account, and triggers
+  // a sign-in success notification.
+  void OnSignedIn(const std::string& username);
+
   // Called when a new request to re-authenticate a user is in progress.
   // Will clear in memory data but leaves the db as such so when the browser
   // restarts we can use the old token(which might throw a password error).
diff --git a/chrome/browser/signin/signin_manager_base.cc b/chrome/browser/signin/signin_manager_base.cc
index b9d2071..cab9de26 100644
--- a/chrome/browser/signin/signin_manager_base.cc
+++ b/chrome/browser/signin/signin_manager_base.cc
@@ -13,16 +13,13 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/signin/about_signin_internals.h"
 #include "chrome/browser/signin/about_signin_internals_factory.h"
-#include "chrome/browser/signin/signin_global_error.h"
 #include "chrome/browser/signin/signin_manager_cookie_helper.h"
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/signin/token_service_factory.h"
 #include "chrome/browser/sync/sync_prefs.h"
-#include "chrome/browser/ui/global_error/global_error_service.h"
-#include "chrome/browser/ui/global_error/global_error_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
@@ -39,18 +36,12 @@
 }
 
 SigninManagerBase::~SigninManagerBase() {
-  DCHECK(!signin_global_error_.get()) <<
-      "SigninManagerBase::Initialize called but not "
-      "SigninManagerBase::Shutdown";
 }
 
 void SigninManagerBase::Initialize(Profile* profile, PrefService* local_state) {
   // Should never call Initialize() twice.
   DCHECK(!IsInitialized());
   profile_ = profile;
-  signin_global_error_.reset(new SigninGlobalError(this, profile));
-  GlobalErrorServiceFactory::GetForProfile(profile_)->AddGlobalError(
-      signin_global_error_.get());
 
   // If the user is clearing the token service from the command line, then
   // clear their login info also (not valid to be logged in without any
@@ -118,11 +109,6 @@
 }
 
 void SigninManagerBase::Shutdown() {
-  if (signin_global_error_.get()) {
-    GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError(
-        signin_global_error_.get());
-    signin_global_error_.reset();
-  }
 }
 
 void SigninManagerBase::AddSigninDiagnosticsObserver(
diff --git a/chrome/browser/signin/signin_manager_base.h b/chrome/browser/signin/signin_manager_base.h
index 87c6be9..de49af1 100644
--- a/chrome/browser/signin/signin_manager_base.h
+++ b/chrome/browser/signin/signin_manager_base.h
@@ -39,7 +39,6 @@
 class CookieSettings;
 class ProfileIOData;
 class PrefService;
-class SigninGlobalError;
 
 // Details for the Notification type GOOGLE_SIGNIN_SUCCESSFUL.
 // A listener might use this to make note of a username / password
@@ -91,14 +90,6 @@
   // Returns true if there's a signin in progress.
   virtual bool AuthInProgress() const;
 
-  SigninGlobalError* signin_global_error() {
-    return signin_global_error_.get();
-  }
-
-  const SigninGlobalError* signin_global_error() const {
-    return signin_global_error_.get();
-  }
-
   // BrowserContextKeyedService implementation.
   virtual void Shutdown() OVERRIDE;
 
@@ -121,11 +112,6 @@
   // it).
   Profile* profile_;
 
-  // Used to show auth errors in the wrench menu. The SigninGlobalError is
-  // different than most GlobalErrors in that its lifetime is controlled by
-  // SigninManager (so we can expose a reference for use in the wrench menu).
-  scoped_ptr<SigninGlobalError> signin_global_error_;
-
   // Helper methods to notify all registered diagnostics observers with.
   void NotifyDiagnosticsObservers(
       const signin_internals_util::UntimedSigninStatusField& field,
diff --git a/chrome/browser/signin/signin_manager_factory.cc b/chrome/browser/signin/signin_manager_factory.cc
index f8974cf..8eb4645 100644
--- a/chrome/browser/signin/signin_manager_factory.cc
+++ b/chrome/browser/signin/signin_manager_factory.cc
@@ -9,7 +9,6 @@
 #include "chrome/browser/signin/chrome_signin_manager_delegate.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/token_service_factory.h"
-#include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "chrome/common/pref_names.h"
 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -19,7 +18,6 @@
         "SigninManager",
         BrowserContextDependencyManager::GetInstance()) {
   DependsOn(TokenServiceFactory::GetInstance());
-  DependsOn(GlobalErrorServiceFactory::GetInstance());
 }
 
 SigninManagerFactory::~SigninManagerFactory() {}
@@ -58,7 +56,7 @@
   return Singleton<SigninManagerFactory>::get();
 }
 
-void SigninManagerFactory::RegisterUserPrefs(
+void SigninManagerFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterStringPref(
       prefs::kGoogleServicesLastUsername,
diff --git a/chrome/browser/signin/signin_manager_factory.h b/chrome/browser/signin/signin_manager_factory.h
index 828ecb9..8278404 100644
--- a/chrome/browser/signin/signin_manager_factory.h
+++ b/chrome/browser/signin/signin_manager_factory.h
@@ -41,7 +41,7 @@
 
   // Implementation of BrowserContextKeyedServiceFactory (public so tests
   // can call it).
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
 
   // Registers the browser-global prefs used by SigninManager.
diff --git a/chrome/browser/signin/signin_manager_unittest.cc b/chrome/browser/signin/signin_manager_unittest.cc
index 0c5b796..232d9c5 100644
--- a/chrome/browser/signin/signin_manager_unittest.cc
+++ b/chrome/browser/signin/signin_manager_unittest.cc
@@ -11,11 +11,11 @@
 #include "base/prefs/testing_pref_service.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/signin/chrome_signin_manager_delegate.h"
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/signin/token_service_unittest.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/testing_browser_process.h"
@@ -658,3 +658,18 @@
       prefs::kGoogleServicesUsernamePattern, ".*@google.com");
   EXPECT_EQ("", manager_->GetAuthenticatedUsername());
 }
+
+TEST_F(SigninManagerTest, ExternalSignIn) {
+  manager_->Initialize(profile_.get(), g_browser_process->local_state());
+  EXPECT_EQ("",
+            profile_->GetPrefs()->GetString(prefs::kGoogleServicesUsername));
+  EXPECT_EQ("", manager_->GetAuthenticatedUsername());
+  EXPECT_EQ(0u, google_login_success_.size());
+
+  manager_->OnExternalSigninCompleted("external@example.com");
+  EXPECT_EQ(1u, google_login_success_.size());
+  EXPECT_EQ(0u, google_login_failure_.size());
+  EXPECT_EQ("external@example.com",
+            profile_->GetPrefs()->GetString(prefs::kGoogleServicesUsername));
+  EXPECT_EQ("external@example.com", manager_->GetAuthenticatedUsername());
+}
diff --git a/chrome/browser/signin/signin_names_io_thread.cc b/chrome/browser/signin/signin_names_io_thread.cc
index 0367988..2186ce3 100644
--- a/chrome/browser/signin/signin_names_io_thread.cc
+++ b/chrome/browser/signin/signin_names_io_thread.cc
@@ -7,10 +7,10 @@
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/signin_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/signin/signin_names_io_thread_unittest.cc b/chrome/browser/signin/signin_names_io_thread_unittest.cc
index 64674d4..f6f4beb 100644
--- a/chrome/browser/signin/signin_names_io_thread_unittest.cc
+++ b/chrome/browser/signin/signin_names_io_thread_unittest.cc
@@ -5,10 +5,10 @@
 #include "base/message_loop.h"
 #include "base/prefs/testing_pref_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_names_io_thread.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
diff --git a/chrome/browser/signin/signin_tracker.cc b/chrome/browser/signin/signin_tracker.cc
index 33c1c7f..b356efb 100644
--- a/chrome/browser/signin/signin_tracker.cc
+++ b/chrome/browser/signin/signin_tracker.cc
@@ -4,12 +4,12 @@
 
 #include "chrome/browser/signin/signin_tracker.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/signin/token_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "google_apis/gaia/gaia_constants.h"
diff --git a/chrome/browser/signin/signin_tracker_unittest.cc b/chrome/browser/signin/signin_tracker_unittest.cc
index b8fca1a..ac2d366 100644
--- a/chrome/browser/signin/signin_tracker_unittest.cc
+++ b/chrome/browser/signin/signin_tracker_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/compiler_specific.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/fake_auth_status_provider.h"
 #include "chrome/browser/signin/fake_signin_manager.h"
@@ -16,9 +17,8 @@
 #include "chrome/browser/signin/token_service_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/profile_sync_service_mock.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
-#include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "google_apis/gaia/gaia_constants.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 
@@ -59,8 +59,7 @@
 
 class SigninTrackerTest : public testing::Test {
  public:
-  SigninTrackerTest()
-    : ui_thread_(content::BrowserThread::UI, &ui_loop_) {}
+  SigninTrackerTest() {}
   virtual void SetUp() OVERRIDE {
     profile_.reset(new TestingProfile());
     mock_token_service_ = static_cast<MockTokenService*>(
@@ -87,13 +86,12 @@
         content::Details<const GoogleServiceSigninSuccessDetails>(&details));
   }
 
+  content::TestBrowserThreadBundle thread_bundle_;
   scoped_ptr<SigninTracker> tracker_;
   scoped_ptr<TestingProfile> profile_;
   FakeSigninManagerBase* mock_signin_manager_;
   MockTokenService* mock_token_service_;
   MockObserver observer_;
-  base::MessageLoop ui_loop_;
-  content::TestBrowserThread ui_thread_;
 };
 
 TEST_F(SigninTrackerTest, GaiaSignInFailed) {
diff --git a/chrome/browser/signin/signin_ui_util.cc b/chrome/browser/signin/signin_ui_util.cc
index 95396be..1c75cc6 100644
--- a/chrome/browser/signin/signin_ui_util.cc
+++ b/chrome/browser/signin/signin_ui_util.cc
@@ -39,9 +39,7 @@
 
   // Auth errors have the highest priority - after that, individual service
   // errors.
-  SigninManagerBase* signin_manager =
-      SigninManagerFactory::GetForProfile(profile);
-  SigninGlobalError* signin_error = signin_manager->signin_global_error();
+  SigninGlobalError* signin_error = SigninGlobalError::GetForProfile(profile);
   if (signin_error && signin_error->HasMenuItem())
     errors.push_back(signin_error);
 
@@ -90,7 +88,8 @@
 
 // Given an authentication state this helper function returns various labels
 // that can be used to display information about the state.
-void GetStatusLabelsForAuthError(const SigninManagerBase& signin_manager,
+void GetStatusLabelsForAuthError(Profile* profile,
+                                 const SigninManagerBase& signin_manager,
                                  string16* status_label,
                                  string16* link_label) {
   string16 username = UTF8ToUTF16(signin_manager.GetAuthenticatedUsername());
@@ -98,7 +97,9 @@
   if (link_label)
     link_label->assign(l10n_util::GetStringUTF16(IDS_SYNC_RELOGIN_LINK_LABEL));
 
-  switch (signin_manager.signin_global_error()->GetLastAuthError().state()) {
+  const GoogleServiceAuthError::State state =
+      SigninGlobalError::GetForProfile(profile)->GetLastAuthError().state();
+  switch (state) {
     case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
     case GoogleServiceAuthError::ACCOUNT_DELETED:
     case GoogleServiceAuthError::ACCOUNT_DISABLED:
@@ -143,5 +144,4 @@
   }
 }
 
-
 }  // namespace signin_ui_util
diff --git a/chrome/browser/signin/signin_ui_util.h b/chrome/browser/signin/signin_ui_util.h
index 3e63e1a..86034ac 100644
--- a/chrome/browser/signin/signin_ui_util.h
+++ b/chrome/browser/signin/signin_ui_util.h
@@ -28,7 +28,8 @@
 // "Sign in to Chromium", "Signin Error...", etc).
 string16 GetSigninMenuLabel(Profile* profile);
 
-void GetStatusLabelsForAuthError(const SigninManagerBase& signin_manager,
+void GetStatusLabelsForAuthError(Profile* profile,
+                                 const SigninManagerBase& signin_manager,
                                  string16* status_label,
                                  string16* link_label);
 
diff --git a/chrome/browser/signin/token_service.cc b/chrome/browser/signin/token_service.cc
index 2237ada..6de5e32 100644
--- a/chrome/browser/signin/token_service.cc
+++ b/chrome/browser/signin/token_service.cc
@@ -8,11 +8,11 @@
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/webdata/token_web_data.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/signin/token_service_unittest.cc b/chrome/browser/signin/token_service_unittest.cc
index bfe08ea..fb23962 100644
--- a/chrome/browser/signin/token_service_unittest.cc
+++ b/chrome/browser/signin/token_service_unittest.cc
@@ -11,9 +11,9 @@
 #include "base/command_line.h"
 #include "base/message_loop.h"
 #include "base/synchronization/waitable_event.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/signin/token_service_factory.h"
 #include "chrome/browser/webdata/token_web_data.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/webdata/encryptor/encryptor.h"
 #include "google_apis/gaia/gaia_constants.h"
diff --git a/chrome/browser/signin/ubertoken_fetcher.cc b/chrome/browser/signin/ubertoken_fetcher.cc
index 4cf5d39..01d9ad4 100644
--- a/chrome/browser/signin/ubertoken_fetcher.cc
+++ b/chrome/browser/signin/ubertoken_fetcher.cc
@@ -8,10 +8,10 @@
 
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/signin/token_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "google_apis/gaia/gaia_constants.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "google_apis/gaia/google_service_auth_error.h"
diff --git a/chrome/browser/signin/ubertoken_fetcher_unittest.cc b/chrome/browser/signin/ubertoken_fetcher_unittest.cc
index 060fa88..eddb39a 100644
--- a/chrome/browser/signin/ubertoken_fetcher_unittest.cc
+++ b/chrome/browser/signin/ubertoken_fetcher_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "chrome/browser/signin/ubertoken_fetcher.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/signin/token_service.h"
 #include "chrome/browser/signin/token_service_unittest.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "google_apis/gaia/gaia_constants.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc
index e29d4f4..0d4bb39 100644
--- a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc
+++ b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc
@@ -15,7 +15,6 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/speech/chrome_speech_recognition_preferences.h"
 #include "chrome/browser/tab_contents/tab_util.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
@@ -32,9 +31,7 @@
 #include "content/public/common/speech_recognition_error.h"
 #include "content/public/common/speech_recognition_result.h"
 #include "extensions/browser/view_type_utils.h"
-#include "grit/generated_resources.h"
 #include "net/url_request/url_request_context_getter.h"
-#include "ui/base/l10n/l10n_util.h"
 
 #if defined(OS_WIN)
 #include "chrome/installer/util/wmi.h"
@@ -44,21 +41,6 @@
 using content::SpeechRecognitionManager;
 using content::WebContents;
 
-namespace {
-
-const char kExtensionPrefix[] = "chrome-extension://";
-
-bool RequiresBubble(int session_id) {
-  return SpeechRecognitionManager::GetInstance()->
-      GetSessionContext(session_id).requested_by_page_element;
-}
-
-bool RequiresTrayIcon(int session_id) {
-  return !RequiresBubble(session_id);
-}
-
-}  // namespace
-
 namespace speech {
 
 // Asynchronously fetches the PC and audio hardware/driver info if
@@ -269,59 +251,6 @@
 
 ChromeSpeechRecognitionManagerDelegate
 ::~ChromeSpeechRecognitionManagerDelegate() {
-  if (bubble_controller_.get())
-    bubble_controller_->CloseBubble();
-}
-
-void ChromeSpeechRecognitionManagerDelegate::InfoBubbleButtonClicked(
-    int session_id, SpeechRecognitionBubble::Button button) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
-  // Note, the session might have been destroyed, therefore avoid calls to the
-  // manager which imply its existance (e.g., GetSessionContext()).
-
-  if (button == SpeechRecognitionBubble::BUTTON_CANCEL) {
-    GetBubbleController()->CloseBubble();
-    last_session_config_.reset();
-
-    // We can safely call AbortSession even if the session has already ended,
-    // the manager's public methods are reliable and will handle it properly.
-    SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
-  } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) {
-    GetBubbleController()->CloseBubble();
-    RestartLastSession();
-  } else {
-    NOTREACHED();
-  }
-}
-
-void ChromeSpeechRecognitionManagerDelegate::InfoBubbleFocusChanged(
-    int session_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
-  // This check is needed since on some systems (MacOS), in rare cases, if the
-  // user clicks repeatedly and fast on the input element, the FocusChanged
-  // event (corresponding to the old session that should be aborted) can be
-  // received after a new session (corresponding to the 2nd click) is started.
-  if (GetBubbleController()->GetActiveSessionID() != session_id)
-    return;
-
-  // Note, the session might have been destroyed, therefore avoid calls to the
-  // manager which imply its existance (e.g., GetSessionContext()).
-  GetBubbleController()->CloseBubble();
-  last_session_config_.reset();
-
-  // Clicking outside the bubble means we should abort.
-  SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
-}
-
-void ChromeSpeechRecognitionManagerDelegate::RestartLastSession() {
-  DCHECK(last_session_config_.get());
-  SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance();
-  const int new_session_id = manager->CreateSession(*last_session_config_);
-  DCHECK_NE(SpeechRecognitionManager::kSessionIDInvalid, new_session_id);
-  last_session_config_.reset();
-  manager->StartSession(new_session_id);
 }
 
 void ChromeSpeechRecognitionManagerDelegate::TabClosedCallback(
@@ -336,12 +265,6 @@
     return;
 
   manager->AbortAllSessionsForRenderView(render_process_id, render_view_id);
-
-  if (bubble_controller_.get() &&
-      bubble_controller_->IsShowingBubbleForRenderView(render_process_id,
-                                                       render_view_id)) {
-    bubble_controller_->CloseBubble();
-  }
 }
 
 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart(
@@ -349,18 +272,6 @@
   const content::SpeechRecognitionSessionContext& context =
       SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
 
-  if (RequiresBubble(session_id)) {
-    // Copy the configuration of the session (for the "try again" button).
-    last_session_config_.reset(new content::SpeechRecognitionSessionConfig(
-        SpeechRecognitionManager::GetInstance()->GetSessionConfig(session_id)));
-
-    // Create and show the bubble.
-    GetBubbleController()->CreateBubble(session_id,
-                                        context.render_process_id,
-                                        context.render_view_id,
-                                        context.element_rect);
-  }
-
   // Register callback to auto abort session on tab closure.
   // |tab_watcher_| is lazyly istantiated on the first call.
   if (!tab_watcher_.get()) {
@@ -373,10 +284,6 @@
 }
 
 void ChromeSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) {
-  if (RequiresBubble(session_id)) {
-    DCHECK_EQ(session_id, GetBubbleController()->GetActiveSessionID());
-    GetBubbleController()->SetBubbleRecordingMode();
-  }
 }
 
 void ChromeSpeechRecognitionManagerDelegate::OnEnvironmentEstimationComplete(
@@ -390,76 +297,21 @@
 }
 
 void ChromeSpeechRecognitionManagerDelegate::OnAudioEnd(int session_id) {
-  // OnAudioEnd can be also raised after an abort, when the bubble has already
-  // been closed.
-  if (GetBubbleController()->GetActiveSessionID() == session_id) {
-    DCHECK(RequiresBubble(session_id));
-    GetBubbleController()->SetBubbleRecognizingMode();
-  }
 }
 
 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionResults(
     int session_id, const content::SpeechRecognitionResults& result) {
-  // The bubble will be closed upon the OnEnd event, which will follow soon.
 }
 
 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionError(
     int session_id, const content::SpeechRecognitionError& error) {
-  // An error can be dispatched when the bubble is not visible anymore.
-  if (GetBubbleController()->GetActiveSessionID() != session_id)
-    return;
-  DCHECK(RequiresBubble(session_id));
-
-  int error_message_id = 0;
-  switch (error.code) {
-    case content::SPEECH_RECOGNITION_ERROR_AUDIO:
-      switch (error.details) {
-        case content::SPEECH_AUDIO_ERROR_DETAILS_NO_MIC:
-          error_message_id = IDS_SPEECH_INPUT_NO_MIC;
-          break;
-        default:
-          error_message_id = IDS_SPEECH_INPUT_MIC_ERROR;
-          break;
-      }
-      break;
-    case content::SPEECH_RECOGNITION_ERROR_ABORTED:
-      error_message_id = IDS_SPEECH_INPUT_ABORTED;
-      break;
-    case content::SPEECH_RECOGNITION_ERROR_NO_SPEECH:
-      error_message_id = IDS_SPEECH_INPUT_NO_SPEECH;
-      break;
-    case content::SPEECH_RECOGNITION_ERROR_NO_MATCH:
-      error_message_id = IDS_SPEECH_INPUT_NO_RESULTS;
-      break;
-    case content::SPEECH_RECOGNITION_ERROR_NETWORK:
-      error_message_id = IDS_SPEECH_INPUT_NET_ERROR;
-      break;
-    default:
-      NOTREACHED() << "unknown error " << error.code;
-      return;
-  }
-  GetBubbleController()->SetBubbleMessage(
-      l10n_util::GetStringUTF16(error_message_id));
 }
 
 void ChromeSpeechRecognitionManagerDelegate::OnAudioLevelsChange(
     int session_id, float volume, float noise_volume) {
-  if (GetBubbleController()->GetActiveSessionID() == session_id) {
-    DCHECK(RequiresBubble(session_id));
-    GetBubbleController()->SetBubbleInputVolume(volume, noise_volume);
-  }
 }
 
 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionEnd(int session_id) {
-  // The only case in which the OnRecognitionEnd should not close the bubble is
-  // when we are showing an error. In this case the bubble will be closed by
-  // the |InfoBubbleFocusChanged| method, when the users clicks either the
-  // "Cancel" button or outside of the bubble.
-  if (GetBubbleController()->GetActiveSessionID() == session_id &&
-      !GetBubbleController()->IsShowingMessage()) {
-    DCHECK(RequiresBubble(session_id));
-    GetBubbleController()->CloseBubble();
-  }
 }
 
 void ChromeSpeechRecognitionManagerDelegate::GetDiagnosticInformation(
@@ -490,8 +342,7 @@
       SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
 
   // Make sure that initiators (extensions/web pages) properly set the
-  // |render_process_id| field, which is needed later to retrieve the
-  // ChromeSpeechRecognitionPreferences associated to their profile.
+  // |render_process_id| field, which is needed later to retrieve the profile.
   DCHECK_NE(context.render_process_id, 0);
 
   // Check that the render view type is appropriate, and whether or not we
@@ -501,7 +352,7 @@
                                      callback,
                                      context.render_process_id,
                                      context.render_view_id,
-                                     RequiresTrayIcon(session_id)));
+                                     !context.requested_by_page_element));
 }
 
 content::SpeechRecognitionEventListener*
@@ -509,6 +360,17 @@
   return this;
 }
 
+bool ChromeSpeechRecognitionManagerDelegate::FilterProfanities(
+    int render_process_id) {
+  content::RenderProcessHost* rph =
+      content::RenderProcessHost::FromID(render_process_id);
+  if (!rph)  // Guard against race conditions on RPH lifetime.
+    return true;
+
+  return Profile::FromBrowserContext(rph->GetBrowserContext())->GetPrefs()->
+      GetBoolean(prefs::kSpeechRecognitionFilterProfanities);
+}
+
 void ChromeSpeechRecognitionManagerDelegate::CheckRenderViewType(
     base::Callback<void(bool ask_user, bool is_allowed)> callback,
     int render_process_id,
@@ -560,11 +422,4 @@
                           base::Bind(callback, ask_permission, allowed));
 }
 
-SpeechRecognitionBubbleController*
-ChromeSpeechRecognitionManagerDelegate::GetBubbleController() {
-  if (!bubble_controller_.get())
-    bubble_controller_ = new SpeechRecognitionBubbleController(this);
-  return bubble_controller_.get();
-}
-
 }  // namespace speech
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h
index a2d2a9b..1d33a71 100644
--- a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h
+++ b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h
@@ -7,30 +7,22 @@
 
 #include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
-#include "chrome/browser/speech/speech_recognition_bubble_controller.h"
 #include "content/public/browser/speech_recognition_event_listener.h"
 #include "content/public/browser/speech_recognition_manager_delegate.h"
 #include "content/public/browser/speech_recognition_session_config.h"
 
-
 namespace speech {
 
 // This is Chrome's implementation of the SpeechRecognitionManagerDelegate
 // interface.
 class ChromeSpeechRecognitionManagerDelegate
-    : NON_EXPORTED_BASE(public content::SpeechRecognitionManagerDelegate),
-      public content::SpeechRecognitionEventListener,
-      public SpeechRecognitionBubbleControllerDelegate {
+    : public content::SpeechRecognitionManagerDelegate,
+      public content::SpeechRecognitionEventListener {
  public:
   ChromeSpeechRecognitionManagerDelegate();
   virtual ~ChromeSpeechRecognitionManagerDelegate();
 
  protected:
-  // SpeechRecognitionBubbleControllerDelegate methods.
-  virtual void InfoBubbleButtonClicked(
-      int session_id, SpeechRecognitionBubble::Button button) OVERRIDE;
-  virtual void InfoBubbleFocusChanged(int session_id) OVERRIDE;
-
   // SpeechRecognitionEventListener methods.
   virtual void OnRecognitionStart(int session_id) OVERRIDE;
   virtual void OnAudioStart(int session_id) OVERRIDE;
@@ -53,6 +45,10 @@
       int session_id,
       base::Callback<void(bool ask_user, bool is_allowed)> callback) OVERRIDE;
   virtual content::SpeechRecognitionEventListener* GetEventListener() OVERRIDE;
+  virtual bool FilterProfanities(int render_process_id) OVERRIDE;
+
+  // Callback called by |tab_watcher_| on the IO thread to signal tab closure.
+  virtual void TabClosedCallback(int render_process_id, int render_view_id);
 
  private:
   class OptionalRequestInfo;
@@ -66,19 +62,7 @@
       int render_view_id,
       bool js_api);
 
-  // Starts a new recognition session, using the config of the last one
-  // (which is copied into |last_session_config_|). Used for "try again".
-  void RestartLastSession();
-
-  // Callback called by |tab_watcher_| on the IO thread to signal tab closure.
-  void TabClosedCallback(int render_process_id, int render_view_id);
-
-  // Lazy initializers for bubble and tray icon controller.
-  SpeechRecognitionBubbleController* GetBubbleController();
-
-  scoped_refptr<SpeechRecognitionBubbleController> bubble_controller_;
   scoped_refptr<OptionalRequestInfo> optional_request_info_;
-  scoped_ptr<content::SpeechRecognitionSessionConfig> last_session_config_;
   scoped_refptr<TabWatcher> tab_watcher_;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeSpeechRecognitionManagerDelegate);
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.cc b/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.cc
new file mode 100644
index 0000000..8deac37
--- /dev/null
+++ b/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.cc
@@ -0,0 +1,219 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/speech_recognition_manager.h"
+#include "content/public/browser/speech_recognition_session_context.h"
+#include "content/public/common/speech_recognition_error.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+using content::BrowserThread;
+using content::SpeechRecognitionManager;
+
+namespace {
+
+bool RequiresBubble(int session_id) {
+  return SpeechRecognitionManager::GetInstance()->
+      GetSessionContext(session_id).requested_by_page_element;
+}
+
+}  // namespace
+
+namespace speech {
+
+ChromeSpeechRecognitionManagerDelegateBubbleUI
+::ChromeSpeechRecognitionManagerDelegateBubbleUI() {
+}
+
+ChromeSpeechRecognitionManagerDelegateBubbleUI
+::~ChromeSpeechRecognitionManagerDelegateBubbleUI() {
+  if (bubble_controller_.get())
+    bubble_controller_->CloseBubble();
+}
+
+void ChromeSpeechRecognitionManagerDelegateBubbleUI::InfoBubbleButtonClicked(
+    int session_id, SpeechRecognitionBubble::Button button) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  // Note, the session might have been destroyed, therefore avoid calls to the
+  // manager which imply its existance (e.g., GetSessionContext()).
+
+  if (button == SpeechRecognitionBubble::BUTTON_CANCEL) {
+    GetBubbleController()->CloseBubble();
+    last_session_config_.reset();
+
+    // We can safely call AbortSession even if the session has already ended,
+    // the manager's public methods are reliable and will handle it properly.
+    SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
+  } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) {
+    GetBubbleController()->CloseBubble();
+    RestartLastSession();
+  } else {
+    NOTREACHED();
+  }
+}
+
+void ChromeSpeechRecognitionManagerDelegateBubbleUI::InfoBubbleFocusChanged(
+    int session_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  // This check is needed since on some systems (MacOS), in rare cases, if the
+  // user clicks repeatedly and fast on the input element, the FocusChanged
+  // event (corresponding to the old session that should be aborted) can be
+  // received after a new session (corresponding to the 2nd click) is started.
+  if (GetBubbleController()->GetActiveSessionID() != session_id)
+    return;
+
+  // Note, the session might have been destroyed, therefore avoid calls to the
+  // manager which imply its existance (e.g., GetSessionContext()).
+  GetBubbleController()->CloseBubble();
+  last_session_config_.reset();
+
+  // Clicking outside the bubble means we should abort.
+  SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
+}
+
+void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnRecognitionStart(
+    int session_id) {
+  ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart(session_id);
+
+  const content::SpeechRecognitionSessionContext& context =
+      SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
+
+  if (RequiresBubble(session_id)) {
+    // Copy the configuration of the session (for the "try again" button).
+    last_session_config_.reset(new content::SpeechRecognitionSessionConfig(
+        SpeechRecognitionManager::GetInstance()->GetSessionConfig(session_id)));
+
+    // Create and show the bubble. It will be closed upon the OnEnd event.
+    GetBubbleController()->CreateBubble(session_id,
+                                        context.render_process_id,
+                                        context.render_view_id,
+                                        context.element_rect);
+  }
+}
+
+void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnAudioStart(
+    int session_id) {
+  ChromeSpeechRecognitionManagerDelegate::OnAudioStart(session_id);
+
+  if (RequiresBubble(session_id)) {
+    DCHECK_EQ(session_id, GetBubbleController()->GetActiveSessionID());
+    GetBubbleController()->SetBubbleRecordingMode();
+  }
+}
+
+void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnAudioEnd(
+    int session_id) {
+  ChromeSpeechRecognitionManagerDelegate::OnAudioEnd(session_id);
+
+  // OnAudioEnd can be also raised after an abort, when the bubble has already
+  // been closed.
+  if (GetBubbleController()->GetActiveSessionID() == session_id) {
+    DCHECK(RequiresBubble(session_id));
+    GetBubbleController()->SetBubbleRecognizingMode();
+  }
+}
+
+void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnRecognitionError(
+    int session_id, const content::SpeechRecognitionError& error) {
+  ChromeSpeechRecognitionManagerDelegate::OnRecognitionError(session_id, error);
+
+  // An error can be dispatched when the bubble is not visible anymore.
+  if (GetBubbleController()->GetActiveSessionID() != session_id)
+    return;
+  DCHECK(RequiresBubble(session_id));
+
+  int error_message_id = 0;
+  switch (error.code) {
+    case content::SPEECH_RECOGNITION_ERROR_AUDIO:
+      switch (error.details) {
+        case content::SPEECH_AUDIO_ERROR_DETAILS_NO_MIC:
+          error_message_id = IDS_SPEECH_INPUT_NO_MIC;
+          break;
+        default:
+          error_message_id = IDS_SPEECH_INPUT_MIC_ERROR;
+          break;
+      }
+      break;
+    case content::SPEECH_RECOGNITION_ERROR_ABORTED:
+      error_message_id = IDS_SPEECH_INPUT_ABORTED;
+      break;
+    case content::SPEECH_RECOGNITION_ERROR_NO_SPEECH:
+      error_message_id = IDS_SPEECH_INPUT_NO_SPEECH;
+      break;
+    case content::SPEECH_RECOGNITION_ERROR_NO_MATCH:
+      error_message_id = IDS_SPEECH_INPUT_NO_RESULTS;
+      break;
+    case content::SPEECH_RECOGNITION_ERROR_NETWORK:
+      error_message_id = IDS_SPEECH_INPUT_NET_ERROR;
+      break;
+    default:
+      NOTREACHED() << "unknown error " << error.code;
+      return;
+  }
+  GetBubbleController()->SetBubbleMessage(
+      l10n_util::GetStringUTF16(error_message_id));
+
+}
+
+void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnAudioLevelsChange(
+    int session_id, float volume, float noise_volume) {
+  ChromeSpeechRecognitionManagerDelegate::OnAudioLevelsChange(
+      session_id, volume, noise_volume);
+
+  if (GetBubbleController()->GetActiveSessionID() == session_id) {
+    DCHECK(RequiresBubble(session_id));
+    GetBubbleController()->SetBubbleInputVolume(volume, noise_volume);
+  }
+}
+
+void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnRecognitionEnd(
+    int session_id) {
+  ChromeSpeechRecognitionManagerDelegate::OnRecognitionEnd(session_id);
+
+  // The only case in which the OnRecognitionEnd should not close the bubble is
+  // when we are showing an error. In this case the bubble will be closed by
+  // the |InfoBubbleFocusChanged| method, when the users clicks either the
+  // "Cancel" button or outside of the bubble.
+  if (GetBubbleController()->GetActiveSessionID() == session_id &&
+      !GetBubbleController()->IsShowingMessage()) {
+    DCHECK(RequiresBubble(session_id));
+    GetBubbleController()->CloseBubble();
+  }
+}
+
+void ChromeSpeechRecognitionManagerDelegateBubbleUI::TabClosedCallback(
+    int render_process_id, int render_view_id) {
+  ChromeSpeechRecognitionManagerDelegate::TabClosedCallback(
+      render_process_id, render_view_id);
+
+  if (bubble_controller_.get() &&
+      bubble_controller_->IsShowingBubbleForRenderView(render_process_id,
+                                                       render_view_id)) {
+    bubble_controller_->CloseBubble();
+  }
+}
+
+SpeechRecognitionBubbleController*
+ChromeSpeechRecognitionManagerDelegateBubbleUI::GetBubbleController() {
+  if (!bubble_controller_.get())
+    bubble_controller_ = new SpeechRecognitionBubbleController(this);
+  return bubble_controller_.get();
+}
+
+void ChromeSpeechRecognitionManagerDelegateBubbleUI::RestartLastSession() {
+  DCHECK(last_session_config_.get());
+  SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance();
+  const int new_session_id = manager->CreateSession(*last_session_config_);
+  DCHECK_NE(SpeechRecognitionManager::kSessionIDInvalid, new_session_id);
+  last_session_config_.reset();
+  manager->StartSession(new_session_id);
+}
+
+}  // namespace speech
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h b/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h
new file mode 100644
index 0000000..cc877fa
--- /dev/null
+++ b/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h
@@ -0,0 +1,62 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SPEECH_CHROME_SPEECH_RECOGNITION_MANAGER_DELEGATE_BUBBLE_UI_H_
+#define CHROME_BROWSER_SPEECH_CHROME_SPEECH_RECOGNITION_MANAGER_DELEGATE_BUBBLE_UI_H_
+
+#include "base/compiler_specific.h"
+#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h"
+#include "chrome/browser/speech/speech_recognition_bubble_controller.h"
+
+namespace speech {
+
+// This class extends ChromeSpeechRecognitionManagerDelegate to add the behavior
+// required to handle the (bubble) UI for speech recognition sessions initiated
+// by input elements with a x-webkit-speech attribute. This extended behavior is
+// achieved by means of overriding some SpeechRecognitionEventListener methods
+// and intercepting the calls required to show, animate and hide the bubble UI.
+class ChromeSpeechRecognitionManagerDelegateBubbleUI
+    : public ChromeSpeechRecognitionManagerDelegate,
+      public SpeechRecognitionBubbleControllerDelegate {
+ public:
+  ChromeSpeechRecognitionManagerDelegateBubbleUI();
+  virtual ~ChromeSpeechRecognitionManagerDelegateBubbleUI();
+
+ protected:
+  // SpeechRecognitionBubbleControllerDelegate methods.
+  virtual void InfoBubbleButtonClicked(
+      int session_id, SpeechRecognitionBubble::Button button) OVERRIDE;
+  virtual void InfoBubbleFocusChanged(int session_id) OVERRIDE;
+
+  // Overridden base class SpeechRecognitionEventListener methods.
+  virtual void OnRecognitionStart(int session_id) OVERRIDE;
+  virtual void OnAudioStart(int session_id) OVERRIDE;
+  virtual void OnAudioEnd(int session_id) OVERRIDE;
+  virtual void OnRecognitionEnd(int session_id) OVERRIDE;
+  virtual void OnRecognitionError(
+      int session_id, const content::SpeechRecognitionError& error) OVERRIDE;
+  virtual void OnAudioLevelsChange(
+      int session_id, float volume, float noise_volume) OVERRIDE;
+
+  // Starts a new recognition session, using the config of the last one
+  // (which is copied into |last_session_config_|). Used for "try again".
+  void RestartLastSession();
+
+  // Called by the base class when tab closure was detected.
+  virtual void TabClosedCallback(
+      int render_process_id, int render_view_id) OVERRIDE;
+
+ private:
+  // Lazy initializer for bubble controller.
+  SpeechRecognitionBubbleController* GetBubbleController();
+
+  scoped_refptr<SpeechRecognitionBubbleController> bubble_controller_;
+  scoped_ptr<content::SpeechRecognitionSessionConfig> last_session_config_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeSpeechRecognitionManagerDelegateBubbleUI);
+};
+
+}  // namespace speech
+
+#endif  // CHROME_BROWSER_SPEECH_CHROME_SPEECH_RECOGNITION_MANAGER_DELEGATE_BUBBLE_UI_H_
diff --git a/chrome/browser/speech/chrome_speech_recognition_preferences.cc b/chrome/browser/speech/chrome_speech_recognition_preferences.cc
deleted file mode 100644
index 62be83a..0000000
--- a/chrome/browser/speech/chrome_speech_recognition_preferences.cc
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/speech/chrome_speech_recognition_preferences.h"
-
-#include "base/bind.h"
-#include "base/prefs/pref_service.h"
-#include "base/values.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/pref_names.h"
-#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
-#include "components/user_prefs/pref_registry_syncable.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_details.h"
-
-using base::ListValue;
-using content::BrowserThread;
-
-namespace {
-const bool kDefaultFilterProfanities = true;
-const bool kDefaultShownSecurityNotification = false;
-}
-
-ChromeSpeechRecognitionPreferences::Factory*
-ChromeSpeechRecognitionPreferences::Factory::GetInstance() {
-  return Singleton<ChromeSpeechRecognitionPreferences::Factory>::get();
-}
-
-void ChromeSpeechRecognitionPreferences::InitializeFactory() {
-  ChromeSpeechRecognitionPreferences::Factory::GetInstance();
-}
-
-scoped_refptr<ChromeSpeechRecognitionPreferences>
-ChromeSpeechRecognitionPreferences::Factory::GetForProfile(Profile* profile) {
-  DCHECK(profile);
-  // GetServiceForBrowserContext will let us instantiate a new (if not already
-  // cached for the profile) Service through BuildServiceInstanceFor method.
-  ChromeSpeechRecognitionPreferences::Service* service =
-      static_cast<ChromeSpeechRecognitionPreferences::Service*>(
-          GetServiceForBrowserContext(profile, true));
-
-  if (!service) {
-    // Incognito won't have this service.
-    return NULL;
-  }
-
-  return service->GetPreferences();
-}
-
-ChromeSpeechRecognitionPreferences::Factory::Factory()
-    : BrowserContextKeyedServiceFactory(
-        "ChromeSpeechRecognitionPreferences",
-        BrowserContextDependencyManager::GetInstance()) {
-}
-
-ChromeSpeechRecognitionPreferences::Factory::~Factory() {
-}
-
-BrowserContextKeyedService*
-ChromeSpeechRecognitionPreferences::Factory::BuildServiceInstanceFor(
-    content::BrowserContext* profile) const {
-  DCHECK(profile);
-  return new ChromeSpeechRecognitionPreferences::Service(
-      static_cast<Profile*>(profile));
-}
-
-void ChromeSpeechRecognitionPreferences::Factory::RegisterUserPrefs(
-    user_prefs::PrefRegistrySyncable* prefs) {
-  prefs->RegisterBooleanPref(
-      prefs::kSpeechRecognitionFilterProfanities,
-      kDefaultFilterProfanities,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-
-  prefs->RegisterListPref(
-      prefs::kSpeechRecognitionTrayNotificationShownContexts,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-}
-
-bool ChromeSpeechRecognitionPreferences::Factory::
-ServiceIsNULLWhileTesting() const {
-  return true;
-}
-
-bool ChromeSpeechRecognitionPreferences::Factory::
-ServiceIsCreatedWithBrowserContext() const {
-  return false;
-}
-
-ChromeSpeechRecognitionPreferences::Service::Service(
-    Profile* profile)
-    : preferences_(new ChromeSpeechRecognitionPreferences(profile)) {
-}
-
-ChromeSpeechRecognitionPreferences::Service::~Service() {
-}
-
-void ChromeSpeechRecognitionPreferences::Service::Shutdown() {
-  DCHECK(preferences_.get());
-  preferences_->DetachFromProfile();
-}
-
-scoped_refptr<ChromeSpeechRecognitionPreferences>
-ChromeSpeechRecognitionPreferences::Service::GetPreferences() const {
-  return preferences_;
-}
-
-scoped_refptr<ChromeSpeechRecognitionPreferences>
-ChromeSpeechRecognitionPreferences::GetForProfile(Profile* profile) {
-  scoped_refptr<ChromeSpeechRecognitionPreferences> ret;
-  if (profile) {
-    // Note that when in incognito, GetForProfile will return NULL.
-    // We catch that case below and return the default preferences.
-    ret = Factory::GetInstance()->GetForProfile(profile);
-  }
-
-  if (!ret.get()) {
-    // Create a detached preferences object if no profile is provided.
-    ret = new ChromeSpeechRecognitionPreferences(NULL);
-  }
-
-  return ret;
-}
-
-ChromeSpeechRecognitionPreferences::ChromeSpeechRecognitionPreferences(
-    Profile* profile)
-    : profile_(profile),
-      pref_change_registrar_(new PrefChangeRegistrar()),
-      filter_profanities_(kDefaultFilterProfanities),
-      notifications_shown_(new ListValue()) {
-  if (!profile_)
-    return;
-
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  pref_change_registrar_->Init(profile_->GetPrefs());
-
-  ReloadFilterProfanities();
-  pref_change_registrar_->Add(
-      prefs::kSpeechRecognitionFilterProfanities,
-      base::Bind(&ChromeSpeechRecognitionPreferences::ReloadFilterProfanities,
-                 base::Unretained(this)));
-
-  ReloadNotificationsShown();
-  pref_change_registrar_->Add(
-      prefs::kSpeechRecognitionTrayNotificationShownContexts,
-      base::Bind(&ChromeSpeechRecognitionPreferences::ReloadNotificationsShown,
-                 base::Unretained(this)));
-}
-
-ChromeSpeechRecognitionPreferences::~ChromeSpeechRecognitionPreferences() {
-}
-
-void ChromeSpeechRecognitionPreferences::DetachFromProfile() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(profile_);
-  pref_change_registrar_.reset();
-  profile_ = NULL;
-}
-
-bool ChromeSpeechRecognitionPreferences::FilterProfanities() const {
-  base::AutoLock read_lock(preferences_lock_);
-  return filter_profanities_;
-}
-
-void ChromeSpeechRecognitionPreferences::SetFilterProfanities(
-    bool filter_profanities) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  {
-    base::AutoLock write_lock(preferences_lock_);
-    filter_profanities_ = filter_profanities;
-  }
-  if (profile_) {
-    profile_->GetPrefs()->SetBoolean(prefs::kSpeechRecognitionFilterProfanities,
-                                     filter_profanities);
-  }
-}
-
-void ChromeSpeechRecognitionPreferences::ToggleFilterProfanities() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  SetFilterProfanities(!FilterProfanities());
-}
-
-bool ChromeSpeechRecognitionPreferences::ShouldShowSecurityNotification(
-    const std::string& context_name) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(notifications_shown_.get());
-  scoped_ptr<base::StringValue> match_name(
-      base::Value::CreateStringValue(context_name));
-  return notifications_shown_->Find(*match_name) == notifications_shown_->end();
-}
-
-void ChromeSpeechRecognitionPreferences::SetHasShownSecurityNotification(
-    const std::string& context_name) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(notifications_shown_.get());
-  notifications_shown_->AppendIfNotPresent(
-      base::Value::CreateStringValue(context_name));
-  if (profile_) {
-    profile_->GetPrefs()->Set(
-        prefs::kSpeechRecognitionTrayNotificationShownContexts,
-        *notifications_shown_);
-  }
-}
-
-void ChromeSpeechRecognitionPreferences::ReloadFilterProfanities() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  base::AutoLock write_lock(preferences_lock_);
-  filter_profanities_ = profile_->GetPrefs()->GetBoolean(
-      prefs::kSpeechRecognitionFilterProfanities);
-}
-
-void ChromeSpeechRecognitionPreferences::ReloadNotificationsShown() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  base::AutoLock write_lock(preferences_lock_);
-  const base::ListValue* pref_list = profile_->GetPrefs()->GetList(
-      prefs::kSpeechRecognitionTrayNotificationShownContexts);
-  notifications_shown_.reset(pref_list->DeepCopy());
-}
diff --git a/chrome/browser/speech/chrome_speech_recognition_preferences.h b/chrome/browser/speech/chrome_speech_recognition_preferences.h
deleted file mode 100644
index cd1fc09..0000000
--- a/chrome/browser/speech/chrome_speech_recognition_preferences.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_SPEECH_CHROME_SPEECH_RECOGNITION_PREFERENCES_H_
-#define CHROME_BROWSER_SPEECH_CHROME_SPEECH_RECOGNITION_PREFERENCES_H_
-
-#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/singleton.h"
-#include "base/prefs/pref_change_registrar.h"
-#include "base/synchronization/lock.h"
-#include "base/threading/non_thread_safe.h"
-#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
-#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
-#include "content/public/browser/speech_recognition_preferences.h"
-
-class PrefService;
-class Profile;
-
-namespace base {
-class ListValue;
-}
-
-// Utility class that handles persistent storage of speech recognition
-// preferences. Instances of this class must be obtained exclusively through the
-// method ChromeSpeechRecognitionPreferences::GetForProfile(...), so that
-// preferences are handled within the Profile (if not NULL). The internal
-// factory class also handles ownership and lifetime of the
-// ChromeSpeechRecognitionPreferences instances (through the inner Service
-// class), allowing them to be used in a detached mode (no persistent storage)
-// even when a Profile is not available (or has been shutdown).
-
-class ChromeSpeechRecognitionPreferences
-    : public content::SpeechRecognitionPreferences {
- public:
-  static void InitializeFactory();
-  static scoped_refptr<ChromeSpeechRecognitionPreferences> GetForProfile(
-      Profile* profile);
-
-  // content::SpeechRecognitionPreferences implementation.
-  // Called by both Content (on IO thread) and Chrome (on UI thread).
-  virtual bool FilterProfanities() const OVERRIDE;
-
-  // Called only by Chrome (on UI thread).
-  void SetFilterProfanities(bool filter_profanities);
-  void ToggleFilterProfanities();
-  bool ShouldShowSecurityNotification(const std::string& context_name) const;
-  void SetHasShownSecurityNotification(const std::string& context_name);
-
- private:
-  // The two classes below are needed to handle storage of speech recognition
-  // preferences in profile preferences, according to the Chromium Profile
-  // Architecture document entitled "The New Way:
-  // BrowserContextKeyedServiceFactory".
-
-  // Singleton that manages instantiation of ChromeSpeechRecognitionPreferences
-  // handling its association with Profiles.
-  class Factory : public BrowserContextKeyedServiceFactory {
-   public:
-    static Factory* GetInstance();
-    scoped_refptr<ChromeSpeechRecognitionPreferences> GetForProfile(
-        Profile* profile);
-
-   private:
-    friend struct DefaultSingletonTraits<Factory>;
-
-    Factory();
-    virtual ~Factory();
-
-    // BrowserContextKeyedServiceFactory methods:
-    virtual BrowserContextKeyedService* BuildServiceInstanceFor(
-        content::BrowserContext* profile) const OVERRIDE;
-    virtual void RegisterUserPrefs(
-        user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
-    virtual bool ServiceIsNULLWhileTesting() const OVERRIDE;
-    virtual bool ServiceIsCreatedWithBrowserContext() const OVERRIDE;
-
-    DISALLOW_COPY_AND_ASSIGN(Factory);
-  };
-
-  // This wrapper handles the binding between ChromeSpeechRecognitionPreferences
-  // instances (which can have a longer lifetime, since they are refcounted) and
-  // BrowserContextKeyedService (which lifetime depends on the Profile service).
-  // Upon profile shutdown, the ChromeSpeechRecognitionPreferences instance is
-  // detached from profile, meaning that after that point its clients can still
-  // use it, but preferences will no longer be kept in sync with the profile.
-  class Service : public BrowserContextKeyedService {
-   public:
-    explicit Service(Profile* profile);
-    virtual ~Service();
-
-    // BrowserContextKeyedService implementation.
-    virtual void Shutdown() OVERRIDE;
-
-    scoped_refptr<ChromeSpeechRecognitionPreferences> GetPreferences() const;
-
-   private:
-    scoped_refptr<ChromeSpeechRecognitionPreferences> preferences_;
-
-    DISALLOW_COPY_AND_ASSIGN(Service);
-  };
-
-  explicit ChromeSpeechRecognitionPreferences(Profile* profile);
-  virtual ~ChromeSpeechRecognitionPreferences();
-
-  void DetachFromProfile();
-  void ReloadFilterProfanities();
-  void ReloadNotificationsShown();
-
-  Profile* profile_;  // NULL when detached.
-  scoped_ptr<PrefChangeRegistrar> pref_change_registrar_;
-  bool filter_profanities_;
-  scoped_ptr<base::ListValue> notifications_shown_;
-
-  // Lock used to ensure exclusive access to preference variables that are
-  // accessed by both threads (note: mutable is required to keep getters const).
-  mutable base::Lock preferences_lock_;
-
-  DISALLOW_COPY_AND_ASSIGN(ChromeSpeechRecognitionPreferences);
-};
-
-#endif  // CHROME_BROWSER_SPEECH_CHROME_SPEECH_RECOGNITION_PREFERENCES_H_
diff --git a/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc b/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc
index c3d2484..c5c8163 100644
--- a/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc
+++ b/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc
@@ -96,13 +96,13 @@
     return;
   // Checksum is not valid. See if there's a backup.
   base::FilePath backup = path.AddExtension(BACKUP_EXTENSION);
-  if (!file_util::PathExists(backup))
+  if (!base::PathExists(backup))
     return;
   // Load the backup and verify its checksum.
   if (LoadFile(backup, custom_words) != VALID_CHECKSUM)
     return;
   // Backup checksum is valid. Restore the backup.
-  file_util::CopyFile(backup, path);
+  base::CopyFile(backup, path);
 }
 
 // Backs up the original dictionary, saves |custom_words| and its checksum into
@@ -119,7 +119,7 @@
   }
   std::string checksum = base::MD5String(content.str());
   content << CHECKSUM_PREFIX << checksum;
-  file_util::CopyFile(path, path.AddExtension(BACKUP_EXTENSION));
+  base::CopyFile(path, path.AddExtension(BACKUP_EXTENSION));
   base::ImportantFileWriter::WriteFileAtomically(path, content.str());
 }
 
diff --git a/chrome/browser/spellchecker/spellcheck_factory.cc b/chrome/browser/spellchecker/spellcheck_factory.cc
index 0e6bd19..068bbfc 100644
--- a/chrome/browser/spellchecker/spellcheck_factory.cc
+++ b/chrome/browser/spellchecker/spellcheck_factory.cc
@@ -71,7 +71,7 @@
   return spellcheck;
 }
 
-void SpellcheckServiceFactory::RegisterUserPrefs(
+void SpellcheckServiceFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* user_prefs) {
   // TODO(estade): IDS_SPELLCHECK_DICTIONARY should be an ASCII string.
   user_prefs->RegisterLocalizedStringPref(
diff --git a/chrome/browser/spellchecker/spellcheck_factory.h b/chrome/browser/spellchecker/spellcheck_factory.h
index 59aff27..db2eca8 100644
--- a/chrome/browser/spellchecker/spellcheck_factory.h
+++ b/chrome/browser/spellchecker/spellcheck_factory.h
@@ -37,7 +37,7 @@
   // BrowserContextKeyedServiceFactory:
   virtual BrowserContextKeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const OVERRIDE;
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
index a6f5169..ff84d7f 100644
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
@@ -80,7 +80,7 @@
   base::FilePath user_dir;
   PathService::Get(chrome::DIR_USER_DATA, &user_dir);
   base::FilePath fallback = user_dir.Append(file->path.BaseName());
-  if (!file_util::PathExists(file->path) && file_util::PathExists(fallback))
+  if (!base::PathExists(file->path) && base::PathExists(fallback))
     file->path = fallback;
 #endif
 
@@ -89,7 +89,7 @@
   bool bdict_is_valid;
   {
     base::MemoryMappedFile map;
-    bdict_is_valid = file_util::PathExists(file->path) &&
+    bdict_is_valid = base::PathExists(file->path) &&
         map.Initialize(file->path) &&
         hunspell::BDict::Verify(reinterpret_cast<const char*>(map.data()),
                                 map.length());
@@ -101,7 +101,7 @@
         NULL,
         NULL);
   } else {
-    base::Delete(file->path, false);
+    base::DeleteFile(file->path, false);
   }
 
   return file.Pass();
@@ -148,7 +148,7 @@
 #endif
 
     if (!success) {
-      base::Delete(path, false);
+      base::DeleteFile(path, false);
       return false;
     }
   }
diff --git a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
index 5130600..2d1bda7 100644
--- a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
+++ b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
@@ -78,8 +78,8 @@
   content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
   EXPECT_EQ(SpellcheckService::BDICT_CORRUPTED,
             SpellcheckService::GetStatusEvent());
-  if (file_util::PathExists(bdict_path)) {
+  if (base::PathExists(bdict_path)) {
     ADD_FAILURE();
-    EXPECT_TRUE(base::Delete(bdict_path, true));
+    EXPECT_TRUE(base::DeleteFile(bdict_path, true));
   }
 }
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc
index 1c0c5e1..cd45137 100644
--- a/chrome/browser/ssl/ssl_browser_tests.cc
+++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -10,6 +10,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -1292,7 +1292,7 @@
 // - navigate to a bad HTTPS (expect unsafe content and filtered frame), then
 //   back
 // - navigate to HTTP (expect insecure content), then back
-IN_PROC_BROWSER_TEST_F(SSLUITest, TestGoodFrameNavigation) {
+IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestGoodFrameNavigation) {
   ASSERT_TRUE(test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
   ASSERT_TRUE(https_server_expired_.Start());
diff --git a/chrome/browser/ssl/ssl_client_auth_observer.cc b/chrome/browser/ssl/ssl_client_auth_observer.cc
index 8e1d162..93a90c0 100644
--- a/chrome/browser/ssl/ssl_client_auth_observer.cc
+++ b/chrome/browser/ssl/ssl_client_auth_observer.cc
@@ -8,7 +8,7 @@
 
 #include "base/bind.h"
 #include "base/logging.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "net/cert/x509_certificate.h"
diff --git a/chrome/browser/ssl/ssl_tab_helper.cc b/chrome/browser/ssl/ssl_tab_helper.cc
index 2391e2f..802687e 100644
--- a/chrome/browser/ssl/ssl_tab_helper.cc
+++ b/chrome/browser/ssl/ssl_tab_helper.cc
@@ -13,6 +13,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/certificate_viewer.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/ssl/ssl_add_cert_handler.h"
 #include "chrome/browser/ssl/ssl_client_certificate_selector.h"
 #include "chrome/browser/ui/browser_finder.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_observer.h"
@@ -134,7 +134,7 @@
 class SSLTabHelper::SSLAddCertData
     : public content::NotificationObserver {
  public:
-  explicit SSLAddCertData(content::WebContents* contents);
+  explicit SSLAddCertData(InfoBarService* infobar_service);
   virtual ~SSLAddCertData();
 
   // Displays an infobar, replacing |infobar_delegate_| if it exists.
@@ -153,8 +153,8 @@
   DISALLOW_COPY_AND_ASSIGN(SSLAddCertData);
 };
 
-SSLTabHelper::SSLAddCertData::SSLAddCertData(content::WebContents* contents)
-    : infobar_service_(InfoBarService::FromWebContents(contents)),
+SSLTabHelper::SSLAddCertData::SSLAddCertData(InfoBarService* infobar_service)
+    : infobar_service_(infobar_service),
       infobar_delegate_(NULL) {
   content::Source<InfoBarService> source(infobar_service_);
   registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
@@ -210,16 +210,15 @@
     const net::HttpNetworkSession* network_session,
     net::SSLCertRequestInfo* cert_request_info,
     const base::Callback<void(net::X509Certificate*)>& callback) {
-  chrome::ShowSSLClientCertificateSelector(
-      web_contents_, network_session, cert_request_info, callback);
+  chrome::ShowSSLClientCertificateSelector(web_contents_, network_session,
+                                           cert_request_info, callback);
 }
 
 void SSLTabHelper::OnVerifyClientCertificateError(
     scoped_refptr<SSLAddCertHandler> handler, int error_code) {
-  SSLAddCertData* add_cert_data = GetAddCertData(handler.get());
   // Display an infobar with the error message.
   // TODO(davidben): Display a more user-friendly error string.
-  add_cert_data->ShowInfoBar(
+  GetAddCertData(handler.get())->ShowInfoBar(
       l10n_util::GetStringFUTF16(IDS_ADD_CERT_ERR_INVALID_CERT,
                                  base::IntToString16(-error_code),
                                  ASCIIToUTF16(net::ErrorToString(error_code))),
@@ -233,22 +232,19 @@
 
 void SSLTabHelper::OnAddClientCertificateSuccess(
     scoped_refptr<SSLAddCertHandler> handler) {
-  SSLAddCertData* add_cert_data = GetAddCertData(handler.get());
-  // Display an infobar to inform the user.
   net::X509Certificate* cert = handler->cert();
   // TODO(evanm): GetDisplayName should return UTF-16.
-  add_cert_data->ShowInfoBar(
+  GetAddCertData(handler.get())->ShowInfoBar(
       l10n_util::GetStringFUTF16(IDS_ADD_CERT_SUCCESS_INFOBAR_LABEL,
                                  UTF8ToUTF16(cert->issuer().GetDisplayName())),
       cert);
 }
 
 void SSLTabHelper::OnAddClientCertificateError(
-    scoped_refptr<SSLAddCertHandler> handler, int error_code) {
-  SSLAddCertData* add_cert_data = GetAddCertData(handler.get());
-  // Display an infobar with the error message.
+    scoped_refptr<SSLAddCertHandler> handler,
+    int error_code) {
   // TODO(davidben): Display a more user-friendly error string.
-  add_cert_data->ShowInfoBar(
+  GetAddCertData(handler.get())->ShowInfoBar(
       l10n_util::GetStringFUTF16(IDS_ADD_CERT_ERR_FAILED,
                                  base::IntToString16(-error_code),
                                  ASCIIToUTF16(net::ErrorToString(error_code))),
@@ -262,12 +258,14 @@
 }
 
 SSLTabHelper::SSLAddCertData*
-SSLTabHelper::GetAddCertData(SSLAddCertHandler* handler) {
+    SSLTabHelper::GetAddCertData(SSLAddCertHandler* handler) {
   // Find/create the slot.
   linked_ptr<SSLAddCertData>& ptr_ref =
       request_id_to_add_cert_data_[handler->network_request_id()];
   // Fill it if necessary.
-  if (!ptr_ref.get())
-    ptr_ref.reset(new SSLAddCertData(web_contents_));
+  if (!ptr_ref.get()) {
+    ptr_ref.reset(
+        new SSLAddCertData(InfoBarService::FromWebContents(web_contents_)));
+  }
   return ptr_ref.get();
 }
diff --git a/chrome/browser/storage_monitor/media_storage_util.cc b/chrome/browser/storage_monitor/media_storage_util.cc
index 785440c..aef5b0b 100644
--- a/chrome/browser/storage_monitor/media_storage_util.cc
+++ b/chrome/browser/storage_monitor/media_storage_util.cc
@@ -44,7 +44,7 @@
     const base::Callback<void(bool)>& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-                          base::Bind(callback, file_util::PathExists(path)));
+                          base::Bind(callback, base::PathExists(path)));
 }
 
 typedef std::vector<StorageInfo> StorageInfoList;
@@ -79,7 +79,7 @@
     if (type == StorageInfo::FIXED_MASS_STORAGE ||
         type == StorageInfo::ITUNES ||
         type == StorageInfo::PICASA) {
-      if (!file_util::PathExists(base::FilePath::FromUTF8Unsafe(unique_id)))
+      if (!base::PathExists(base::FilePath::FromUTF8Unsafe(unique_id)))
         missing_devices.insert(*it);
       continue;
     }
@@ -103,11 +103,11 @@
   DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 
   base::FilePath::StringType dcim_dir(kDCIMDirectoryName);
-  if (!file_util::DirectoryExists(mount_point.Append(dcim_dir))) {
+  if (!base::DirectoryExists(mount_point.Append(dcim_dir))) {
     // Check for lowercase 'dcim' as well.
     base::FilePath dcim_path_lower(
         mount_point.Append(StringToLowerASCII(dcim_dir)));
-    if (!file_util::DirectoryExists(dcim_path_lower))
+    if (!base::DirectoryExists(dcim_path_lower))
       return false;
   }
   return true;
diff --git a/chrome/browser/storage_monitor/storage_monitor.cc b/chrome/browser/storage_monitor/storage_monitor.cc
index 6d27d3b..a771fd5 100644
--- a/chrome/browser/storage_monitor/storage_monitor.cc
+++ b/chrome/browser/storage_monitor/storage_monitor.cc
@@ -156,7 +156,7 @@
     storage_map_.insert(std::make_pair(info.device_id(), info));
   }
 
-  DVLOG(1) << "RemovableStorageAttached with name " << UTF16ToUTF8(info.name())
+  DVLOG(1) << "StorageAttached with name " << UTF16ToUTF8(info.name())
            << " and id " << info.device_id();
   if (StorageInfo::IsRemovableDevice(info.device_id())) {
     observer_list_->Notify(
@@ -175,7 +175,7 @@
     storage_map_.erase(it);
   }
 
-  DVLOG(1) << "RemovableStorageDetached for id " << id;
+  DVLOG(1) << "StorageDetached for id " << id;
   if (StorageInfo::IsRemovableDevice(info.device_id())) {
     observer_list_->Notify(
         &RemovableStorageObserver::OnRemovableStorageDetached, info);
diff --git a/chrome/browser/storage_monitor/storage_monitor.h b/chrome/browser/storage_monitor/storage_monitor.h
index 5661c80..9258dd4 100644
--- a/chrome/browser/storage_monitor/storage_monitor.h
+++ b/chrome/browser/storage_monitor/storage_monitor.h
@@ -14,6 +14,7 @@
 #include "base/observer_list_threadsafe.h"
 #include "base/strings/string16.h"
 #include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
 #include "chrome/browser/storage_monitor/storage_info.h"
 
 class ChromeBrowserMainPartsLinux;
@@ -22,6 +23,7 @@
 class MediaGalleriesPrivateApiTest;
 class MediaGalleriesPrivateEjectApiTest;
 class SystemInfoStorageApiTest;
+class SystemInfoStorageEjectApiTest;
 
 namespace device {
 class MediaTransferProtocolManager;
@@ -130,6 +132,7 @@
   friend class ::MediaGalleriesPrivateEjectApiTest;
   friend class MediaFileSystemRegistryTest;
   friend class ::SystemInfoStorageApiTest;
+  friend class ::SystemInfoStorageEjectApiTest;
 
   StorageMonitor();
   virtual ~StorageMonitor();
diff --git a/chrome/browser/storage_monitor/storage_monitor_linux_unittest.cc b/chrome/browser/storage_monitor/storage_monitor_linux_unittest.cc
index a8c82a5..047711a 100644
--- a/chrome/browser/storage_monitor/storage_monitor_linux_unittest.cc
+++ b/chrome/browser/storage_monitor/storage_monitor_linux_unittest.cc
@@ -235,7 +235,7 @@
   void RemoveDCIMDirFromMountPoint(const std::string& dir) {
     base::FilePath dcim =
         scoped_temp_dir_.path().AppendASCII(dir).Append(kDCIMDirectoryName);
-    base::Delete(dcim, false);
+    base::DeleteFile(dcim, false);
   }
 
   MockRemovableStorageObserver& observer() {
@@ -558,7 +558,7 @@
   MtabTestData test_data5[] = {
     MtabTestData(kDeviceNoDCIM, test_path_b.value(), kValidFS),
   };
-  base::Delete(test_path_b.Append(kDCIMDirectoryName), false);
+  base::DeleteFile(test_path_b.Append(kDCIMDirectoryName), false);
   AppendToMtabAndRunLoop(test_data5, arraysize(test_data5));
   EXPECT_EQ(4, observer().attach_calls());
   EXPECT_EQ(2, observer().detach_calls());
diff --git a/chrome/browser/storage_monitor/transient_device_ids.cc b/chrome/browser/storage_monitor/transient_device_ids.cc
index cfdf8d6..850c17c 100644
--- a/chrome/browser/storage_monitor/transient_device_ids.cc
+++ b/chrome/browser/storage_monitor/transient_device_ids.cc
@@ -20,7 +20,6 @@
 std::string TransientDeviceIds::GetTransientIdForDeviceId(
     const std::string& device_id) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(StorageInfo::IsRemovableDevice(device_id));
 
   if (!ContainsKey(device_id_map_, device_id)) {
     std::string transient_id;
diff --git a/chrome/browser/storage_monitor/transient_device_ids.h b/chrome/browser/storage_monitor/transient_device_ids.h
index 8f81650..cf6396f 100644
--- a/chrome/browser/storage_monitor/transient_device_ids.h
+++ b/chrome/browser/storage_monitor/transient_device_ids.h
@@ -24,7 +24,7 @@
   ~TransientDeviceIds();
 
   // Returns the transient ID for a given |device_id|.
-  // |device_id| must be for a removable device.
+  // |device_id| must be for a fixed or removable storage device.
   // If |device_id| has never been seen before, a new, unique transient id will
   // be assigned.
   std::string GetTransientIdForDeviceId(const std::string& device_id);
diff --git a/chrome/browser/sync/about_sync_util_unittest.cc b/chrome/browser/sync/about_sync_util_unittest.cc
index 77c8caa..e94d6e1 100644
--- a/chrome/browser/sync/about_sync_util_unittest.cc
+++ b/chrome/browser/sync/about_sync_util_unittest.cc
@@ -18,7 +18,7 @@
 namespace sync_ui_util {
 namespace {
 
-TEST(SyncUIUtilTest, ConstructAboutInformationWithUnrecoverableErrorTest) {
+TEST(SyncUIUtilTestAbout, ConstructAboutInformationWithUnrecoverableErrorTest) {
   base::MessageLoopForUI message_loop;
   content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
   scoped_ptr<Profile> profile(
diff --git a/chrome/browser/sync/backend_migrator.cc b/chrome/browser/sync/backend_migrator.cc
index 5a0967f..cba80c1 100644
--- a/chrome/browser/sync/backend_migrator.cc
+++ b/chrome/browser/sync/backend_migrator.cc
@@ -7,8 +7,8 @@
 #include "base/message_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/tracked_objects.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "sync/internal_api/public/configure_reason.h"
diff --git a/chrome/browser/sync/backend_migrator_unittest.cc b/chrome/browser/sync/backend_migrator_unittest.cc
index b2a6ac7..9c49eeb 100644
--- a/chrome/browser/sync/backend_migrator_unittest.cc
+++ b/chrome/browser/sync/backend_migrator_unittest.cc
@@ -6,9 +6,9 @@
 
 #include "base/message_loop.h"
 #include "base/tracked_objects.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/sync/glue/data_type_manager_mock.h"
 #include "chrome/browser/sync/profile_sync_service_mock.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "sync/internal_api/public/base/model_type_test_util.h"
 #include "sync/internal_api/public/test/test_user_share.h"
 #include "sync/internal_api/public/write_transaction.h"
diff --git a/chrome/browser/sync/glue/android_invalidator_bridge_unittest.cc b/chrome/browser/sync/glue/android_invalidator_bridge_unittest.cc
index 8298c2a..1b78cfc 100644
--- a/chrome/browser/sync/glue/android_invalidator_bridge_unittest.cc
+++ b/chrome/browser/sync/glue/android_invalidator_bridge_unittest.cc
@@ -17,7 +17,7 @@
 #include "base/run_loop.h"
 #include "base/sequenced_task_runner.h"
 #include "base/threading/thread.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/test/base/profile_mock.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
@@ -97,13 +97,13 @@
   }
 
   void TriggerRefreshNotification(
-      int type,
       const syncer::ModelTypeInvalidationMap& invalidation_map) {
     content::NotificationService::current()->Notify(
-        type,
+        chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
         content::Source<Profile>(&mock_profile_),
-        content::Details<const syncer::ModelTypeInvalidationMap>(
-            &invalidation_map));
+        content::Details<const syncer::ObjectIdInvalidationMap>(
+            ModelTypeInvalidationMapToObjectIdInvalidationMap(
+                &invalidation_map));
     BlockForSyncThread();
   }
 
@@ -168,8 +168,7 @@
       ModelTypeSetToInvalidationMap(types, std::string());
   CreateObserver();
   UpdateEnabledTypes(syncer::ModelTypeSet(syncer::SESSIONS));
-  TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
-                             invalidation_map);
+  TriggerRefreshNotification(invalidation_map);
   VerifyAndDestroyObserver(invalidation_map);
 }
 
@@ -183,8 +182,7 @@
       syncer::ModelTypeSetToInvalidationMap(enabled_types, std::string());
   CreateObserver();
   UpdateEnabledTypes(enabled_types);
-  TriggerRefreshNotification(chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
-                             syncer::ModelTypeInvalidationMap());
+  TriggerRefreshNotification(syncer::ModelTypeInvalidationMap());
   VerifyAndDestroyObserver(enabled_types_invalidation_map);
 }
 
diff --git a/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc b/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc
index a52c3a4..21d3e2f 100644
--- a/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop.h"
 #include "base/run_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/sync/glue/autofill_data_type_controller.h"
 #include "chrome/browser/sync/glue/data_type_controller_mock.h"
 #include "chrome/browser/sync/glue/shared_change_processor_mock.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/sync/profile_sync_service_mock.h"
 #include "chrome/browser/webdata/autocomplete_syncable_service.h"
 #include "chrome/browser/webdata/web_data_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/profile_mock.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #include "components/webdata/common/web_data_service_test_util.h"
diff --git a/chrome/browser/sync/glue/bookmark_change_processor.cc b/chrome/browser/sync/glue/bookmark_change_processor.cc
index e0ed06f..fd04dcd 100644
--- a/chrome/browser/sync/glue/bookmark_change_processor.cc
+++ b/chrome/browser/sync/glue/bookmark_change_processor.cc
@@ -559,6 +559,13 @@
   // A map to keep track of some reordering work we defer until later.
   std::multimap<int, const BookmarkNode*> to_reposition;
 
+  syncer::ReadNode synced_bookmarks(trans);
+  int64 synced_bookmarks_id = syncer::kInvalidId;
+  if (synced_bookmarks.InitByTagLookup(kMobileBookmarksTag) ==
+      syncer::BaseNode::INIT_OK) {
+    synced_bookmarks_id = synced_bookmarks.GetId();
+  }
+
   // Continue iterating where the previous loop left off.
   for ( ; it != changes.Get().end(); ++it) {
     const BookmarkNode* dst =
@@ -569,10 +576,21 @@
     if (model->is_permanent_node(dst))
       continue;
 
+    // Because the Synced Bookmarks node can be created server side, it's
+    // possible it'll arrive at the client as an update. In that case it won't
+    // have been associated at startup, the GetChromeNodeFromSyncId call above
+    // will return NULL, and we won't detect it as a permanent node, resulting
+    // in us trying to create it here (which will fail). Therefore, we add
+    // special logic here just to detect the Synced Bookmarks folder.
+    if (synced_bookmarks_id != syncer::kInvalidId &&
+        it->id == synced_bookmarks_id) {
+      // This is a newly created Synced Bookmarks node. Associate it.
+      model_associator_->Associate(model->mobile_node(), it->id);
+      continue;
+    }
+
     DCHECK_NE(it->action, ChangeRecord::ACTION_DELETE)
         << "We should have passed all deletes by this point.";
-    DCHECK_EQ((it->action == ChangeRecord::ACTION_ADD), (dst == NULL))
-        << "ACTION_ADD should be seen if and only if the node is unknown.";
 
     syncer::ReadNode src(trans);
     if (src.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) {
@@ -581,34 +599,45 @@
       return;
     }
 
-    const BookmarkNode* node = CreateOrUpdateBookmarkNode(&src, model,
-                                                          profile_,
-                                                          model_associator_);
-    if (node) {
-      to_reposition.insert(std::make_pair(src.GetPositionIndex(), node));
-      bookmark_model_->SetNodeMetaInfo(node, kBookmarkTransactionVersionKey,
-                                       base::Int64ToString(model_version));
+    const BookmarkNode* parent =
+        model_associator_->GetChromeNodeFromSyncId(src.GetParentId());
+    if (!parent) {
+      LOG(ERROR) << "Could not find parent of node being added/updated."
+        << " Node title: " << src.GetTitle()
+        << ", parent id = " << src.GetParentId();
+      continue;
+    }
+
+    if (dst) {
+      DCHECK(it->action == ChangeRecord::ACTION_UPDATE)
+          << "ACTION_UPDATE should be seen if and only if the node is known.";
+      UpdateBookmarkWithSyncData(src, model, dst, profile_);
+
+      // Move all modified entries to the right.  We'll fix it later.
+      model->Move(dst, parent, parent->child_count());
     } else {
-      // Because the Synced Bookmarks node can be created server side, it's
-      // possible it'll arrive at the client as an update. In that case it won't
-      // have been associated at startup, the GetChromeNodeFromSyncId call above
-      // will return NULL, and we won't detect it as a permanent node, resulting
-      // in us trying to create it here (which will fail). Therefore, we add
-      // special logic here just to detect the Synced Bookmarks folder.
-      syncer::ReadNode synced_bookmarks(trans);
-      if (synced_bookmarks.InitByTagLookup(kMobileBookmarksTag) ==
-              syncer::BaseNode::INIT_OK &&
-          synced_bookmarks.GetId() == it->id) {
-        // This is a newly created Synced Bookmarks node. Associate it.
-        model_associator_->Associate(model->mobile_node(), it->id);
-      } else {
+      DCHECK(it->action == ChangeRecord::ACTION_ADD)
+          << "ACTION_ADD should be seen if and only if the node is unknown.";
+
+      dst = CreateBookmarkNode(&src,
+                               parent,
+                               model,
+                               profile_,
+                               parent->child_count());
+      if (!dst) {
         // We ignore bookmarks we can't add. Chances are this is caused by
         // a bookmark that was not fully associated.
         LOG(ERROR) << "Failed to create bookmark node with title "
                    << src.GetTitle() + " and url "
                    << src.GetBookmarkSpecifics().url();
+        continue;
       }
+      model_associator_->Associate(dst, src.GetId());
     }
+
+    to_reposition.insert(std::make_pair(src.GetPositionIndex(), dst));
+    bookmark_model_->SetNodeMetaInfo(dst, kBookmarkTransactionVersionKey,
+                                     base::Int64ToString(model_version));
   }
 
   // When we added or updated bookmarks in the previous loop, we placed them to
@@ -642,50 +671,24 @@
 }
 
 // Static.
-// Create a bookmark node corresponding to |src| if one is not already
-// associated with |src|.
-const BookmarkNode* BookmarkChangeProcessor::CreateOrUpdateBookmarkNode(
-    syncer::BaseNode* src,
+// Update a bookmark node with specified sync data.
+void BookmarkChangeProcessor::UpdateBookmarkWithSyncData(
+    const syncer::BaseNode& sync_node,
     BookmarkModel* model,
-    Profile* profile,
-    BookmarkModelAssociator* model_associator) {
-  const BookmarkNode* parent =
-      model_associator->GetChromeNodeFromSyncId(src->GetParentId());
-  if (!parent) {
-    DLOG(WARNING) << "Could not find parent of node being added/updated."
-      << " Node title: " << src->GetTitle()
-      << ", parent id = " << src->GetParentId();
-
-    return NULL;
+    const BookmarkNode* node,
+    Profile* profile) {
+  DCHECK_EQ(sync_node.GetIsFolder(), node->is_folder());
+  const sync_pb::BookmarkSpecifics& specifics =
+      sync_node.GetBookmarkSpecifics();
+  if (!sync_node.GetIsFolder())
+    model->SetURL(node, GURL(specifics.url()));
+  model->SetTitle(node, UTF8ToUTF16(sync_node.GetTitle()));
+  if (specifics.has_creation_time_us()) {
+    model->SetDateAdded(
+        node,
+        base::Time::FromInternalValue(specifics.creation_time_us()));
   }
-  const BookmarkNode* dst = model_associator->GetChromeNodeFromSyncId(
-      src->GetId());
-  if (!dst) {
-    dst = CreateBookmarkNode(src, parent, model, profile);
-    if (dst)
-      model_associator->Associate(dst, src->GetId());
-  } else {
-    // URL and is_folder are not expected to change.
-    // TODO(ncarter): Determine if such changes should be legal or not.
-    DCHECK_EQ(src->GetIsFolder(), dst->is_folder());
-
-    // Move all modified entries to the right.  The caller will fix this later.
-    model->Move(dst, parent, parent->child_count());
-
-    const sync_pb::BookmarkSpecifics& specifics = src->GetBookmarkSpecifics();
-    if (!src->GetIsFolder())
-      model->SetURL(dst, GURL(specifics.url()));
-    model->SetTitle(dst, UTF8ToUTF16(src->GetTitle()));
-    if (specifics.has_creation_time_us()) {
-      model->SetDateAdded(dst,
-                          base::Time::FromInternalValue(
-                              specifics.creation_time_us()));
-    }
-
-    SetBookmarkFavicon(src, dst, model, profile);
-  }
-
-  return dst;
+  SetBookmarkFavicon(&sync_node, node, model, profile);
 }
 
 // static
@@ -710,13 +713,13 @@
     syncer::BaseNode* sync_node,
     const BookmarkNode* parent,
     BookmarkModel* model,
-    Profile* profile) {
+    Profile* profile,
+    int index) {
   DCHECK(parent);
 
   const BookmarkNode* node;
   if (sync_node->GetIsFolder()) {
-    node = model->AddFolder(parent, parent->child_count(),
-                            UTF8ToUTF16(sync_node->GetTitle()));
+    node = model->AddFolder(parent, index, UTF8ToUTF16(sync_node->GetTitle()));
   } else {
     // 'creation_time_us' was added in m24. Assume a time of 0 means now.
     const sync_pb::BookmarkSpecifics& specifics =
@@ -724,7 +727,7 @@
     const int64 create_time_internal = specifics.creation_time_us();
     base::Time create_time = (create_time_internal == 0) ?
         base::Time::Now() : base::Time::FromInternalValue(create_time_internal);
-    node = model->AddURLWithCreationTime(parent, parent->child_count(),
+    node = model->AddURLWithCreationTime(parent, index,
                                          UTF8ToUTF16(sync_node->GetTitle()),
                                          GURL(specifics.url()), create_time);
     if (node)
@@ -736,7 +739,7 @@
 // static
 // Sets the favicon of the given bookmark node from the given sync node.
 bool BookmarkChangeProcessor::SetBookmarkFavicon(
-    syncer::BaseNode* sync_node,
+    const syncer::BaseNode* sync_node,
     const BookmarkNode* bookmark_node,
     BookmarkModel* bookmark_model,
     Profile* profile) {
diff --git a/chrome/browser/sync/glue/bookmark_change_processor.h b/chrome/browser/sync/glue/bookmark_change_processor.h
index b356208..76fdd83 100644
--- a/chrome/browser/sync/glue/bookmark_change_processor.h
+++ b/chrome/browser/sync/glue/bookmark_change_processor.h
@@ -69,31 +69,32 @@
       int64 model_version,
       const syncer::ImmutableChangeRecordList& changes) OVERRIDE;
 
-  // Create a bookmark node corresponding to |src| if one is not already
-  // associated with |src|.  Returns the node that was created or updated.  The
-  // bookmark will be placed at the far right position of its containing folder.
-  static const BookmarkNode* CreateOrUpdateBookmarkNode(
-      syncer::BaseNode* src,
-      BookmarkModel* model,
-      Profile* profile,
-      BookmarkModelAssociator* model_associator);
-
   // The following methods are static and hence may be invoked at any time, and
-  // do not depend on having a running ChangeProcessor.  Creates a bookmark node
-  // under the given parent node from the given sync node. Returns the newly
-  // created node.  The created node is placed in the far right position under
-  // the specified parent.
+  // do not depend on having a running ChangeProcessor.
+
+  // Updates the title, URL, creation time and favicon of the bookmark |node|
+  // with data taken from the |sync_node| sync node.
+  static void UpdateBookmarkWithSyncData(
+      const syncer::BaseNode& sync_node,
+      BookmarkModel* model,
+      const BookmarkNode* node,
+      Profile* profile);
+
+  // Creates a bookmark node under the given parent node from the given sync
+  // node. Returns the newly created node.  The created node is placed at the
+  // specified index among the parent's children.
   static const BookmarkNode* CreateBookmarkNode(
       syncer::BaseNode* sync_node,
       const BookmarkNode* parent,
       BookmarkModel* model,
-      Profile* profile);
+      Profile* profile,
+      int index);
 
   // Sets the favicon of the given bookmark node from the given sync node.
   // Returns whether the favicon was set in the bookmark node.
   // |profile| is the profile that contains the HistoryService and BookmarkModel
   // for the bookmark in question.
-  static bool SetBookmarkFavicon(syncer::BaseNode* sync_node,
+  static bool SetBookmarkFavicon(const syncer::BaseNode* sync_node,
                                  const BookmarkNode* bookmark_node,
                                  BookmarkModel* model,
                                  Profile* profile);
diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller.cc b/chrome/browser/sync/glue/bookmark_data_type_controller.cc
index f8958c4..c91de7c 100644
--- a/chrome/browser/sync/glue/bookmark_data_type_controller.cc
+++ b/chrome/browser/sync/glue/bookmark_data_type_controller.cc
@@ -7,12 +7,12 @@
 #include "base/metrics/histogram.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/profile_sync_components_factory.h"
 #include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
index e581409..24438a6 100644
--- a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/run_loop.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
@@ -20,7 +21,6 @@
 #include "chrome/browser/sync/glue/model_associator_mock.h"
 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
 #include "chrome/browser/sync/profile_sync_service_mock.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/profile_mock.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/browser_context_keyed_service/refcounted_browser_context_keyed_service.h"
diff --git a/chrome/browser/sync/glue/bookmark_model_associator.cc b/chrome/browser/sync/glue/bookmark_model_associator.cc
index c5b5434..9137501 100644
--- a/chrome/browser/sync/glue/bookmark_model_associator.cc
+++ b/chrome/browser/sync/glue/bookmark_model_associator.cc
@@ -501,25 +501,24 @@
           GURL(sync_child_node.GetBookmarkSpecifics().url()),
           sync_child_node.GetTitle(),
           sync_child_node.GetIsFolder());
-      if (child_node)
+      if (child_node) {
         Associate(child_node, sync_child_id);
-      // All bookmarks are currently modified at association time (even if
-      // it doesn't change anything).
-      // TODO(sync): introduce logic to only modify the bookmark model if
-      // necessary.
-      const BookmarkNode* new_child_node =
-          BookmarkChangeProcessor::CreateOrUpdateBookmarkNode(
-              &sync_child_node,
-              bookmark_model_,
-              profile_,
-              this);
-      bookmark_model_->Move(new_child_node, parent_node, index);
-      if (new_child_node != child_node) {
-        local_merge_result->set_num_items_added(
-            local_merge_result->num_items_added() + 1);
-      } else {
+
+        // All bookmarks are currently modified at association time, even if
+        // nothing has changed.
+        // TODO(sync): Only modify the bookmark model if necessary.
+        BookmarkChangeProcessor::UpdateBookmarkWithSyncData(
+            sync_child_node, bookmark_model_, child_node, profile_);
+        bookmark_model_->Move(child_node, parent_node, index);
         local_merge_result->set_num_items_modified(
             local_merge_result->num_items_modified() + 1);
+      } else {
+        child_node = BookmarkChangeProcessor::CreateBookmarkNode(
+            &sync_child_node, parent_node, bookmark_model_, profile_, index);
+        if (child_node)
+          Associate(child_node, sync_child_id);
+        local_merge_result->set_num_items_added(
+            local_merge_result->num_items_added() + 1);
       }
       if (sync_child_node.GetIsFolder())
         dfs_stack.push(sync_child_id);
diff --git a/chrome/browser/sync/glue/chrome_extensions_activity_monitor.cc b/chrome/browser/sync/glue/chrome_extensions_activity_monitor.cc
index 7518a83..fbe3d2a 100644
--- a/chrome/browser/sync/glue/chrome_extensions_activity_monitor.cc
+++ b/chrome/browser/sync/glue/chrome_extensions_activity_monitor.cc
@@ -5,8 +5,8 @@
 #include "chrome/browser/sync/glue/chrome_extensions_activity_monitor.h"
 
 #include "base/bind.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/bookmarks/bookmarks_api.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/sync/glue/chrome_extensions_activity_monitor_unittest.cc b/chrome/browser/sync/glue/chrome_extensions_activity_monitor_unittest.cc
index 799ff7d..c8512f8 100644
--- a/chrome/browser/sync/glue/chrome_extensions_activity_monitor_unittest.cc
+++ b/chrome/browser/sync/glue/chrome_extensions_activity_monitor_unittest.cc
@@ -8,8 +8,8 @@
 #include "base/message_loop.h"
 #include "base/path_service.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/bookmarks/bookmarks_api.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
diff --git a/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc b/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
index 999c684..a8da6e3 100644
--- a/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
+++ b/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
@@ -6,13 +6,13 @@
 
 #include "base/compiler_specific.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/sync/glue/backend_data_type_configurer.h"
 #include "chrome/browser/sync/glue/data_type_controller.h"
 #include "chrome/browser/sync/glue/data_type_encryption_handler.h"
 #include "chrome/browser/sync/glue/data_type_manager_observer.h"
 #include "chrome/browser/sync/glue/failed_data_types_handler.h"
 #include "chrome/browser/sync/glue/fake_data_type_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/test/test_browser_thread.h"
 #include "sync/internal_api/public/base/model_type.h"
 #include "sync/internal_api/public/configure_reason.h"
diff --git a/chrome/browser/sync/glue/data_type_manager_mock.cc b/chrome/browser/sync/glue/data_type_manager_mock.cc
index d0c155a..425b491 100644
--- a/chrome/browser/sync/glue/data_type_manager_mock.cc
+++ b/chrome/browser/sync/glue/data_type_manager_mock.cc
@@ -3,8 +3,8 @@
 // found in the LICENSE file.
 
 #include "base/location.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/sync/glue/data_type_manager_mock.h"
-#include "chrome/common/chrome_notification_types.h"
 
 namespace browser_sync {
 
diff --git a/chrome/browser/sync/glue/device_info.cc b/chrome/browser/sync/glue/device_info.cc
index 8efc994..e593d00 100644
--- a/chrome/browser/sync/glue/device_info.cc
+++ b/chrome/browser/sync/glue/device_info.cc
@@ -42,11 +42,13 @@
 
 }  // namespace
 
-DeviceInfo::DeviceInfo(const std::string& client_name,
+DeviceInfo::DeviceInfo(const std::string& guid,
+                       const std::string& client_name,
                        const std::string& chrome_version,
                        const std::string& sync_user_agent,
                        const sync_pb::SyncEnums::DeviceType device_type)
-    : client_name_(client_name),
+    : guid_(guid),
+      client_name_(client_name),
       chrome_version_(chrome_version),
       sync_user_agent_(sync_user_agent),
       device_type_(device_type) {
@@ -54,6 +56,10 @@
 
 DeviceInfo::~DeviceInfo() { }
 
+const std::string& DeviceInfo::guid() const {
+  return guid_;
+}
+
 const std::string& DeviceInfo::client_name() const {
   return client_name_;
 }
@@ -71,7 +77,8 @@
 }
 
 bool DeviceInfo::Equals(const DeviceInfo& other) const {
-  return this->client_name() == other.client_name()
+  return this->guid() == other.guid()
+      && this->client_name() == other.client_name()
       && this->chrome_version() == other.chrome_version()
       && this->sync_user_agent() == other.sync_user_agent()
       && this->device_type() == other.device_type();
@@ -138,19 +145,38 @@
 
 // static.
 void DeviceInfo::CreateLocalDeviceInfo(
+    const std::string& guid,
     base::Callback<void(const DeviceInfo& local_info)> callback) {
+  GetClientName(
+      base::Bind(&DeviceInfo::CreateLocalDeviceInfoContinuation,
+                 guid,
+                 callback));
+}
+
+// static.
+void DeviceInfo::GetClientName(
+    base::Callback<void(const std::string& client_name)> callback) {
   syncer::GetSessionName(
       content::BrowserThread::GetBlockingPool(),
-      base::Bind(&DeviceInfo::CreateLocalDeviceInfoContinuation, callback));
+      base::Bind(&DeviceInfo::GetClientNameContinuation,
+                 callback));
+}
+
+void DeviceInfo::GetClientNameContinuation(
+    base::Callback<void(const std::string& local_info)> callback,
+    const std::string& session_name) {
+  callback.Run(session_name);
 }
 
 // static.
 void DeviceInfo::CreateLocalDeviceInfoContinuation(
+    const std::string& guid,
     base::Callback<void(const DeviceInfo& local_info)> callback,
     const std::string& session_name) {
   chrome::VersionInfo version_info;
 
   DeviceInfo local_info(
+      guid,
       session_name,
       version_info.CreateVersionString(),
       MakeUserAgentForSyncApi(version_info),
diff --git a/chrome/browser/sync/glue/device_info.h b/chrome/browser/sync/glue/device_info.h
index d5a9998..4711925 100644
--- a/chrome/browser/sync/glue/device_info.h
+++ b/chrome/browser/sync/glue/device_info.h
@@ -18,29 +18,50 @@
 namespace browser_sync {
 
 // A class that holds information regarding the properties of a device.
-//
-// These objects do not contain enough information to uniquely identify devices.
-// Two different devices may end up generating identical DeviceInfos.
 class DeviceInfo {
  public:
-  DeviceInfo(const std::string& client_name,
+  DeviceInfo(const std::string& guid,
+             const std::string& client_name,
              const std::string& chrome_version,
              const std::string& sync_user_agent,
              const sync_pb::SyncEnums::DeviceType device_type);
   ~DeviceInfo();
 
+  // Sync specific unique identifier for the device. Note if a device
+  // is wiped and sync is set up again this id WILL be different.
+  // The same device might have more than 1 guid if the device has multiple
+  // accounts syncing.
+  const std::string& guid() const;
+
+  // The host name for the client.
   const std::string& client_name() const;
+
+  // Chrome version string.
   const std::string& chrome_version() const;
+
+  // The user agent is the combination of OS type, chrome version and which
+  // channel of chrome(stable or beta). For more information see
+  // |DeviceInfo::MakeUserAgentForSyncApi|.
   const std::string& sync_user_agent() const;
+
+  // Device Type.
   sync_pb::SyncEnums::DeviceType device_type() const;
 
   // Compares this object's fields with another's.
   bool Equals(const DeviceInfo& other) const;
 
   static sync_pb::SyncEnums::DeviceType GetLocalDeviceType();
+
+  // Creates a |DeviceInfo| object representing the local device and passes
+  // it as parameter to the callback.
   static void CreateLocalDeviceInfo(
+      const std::string& guid,
       base::Callback<void(const DeviceInfo& local_info)> callback);
 
+  // Gets the local device name and passes it as a parameter to callback.
+  static void GetClientName(
+      base::Callback<void(const std::string& local_info)> callback);
+
   // Helper to construct a user agent string (ASCII) suitable for use by
   // the syncapi for any HTTP communication. This string is used by the sync
   // backend for classifying client types when calculating statistics.
@@ -48,18 +69,28 @@
       const chrome::VersionInfo& version_info);
 
  private:
+  static void GetClientNameContinuation(
+      base::Callback<void(const std::string& local_info)> callback,
+      const std::string& session_name);
+
   static void CreateLocalDeviceInfoContinuation(
+      const std::string& guid,
       base::Callback<void(const DeviceInfo& local_info)> callback,
       const std::string& session_name);
 
+  const std::string guid_;
+
   const std::string client_name_;
+
   const std::string chrome_version_;
+
   const std::string sync_user_agent_;
+
   const sync_pb::SyncEnums::DeviceType device_type_;
 
   DISALLOW_COPY_AND_ASSIGN(DeviceInfo);
 };
 
-}
+}  // namespace browser_sync
 
 #endif  // CHROME_BROWSER_SYNC_GLUE_DEVICE_INFO_H_
diff --git a/chrome/browser/sync/glue/favicon_cache.cc b/chrome/browser/sync/glue/favicon_cache.cc
index 58416fc..a4a3fb8 100644
--- a/chrome/browser/sync/glue/favicon_cache.cc
+++ b/chrome/browser/sync/glue/favicon_cache.cc
@@ -6,11 +6,11 @@
 
 #include "base/message_loop.h"
 #include "base/metrics/histogram.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_service.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/history_types.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "sync/api/time.h"
@@ -213,14 +213,21 @@
   return !favicon_info.last_visit_time.is_null();
 }
 
-}  // namespace
+bool FaviconInfoHasValidTypeData(const SyncedFaviconInfo& favicon_info,
+                             syncer::ModelType type) {
+  if (type == syncer::FAVICON_IMAGES)
+    return FaviconInfoHasImages(favicon_info);
+  else if (type == syncer::FAVICON_TRACKING)
+    return FaviconInfoHasTracking(favicon_info);
+  NOTREACHED();
+  return false;
+}
 
-FaviconCacheObserver::~FaviconCacheObserver() {}
+}  // namespace
 
 FaviconCache::FaviconCache(Profile* profile, int max_sync_favicon_limit)
     : profile_(profile),
       weak_ptr_factory_(this),
-      legacy_delegate_(NULL),
       max_sync_favicon_limit_(max_sync_favicon_limit) {
   notification_registrar_.Add(this,
                               chrome::NOTIFICATION_HISTORY_URLS_DELETED,
@@ -246,12 +253,14 @@
   std::set<GURL> unsynced_favicon_urls;
   for (FaviconMap::const_iterator iter = synced_favicons_.begin();
        iter != synced_favicons_.end(); ++iter) {
-    unsynced_favicon_urls.insert(iter->first);
+    if (FaviconInfoHasValidTypeData(*(iter->second), type))
+      unsynced_favicon_urls.insert(iter->first);
   }
 
   syncer::SyncChangeList local_changes;
   for (syncer::SyncDataList::const_iterator iter = initial_sync_data.begin();
        iter != initial_sync_data.end(); ++iter) {
+    GURL remote_url = GetFaviconURLFromSpecifics(iter->GetSpecifics());
     GURL favicon_url = GetLocalFaviconFromSyncedData(*iter);
     if (favicon_url.is_valid()) {
       unsynced_favicon_urls.erase(favicon_url);
@@ -372,11 +381,13 @@
             favicon_iter->second->is_bookmarked = false;
             recent_favicons_.insert(favicon_iter->second);
             DCHECK(!FaviconInfoHasTracking(*(favicon_iter->second)));
+            DCHECK(FaviconInfoHasImages(*(favicon_iter->second)));
           } else {
             for (int i = 0; i < NUM_SIZES; ++i) {
               favicon_iter->second->bitmap_data[i] =
                   chrome::FaviconBitmapResult();
             }
+            DCHECK(FaviconInfoHasTracking(*(favicon_iter->second)));
             DCHECK(!FaviconInfoHasImages(*(favicon_iter->second)));
           }
         }
@@ -581,14 +592,6 @@
                    syncer::SyncChange::ACTION_UPDATE));
 }
 
-void FaviconCache::SetLegacyDelegate(FaviconCacheObserver* observer) {
-  legacy_delegate_ = observer;
-}
-
-void FaviconCache::RemoveLegacyDelegate() {
-  legacy_delegate_ = NULL;
-}
-
 void FaviconCache::Observe(int type,
                            const content::NotificationSource& source,
                            const content::NotificationDetails& details) {
@@ -608,17 +611,17 @@
   // All history was cleared: just delete all favicons.
   DVLOG(1) << "History clear detected, deleting all synced favicons.";
   syncer::SyncChangeList image_deletions, tracking_deletions;
-  for (FaviconMap::iterator iter = synced_favicons_.begin();
-       iter != synced_favicons_.end();) {
-    iter = DeleteSyncedFavicon(iter,
-                               &image_deletions,
-                               &tracking_deletions);
+  while (!synced_favicons_.empty()) {
+    DeleteSyncedFavicon(synced_favicons_.begin(),
+                        &image_deletions,
+                        &tracking_deletions);
   }
 
-  if (favicon_images_sync_processor_.get() &&
-      favicon_tracking_sync_processor_.get()) {
+  if (favicon_images_sync_processor_.get()) {
     favicon_images_sync_processor_->ProcessSyncChanges(FROM_HERE,
                                                        image_deletions);
+  }
+  if (favicon_tracking_sync_processor_.get()) {
     favicon_tracking_sync_processor_->ProcessSyncChanges(FROM_HERE,
                                                          tracking_deletions);
   }
@@ -695,8 +698,6 @@
     if (iter->second.new_tracking)
       tracking_change = syncer::SyncChange::ACTION_ADD;
     UpdateSyncState(favicon_url, image_change, tracking_change);
-    if (legacy_delegate_)
-      legacy_delegate_->OnFaviconUpdated(page_url, favicon_url);
 
     // TODO(zea): support multiple favicon urls per page.
     page_favicon_map_[page_url] = favicon_url;
@@ -712,8 +713,9 @@
   // have finished setting up. In that case ignore the update.
   // TODO(zea): consider tracking these skipped updates somehow?
   if (!favicon_images_sync_processor_.get() ||
-      !favicon_tracking_sync_processor_.get())
+      !favicon_tracking_sync_processor_.get()) {
     return;
+  }
 
   FaviconMap::const_iterator iter = synced_favicons_.find(icon_url);
   DCHECK(iter != synced_favicons_.end());
@@ -833,12 +835,12 @@
   DCHECK(type == syncer::FAVICON_IMAGES || type == syncer::FAVICON_TRACKING);
   sync_pb::EntitySpecifics new_specifics;
   GURL favicon_url = GetFaviconURLFromSpecifics(sync_favicon.GetSpecifics());
+  FaviconMap::const_iterator iter = synced_favicons_.find(favicon_url);
+  DCHECK(iter != synced_favicons_.end());
+  SyncedFaviconInfo* favicon_info = iter->second.get();
   if (type == syncer::FAVICON_IMAGES) {
     sync_pb::FaviconImageSpecifics image_specifics =
         sync_favicon.GetSpecifics().favicon_image();
-    FaviconMap::const_iterator iter = synced_favicons_.find(favicon_url);
-    DCHECK(iter != synced_favicons_.end());
-    SyncedFaviconInfo* favicon_info = iter->second.get();
 
     // Remote image data always clobbers local image data.
     bool needs_update = false;
@@ -866,15 +868,19 @@
   } else {
     sync_pb::FaviconTrackingSpecifics tracking_specifics =
         sync_favicon.GetSpecifics().favicon_tracking();
-    FaviconMap::const_iterator iter = synced_favicons_.find(favicon_url);
-    DCHECK(iter != synced_favicons_.end());
-    SyncedFaviconInfo* favicon_info = iter->second.get();
 
     // Tracking data is merged, such that bookmark data is the logical OR
     // of the two, and last visit time is the most recent.
-    UpdateFaviconVisitTime(favicon_url,
-                           syncer::ProtoTimeToTime(
-                               tracking_specifics.last_visit_time_ms()));
+
+    base::Time last_visit =  syncer::ProtoTimeToTime(
+        tracking_specifics.last_visit_time_ms());
+    // Due to crbug.com/258196, there are tracking nodes out there with
+    // null visit times. If this is one of those, artificially make it a valid
+    // visit time, so we know the node exists and update it properly on the next
+    // real visit.
+    if (last_visit.is_null())
+      last_visit = last_visit + base::TimeDelta::FromMilliseconds(1);
+    UpdateFaviconVisitTime(favicon_url, last_visit);
     favicon_info->is_bookmarked = (favicon_info->is_bookmarked ||
                                    tracking_specifics.is_bookmarked());
 
@@ -884,6 +890,7 @@
       BuildTrackingSpecifics(favicon_info,
                              new_specifics.mutable_favicon_tracking());
     }
+    DCHECK(!favicon_info->last_visit_time.is_null());
   }
 
   if (new_specifics.has_favicon_image() ||
@@ -933,10 +940,17 @@
     SyncedFaviconInfo* favicon_info = GetFaviconInfo(favicon_url);
     if (!favicon_info)
       return;  // We reached the in-memory limit.
-    UpdateFaviconVisitTime(favicon_url,
-                           syncer::ProtoTimeToTime(
-                               tracking_specifics.last_visit_time_ms()));
+    base::Time last_visit =  syncer::ProtoTimeToTime(
+        tracking_specifics.last_visit_time_ms());
+    // Due to crbug.com/258196, there are tracking nodes out there with
+    // null visit times. If this is one of those, artificially make it a valid
+    // visit time, so we know the node exists and update it properly on the next
+    // real visit.
+    if (last_visit.is_null())
+      last_visit = last_visit + base::TimeDelta::FromMilliseconds(1);
+    UpdateFaviconVisitTime(favicon_url, last_visit);
     favicon_info->is_bookmarked = tracking_specifics.is_bookmarked();
+    DCHECK(!favicon_info->last_visit_time.is_null());
   }
 }
 
@@ -978,16 +992,17 @@
                         &tracking_deletions);
   }
   DVLOG(1) << "Deleting " << image_deletions.size() << " synced favicons.";
-  if (favicon_images_sync_processor_.get() &&
-      favicon_tracking_sync_processor_.get()) {
+  if (favicon_images_sync_processor_.get()) {
     favicon_images_sync_processor_->ProcessSyncChanges(FROM_HERE,
                                                        image_deletions);
+  }
+  if (favicon_tracking_sync_processor_.get()) {
     favicon_tracking_sync_processor_->ProcessSyncChanges(FROM_HERE,
                                                          tracking_deletions);
   }
 }
 
-FaviconCache::FaviconMap::iterator FaviconCache::DeleteSyncedFavicon(
+void FaviconCache::DeleteSyncedFavicon(
     FaviconMap::iterator favicon_iter,
     syncer::SyncChangeList* image_changes,
     syncer::SyncChangeList* tracking_changes) {
@@ -1008,10 +1023,7 @@
                                favicon_info->favicon_url.spec(),
                                syncer::FAVICON_TRACKING)));
   }
-  FaviconMap::iterator next = favicon_iter;
-  next++;
   DropSyncedFavicon(favicon_iter);
-  return next;
 }
 
 void FaviconCache::DropSyncedFavicon(FaviconMap::iterator favicon_iter) {
diff --git a/chrome/browser/sync/glue/favicon_cache.h b/chrome/browser/sync/glue/favicon_cache.h
index a273aa0..cb897f0 100644
--- a/chrome/browser/sync/glue/favicon_cache.h
+++ b/chrome/browser/sync/glue/favicon_cache.h
@@ -43,15 +43,6 @@
 
 struct SyncedFaviconInfo;
 
-// Observer interface.
-class FaviconCacheObserver {
- public:
-  virtual void OnFaviconUpdated(const GURL& page_url, const GURL& icon_url) = 0;
-
- protected:
-  virtual ~FaviconCacheObserver();
-};
-
 // Encapsulates the logic for loading and storing synced favicons.
 // TODO(zea): make this a BrowserContextKeyedService.
 class FaviconCache : public syncer::SyncableService,
@@ -106,10 +97,6 @@
                              const std::string& icon_bytes,
                              int64 visit_time_ms);
 
-  // Support for syncing favicons using the legacy format (within tab sync).
-  void SetLegacyDelegate(FaviconCacheObserver* observer);
-  void RemoveLegacyDelegate();
-
   // NotificationObserver implementation.
   virtual void Observe(int type,
                        const content::NotificationSource& source,
@@ -195,11 +182,9 @@
 
   // Deletes the favicon pointed to by |favicon_iter| and appends the necessary
   // sync deletions to |image_changes| and |tracking_changes|.
-  // Returns an iterator to the favicon after |favicon_iter|.
-  FaviconMap::iterator DeleteSyncedFavicon(
-      FaviconMap::iterator favicon_iter,
-      syncer::SyncChangeList* image_changes,
-      syncer::SyncChangeList* tracking_changes);
+  void DeleteSyncedFavicon(FaviconMap::iterator favicon_iter,
+                           syncer::SyncChangeList* image_changes,
+                           syncer::SyncChangeList* tracking_changes);
 
   // Locally drops the favicon pointed to by |favicon_iter|.
   void DropSyncedFavicon(FaviconMap::iterator favicon_iter);
@@ -232,10 +217,6 @@
   // Weak pointer factory for favicon loads.
   base::WeakPtrFactory<FaviconCache> weak_ptr_factory_;
 
-  // Delegate for legacy favicon sync support.
-  // TODO(zea): Remove this eventually.
-  FaviconCacheObserver* legacy_delegate_;
-
   scoped_ptr<syncer::SyncChangeProcessor> favicon_images_sync_processor_;
   scoped_ptr<syncer::SyncChangeProcessor> favicon_tracking_sync_processor_;
 
diff --git a/chrome/browser/sync/glue/favicon_cache_unittest.cc b/chrome/browser/sync/glue/favicon_cache_unittest.cc
index 697f371..803f93b 100644
--- a/chrome/browser/sync/glue/favicon_cache_unittest.cc
+++ b/chrome/browser/sync/glue/favicon_cache_unittest.cc
@@ -6,10 +6,12 @@
 
 #include "base/message_loop.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "base/time/time.h"
 #include "chrome/browser/history/history_notifications.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "sync/api/sync_error_factory_mock.h"
+#include "sync/api/time.h"
 #include "sync/protocol/favicon_image_specifics.pb.h"
 #include "sync/protocol/favicon_tracking_specifics.pb.h"
 #include "sync/protocol/sync.pb.h"
@@ -624,12 +626,14 @@
                        image_specifics.mutable_favicon_image());
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
   }
 
   syncer::SyncMergeResult merge_result =
@@ -697,12 +701,14 @@
 
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(test_data,
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
   }
 
   syncer::SyncMergeResult merge_result =
@@ -776,12 +782,14 @@
 
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(test_data,
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
   }
 
   syncer::SyncMergeResult merge_result =
@@ -835,19 +843,23 @@
                        image_specifics.mutable_favicon_image());
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
     image_specifics.mutable_favicon_image()->clear_favicon_web();
     stale_changes.push_back(
         syncer::SyncChange(
              FROM_HERE,
              syncer::SyncChange::ACTION_UPDATE,
-             syncer::SyncData::CreateRemoteData(1, image_specifics)));
+             syncer::SyncData::CreateRemoteData(1,
+                                                image_specifics,
+                                                base::Time())));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -879,17 +891,21 @@
         syncer::SyncChange(
              FROM_HERE,
              syncer::SyncChange::ACTION_UPDATE,
-             syncer::SyncData::CreateRemoteData(1, image_specifics)));
+             syncer::SyncData::CreateRemoteData(1,
+                                                image_specifics,
+                                                base::Time())));
     image_specifics.mutable_favicon_image()->mutable_favicon_web()->
         mutable_favicon()->append("old");
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -915,15 +931,19 @@
         syncer::SyncChange(
              FROM_HERE,
              syncer::SyncChange::ACTION_UPDATE,
-             syncer::SyncData::CreateRemoteData(1, image_specifics)));
+             syncer::SyncData::CreateRemoteData(1,
+                                                image_specifics,
+                                                base::Time())));
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -948,19 +968,23 @@
                        image_specifics.mutable_favicon_image());
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
     tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(-1);
     stale_changes.push_back(
         syncer::SyncChange(
              FROM_HERE,
              syncer::SyncChange::ACTION_UPDATE,
-             syncer::SyncData::CreateRemoteData(1, tracking_specifics)));
+             syncer::SyncData::CreateRemoteData(1,
+                                                tracking_specifics,
+                                                base::Time())));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -990,18 +1014,22 @@
                        image_specifics.mutable_favicon_image());
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     new_changes.push_back(
         syncer::SyncChange(
              FROM_HERE,
              syncer::SyncChange::ACTION_UPDATE,
-             syncer::SyncData::CreateRemoteData(1, tracking_specifics)));
+             syncer::SyncData::CreateRemoteData(1,
+                                                tracking_specifics,
+                                                base::Time())));
     tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(i-1);
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1025,17 +1053,21 @@
                        image_specifics.mutable_favicon_image());
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
     same_changes.push_back(
         syncer::SyncChange(
              FROM_HERE,
              syncer::SyncChange::ACTION_UPDATE,
-             syncer::SyncData::CreateRemoteData(1, tracking_specifics)));
+             syncer::SyncData::CreateRemoteData(1,
+                                                tracking_specifics,
+                                                base::Time())));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1056,22 +1088,28 @@
                        image_specifics.mutable_favicon_image());
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
     tracking_deletions.push_back(
         syncer::SyncChange(
              FROM_HERE,
              syncer::SyncChange::ACTION_DELETE,
-             syncer::SyncData::CreateRemoteData(1, tracking_specifics)));
+             syncer::SyncData::CreateRemoteData(1,
+                                                tracking_specifics,
+                                                base::Time())));
     image_deletions.push_back(
         syncer::SyncChange(
              FROM_HERE,
              syncer::SyncChange::ACTION_DELETE,
-             syncer::SyncData::CreateRemoteData(1, image_specifics)));
+             syncer::SyncData::CreateRemoteData(1,
+                                                image_specifics,
+                                                base::Time())));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1103,12 +1141,14 @@
                        image_specifics.mutable_favicon_image());
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
     expected_icons.push_back(i);
 
     TestFaviconData favicon = BuildFaviconData(i+kMaxSyncFavicons);
@@ -1164,13 +1204,14 @@
                        image_specifics.mutable_favicon_image());
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
-
+                                           tracking_specifics,
+                                           base::Time()));
     // Set up new tracking specifics for the icons received at change time.
     expected_icons.push_back(i + kMaxSyncFavicons);
     FillImageSpecifics(BuildFaviconData(i + kMaxSyncFavicons),
@@ -1179,14 +1220,18 @@
         syncer::SyncChange(
              FROM_HERE,
              syncer::SyncChange::ACTION_ADD,
-             syncer::SyncData::CreateRemoteData(1, image_specifics)));
+             syncer::SyncData::CreateRemoteData(1,
+                                                image_specifics,
+                                                base::Time())));
     FillTrackingSpecifics(BuildFaviconData(i + kMaxSyncFavicons),
                           tracking_specifics.mutable_favicon_tracking());
     tracking_changes.push_back(
         syncer::SyncChange(
              FROM_HERE,
              syncer::SyncChange::ACTION_ADD,
-             syncer::SyncData::CreateRemoteData(1, tracking_specifics)));
+             syncer::SyncData::CreateRemoteData(1,
+                                                tracking_specifics,
+                                                base::Time())));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1339,12 +1384,14 @@
                        image_specifics.mutable_favicon_image());
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1395,12 +1442,14 @@
                        image_specifics.mutable_favicon_image());
     initial_image_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           image_specifics));
+                                           image_specifics,
+                                           base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(
         syncer::SyncData::CreateRemoteData(1,
-                                           tracking_specifics));
+                                           tracking_specifics,
+                                           base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1516,7 +1565,7 @@
           syncer::SyncChange(FROM_HERE,
                              syncer::SyncChange::ACTION_ADD,
                              syncer::SyncData::CreateRemoteData(
-                                 1, image_specifics)));
+                                 1, image_specifics, base::Time())));
     } else {
       sync_pb::EntitySpecifics tracking_specifics;
       FillTrackingSpecifics(BuildFaviconData(i),
@@ -1525,7 +1574,7 @@
           syncer::SyncChange(FROM_HERE,
                              syncer::SyncChange::ACTION_ADD,
                              syncer::SyncData::CreateRemoteData(
-                                 1, tracking_specifics)));
+                                 1, tracking_specifics, base::Time())));
     }
   }
 
@@ -1576,4 +1625,85 @@
   EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
 }
 
+// Verify that orphaned favicon images don't result in creating invalid
+// favicon tracking data.
+TEST_F(SyncFaviconCacheTest, PartialAssociationInfo) {
+  syncer::SyncDataList initial_image_data, initial_tracking_data;
+  for (int i = 0; i < kFaviconBatchSize; ++i) {
+    sync_pb::EntitySpecifics image_specifics;
+    FillImageSpecifics(BuildFaviconData(i),
+                       image_specifics.mutable_favicon_image());
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1,
+                                           image_specifics,
+                                           base::Time()));
+    image_specifics.mutable_favicon_image()->clear_favicon_web();
+  }
+
+  SetUpInitialSync(initial_image_data, initial_tracking_data);
+  syncer::SyncChangeList change_list = processor()->GetAndResetChangeList();
+  EXPECT_TRUE(change_list.empty());
+  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
+}
+
+// Tests that we don't choke if a favicon visit node with a null visit time is
+// present (see crbug.com/258196) and an update is made.
+TEST_F(SyncFaviconCacheTest, NullFaviconVisitTime) {
+  EXPECT_EQ(0U, GetFaviconCount());
+
+  syncer::SyncDataList initial_image_data, initial_tracking_data;
+  std::vector<int> expected_icons;
+  for (int i = 0; i < kFaviconBatchSize; ++i) {
+    expected_icons.push_back(i);
+    sync_pb::EntitySpecifics image_specifics, tracking_specifics;
+    FillImageSpecifics(BuildFaviconData(i),
+                       image_specifics.mutable_favicon_image());
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1,
+                                           image_specifics,
+                                           base::Time()));
+    FillTrackingSpecifics(BuildFaviconData(i),
+                          tracking_specifics.mutable_favicon_tracking());
+    tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(
+        syncer::TimeToProtoTime(base::Time()));
+    initial_tracking_data.push_back(
+        syncer::SyncData::CreateRemoteData(1,
+                                           tracking_specifics,
+                                           base::Time()));
+  }
+
+  cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
+                                    initial_image_data,
+                                    CreateAndPassProcessor(),
+                                    CreateAndPassSyncErrorFactory());
+  ASSERT_EQ(0U, processor()->GetAndResetChangeList().size());
+  cache()->MergeDataAndStartSyncing(syncer::FAVICON_TRACKING,
+                                    initial_tracking_data,
+                                    CreateAndPassProcessor(),
+                                    CreateAndPassSyncErrorFactory());
+  ASSERT_EQ((unsigned long)kFaviconBatchSize,
+            processor()->GetAndResetChangeList().size());
+  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
+
+  // Visit the favicons again.
+  EXPECT_EQ(0U, GetTaskCount());
+  for (int i = 0; i < kFaviconBatchSize; ++i) {
+    TestFaviconData test_data = BuildFaviconData(i);
+    cache()->OnFaviconVisited(test_data.page_url, test_data.icon_url);
+
+    syncer::SyncChangeList changes = processor()->GetAndResetChangeList();
+    ASSERT_EQ(1U, changes.size());
+    // Just verify the favicon url for the tracking specifics and that the
+    // timestamp is non-null.
+    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, changes[0].change_type());
+    EXPECT_EQ(test_data.icon_url.spec(),
+              changes[0].sync_data().GetSpecifics().favicon_tracking().
+                  favicon_url());
+    EXPECT_NE(changes[0].sync_data().GetSpecifics().favicon_tracking().
+                  last_visit_time_ms(), 0);
+  }
+  EXPECT_EQ(0U, GetTaskCount());
+  EXPECT_EQ((unsigned long)kFaviconBatchSize, GetFaviconCount());
+}
+
 }  // namespace browser_sync
diff --git a/chrome/browser/sync/glue/generic_change_processor.cc b/chrome/browser/sync/glue/generic_change_processor.cc
index 591e717..c40fca2 100644
--- a/chrome/browser/sync/glue/generic_change_processor.cc
+++ b/chrome/browser/sync/glue/generic_change_processor.cc
@@ -24,6 +24,42 @@
 
 namespace browser_sync {
 
+namespace {
+
+void SetNodeSpecifics(const sync_pb::EntitySpecifics& entity_specifics,
+                      syncer::WriteNode* write_node) {
+  if (syncer::GetModelTypeFromSpecifics(entity_specifics) ==
+          syncer::PASSWORDS) {
+    write_node->SetPasswordSpecifics(
+        entity_specifics.password().client_only_encrypted_data());
+  } else {
+    write_node->SetEntitySpecifics(entity_specifics);
+  }
+}
+
+syncer::SyncData BuildRemoteSyncData(
+    int64 sync_id,
+    const syncer::BaseNode& read_node) {
+  // Use the specifics of non-password datatypes directly (encryption has
+  // already been handled).
+  if (read_node.GetModelType() != syncer::PASSWORDS) {
+    return syncer::SyncData::CreateRemoteData(sync_id,
+                                              read_node.GetEntitySpecifics(),
+                                              read_node.GetModificationTime());
+  }
+
+  // Passwords must be accessed differently, to account for their encryption,
+  // and stored into a temporary EntitySpecifics.
+  sync_pb::EntitySpecifics password_holder;
+  password_holder.mutable_password()->mutable_client_only_encrypted_data()->
+      CopyFrom(read_node.GetPasswordSpecifics());
+  return syncer::SyncData::CreateRemoteData(sync_id,
+                                            password_holder,
+                                            read_node.GetModificationTime());
+}
+
+}  // namespace
+
 GenericChangeProcessor::GenericChangeProcessor(
     DataTypeErrorHandler* error_handler,
     const base::WeakPtr<syncer::SyncableService>& local_service,
@@ -53,7 +89,8 @@
           syncer::SyncChange(
               FROM_HERE,
               syncer::SyncChange::ACTION_DELETE,
-              syncer::SyncData::CreateRemoteData(it->id, it->specifics)));
+              syncer::SyncData::CreateRemoteData(
+                  it->id, it->specifics, base::Time())));
     } else {
       syncer::SyncChange::SyncChangeType action =
           (it->action == syncer::ChangeRecord::ACTION_ADD) ?
@@ -71,8 +108,7 @@
           syncer::SyncChange(
               FROM_HERE,
               action,
-              syncer::SyncData::CreateRemoteData(
-                  it->id, read_node.GetEntitySpecifics())));
+              BuildRemoteSyncData(it->id, read_node)));
     }
   }
 }
@@ -136,8 +172,8 @@
                               type);
       return error;
     }
-    current_sync_data->push_back(syncer::SyncData::CreateRemoteData(
-        sync_child_node.GetId(), sync_child_node.GetEntitySpecifics()));
+    current_sync_data->push_back(BuildRemoteSyncData(sync_child_node.GetId(),
+                                                     sync_child_node));
   }
   return syncer::SyncError();
 }
@@ -317,8 +353,8 @@
       }
       syncer::WriteNode::InitUniqueByCreationResult result =
           sync_node.InitUniqueByCreation(change.sync_data().GetDataType(),
-                                          root_node,
-                                          change.sync_data().GetTag());
+                                         root_node,
+                                         change.sync_data().GetTag());
       if (result != syncer::WriteNode::INIT_SUCCESS) {
         std::string error_prefix = "Failed to create " + type_str + " node: " +
             change.location().ToString() + ", ";
@@ -368,7 +404,7 @@
         }
       }
       sync_node.SetTitle(UTF8ToWide(change.sync_data().GetTitle()));
-      sync_node.SetEntitySpecifics(change.sync_data().GetSpecifics());
+      SetNodeSpecifics(change.sync_data().GetSpecifics(), &sync_node);
       if (merge_result_.get()) {
         merge_result_->set_num_items_added(merge_result_->num_items_added() +
                                            1);
@@ -461,7 +497,7 @@
       }
 
       sync_node.SetTitle(UTF8ToWide(change.sync_data().GetTitle()));
-      sync_node.SetEntitySpecifics(change.sync_data().GetSpecifics());
+      SetNodeSpecifics(change.sync_data().GetSpecifics(), &sync_node);
       if (merge_result_.get()) {
         merge_result_->set_num_items_modified(
             merge_result_->num_items_modified() + 1);
diff --git a/chrome/browser/sync/glue/generic_change_processor_unittest.cc b/chrome/browser/sync/glue/generic_change_processor_unittest.cc
index bb90a50..25b562c 100644
--- a/chrome/browser/sync/glue/generic_change_processor_unittest.cc
+++ b/chrome/browser/sync/glue/generic_change_processor_unittest.cc
@@ -10,9 +10,11 @@
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/sync/glue/data_type_error_handler_mock.h"
 #include "sync/api/fake_syncable_service.h"
+#include "sync/api/sync_change.h"
 #include "sync/api/sync_merge_result.h"
 #include "sync/internal_api/public/base/model_type.h"
 #include "sync/internal_api/public/read_node.h"
+#include "sync/internal_api/public/read_transaction.h"
 #include "sync/internal_api/public/test/test_user_share.h"
 #include "sync/internal_api/public/user_share.h"
 #include "sync/internal_api/public/write_node.h"
@@ -23,12 +25,12 @@
 
 namespace {
 
-class GenericChangeProcessorTest : public testing::Test {
+class SyncGenericChangeProcessorTest : public testing::Test {
  public:
   // It doesn't matter which type we use.  Just pick one.
   static const syncer::ModelType kType = syncer::PREFERENCES;
 
-  GenericChangeProcessorTest() :
+  SyncGenericChangeProcessorTest() :
       loop_(base::MessageLoop::TYPE_UI),
       sync_merge_result_(kType),
       merge_result_ptr_factory_(&sync_merge_result_),
@@ -37,7 +39,13 @@
 
   virtual void SetUp() OVERRIDE {
     test_user_share_.SetUp();
-    syncer::TestUserShare::CreateRoot(kType, test_user_share_.user_share());
+    syncer::ModelTypeSet types = syncer::ProtocolTypes();
+    for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good();
+         iter.Inc()) {
+      syncer::TestUserShare::CreateRoot(iter.Get(),
+                                        test_user_share_.user_share());
+    }
+    test_user_share_.encryption_handler()->Init();
     change_processor_.reset(
         new GenericChangeProcessor(
             &data_type_error_handler_,
@@ -88,7 +96,7 @@
 // This test exercises GenericChangeProcessor's GetSyncDataForType function.
 // It's not a great test, but, by modifying some of the parameters, you could
 // turn it into a micro-benchmark for model association.
-TEST_F(GenericChangeProcessorTest, StressGetSyncDataForType) {
+TEST_F(SyncGenericChangeProcessorTest, StressGetSyncDataForType) {
   const int kNumChildNodes = 1000;
   const int kRepeatCount = 1;
 
@@ -103,6 +111,138 @@
   }
 }
 
+TEST_F(SyncGenericChangeProcessorTest, SetGetPasswords) {
+  const int kNumPasswords = 10;
+  sync_pb::PasswordSpecificsData password_data;
+  password_data.set_username_value("user");
+
+  sync_pb::EntitySpecifics password_holder;
+
+  syncer::SyncChangeList change_list;
+  for (int i = 0; i < kNumPasswords; ++i) {
+    password_data.set_password_value(
+        base::StringPrintf("password%i", i));
+    password_holder.mutable_password()->mutable_client_only_encrypted_data()->
+        CopyFrom(password_data);
+    change_list.push_back(
+        syncer::SyncChange(FROM_HERE,
+                           syncer::SyncChange::ACTION_ADD,
+                           syncer::SyncData::CreateLocalData(
+                               base::StringPrintf("tag%i", i),
+                               base::StringPrintf("title%i", i),
+                               password_holder)));
+  }
+
+  ASSERT_FALSE(
+      change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
+
+  syncer::SyncDataList password_list;
+  ASSERT_FALSE(
+      change_processor()->GetSyncDataForType(syncer::PASSWORDS, &password_list).
+          IsSet());
+
+  ASSERT_EQ(password_list.size(), change_list.size());
+  for (int i = 0; i < kNumPasswords; ++i) {
+    // Verify the password is returned properly.
+    ASSERT_TRUE(password_list[i].GetSpecifics().has_password());
+    ASSERT_TRUE(password_list[i].GetSpecifics().password().
+                    has_client_only_encrypted_data());
+    ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted());
+    const sync_pb::PasswordSpecificsData& sync_password =
+        password_list[i].GetSpecifics().password().client_only_encrypted_data();
+    const sync_pb::PasswordSpecificsData& change_password =
+        change_list[i].sync_data().GetSpecifics().password().
+            client_only_encrypted_data();
+    ASSERT_EQ(sync_password.password_value(), change_password.password_value());
+    ASSERT_EQ(sync_password.username_value(), change_password.username_value());
+
+    // Verify the raw sync data was stored securely.
+    syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
+    syncer::ReadNode node(&read_transaction);
+    ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS,
+                                         base::StringPrintf("tag%i", i)),
+              syncer::BaseNode::INIT_OK);
+    ASSERT_EQ(node.GetTitle(), "encrypted");
+    const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics();
+    ASSERT_TRUE(raw_specifics.has_password());
+    ASSERT_TRUE(raw_specifics.password().has_encrypted());
+    ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data());
+  }
+}
+
+TEST_F(SyncGenericChangeProcessorTest, UpdatePasswords) {
+  const int kNumPasswords = 10;
+  sync_pb::PasswordSpecificsData password_data;
+  password_data.set_username_value("user");
+
+  sync_pb::EntitySpecifics password_holder;
+
+  syncer::SyncChangeList change_list;
+  syncer::SyncChangeList change_list2;
+  for (int i = 0; i < kNumPasswords; ++i) {
+    password_data.set_password_value(
+        base::StringPrintf("password%i", i));
+    password_holder.mutable_password()->mutable_client_only_encrypted_data()->
+        CopyFrom(password_data);
+    change_list.push_back(
+        syncer::SyncChange(FROM_HERE,
+                           syncer::SyncChange::ACTION_ADD,
+                           syncer::SyncData::CreateLocalData(
+                               base::StringPrintf("tag%i", i),
+                               base::StringPrintf("title%i", i),
+                               password_holder)));
+    password_data.set_password_value(
+        base::StringPrintf("password_m%i", i));
+    password_holder.mutable_password()->mutable_client_only_encrypted_data()->
+        CopyFrom(password_data);
+    change_list2.push_back(
+        syncer::SyncChange(FROM_HERE,
+                           syncer::SyncChange::ACTION_UPDATE,
+                           syncer::SyncData::CreateLocalData(
+                               base::StringPrintf("tag%i", i),
+                               base::StringPrintf("title_m%i", i),
+                               password_holder)));
+  }
+
+  ASSERT_FALSE(
+      change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
+  ASSERT_FALSE(
+      change_processor()->ProcessSyncChanges(FROM_HERE, change_list2).IsSet());
+
+  syncer::SyncDataList password_list;
+  ASSERT_FALSE(
+      change_processor()->GetSyncDataForType(syncer::PASSWORDS, &password_list).
+          IsSet());
+
+  ASSERT_EQ(password_list.size(), change_list2.size());
+  for (int i = 0; i < kNumPasswords; ++i) {
+    // Verify the password is returned properly.
+    ASSERT_TRUE(password_list[i].GetSpecifics().has_password());
+    ASSERT_TRUE(password_list[i].GetSpecifics().password().
+                    has_client_only_encrypted_data());
+    ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted());
+    const sync_pb::PasswordSpecificsData& sync_password =
+        password_list[i].GetSpecifics().password().client_only_encrypted_data();
+    const sync_pb::PasswordSpecificsData& change_password =
+        change_list2[i].sync_data().GetSpecifics().password().
+            client_only_encrypted_data();
+    ASSERT_EQ(sync_password.password_value(), change_password.password_value());
+    ASSERT_EQ(sync_password.username_value(), change_password.username_value());
+
+    // Verify the raw sync data was stored securely.
+    syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
+    syncer::ReadNode node(&read_transaction);
+    ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS,
+                                         base::StringPrintf("tag%i", i)),
+              syncer::BaseNode::INIT_OK);
+    ASSERT_EQ(node.GetTitle(), "encrypted");
+    const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics();
+    ASSERT_TRUE(raw_specifics.has_password());
+    ASSERT_TRUE(raw_specifics.password().has_encrypted());
+    ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data());
+  }
+}
+
 }  // namespace
 
 }  // namespace browser_sync
diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
index 56a07f3..6d80bef 100644
--- a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
+++ b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
@@ -161,8 +161,8 @@
   DCHECK_NE(state_, NOT_RUNNING);
 
   // TODO(sync): Blocking the UI thread at shutdown is bad. The new API avoids
-  // this. Once all non-frontend datatypes use the new API, we can get rid of this
-  // locking (see implementation in AutofillProfileDataTypeController).
+  // this. Once all non-frontend datatypes use the new API, we can get rid of
+  // this locking (see implementation in AutofillProfileDataTypeController).
   // http://crbug.com/19757
   base::ThreadRestrictions::ScopedAllowWait allow_wait;
 
diff --git a/chrome/browser/sync/glue/password_change_processor.cc b/chrome/browser/sync/glue/password_change_processor.cc
index 2a97720..83b8cb5 100644
--- a/chrome/browser/sync/glue/password_change_processor.cc
+++ b/chrome/browser/sync/glue/password_change_processor.cc
@@ -9,13 +9,12 @@
 #include "base/location.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/password_manager/password_store.h"
 #include "chrome/browser/password_manager/password_store_change.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/glue/password_model_associator.h"
 #include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/common/password_form.h"
diff --git a/chrome/browser/sync/glue/search_engine_data_type_controller.cc b/chrome/browser/sync/glue/search_engine_data_type_controller.cc
index c2baa83..9718b23 100644
--- a/chrome/browser/sync/glue/search_engine_data_type_controller.cc
+++ b/chrome/browser/sync/glue/search_engine_data_type_controller.cc
@@ -5,12 +5,12 @@
 #include "chrome/browser/sync/glue/search_engine_data_type_controller.h"
 
 #include "base/metrics/histogram.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/sync/profile_sync_components_factory.h"
 #include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "sync/api/syncable_service.h"
 
diff --git a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
index 1e2a360..ec8ba1f 100644
--- a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/tracked_objects.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/search_engines/template_url_service_test_util.h"
 #include "chrome/browser/sync/glue/data_type_controller_mock.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/sync/glue/search_engine_data_type_controller.h"
 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
 #include "chrome/browser/sync/profile_sync_service_mock.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/profile_mock.h"
 #include "content/public/browser/notification_service.h"
 #include "sync/api/fake_syncable_service.h"
diff --git a/chrome/browser/sync/glue/session_change_processor.cc b/chrome/browser/sync/glue/session_change_processor.cc
index c5c87cb..24b90c9 100644
--- a/chrome/browser/sync/glue/session_change_processor.cc
+++ b/chrome/browser/sync/glue/session_change_processor.cc
@@ -8,13 +8,13 @@
 #include <vector>
 
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/favicon/favicon_changed_details.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/glue/session_model_associator.h"
 #include "chrome/browser/sync/glue/synced_tab_delegate.h"
 #include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_details.h"
@@ -207,13 +207,10 @@
         entry->GetVirtualURL().spec() == kNTPOpenTabSyncURL) {
       DVLOG(1) << "Triggering sync refresh for sessions datatype.";
       const syncer::ModelTypeSet types(syncer::SESSIONS);
-      const syncer::ModelTypeInvalidationMap& invalidation_map =
-          ModelTypeSetToInvalidationMap(types, std::string());
       content::NotificationService::current()->Notify(
           chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
           content::Source<Profile>(profile_),
-          content::Details<const syncer::ModelTypeInvalidationMap>(
-              &invalidation_map));
+          content::Details<const syncer::ModelTypeSet>(&types));
     }
   }
 
diff --git a/chrome/browser/sync/glue/session_data_type_controller.cc b/chrome/browser/sync/glue/session_data_type_controller.cc
index a8f627f..8e69ad5 100644
--- a/chrome/browser/sync/glue/session_data_type_controller.cc
+++ b/chrome/browser/sync/glue/session_data_type_controller.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/sync/glue/session_data_type_controller.h"
 
 #include "base/metrics/histogram.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/sync/glue/synced_window_delegate.h"
 #include "chrome/browser/sync/profile_sync_components_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/sync/glue/session_model_associator.cc b/chrome/browser/sync/glue/session_model_associator.cc
index 8b6dc4e..ec7e281 100644
--- a/chrome/browser/sync/glue/session_model_associator.cc
+++ b/chrome/browser/sync/glue/session_model_associator.cc
@@ -9,11 +9,11 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/command_line.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/sequenced_worker_pool.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/managed_mode/managed_user_service.h"
@@ -26,7 +26,6 @@
 #include "chrome/browser/sync/glue/synced_tab_delegate.h"
 #include "chrome/browser/sync/glue/synced_window_delegate.h"
 #include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -111,9 +110,6 @@
   DCHECK(CalledOnValidThread());
   DCHECK(sync_service_);
   DCHECK(profile_);
-  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
-  if (command_line.HasSwitch(switches::kSyncTabFavicons))
-    favicon_cache_.SetLegacyDelegate(this);
 }
 
 SessionModelAssociator::SessionModelAssociator(ProfileSyncService* sync_service,
@@ -180,6 +176,7 @@
   synced_session_tracker_.ResetSessionTracking(local_tag);
   std::set<SyncedWindowDelegate*> windows =
       SyncedWindowDelegate::GetSyncedWindowDelegates();
+  std::set<int64> used_sync_ids;
   for (std::set<SyncedWindowDelegate*>::const_iterator i =
            windows.begin(); i != windows.end(); ++i) {
     // Make sure the window has tabs and a viewable window. The viewable window
@@ -210,13 +207,34 @@
       bool found_tabs = false;
       for (int j = 0; j < (*i)->GetTabCount(); ++j) {
         SessionID::id_type tab_id = (*i)->GetTabIdAt(j);
+        SyncedTabDelegate* synced_tab = (*i)->GetTabAt(j);
+
+        // GetTabAt can return a null tab; in that case just skip it.
+        if (!synced_tab)
+          continue;
+
+        if (!synced_tab->HasWebContents()) {
+          // For tabs without WebContents update the |tab_id|, as it could have
+          // changed after a session restore.
+          // Note: We cannot check if a tab is valid if it has no WebContents.
+          // We assume any such tab is valid and leave the contents of
+          // corresponding sync node unchanged.
+          if (synced_tab->GetSyncId() > syncer::kInvalidId &&
+              tab_id > TabNodePool::kInvalidTabID) {
+            UpdateTabIdIfNecessary(synced_tab->GetSyncId(), tab_id);
+            found_tabs = true;
+            used_sync_ids.insert(synced_tab->GetSyncId());
+            window_s.add_tab(tab_id);
+          }
+          continue;
+        }
 
         if (reload_tabs) {
-          SyncedTabDelegate* tab = (*i)->GetTabAt(j);
           // It's possible for GetTabAt to return a tab which has no web
           // contents. We can assume this means the tab already existed but
           // hasn't changed, so no need to reassociate.
-          if (tab && tab->HasWebContents() && !AssociateTab(*tab, error)) {
+          if (synced_tab->HasWebContents() &&
+              !AssociateTab(synced_tab, error)) {
             // Association failed. Either we need to re-associate, or this is an
             // unrecoverable error.
             return false;
@@ -250,6 +268,15 @@
       }
     }
   }
+
+  // Sync nodes tracked by tab_map_ are used.
+  for (TabLinksMap::const_iterator tab_iter = tab_map_.begin();
+       tab_iter != tab_map_.end(); ++tab_iter) {
+    used_sync_ids.insert(tab_iter->second->sync_id());
+  }
+
+  // Free old sync nodes.
+  tab_pool_.FreeUnusedTabNodes(used_sync_ids);
   // Free memory for closed windows and tabs.
   synced_session_tracker_.CleanupSession(local_tag);
 
@@ -285,19 +312,20 @@
   for (std::vector<SyncedTabDelegate*>::const_iterator i = tabs.begin();
        i != tabs.end();
        ++i) {
-    if (!AssociateTab(**i, error))
+    if (!AssociateTab(*i, error))
       return false;
   }
   if (waiting_for_change_) QuitLoopForSubtleTesting();
   return true;
 }
 
-bool SessionModelAssociator::AssociateTab(const SyncedTabDelegate& tab,
+bool SessionModelAssociator::AssociateTab(SyncedTabDelegate* const tab,
                                           syncer::SyncError* error) {
   DCHECK(CalledOnValidThread());
+  DCHECK(tab->HasWebContents());
   int64 sync_id;
-  SessionID::id_type tab_id = tab.GetSessionId();
-  if (tab.IsBeingDestroyed()) {
+  SessionID::id_type tab_id = tab->GetSessionId();
+  if (tab->IsBeingDestroyed()) {
     // This tab is closing.
     TabLinksMap::iterator tab_iter = tab_map_.find(tab_id);
     if (tab_iter == tab_map_.end()) {
@@ -309,37 +337,43 @@
     return true;
   }
 
-  if (!ShouldSyncTab(tab))
+  if (!ShouldSyncTab(*tab))
     return true;
 
   TabLinksMap::iterator tab_map_iter = tab_map_.find(tab_id);
   TabLink* tab_link = NULL;
   if (tab_map_iter == tab_map_.end()) {
-    // This is a new tab, get a sync node for it.
-    sync_id = tab_pool_.GetFreeTabNode();
-    if (sync_id == syncer::kInvalidId) {
-      if (error) {
-        *error = error_handler_->CreateAndUploadError(
-            FROM_HERE,
-            "Received invalid tab node from tab pool.",
-            model_type());
+    sync_id = tab->GetSyncId();
+    // if there is an old sync node for the tab, reuse it.
+    if (!tab_pool_.ReassociateTabNode(sync_id, tab_id)) {
+      // This is a new tab, get a sync node for it.
+      sync_id = tab_pool_.GetFreeTabNode();
+      if (sync_id == syncer::kInvalidId) {
+        if (error) {
+          *error = error_handler_->CreateAndUploadError(
+              FROM_HERE,
+              "Received invalid tab node from tab pool.",
+              model_type());
+        }
+        return false;
       }
-      return false;
+      tab_pool_.AssociateTabNode(sync_id, tab_id);
+      tab->SetSyncId(sync_id);
     }
-    tab_link = new TabLink(sync_id, &tab);
+    tab_link = new TabLink(sync_id, tab);
     tab_map_[tab_id] = make_linked_ptr<TabLink>(tab_link);
   } else {
     // This tab is already associated with a sync node, reuse it.
     // Note: on some platforms the tab object may have changed, so we ensure
     // the tab link is up to date.
     tab_link = tab_map_iter->second.get();
-    tab_map_iter->second->set_tab(&tab);
+    tab_map_iter->second->set_tab(tab);
   }
   DCHECK(tab_link);
   DCHECK_NE(tab_link->sync_id(), syncer::kInvalidId);
 
   DVLOG(1) << "Reloading tab " << tab_id << " from window "
-           << tab.GetWindowId();
+           << tab->GetWindowId();
   return WriteTabContentsToSyncModel(tab_link, error);
 }
 
@@ -498,53 +532,6 @@
   }
 }
 
-void SessionModelAssociator::OnFaviconUpdated(
-    const GURL& page_url,
-    const GURL& icon_url) {
-  TabLink* tab_link = NULL;
-  for (TabLinksMap::const_iterator iter = tab_map_.begin();
-       iter != tab_map_.end(); ++iter) {
-    if (iter->second->url() == page_url) {
-      tab_link = iter->second.get();
-      if (tab_link->sync_id() == syncer::kInvalidId)
-        continue;
-
-      scoped_refptr<base::RefCountedMemory> favicon_png;
-      if (!favicon_cache_.GetSyncedFaviconForPageURL(page_url, &favicon_png)) {
-        LOG(ERROR) << "Unable to look up favicon for page url after "
-                   << "notification";
-      }
-
-      // Load the sync tab node and update the favicon data.
-      syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
-      syncer::WriteNode tab_node(&trans);
-      if (tab_node.InitByIdLookup(tab_link->sync_id()) !=
-              syncer::BaseNode::INIT_OK) {
-        LOG(WARNING) << "Failed to load sync tab node for url "
-                     << tab_link->url().spec();
-        return;
-      }
-      sync_pb::SessionSpecifics session_specifics =
-          tab_node.GetSessionSpecifics();
-      DCHECK(session_specifics.has_tab());
-      sync_pb::SessionTab* tab = session_specifics.mutable_tab();
-      if (favicon_png.get() && favicon_png->size() > 0) {
-        DVLOG(1) << "Storing session favicon for "
-                 << tab_link->url() << " with size "
-                 << favicon_png->size() << " bytes.";
-        tab->set_favicon(favicon_png->front(),
-                         favicon_png->size());
-        tab->set_favicon_type(sync_pb::SessionTab::TYPE_WEB_FAVICON);
-        tab->set_favicon_source(icon_url.spec());
-      } else {
-        LOG(WARNING) << "Null favicon stored for url "
-                     << tab_link->url().spec();
-      }
-      tab_node.SetSessionSpecifics(session_specifics);
-    }
-  }
-}
-
 syncer::SyncError SessionModelAssociator::AssociateModels(
     syncer::SyncMergeResult* local_merge_result,
     syncer::SyncMergeResult* syncer_merge_result) {
@@ -553,7 +540,7 @@
 
   // Ensure that we disassociated properly, otherwise memory might leak.
   DCHECK(synced_session_tracker_.Empty());
-  DCHECK_EQ(0U, tab_pool_.capacity());
+  DCHECK_EQ(0U, tab_pool_.Capacity());
 
   local_session_syncid_ = syncer::kInvalidId;
 
@@ -646,10 +633,9 @@
 syncer::SyncError SessionModelAssociator::DisassociateModels() {
   DCHECK(CalledOnValidThread());
   DVLOG(1) << "Disassociating local session " << GetCurrentMachineTag();
-  favicon_cache_.RemoveLegacyDelegate();
   synced_session_tracker_.Clear();
   tab_map_.clear();
-  tab_pool_.clear();
+  tab_pool_.Clear();
   local_session_syncid_ = syncer::kInvalidId;
   current_machine_tag_ = "";
   current_session_name_ = "";
@@ -680,7 +666,7 @@
     prefs.SetSyncSessionsGUID(current_machine_tag_);
   }
 
-  tab_pool_.set_machine_tag(current_machine_tag_);
+  tab_pool_.SetMachineTag(current_machine_tag_);
 }
 
 bool SessionModelAssociator::GetSyncedFaviconForPageURL(
@@ -694,7 +680,7 @@
     syncer::WriteTransaction* trans,
     syncer::SyncError* error) {
   DCHECK(CalledOnValidThread());
-  DCHECK(tab_pool_.empty());
+  DCHECK(tab_pool_.Empty());
   DCHECK_EQ(local_session_syncid_, syncer::kInvalidId);
 
   // Iterate through the nodes and associate any foreign sessions.
@@ -731,24 +717,22 @@
           current_session_name_ = specifics.header().client_name();
         }
       } else {
-        if (specifics.has_header()) {
-          LOG(WARNING) << "Found more than one session header node with local "
-                       << " tag.";
-        } else if (!specifics.has_tab()) {
-          LOG(WARNING) << "Found local node with no header or tag field.";
+        if (specifics.has_header() || !specifics.has_tab() ||
+            !specifics.has_tab_node_id() || !specifics.tab().has_tab_id()) {
+          LOG(WARNING) << "Found invalid session node, deleting.";
+          sync_node.Tombstone();
+        } else {
+          // This is a valid old tab node, add it to the pool so it can be
+          // reused for reassociation.
+          SessionID tab_id;
+          tab_id.set_id(specifics.tab().tab_id());
+          tab_pool_.AddTabNode(id, tab_id, specifics.tab_node_id());
         }
-
-        // TODO(zea): fix this once we add support for reassociating
-        // pre-existing tabs with pre-existing tab nodes. We'll need to load
-        // the tab_node_id and ensure the tab_pool_ keeps track of them.
-        sync_node.Tombstone();
       }
     }
     id = next_id;
   }
 
-  // After updating from sync model all tabid's should be free.
-  DCHECK(tab_pool_.full());
   return true;
 }
 
@@ -957,13 +941,10 @@
 void SessionModelAssociator::AttemptSessionsDataRefresh() const {
   DVLOG(1) << "Triggering sync refresh for sessions datatype.";
   const syncer::ModelTypeSet types(syncer::SESSIONS);
-  const syncer::ModelTypeInvalidationMap& invalidation_map =
-      ModelTypeSetToInvalidationMap(types, std::string());
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
       content::Source<Profile>(profile_),
-      content::Details<const syncer::ModelTypeInvalidationMap>(
-          &invalidation_map));
+      content::Details<const syncer::ModelTypeSet>(&types));
 }
 
 bool SessionModelAssociator::GetLocalSession(
@@ -1151,4 +1132,28 @@
          sync_service_->IsCryptographerReady(&trans);
 }
 
+void SessionModelAssociator::UpdateTabIdIfNecessary(
+    int64 sync_id,
+    SessionID::id_type new_tab_id) {
+  DCHECK_NE(sync_id, syncer::kInvalidId);
+  SessionID::id_type old_tab_id = tab_pool_.GetTabIdFromSyncId(sync_id);
+  if (old_tab_id != new_tab_id) {
+    // Rewrite tab id if required.
+    syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
+    syncer::WriteNode tab_node(&trans);
+    if (tab_node.InitByIdLookup(sync_id) == syncer::BaseNode::INIT_OK) {
+      sync_pb::SessionSpecifics session_specifics =
+          tab_node.GetSessionSpecifics();
+      DCHECK(session_specifics.has_tab());
+      if (session_specifics.has_tab()) {
+        sync_pb::SessionTab* tab_s = session_specifics.mutable_tab();
+        tab_s->set_tab_id(new_tab_id);
+        tab_node.SetSessionSpecifics(session_specifics);
+        // Update tab node pool with the new association.
+        tab_pool_.ReassociateTabNode(sync_id, new_tab_id);
+      }
+    }
+  }
+}
+
 }  // namespace browser_sync
diff --git a/chrome/browser/sync/glue/session_model_associator.h b/chrome/browser/sync/glue/session_model_associator.h
index 4778c44..6aaa00b 100644
--- a/chrome/browser/sync/glue/session_model_associator.h
+++ b/chrome/browser/sync/glue/session_model_associator.h
@@ -54,7 +54,6 @@
 class SessionModelAssociator
     : public AssociatorInterface,
       public base::SupportsWeakPtr<SessionModelAssociator>,
-      public FaviconCacheObserver,
       public base::NonThreadSafe {
  public:
   // Does not take ownership of sync_service.
@@ -82,10 +81,6 @@
   // tag
   virtual int64 GetSyncIdFromSessionTag(const std::string& tag);
 
-  // FaviconCacheObserver interface.
-  virtual void OnFaviconUpdated(const GURL& page_url,
-                                const GURL& icon_url) OVERRIDE;
-
   // Resync local window information. Updates the local sessions header node
   // with the status of open windows and the order of tabs they contain. Should
   // only be called for changes that affect a window, not a change within a
@@ -108,10 +103,10 @@
   // Reassociates a single tab with the sync model. Will check if the tab
   // already is associated with a sync node and allocate one if necessary.
   // |error| gets set if any association error occurred.
+  // |tab| will be updated with sync id if necessary.
   // Returns: false if the local session's sync nodes were deleted and
   // reassociation is necessary, true otherwise.
-  bool AssociateTab(const SyncedTabDelegate& tab,
-                    syncer::SyncError* error);
+  bool AssociateTab(SyncedTabDelegate* const tab, syncer::SyncError* error);
 
   // Load any foreign session info stored in sync db and update the sync db
   // with local client data. Processes/reuses any sync nodes owned by this
@@ -329,6 +324,9 @@
   // invalid url's.
   bool TabHasValidEntry(const SyncedTabDelegate& tab) const;
 
+  // Update the tab id of the node associated with |sync_id| to |new_tab_id|.
+  void UpdateTabIdIfNecessary(int64 sync_id, SessionID::id_type new_tab_id);
+
   // For testing only.
   void QuitLoopForSubtleTesting();
 
diff --git a/chrome/browser/sync/glue/session_model_associator_unittest.cc b/chrome/browser/sync/glue/session_model_associator_unittest.cc
index 34c01a1..e2fb94b 100644
--- a/chrome/browser/sync/glue/session_model_associator_unittest.cc
+++ b/chrome/browser/sync/glue/session_model_associator_unittest.cc
@@ -7,11 +7,11 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/sessions/session_types.h"
 #include "chrome/browser/sync/glue/session_model_associator.h"
 #include "chrome/browser/sync/glue/synced_tab_delegate.h"
 #include "chrome/browser/sync/profile_sync_service_mock.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/profile_mock.h"
 #include "components/sessions/serialized_navigation_entry_test_helper.h"
@@ -190,6 +190,8 @@
                      const std::vector<const content::NavigationEntry*>*());
   MOCK_CONST_METHOD0(IsPinned, bool());
   MOCK_CONST_METHOD0(HasWebContents, bool());
+  MOCK_CONST_METHOD0(GetSyncId, int64());
+  MOCK_METHOD1(SetSyncId, void(int64));
 };
 
 class SyncRefreshListener : public content::NotificationObserver {
diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc
index 870c4d5..294742e 100644
--- a/chrome/browser/sync/glue/sync_backend_host.cc
+++ b/chrome/browser/sync/glue/sync_backend_host.cc
@@ -21,6 +21,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/invalidation/invalidation_service.h"
 #include "chrome/browser/invalidation/invalidation_service_factory.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/net/network_time_tracker.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/token_service.h"
@@ -31,8 +32,6 @@
 #include "chrome/browser/sync/glue/sync_backend_registrar.h"
 #include "chrome/browser/sync/glue/synced_device_tracker.h"
 #include "chrome/browser/sync/sync_prefs.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "content/public/browser/browser_thread.h"
@@ -314,7 +313,8 @@
       frontend_(NULL),
       cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE),
       invalidator_(
-          invalidation::InvalidationServiceFactory::GetForProfile(profile)) {
+          invalidation::InvalidationServiceFactory::GetForProfile(profile)),
+      invalidation_handler_registered_(false) {
 }
 
 SyncBackendHost::SyncBackendHost(Profile* profile)
@@ -325,7 +325,8 @@
       name_("Unknown"),
       initialization_state_(NOT_ATTEMPTED),
       frontend_(NULL),
-      cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE) {
+      cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE),
+      invalidation_handler_registered_(false) {
 }
 
 SyncBackendHost::~SyncBackendHost() {
@@ -383,8 +384,6 @@
         InternalComponentsFactoryImpl::BACKOFF_SHORT_INITIAL_RETRY_OVERRIDE;
   }
 
-  invalidator_->RegisterInvalidationHandler(this);
-
   initialization_state_ = CREATING_SYNC_MANAGER;
   InitCore(DoInitializeOptions(
       sync_thread_.message_loop(),
@@ -560,10 +559,16 @@
   // called first.
   DCHECK(!frontend_);
 
-  if (sync_disabled)
-    invalidator_->UpdateRegisteredInvalidationIds(this, syncer::ObjectIdSet());
-  invalidator_->UnregisterInvalidationHandler(this);
-  invalidator_ = NULL;
+  if (invalidation_handler_registered_) {
+    if (sync_disabled) {
+      invalidator_->UpdateRegisteredInvalidationIds(
+          this,
+          syncer::ObjectIdSet());
+    }
+    invalidator_->UnregisterInvalidationHandler(this);
+    invalidator_ = NULL;
+  }
+  invalidation_handler_registered_ = false;
 
   // TODO(tim): DCHECK(registrar_->StoppedOnUIThread()) would be nice.
   if (sync_thread_.IsRunning()) {
@@ -839,6 +844,9 @@
   js_backend_ = js_backend;
   debug_info_listener_ = debug_info_listener;
 
+  invalidator_->RegisterInvalidationHandler(this);
+  invalidation_handler_registered_ = true;
+
   // Inform the registrar of those types that have been fully downloaded and
   // applied.
   registrar_->SetInitialTypes(restored_types);
@@ -872,12 +880,8 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK_EQ(type, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL);
 
-  content::Details<const syncer::ModelTypeInvalidationMap>
-      state_details(details);
-  const syncer::ModelTypeInvalidationMap& invalidation_map =
-      *(state_details.ptr());
-  const syncer::ModelTypeSet types =
-      ModelTypeInvalidationMapToSet(invalidation_map);
+  content::Details<const syncer::ModelTypeSet> state_details(details);
+  const syncer::ModelTypeSet& types = *(state_details.ptr());
   sync_thread_.message_loop()->PostTask(FROM_HERE,
       base::Bind(&SyncBackendHost::Core::DoRefreshTypes, core_.get(), types));
 }
@@ -1390,8 +1394,8 @@
 
 void SyncBackendHost::Core::DeleteSyncDataFolder() {
   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
-  if (file_util::DirectoryExists(sync_data_folder_path_)) {
-    if (!base::Delete(sync_data_folder_path_, true))
+  if (base::DirectoryExists(sync_data_folder_path_)) {
+    if (!base::DeleteFile(sync_data_folder_path_, true))
       SLOG(DFATAL) << "Could not delete the Sync Data folder.";
   }
 }
diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h
index 7b054a8..9498ece 100644
--- a/chrome/browser/sync/glue/sync_backend_host.h
+++ b/chrome/browser/sync/glue/sync_backend_host.h
@@ -569,6 +569,7 @@
   syncer::WeakHandle<syncer::DataTypeDebugInfoListener> debug_info_listener_;
 
   invalidation::InvalidationService* invalidator_;
+  bool invalidation_handler_registered_;
 
   DISALLOW_COPY_AND_ASSIGN(SyncBackendHost);
 };
diff --git a/chrome/browser/sync/glue/sync_backend_host_unittest.cc b/chrome/browser/sync/glue/sync_backend_host_unittest.cc
index 9f8542b..0753ca5 100644
--- a/chrome/browser/sync/glue/sync_backend_host_unittest.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_unittest.cc
@@ -11,12 +11,12 @@
 #include "base/message_loop.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/test/test_timeouts.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/invalidation/invalidator_storage.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
 #include "chrome/browser/sync/glue/device_info.h"
 #include "chrome/browser/sync/glue/synced_device_tracker.h"
 #include "chrome/browser/sync/sync_prefs.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/notification_service.h"
@@ -234,14 +234,10 @@
   void IssueRefreshRequest(syncer::ModelTypeSet types) {
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-    syncer::ModelTypeInvalidationMap invalidation_map(
-        ModelTypeSetToInvalidationMap(types, std::string()));
-
     content::NotificationService::current()->Notify(
         chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
         content::Source<Profile>(profile_.get()),
-        content::Details<syncer::ModelTypeInvalidationMap>(
-            &invalidation_map));
+        content::Details<syncer::ModelTypeSet>(&types));
   }
 
  protected:
diff --git a/chrome/browser/sync/glue/synced_device_tracker.cc b/chrome/browser/sync/glue/synced_device_tracker.cc
index 59fa12a..3db32a9 100644
--- a/chrome/browser/sync/glue/synced_device_tracker.cc
+++ b/chrome/browser/sync/glue/synced_device_tracker.cc
@@ -67,7 +67,8 @@
 
   const sync_pb::DeviceInfoSpecifics& specifics = node.GetDeviceInfoSpecifics();
   return scoped_ptr<DeviceInfo> (
-      new DeviceInfo(specifics.client_name(),
+      new DeviceInfo(specifics.cache_guid(),
+                     specifics.client_name(),
                      specifics.chrome_version(),
                      specifics.sync_user_agent(),
                      specifics.device_type()));
@@ -85,7 +86,8 @@
 
   const sync_pb::DeviceInfoSpecifics& specifics = node.GetDeviceInfoSpecifics();
   return scoped_ptr<DeviceInfo> (
-      new DeviceInfo(specifics.client_name(),
+      new DeviceInfo(specifics.cache_guid(),
+                     specifics.client_name(),
                      specifics.chrome_version(),
                      specifics.sync_user_agent(),
                      specifics.device_type()));
@@ -121,7 +123,8 @@
     const sync_pb::DeviceInfoSpecifics& specifics =
         node.GetDeviceInfoSpecifics();
     device_info->push_back(
-        new DeviceInfo(specifics.client_name(),
+        new DeviceInfo(specifics.cache_guid(),
+                       specifics.client_name(),
                        specifics.chrome_version(),
                        specifics.sync_user_agent(),
                        specifics.device_type()));
@@ -131,6 +134,7 @@
 
 void SyncedDeviceTracker::InitLocalDeviceInfo(const base::Closure& callback) {
   DeviceInfo::CreateLocalDeviceInfo(
+      cache_guid_,
       base::Bind(&SyncedDeviceTracker::InitLocalDeviceInfoContinuation,
                  weak_factory_.GetWeakPtr(), callback));
 }
@@ -143,6 +147,7 @@
 
 void SyncedDeviceTracker::WriteLocalDeviceInfo(const DeviceInfo& info) {
   sync_pb::DeviceInfoSpecifics specifics;
+  DCHECK_EQ(cache_guid_, info.guid());
   specifics.set_cache_guid(cache_guid_);
   specifics.set_client_name(info.client_name());
   specifics.set_chrome_version(info.chrome_version());
diff --git a/chrome/browser/sync/glue/synced_device_tracker_unittest.cc b/chrome/browser/sync/glue/synced_device_tracker_unittest.cc
index 94e79f0..4106243 100644
--- a/chrome/browser/sync/glue/synced_device_tracker_unittest.cc
+++ b/chrome/browser/sync/glue/synced_device_tracker_unittest.cc
@@ -24,9 +24,8 @@
 
 void ConvertDeviceInfoSpecifics(
     const DeviceInfo& device_info,
-    const std::string& guid,
     sync_pb::DeviceInfoSpecifics* specifics) {
-  specifics->set_cache_guid(guid);
+  specifics->set_cache_guid(device_info.guid());
   specifics->set_client_name(device_info.client_name());
   specifics->set_chrome_version(device_info.chrome_version());
   specifics->set_sync_user_agent(device_info.sync_user_agent());
@@ -69,11 +68,10 @@
     synced_device_tracker_->WriteLocalDeviceInfo(info);
   }
 
-  void WriteDeviceInfo(const DeviceInfo& device_info,
-                       const std::string& guid) {
+  void WriteDeviceInfo(const DeviceInfo& device_info) {
     sync_pb::DeviceInfoSpecifics specifics;
-    ConvertDeviceInfoSpecifics(device_info, guid, &specifics);
-    synced_device_tracker_->WriteDeviceInfo(specifics, guid);
+    ConvertDeviceInfoSpecifics(device_info, &specifics);
+    synced_device_tracker_->WriteDeviceInfo(specifics, device_info.guid());
   }
 
   void ResetObservedChangesCounter() {
@@ -112,6 +110,7 @@
   // characters, which client names can include on some platforms (e.g., Mac
   // and iOS).
   DeviceInfo write_device_info(
+      user_share()->directory->cache_guid(),
       "John’s Device", "Chromium 3000", "ChromeSyncAgent 3000",
       sync_pb::SyncEnums_DeviceType_TYPE_LINUX);
   WriteLocalDeviceInfo(write_device_info);
@@ -128,6 +127,7 @@
 TEST_F(SyncedDeviceTrackerTest, DontModifyExistingDeviceInfo) {
   // For writing.
   DeviceInfo device_info(
+      user_share()->directory->cache_guid(),
       "John’s Device", "XYZ v1", "XYZ SyncAgent v1",
       sync_pb::SyncEnums_DeviceType_TYPE_LINUX);
   WriteLocalDeviceInfo(device_info);
@@ -156,6 +156,7 @@
 TEST_F(SyncedDeviceTrackerTest, UpdateExistingDeviceInfo) {
   // Write v1 device info.
   DeviceInfo device_info_v1(
+      user_share()->directory->cache_guid(),
       "John’s Device", "XYZ v1", "XYZ SyncAgent v1",
       sync_pb::SyncEnums_DeviceType_TYPE_LINUX);
   WriteLocalDeviceInfo(device_info_v1);
@@ -164,6 +165,7 @@
 
   // Write upgraded device info.
   DeviceInfo device_info_v2(
+      user_share()->directory->cache_guid(),
       "John’s Device", "XYZ v2", "XYZ SyncAgent v2",
       sync_pb::SyncEnums_DeviceType_TYPE_LINUX);
   WriteLocalDeviceInfo(device_info_v2);
@@ -182,19 +184,21 @@
 // Test retrieving DeviceInfos for all the syncing devices.
 TEST_F(SyncedDeviceTrackerTest, GetAllDeviceInfo) {
   DeviceInfo device_info1(
+      base::GenerateGUID(),
       "abc Device", "XYZ v1", "XYZ SyncAgent v1",
       sync_pb::SyncEnums_DeviceType_TYPE_LINUX);
 
   std::string guid1 = base::GenerateGUID();
 
   DeviceInfo device_info2(
+      base::GenerateGUID(),
       "def Device", "XYZ v2", "XYZ SyncAgent v2",
       sync_pb::SyncEnums_DeviceType_TYPE_LINUX);
 
   std::string guid2 = base::GenerateGUID();
 
-  WriteDeviceInfo(device_info1, guid1);
-  WriteDeviceInfo(device_info2, guid2);
+  WriteDeviceInfo(device_info1);
+  WriteDeviceInfo(device_info2);
 
   ScopedVector<DeviceInfo> device_info;
   synced_device_tracker_->GetAllSyncedDeviceInfo(&device_info);
diff --git a/chrome/browser/sync/glue/synced_tab_delegate.h b/chrome/browser/sync/glue/synced_tab_delegate.h
index 9fe1057..2f46b76 100644
--- a/chrome/browser/sync/glue/synced_tab_delegate.h
+++ b/chrome/browser/sync/glue/synced_tab_delegate.h
@@ -54,6 +54,9 @@
   virtual bool IsPinned() const = 0;
   virtual bool HasWebContents() const = 0;
 
+  // Session sync related methods.
+  virtual int64 GetSyncId() const = 0;
+  virtual void SetSyncId(int64 sync_id) = 0;
   // Returns the SyncedTabDelegate associated with WebContents.
   static SyncedTabDelegate* ImplFromWebContents(
       content::WebContents* web_contents);
diff --git a/chrome/browser/sync/glue/synced_tab_delegate_android.cc b/chrome/browser/sync/glue/synced_tab_delegate_android.cc
index 8236cdf..1b5f26d 100644
--- a/chrome/browser/sync/glue/synced_tab_delegate_android.cc
+++ b/chrome/browser/sync/glue/synced_tab_delegate_android.cc
@@ -106,6 +106,14 @@
       ->GetBlockedNavigations();
 }
 
+int64 SyncedTabDelegateAndroid::GetSyncId() const {
+  return tab_android_->GetSyncId();
+}
+
+void SyncedTabDelegateAndroid::SetSyncId(int64 sync_id) {
+  tab_android_->SetSyncId(sync_id);
+}
+
 // static
 SyncedTabDelegate* SyncedTabDelegate::ImplFromWebContents(
     content::WebContents* web_contents) {
diff --git a/chrome/browser/sync/glue/synced_tab_delegate_android.h b/chrome/browser/sync/glue/synced_tab_delegate_android.h
index 17443b3..91d0972 100644
--- a/chrome/browser/sync/glue/synced_tab_delegate_android.h
+++ b/chrome/browser/sync/glue/synced_tab_delegate_android.h
@@ -38,6 +38,8 @@
   virtual content::NavigationEntry* GetActiveEntry() const OVERRIDE;
   virtual bool IsPinned() const OVERRIDE;
   virtual bool HasWebContents() const OVERRIDE;
+  virtual int64 GetSyncId() const OVERRIDE;
+  virtual void SetSyncId(int64 sync_id) OVERRIDE;
 
   // Managed user related methods.
 
diff --git a/chrome/browser/sync/glue/tab_node_pool.cc b/chrome/browser/sync/glue/tab_node_pool.cc
index 2ec77b2..5d44c39 100644
--- a/chrome/browser/sync/glue/tab_node_pool.cc
+++ b/chrome/browser/sync/glue/tab_node_pool.cc
@@ -20,11 +20,10 @@
     "Server did not create the top-level sessions node. We "
     "might be running against an out-of-date server.";
 
-TabNodePool::TabNodePool(
-    ProfileSyncService* sync_service)
-    : tab_pool_fp_(-1),
-      sync_service_(sync_service) {
-}
+static const size_t kMaxNumberOfFreeNodes = 25;
+
+TabNodePool::TabNodePool(ProfileSyncService* sync_service)
+    : max_used_tab_node_id_(0), sync_service_(sync_service) {}
 
 TabNodePool::~TabNodePool() {}
 
@@ -35,14 +34,30 @@
   return base::StringPrintf("%s %" PRIuS "", machine_tag.c_str(), tab_node_id);
 }
 
-void TabNodePool::AddTabNode(int64 sync_id) {
-  tab_syncid_pool_.resize(tab_syncid_pool_.size() + 1);
-  tab_syncid_pool_[static_cast<size_t>(++tab_pool_fp_)] = sync_id;
+void TabNodePool::AddTabNode(int64 sync_id,
+                             const SessionID& tab_id,
+                             size_t tab_node_id) {
+  DCHECK_GT(sync_id, syncer::kInvalidId);
+  DCHECK_GT(tab_id.id(), kInvalidTabID);
+  DCHECK(syncid_tabid_map_.find(sync_id) == syncid_tabid_map_.end());
+  syncid_tabid_map_[sync_id] = tab_id.id();
+  if (max_used_tab_node_id_ < tab_node_id)
+    max_used_tab_node_id_ = tab_node_id;
+}
+
+void TabNodePool::AssociateTabNode(int64 sync_id, SessionID::id_type tab_id) {
+  DCHECK_GT(sync_id, 0);
+  // Remove node from free node pool and associate it with tab.
+  std::set<int64>::iterator it = free_nodes_pool_.find(sync_id);
+  DCHECK(it != free_nodes_pool_.end());
+  free_nodes_pool_.erase(it);
+  DCHECK(syncid_tabid_map_.find(sync_id) == syncid_tabid_map_.end());
+  syncid_tabid_map_[sync_id] = tab_id;
 }
 
 int64 TabNodePool::GetFreeTabNode() {
   DCHECK_GT(machine_tag_.length(), 0U);
-  if (tab_pool_fp_ == -1) {
+  if (free_nodes_pool_.empty()) {
     // Tab pool has no free nodes, allocate new one.
     syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
     syncer::ReadNode root(&trans);
@@ -51,7 +66,7 @@
       LOG(ERROR) << kNoSessionsFolderError;
       return syncer::kInvalidId;
     }
-    size_t tab_node_id = tab_syncid_pool_.size();
+    size_t tab_node_id = ++max_used_tab_node_id_;
     std::string tab_node_tag = TabIdToTag(machine_tag_, tab_node_id);
     syncer::WriteNode tab_node(&trans);
     syncer::WriteNode::InitUniqueByCreationResult result =
@@ -69,23 +84,86 @@
     specifics.set_tab_node_id(tab_node_id);
     tab_node.SetSessionSpecifics(specifics);
 
-    // Grow the pool by 1 since we created a new node. We don't actually need
-    // to put the node's id in the pool now, since the pool is still empty.
-    // The id will be added when that tab is closed and the node is freed.
-    tab_syncid_pool_.resize(tab_node_id + 1);
-    DVLOG(1) << "Adding sync node "
-             << tab_node.GetId() << " to tab syncid pool";
+    // Grow the pool by 1 since we created a new node.
+    DVLOG(1) << "Adding sync node " << tab_node.GetId()
+             << " to tab syncid pool";
+    free_nodes_pool_.insert(tab_node.GetId());
     return tab_node.GetId();
   } else {
-    // There are nodes available, grab next free and decrement free pointer.
-    return tab_syncid_pool_[static_cast<size_t>(tab_pool_fp_--)];
+    // Return the next free node.
+    return *free_nodes_pool_.begin();
   }
 }
 
 void TabNodePool::FreeTabNode(int64 sync_id) {
-  // Pool size should always match # of free tab nodes.
-  DCHECK_LT(tab_pool_fp_, static_cast<int64>(tab_syncid_pool_.size()));
-  tab_syncid_pool_[static_cast<size_t>(++tab_pool_fp_)] = sync_id;
+  SyncIDToTabIDMap::iterator it = syncid_tabid_map_.find(sync_id);
+  DCHECK(it != syncid_tabid_map_.end());
+  syncid_tabid_map_.erase(it);
+  DCHECK(free_nodes_pool_.find(sync_id) == free_nodes_pool_.end());
+
+  // If number of free nodes exceed number of maximum allowed free nodes,
+  // delete the sync node.
+  if (free_nodes_pool_.size() < kMaxNumberOfFreeNodes) {
+    free_nodes_pool_.insert(sync_id);
+  } else {
+    syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
+    syncer::WriteNode tab_node(&trans);
+    if (tab_node.InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) {
+      LOG(ERROR) << "Could not find sync node with id: " << sync_id;
+      return;
+    }
+    tab_node.Tombstone();
+  }
+}
+
+bool TabNodePool::ReassociateTabNode(int64 sync_id, SessionID::id_type tab_id) {
+  SyncIDToTabIDMap::iterator it = syncid_tabid_map_.find(sync_id);
+  if (it != syncid_tabid_map_.end()) {
+    syncid_tabid_map_[sync_id] = tab_id;
+    return true;
+  }
+  return false;
+}
+
+SessionID::id_type TabNodePool::GetTabIdFromSyncId(int64 sync_id) const {
+  SyncIDToTabIDMap::const_iterator it = syncid_tabid_map_.find(sync_id);
+  if (it != syncid_tabid_map_.end()) {
+    return it->second;
+  }
+  return kInvalidTabID;
+}
+
+void TabNodePool::FreeUnusedTabNodes(const std::set<int64>& used_sync_ids) {
+  for (SyncIDToTabIDMap::iterator it = syncid_tabid_map_.begin();
+       it != syncid_tabid_map_.end();) {
+    if (used_sync_ids.find(it->first) == used_sync_ids.end()) {
+      // This sync node is not used, return it to free node pool.
+      int64 sync_id = it->first;
+      ++it;
+      FreeTabNode(sync_id);
+    } else {
+      ++it;
+    }
+  }
+}
+
+// Clear tab pool.
+void TabNodePool::Clear() {
+  free_nodes_pool_.clear();
+  syncid_tabid_map_.clear();
+  max_used_tab_node_id_ = 0;
+}
+
+size_t TabNodePool::Capacity() const {
+  return syncid_tabid_map_.size() + free_nodes_pool_.size();
+}
+
+bool TabNodePool::Empty() const { return free_nodes_pool_.empty(); }
+
+bool TabNodePool::Full() { return syncid_tabid_map_.empty(); }
+
+void TabNodePool::SetMachineTag(const std::string& machine_tag) {
+  machine_tag_ = machine_tag;
 }
 
 }  // namespace browser_sync
diff --git a/chrome/browser/sync/glue/tab_node_pool.h b/chrome/browser/sync/glue/tab_node_pool.h
index 8327d06..4ad3fef 100644
--- a/chrome/browser/sync/glue/tab_node_pool.h
+++ b/chrome/browser/sync/glue/tab_node_pool.h
@@ -5,10 +5,13 @@
 #ifndef CHROME_BROWSER_SYNC_GLUE_TAB_NODE_POOL_H_
 #define CHROME_BROWSER_SYNC_GLUE_TAB_NODE_POOL_H_
 
+#include <map>
+#include <set>
 #include <string>
-#include <vector>
 
 #include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+#include "chrome/browser/sessions/session_id.h"
 
 class ProfileSyncService;
 
@@ -16,77 +19,97 @@
 
 // A pool for managing free/used tab sync nodes. Performs lazy creation
 // of sync nodes when necessary.
+// Note: We make use of the following "id's"
+// - a sync_id: an int64 used in |syncer::InitByIdLookup|
+// - a tab_id: created by session service, unique to this client
+// - a tab_node_id: the id for a particular sync tab node. This is used
+//   to generate the sync tab node tag through:
+//       tab_tag = StringPrintf("%s_%ui", local_session_tag, tab_node_id);
+// tab_node_id and sync_id are both unique to a particular sync node. The
+// difference is that tab_node_id is controlled by the model associator and
+// is used when creating a new sync node, which returns the sync_id, created
+// by the sync db.
 class TabNodePool {
  public:
   explicit TabNodePool(ProfileSyncService* sync_service);
   ~TabNodePool();
-
+  enum InvalidTab {
+    kInvalidTabID = -1
+  };
   // Build a sync tag from tab_node_id.
   static std::string TabIdToTag(const std::string machine_tag,
                                 size_t tab_node_id);
 
-  // Add a previously allocated tab sync node to our pool. Increases the size
-  // of tab_syncid_pool_ by one and marks the new tab node as free.
+  // Returns the sync_id for the next free tab node. If none are available,
+  // creates a new tab node and adds it to free nodes pool. The free node can
+  // then be used to associate with a tab by calling AssociateTabNode.
+  // Note: The node is considered free until it has been associated. Repeated
+  // calls to GetFreeTabNode will return the same sync_id until node has been
+  // associated.
+  int64 GetFreeTabNode();
+
+  // Removes the node from |syncid_tabid_map_| and returns the node to free
+  // pool.
+  void FreeTabNode(int64 sync_id);
+
+  // Removes |sync_id| from free node pool and associates it with |tab_id|.
+  // sync_id should be id of a free node. In order to associate a non free
+  // sync node, use ReassociateTabNode.
+  void AssociateTabNode(int64 sync_id, SessionID::id_type tab_id);
+
+  // Associate sync_id with tab_id but does not add it to free node pool.
   // Note: this should only be called when we discover tab sync nodes from
   // previous sessions, not for freeing tab nodes we created through
   // GetFreeTabNode (use FreeTabNode below for that).
-  void AddTabNode(int64 sync_id);
+  // The difference between AddTabNode and AssociateTabNode is that
+  // AssociateTabNode requires the sync node to be free to be associated.
+  // AddTabNode just adds the association.
+  void AddTabNode(int64 sync_id, const SessionID& tab_id, size_t tab_node_id);
 
-  // Returns the sync_id for the next free tab node. If none are available,
-  // creates a new tab node.
-  // Note: We make use of the following "id's"
-  // - a sync_id: an int64 used in |syncer::InitByIdLookup|
-  // - a tab_id: created by session service, unique to this client
-  // - a tab_node_id: the id for a particular sync tab node. This is used
-  //   to generate the sync tab node tag through:
-  //       tab_tag = StringPrintf("%s_%ui", local_session_tag, tab_node_id);
-  // tab_node_id and sync_id are both unique to a particular sync node. The
-  // difference is that tab_node_id is controlled by the model associator and
-  // is used when creating a new sync node, which returns the sync_id, created
-  // by the sync db.
-  int64 GetFreeTabNode();
+  // Returns the tab_id for |sync_id| if it exists else returns kInvalidTabID.
+  SessionID::id_type GetTabIdFromSyncId(int64 sync_id) const;
 
-  // Return a tab node to our free pool.
-  // Note: the difference between FreeTabNode and AddTabNode is that
-  // FreeTabNode does not modify the size of |tab_syncid_pool_|, while
-  // AddTabNode increases it by one. In the case of FreeTabNode, the size of
-  // the |tab_syncid_pool_| should always be equal to the amount of tab nodes
-  // associated with this machine.
-  void FreeTabNode(int64 sync_id);
+  // Reassociates sync node with id |sync_id| with tab node with |tab_id|.
+  // Returns true if it is able to reassociate the node, false if a sync node
+  // with id |sync_id| is not associated with any tab.
+  bool ReassociateTabNode(int64 sync_id, SessionID::id_type tab_id);
+
+  // Returns any nodes with sync_ids not in |used_synced_ids| to free node pool.
+  void FreeUnusedTabNodes(const std::set<int64>& used_sync_ids);
 
   // Clear tab pool.
-  void clear() {
-    tab_syncid_pool_.clear();
-    tab_pool_fp_ = -1;
-  }
+  void Clear();
 
   // Return the number of tab nodes this client currently has allocated
   // (including both free and used nodes)
-  size_t capacity() const { return tab_syncid_pool_.size(); }
+  size_t Capacity() const;
 
   // Return empty status (all tab nodes are in use).
-  bool empty() const { return tab_pool_fp_ == -1; }
+  bool Empty() const;
 
   // Return full status (no tab nodes are in use).
-  bool full() {
-    return tab_pool_fp_ == static_cast<int64>(tab_syncid_pool_.size())-1;
-  }
+  bool Full();
 
-  void set_machine_tag(const std::string& machine_tag) {
-    machine_tag_ = machine_tag;
-  }
+  void SetMachineTag(const std::string& machine_tag);
 
  private:
-  // Pool of all available syncid's for tab's we have created.
-  std::vector<int64> tab_syncid_pool_;
+  friend class SyncTabNodePoolTest;
+  typedef std::map<int64, SessionID::id_type> SyncIDToTabIDMap;
 
-  // Free pointer for tab pool. Only those node id's, up to and including the
-  // one indexed by the free pointer, are valid and free. The rest of the
-  // |tab_syncid_pool_| is invalid because the nodes are in use.
-  // To get the next free node, use tab_syncid_pool_[tab_pool_fp_--].
-  int64 tab_pool_fp_;
+  // Stores mapping of sync_ids associated with tab_ids, these are the used
+  // nodes of tab node pool.
+  // The nodes in the map can be returned to free tab node pool by calling
+  // FreeTabNode(sync_id).
+  SyncIDToTabIDMap syncid_tabid_map_;
 
-  // The machiine tag associated with this tab pool. Used in the title of new
+  // The sync ids for the set of free sync nodes.
+  std::set<int64> free_nodes_pool_;
+
+  // The maximum used tab_node id for a sync node. A new sync node will always
+  // be created with max_used_tab_node_id_ + 1.
+  size_t max_used_tab_node_id_;
+
+  // The machine tag associated with this tab pool. Used in the title of new
   // sync nodes.
   std::string machine_tag_;
 
diff --git a/chrome/browser/sync/glue/tab_node_pool_unittest.cc b/chrome/browser/sync/glue/tab_node_pool_unittest.cc
index 43d4768..b3ee12f 100644
--- a/chrome/browser/sync/glue/tab_node_pool_unittest.cc
+++ b/chrome/browser/sync/glue/tab_node_pool_unittest.cc
@@ -8,80 +8,199 @@
 
 namespace browser_sync {
 
+class SyncTabNodePoolTest : public testing::Test {
+ protected:
+  SyncTabNodePoolTest() : pool_(NULL) { pool_.SetMachineTag("tag"); }
+
+  size_t GetMaxUsedTabNodeId() const { return pool_.max_used_tab_node_id_; }
+
+  TabNodePool pool_;
+};
+
 namespace {
 
-typedef testing::Test SyncTabNodePoolTest;
+TEST_F(SyncTabNodePoolTest, TabNodeIdIncreases) {
+  // max_used_tab_node_ always increases.
+  SessionID session_id;
+  session_id.set_id(1);
+  pool_.AddTabNode(4, session_id, 10);
+  EXPECT_EQ(10u, GetMaxUsedTabNodeId());
+  session_id.set_id(2);
+  pool_.AddTabNode(5, session_id, 1);
+  EXPECT_EQ(10u, GetMaxUsedTabNodeId());
+  session_id.set_id(3);
+  pool_.AddTabNode(6, session_id, 1000);
+  EXPECT_EQ(1000u, GetMaxUsedTabNodeId());
+  pool_.ReassociateTabNode(6, 500);
+  // Freeing a tab node does not change max_used_tab_node_id_.
+  pool_.FreeTabNode(4);
+  pool_.FreeUnusedTabNodes(std::set<int64>());
+  EXPECT_EQ(1000u, GetMaxUsedTabNodeId());
+  for (int i = 0; i < 3; ++i) {
+    pool_.AssociateTabNode(pool_.GetFreeTabNode(), i + 1);
+    EXPECT_EQ(1000u, GetMaxUsedTabNodeId());
+  }
+
+  EXPECT_EQ(1000u, GetMaxUsedTabNodeId());
+}
+
+TEST_F(SyncTabNodePoolTest, OldTabNodesAddAndRemove) {
+  // VerifyOldTabNodes are added.
+  // sync_id =4, tab_node_id = 1, tab_id = 1
+  SessionID session_id;
+  session_id.set_id(1);
+  pool_.AddTabNode(4, session_id, 1);
+  // sync_id = 5, tab_node_id = 5, tab_id = 2
+  session_id.set_id(2);
+  pool_.AddTabNode(5, session_id, 2);
+  EXPECT_EQ(2u, pool_.Capacity());
+  EXPECT_TRUE(pool_.Empty());
+  EXPECT_TRUE(pool_.ReassociateTabNode(4, 2));
+  EXPECT_TRUE(pool_.ReassociateTabNode(5, 1));
+  EXPECT_TRUE(pool_.Empty());
+  // Check free unused tab nodes returns the node to free node pool_.
+  std::set<int64> used_sync_ids;
+  used_sync_ids.insert(5);
+  pool_.FreeUnusedTabNodes(used_sync_ids);
+  // 4 should be returned to free node pool_.
+  EXPECT_EQ(2u, pool_.Capacity());
+  EXPECT_FALSE(pool_.Empty());
+  // 5 should still be in the associated nodes.
+  EXPECT_FALSE(pool_.Full());
+  pool_.FreeTabNode(5);
+  // 5 should be returned to free nodes pool and pool should be full.
+  EXPECT_TRUE(pool_.Full());
+  EXPECT_EQ(4, pool_.GetFreeTabNode());
+  pool_.AssociateTabNode(4, 1);
+  EXPECT_EQ(5, pool_.GetFreeTabNode());
+  pool_.AssociateTabNode(5, 1);
+  EXPECT_TRUE(pool_.Empty());
+  EXPECT_FALSE(pool_.Full());
+}
+
+TEST_F(SyncTabNodePoolTest, OldTabNodesReassociation) {
+  // VerifyOldTabNodes are reassociated correctly.
+  // sync_id =4, tab_node_id = 1, tab_id = 1
+  SessionID session_id;
+  session_id.set_id(1);
+  pool_.AddTabNode(4, session_id, 1);
+  // sync_id = 5, tab_node_id = 2, tab_id = 2
+  session_id.set_id(2);
+  pool_.AddTabNode(5, session_id, 2);
+  // sync_id = 5, tab_node_id = 3, tab_id =3
+  session_id.set_id(3);
+  pool_.AddTabNode(6, session_id, 3);
+  EXPECT_EQ(3u, pool_.Capacity());
+  EXPECT_TRUE(pool_.Empty());
+  // Free 5 and 6.
+  pool_.FreeTabNode(5);
+  pool_.FreeTabNode(6);
+  // 5 and 6 nodes should not get reassociated.
+  EXPECT_TRUE(pool_.ReassociateTabNode(4, 5));
+  EXPECT_FALSE(pool_.ReassociateTabNode(5, 6));
+  EXPECT_FALSE(pool_.ReassociateTabNode(6, 7));
+  // Free node pool should have 5 and 6.
+  EXPECT_FALSE(pool_.Empty());
+  EXPECT_EQ(3u, pool_.Capacity());
+
+  // Free all nodes
+  pool_.FreeUnusedTabNodes(std::set<int64>());
+  EXPECT_TRUE(pool_.Full());
+  std::set<int64> free_sync_ids;
+  for (int i = 0; i < 3; ++i) {
+    free_sync_ids.insert(pool_.GetFreeTabNode());
+    // GetFreeTabNode will return the same value till the node is
+    // reassociated.
+    pool_.AssociateTabNode(pool_.GetFreeTabNode(), i + 1);
+  }
+
+  EXPECT_TRUE(pool_.Empty());
+  EXPECT_EQ(3u, free_sync_ids.size());
+  EXPECT_EQ(1u, free_sync_ids.count(4));
+  EXPECT_EQ(1u, free_sync_ids.count(5));
+  EXPECT_EQ(1u, free_sync_ids.count(6));
+}
 
 TEST_F(SyncTabNodePoolTest, Init) {
-  TabNodePool pool(NULL);
-  pool.set_machine_tag("tag");
-  ASSERT_TRUE(pool.empty());
-  ASSERT_TRUE(pool.full());
+  EXPECT_TRUE(pool_.Empty());
+  EXPECT_TRUE(pool_.Full());
 }
 
 TEST_F(SyncTabNodePoolTest, AddGet) {
-  TabNodePool pool(NULL);
-  pool.set_machine_tag("tag");
+  SessionID session_id;
+  session_id.set_id(1);
+  pool_.AddTabNode(5, session_id, 1);
+  session_id.set_id(2);
+  pool_.AddTabNode(10, session_id, 2);
+  pool_.FreeUnusedTabNodes(std::set<int64>());
+  EXPECT_FALSE(pool_.Empty());
+  EXPECT_TRUE(pool_.Full());
 
-  pool.AddTabNode(5);
-  pool.AddTabNode(10);
-  ASSERT_FALSE(pool.empty());
-  ASSERT_TRUE(pool.full());
-
-  ASSERT_EQ(2U, pool.capacity());
-  ASSERT_EQ(10, pool.GetFreeTabNode());  // Returns last free tab.
-  ASSERT_FALSE(pool.empty());
-  ASSERT_FALSE(pool.full());
-  ASSERT_EQ(2U, pool.capacity());
-  ASSERT_EQ(5, pool.GetFreeTabNode());  // Returns last free tab.
+  EXPECT_EQ(2U, pool_.Capacity());
+  EXPECT_EQ(5, pool_.GetFreeTabNode());
+  pool_.AssociateTabNode(5, 1);
+  EXPECT_FALSE(pool_.Empty());
+  EXPECT_FALSE(pool_.Full());
+  EXPECT_EQ(2U, pool_.Capacity());
+  // 5 is now used, should return 10.
+  EXPECT_EQ(10, pool_.GetFreeTabNode());
 }
 
 TEST_F(SyncTabNodePoolTest, All) {
-  TabNodePool pool(NULL);
-  pool.set_machine_tag("tag");
-  ASSERT_TRUE(pool.empty());
-  ASSERT_TRUE(pool.full());
-  ASSERT_EQ(0U, pool.capacity());
-  pool.AddTabNode(5);
-  pool.AddTabNode(10);
-  ASSERT_FALSE(pool.empty());
-  ASSERT_TRUE(pool.full());
-  ASSERT_EQ(2U, pool.capacity());
-  ASSERT_EQ(10, pool.GetFreeTabNode());  // Returns last free tab.
-  ASSERT_FALSE(pool.empty());
-  ASSERT_FALSE(pool.full());
-  ASSERT_EQ(2U, pool.capacity());
-  ASSERT_EQ(5, pool.GetFreeTabNode());  // Returns last free tab.
-  ASSERT_TRUE(pool.empty());
-  ASSERT_FALSE(pool.full());
-  ASSERT_EQ(2U, pool.capacity());
+  EXPECT_TRUE(pool_.Empty());
+  EXPECT_TRUE(pool_.Full());
+  EXPECT_EQ(0U, pool_.Capacity());
+  SessionID session_id;
+  session_id.set_id(1);
+  pool_.AddTabNode(5, session_id, 1);
+  session_id.set_id(2);
+  pool_.AddTabNode(10, session_id, 2);
+  // Free added nodes.
+  pool_.FreeUnusedTabNodes(std::set<int64>());
+  EXPECT_FALSE(pool_.Empty());
+  EXPECT_TRUE(pool_.Full());
+  EXPECT_EQ(2U, pool_.Capacity());
+  // GetFreeTabNode returns the lowest numbered free node.
+  EXPECT_EQ(5, pool_.GetFreeTabNode());
+  EXPECT_FALSE(pool_.Empty());
+  EXPECT_TRUE(pool_.Full());
+  EXPECT_EQ(2U, pool_.Capacity());
+  // Associate 5, next free node should be 10.
+  pool_.AssociateTabNode(5, 1);
+  EXPECT_EQ(10, pool_.GetFreeTabNode());
+  pool_.AssociateTabNode(10, 2);
+  EXPECT_TRUE(pool_.Empty());
+  EXPECT_FALSE(pool_.Full());
+  EXPECT_EQ(2U, pool_.Capacity());
   // Release them in reverse order.
-  pool.FreeTabNode(10);
-  pool.FreeTabNode(5);
-  ASSERT_EQ(2U, pool.capacity());
-  ASSERT_FALSE(pool.empty());
-  ASSERT_TRUE(pool.full());
-  ASSERT_EQ(5, pool.GetFreeTabNode());  // Returns last free tab.
-  ASSERT_FALSE(pool.empty());
-  ASSERT_FALSE(pool.full());
-  ASSERT_EQ(2U, pool.capacity());
-  ASSERT_FALSE(pool.empty());
-  ASSERT_FALSE(pool.full());
-  ASSERT_EQ(2U, pool.capacity());
-  ASSERT_EQ(10, pool.GetFreeTabNode());  // Returns last free tab.
-  ASSERT_TRUE(pool.empty());
-  ASSERT_FALSE(pool.full());
-  ASSERT_EQ(2U, pool.capacity());
+  pool_.FreeTabNode(10);
+  pool_.FreeTabNode(5);
+  EXPECT_EQ(2U, pool_.Capacity());
+  EXPECT_FALSE(pool_.Empty());
+  EXPECT_TRUE(pool_.Full());
+  EXPECT_EQ(5, pool_.GetFreeTabNode());
+  EXPECT_FALSE(pool_.Empty());
+  EXPECT_TRUE(pool_.Full());
+  EXPECT_EQ(2U, pool_.Capacity());
+  EXPECT_FALSE(pool_.Empty());
+  EXPECT_TRUE(pool_.Full());
+  pool_.AssociateTabNode(5, 1);
+  EXPECT_EQ(2U, pool_.Capacity());
+  EXPECT_EQ(10, pool_.GetFreeTabNode());
+  pool_.AssociateTabNode(10, 2);
+  EXPECT_TRUE(pool_.Empty());
+  EXPECT_FALSE(pool_.Full());
+  EXPECT_EQ(2U, pool_.Capacity());
   // Release them again.
-  pool.FreeTabNode(10);
-  pool.FreeTabNode(5);
-  ASSERT_FALSE(pool.empty());
-  ASSERT_TRUE(pool.full());
-  ASSERT_EQ(2U, pool.capacity());
-  pool.clear();
-  ASSERT_TRUE(pool.empty());
-  ASSERT_TRUE(pool.full());
-  ASSERT_EQ(0U, pool.capacity());
+  pool_.FreeTabNode(10);
+  pool_.FreeTabNode(5);
+  EXPECT_FALSE(pool_.Empty());
+  EXPECT_TRUE(pool_.Full());
+  EXPECT_EQ(2U, pool_.Capacity());
+  pool_.Clear();
+  EXPECT_TRUE(pool_.Empty());
+  EXPECT_TRUE(pool_.Full());
+  EXPECT_EQ(0U, pool_.Capacity());
 }
 
 }  // namespace
diff --git a/chrome/browser/sync/glue/typed_url_change_processor.cc b/chrome/browser/sync/glue/typed_url_change_processor.cc
index 31ba8a2..1a86800 100644
--- a/chrome/browser/sync/glue/typed_url_change_processor.cc
+++ b/chrome/browser/sync/glue/typed_url_change_processor.cc
@@ -8,12 +8,12 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/glue/typed_url_model_associator.h"
 #include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "sync/internal_api/public/change_record.h"
 #include "sync/internal_api/public/read_node.h"
diff --git a/chrome/browser/sync/glue/typed_url_data_type_controller.cc b/chrome/browser/sync/glue/typed_url_data_type_controller.cc
index f5bea83..6a5d4a7 100644
--- a/chrome/browser/sync/glue/typed_url_data_type_controller.cc
+++ b/chrome/browser/sync/glue/typed_url_data_type_controller.cc
@@ -8,13 +8,13 @@
 #include "base/callback.h"
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_db_task.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/profile_sync_components_factory.h"
 #include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/sync/profile_sync_components_factory_impl.cc b/chrome/browser/sync/profile_sync_components_factory_impl.cc
index 8a4cbec..7d796f0 100644
--- a/chrome/browser/sync/profile_sync_components_factory_impl.cc
+++ b/chrome/browser/sync/profile_sync_components_factory_impl.cc
@@ -174,19 +174,8 @@
         new SessionDataTypeController(this, profile_, pss));
   }
 
-  // Migrate sync flags that should be prefs.
-  // TODO(pastarmovj): Remove this code once enough time has passed to not need
-  // to migrate anymore.
-  about_flags::PrefServiceFlagsStorage flags_storage(
-      g_browser_process->local_state());
-  if (command_line_->HasSwitch(switches::kEnableSyncFavicons)) {
-    profile_->GetPrefs()->SetBoolean(prefs::kSyncFaviconsEnabled, true);
-    about_flags::SetExperimentEnabled(&flags_storage,
-                                      syncer::kFaviconSyncFlag,
-                                      false);
-  }
-
-  if (profile_->GetPrefs()->GetBoolean(prefs::kSyncFaviconsEnabled)) {
+  // Favicon sync is enabled by default. Register unless explicitly disabled.
+  if (!command_line_->HasSwitch(switches::kDisableSyncFavicons)) {
     pss->RegisterDataTypeController(
         new UIDataTypeController(syncer::FAVICON_IMAGES,
                                  this,
@@ -394,9 +383,14 @@
       return SpellcheckServiceFactory::GetForProfile(profile_)->
           GetCustomDictionary()->AsWeakPtr();
     case syncer::FAVICON_IMAGES:
-    case syncer::FAVICON_TRACKING:
-      return ProfileSyncServiceFactory::GetForProfile(profile_)->
-          GetSessionModelAssociator()->GetFaviconCache()->AsWeakPtr();
+    case syncer::FAVICON_TRACKING: {
+      browser_sync::SessionModelAssociator* model_associator =
+          ProfileSyncServiceFactory::GetForProfile(profile_)->
+              GetSessionModelAssociator();
+      if (!model_associator)
+        return base::WeakPtr<syncer::SyncableService>();
+      return model_associator->GetFaviconCache()->AsWeakPtr();
+    }
 #if defined(ENABLE_MANAGED_USERS)
     case syncer::MANAGED_USER_SETTINGS:
       return policy::ProfilePolicyConnectorFactory::GetForProfile(profile_)->
diff --git a/chrome/browser/sync/profile_sync_components_factory_impl_unittest.cc b/chrome/browser/sync/profile_sync_components_factory_impl_unittest.cc
index a32eb8a..df209b2 100644
--- a/chrome/browser/sync/profile_sync_components_factory_impl_unittest.cc
+++ b/chrome/browser/sync/profile_sync_components_factory_impl_unittest.cc
@@ -52,6 +52,8 @@
     datatypes.push_back(syncer::PROXY_TABS);
     datatypes.push_back(syncer::THEMES);
     datatypes.push_back(syncer::TYPED_URLS);
+    datatypes.push_back(syncer::FAVICON_TRACKING);
+    datatypes.push_back(syncer::FAVICON_IMAGES);
     return datatypes;
   }
 
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index 26f26d1..5902452 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -23,6 +23,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/net/chrome_cookie_notification_details.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
@@ -53,7 +54,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/global_error/global_error_service.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/pref_names.h"
@@ -111,14 +111,6 @@
 
 static const int kSyncClearDataTimeoutInSeconds = 60;  // 1 minute.
 
-static const char* kOAuth2Scopes[] = {
-  GaiaConstants::kChromeSyncOAuth2Scope,
-};
-
-static const char* kManagedOAuth2Scopes[] = {
-  GaiaConstants::kChromeSyncManagedOAuth2Scope
-};
-
 static const char* kSyncUnrecoverableErrorHistogram =
     "Sync.UnrecoverableErrors";
 
@@ -196,8 +188,6 @@
       channel == chrome::VersionInfo::CHANNEL_BETA) {
     sync_service_url_ = GURL(kSyncServerUrl);
   }
-  if (signin_)
-    signin_->signin_global_error()->AddProvider(this);
 }
 
 ProfileSyncService::~ProfileSyncService() {
@@ -235,6 +225,9 @@
 }
 
 void ProfileSyncService::Initialize() {
+  if (profile_)
+    SigninGlobalError::GetForProfile(profile_)->AddProvider(this);
+
   InitSettings();
 
   // We clear this here (vs Shutdown) because we want to remember that an error
@@ -689,8 +682,8 @@
 }
 
 void ProfileSyncService::Shutdown() {
-  if (signin_)
-    signin_->signin_global_error()->RemoveProvider(this);
+  if (profile_)
+    SigninGlobalError::GetForProfile(profile_)->RemoveProvider(this);
 
   ShutdownImpl(false);
 }
@@ -1021,9 +1014,6 @@
     }
   }
 
-  if (experiments.favicon_sync)
-    profile_->GetPrefs()->SetBoolean(prefs::kSyncFaviconsEnabled, true);
-
   current_experiments_ = experiments;
 }
 
@@ -1034,8 +1024,9 @@
   // Fan the notification out to interested UI-thread components. Notify the
   // SigninGlobalError first so it reflects the latest auth state before we
   // notify observers.
-  if (signin())
-    signin()->signin_global_error()->AuthStatusChanged();
+  if (profile_)
+    SigninGlobalError::GetForProfile(profile_)->AuthStatusChanged();
+
   NotifyObservers();
 }
 
@@ -1813,18 +1804,17 @@
   is_managed = ManagedUserService::ProfileIsManaged(profile_);
 #endif
   if (is_managed) {
-    for (size_t i = 0; i < arraysize(kManagedOAuth2Scopes); i++)
-      oauth2_scopes.insert(kManagedOAuth2Scopes[i]);
+    oauth2_scopes.insert(GaiaConstants::kChromeSyncManagedOAuth2Scope);
   } else {
-    for (size_t i = 0; i < arraysize(kOAuth2Scopes); i++)
-      oauth2_scopes.insert(kOAuth2Scopes[i]);
+    oauth2_scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope);
   }
 
   OAuth2TokenService* token_service =
       ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
   // Invalidate previous token, otherwise token service will return the same
   // token again.
-  token_service->InvalidateToken(oauth2_scopes, access_token_);
+  if (!access_token_.empty())
+    token_service->InvalidateToken(oauth2_scopes, access_token_);
   access_token_.clear();
   access_token_request_ = token_service->StartRequest(oauth2_scopes, this);
 }
diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc
index 7886477..ffefa2e 100644
--- a/chrome/browser/sync/profile_sync_service_android.cc
+++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -15,6 +15,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/oauth2_token_service.h"
 #include "chrome/browser/signin/signin_manager.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/sync_prefs.h"
 #include "chrome/browser/sync/sync_ui_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
@@ -82,20 +82,6 @@
 
 void ProfileSyncServiceAndroid::Init() {
   sync_service_->AddObserver(this);
-
-  std::string signed_in_username =
-      SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
-  if (!signed_in_username.empty()) {
-    // If the user is logged in, see if he has a valid token - if not, fetch
-    // a new one.
-    TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
-    if (!token_service->HasTokenForService(GaiaConstants::kSyncService) ||
-        (sync_service_->GetAuthError().state() ==
-         GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)) {
-      DVLOG(2) << "Trying to update token for user " << signed_in_username;
-      InvalidateAuthToken();
-    }
-  }
 }
 
 void ProfileSyncServiceAndroid::RemoveObserver() {
@@ -116,51 +102,33 @@
 
   // TODO(nileshagrawal): Merge this with ChromeInvalidationClient::Invalidate.
   // Construct the ModelTypeStateMap and send it over with the notification.
-  syncer::ModelType model_type;
-  if (!syncer::NotificationTypeToRealModelType(str_object_id, &model_type)) {
-    DVLOG(1) << "Could not get invalidation model type; "
-            << "Sending notification with empty state map.";
-    syncer::ModelTypeInvalidationMap model_types_with_states;
-    content::NotificationService::current()->Notify(
-          chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
-          content::Source<Profile>(profile_),
-          content::Details<const syncer::ModelTypeInvalidationMap>(
-              &model_types_with_states));
-    return;
-  }
-
+  invalidation::ObjectId object_id(
+      ipc::invalidation::ObjectSource::CHROME_SYNC,
+      str_object_id);
   if (version != ipc::invalidation::Constants::UNKNOWN) {
-    std::map<syncer::ModelType, int64>::const_iterator it =
-        max_invalidation_versions_.find(model_type);
+    ObjectIdVersionMap::iterator it =
+        max_invalidation_versions_.find(object_id);
     if ((it != max_invalidation_versions_.end()) &&
         (version <= it->second)) {
       DVLOG(1) << "Dropping redundant invalidation with version " << version;
       return;
     }
-    max_invalidation_versions_[model_type] = version;
+    max_invalidation_versions_[object_id] = version;
   }
 
-  syncer::ModelTypeSet types;
-  types.Put(model_type);
-  syncer::ModelTypeInvalidationMap model_types_with_states =
-      syncer::ModelTypeSetToInvalidationMap(types, state);
+  syncer::ObjectIdSet object_ids;
+  object_ids.insert(object_id);
+  syncer::ObjectIdInvalidationMap object_ids_with_states =
+      syncer::ObjectIdSetToInvalidationMap(object_ids, state);
 
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
       content::Source<Profile>(profile_),
-      content::Details<const syncer::ModelTypeInvalidationMap>(
-          &model_types_with_states));
+      content::Details<const syncer::ObjectIdInvalidationMap>(
+          &object_ids_with_states));
 }
 
-
 void ProfileSyncServiceAndroid::OnStateChanged() {
-  // Check for auth errors.
-  const GoogleServiceAuthError& auth_error = sync_service_->GetAuthError();
-  if (auth_error.state() == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) {
-      DVLOG(2) << "Updating auth token.";
-      InvalidateAuthToken();
-  }
-
   // Notify the java world that our sync state has changed.
   JNIEnv* env = AttachCurrentThread();
   Java_ProfileSyncService_syncStateChanged(
@@ -174,55 +142,6 @@
       GaiaConstants::kSyncService, token);
 }
 
-void ProfileSyncServiceAndroid::InvalidateOAuth2Token(
-    const std::string& scope, const std::string& invalid_token) {
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jstring> j_scope =
-      ConvertUTF8ToJavaString(env, scope);
-  ScopedJavaLocalRef<jstring> j_invalid_token =
-      ConvertUTF8ToJavaString(env, invalid_token);
-  Java_ProfileSyncService_invalidateOAuth2AuthToken(
-      env, weak_java_profile_sync_service_.get(env).obj(),
-      j_scope.obj(),
-      j_invalid_token.obj());
-}
-
-void ProfileSyncServiceAndroid::FetchOAuth2Token(
-    const std::string& scope, const FetchOAuth2TokenCallback& callback) {
-  const std::string& sync_username =
-      SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
-
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jstring> j_sync_username =
-      ConvertUTF8ToJavaString(env, sync_username);
-  ScopedJavaLocalRef<jstring> j_scope =
-      ConvertUTF8ToJavaString(env, scope);
-
-  // Allocate a copy of the callback on the heap, because the callback
-  // needs to be passed through JNI as an int.
-  // It will be passed back to OAuth2TokenFetched(), where it will be freed.
-  scoped_ptr<FetchOAuth2TokenCallback> heap_callback(
-      new FetchOAuth2TokenCallback(callback));
-
-  // Call into Java to get a new token.
-  Java_ProfileSyncService_getOAuth2AuthToken(
-      env, weak_java_profile_sync_service_.get(env).obj(),
-      j_sync_username.obj(),
-      j_scope.obj(),
-      reinterpret_cast<int>(heap_callback.release()));
-}
-
-void ProfileSyncServiceAndroid::OAuth2TokenFetched(
-    JNIEnv* env, jobject, int callback, jstring auth_token, jboolean result) {
-  std::string token = ConvertJavaStringToUTF8(env, auth_token);
-  scoped_ptr<FetchOAuth2TokenCallback> heap_callback(
-      reinterpret_cast<FetchOAuth2TokenCallback*>(callback));
-  GoogleServiceAuthError err(result ?
-                             GoogleServiceAuthError::NONE :
-                             GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
-  heap_callback->Run(err, token, base::Time());
-}
-
 void ProfileSyncServiceAndroid::EnableSync(JNIEnv* env, jobject) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   // Don't need to do anything if we're already enabled.
@@ -243,8 +162,7 @@
   }
 }
 
-void ProfileSyncServiceAndroid::SignInSync(
-    JNIEnv* env, jobject, jstring username, jstring auth_token) {
+void ProfileSyncServiceAndroid::SignInSync(JNIEnv* env, jobject) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   // Just return if sync already has everything it needs to start up (sync
   // should start up automatically as long as it has credentials). This can
@@ -256,41 +174,6 @@
     return;
   }
 
-  if (!sync_service_->IsSyncEnabledAndLoggedIn() ||
-      !sync_service_->IsOAuthRefreshTokenAvailable()) {
-    // Set the currently-signed-in username, fetch an auth token if necessary,
-    // and enable sync.
-    std::string name = ConvertJavaStringToUTF8(env, username);
-    // TODO(tim) It should be enough to only call
-    // SigninManager::SetAuthenticatedUsername here. See
-    // http://crbug.com/107160.
-    profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, name);
-    SigninManagerFactory::GetForProfile(profile_)->
-        SetAuthenticatedUsername(name);
-    std::string token = ConvertJavaStringToUTF8(env, auth_token);
-    if (token.empty()) {
-      // No credentials passed in - request an auth token.
-      // If fetching the auth token is successful, this will cause
-      // ProfileSyncService to start sync when it receives
-      // NOTIFICATION_TOKEN_AVAILABLE.
-      DVLOG(2) << "Fetching auth token for " << name;
-      InvalidateAuthToken();
-    } else {
-      // OnIssueAuthTokenSuccess will send out a notification to the sync
-      // service that will cause the sync backend to initialize.
-      TokenService* token_service =
-          TokenServiceFactory::GetForProfile(profile_);
-      token_service->OnIssueAuthTokenSuccess(GaiaConstants::kSyncService,
-                                             token);
-    }
-
-    GoogleServiceSigninSuccessDetails details(name, std::string());
-    content::NotificationService::current()->Notify(
-        chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
-        content::Source<Profile>(profile_),
-        content::Details<const GoogleServiceSigninSuccessDetails>(&details));
-  }
-
   // Enable sync (if we don't have credentials yet, this will enable sync but
   // will not start it up - sync will start once credentials arrive).
   sync_service_->UnsuppressAndStart();
@@ -301,9 +184,6 @@
   DCHECK(profile_);
   sync_service_->DisableForUser();
 
-  // Clear the tokens.
-  SigninManagerFactory::GetForProfile(profile_)->SignOut();
-
   // Need to clear suppress start flag manually
   sync_prefs_->SetStartSuppressed(false);
 }
@@ -592,29 +472,6 @@
   return ConvertUTF8ToJavaString(env, about_info_json);
 }
 
-void ProfileSyncServiceAndroid::InvalidateAuthToken() {
-  // Get the token from token-db. If there's no token yet, this must be the
-  // the first time the user is signing in so we don't need to invalidate
-  // anything.
-  TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
-  std::string invalid_token;
-  if (token_service->HasTokenForService(GaiaConstants::kSyncService)) {
-    invalid_token = token_service->GetTokenForService(
-        GaiaConstants::kSyncService);
-  }
-  const std::string& sync_username =
-      SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
-  // Call into java to invalidate the current token and get a new one.
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jstring> j_sync_username =
-      ConvertUTF8ToJavaString(env, sync_username);
-  ScopedJavaLocalRef<jstring> j_invalid_token =
-      ConvertUTF8ToJavaString(env, invalid_token);
-  Java_ProfileSyncService_getNewAuthToken(
-      env, weak_java_profile_sync_service_.get(env).obj(),
-      j_sync_username.obj(), j_invalid_token.obj());
-}
-
 void ProfileSyncServiceAndroid::NudgeSyncer(JNIEnv* env,
                                             jobject obj,
                                             jstring objectId,
@@ -625,6 +482,17 @@
                         ConvertJavaStringToUTF8(env, state));
 }
 
+void ProfileSyncServiceAndroid::NudgeSyncerForAllTypes(JNIEnv* env,
+                                                       jobject obj) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  syncer::ObjectIdInvalidationMap object_ids_with_states;
+  content::NotificationService::current()->Notify(
+        chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
+        content::Source<Profile>(profile_),
+        content::Details<const syncer::ObjectIdInvalidationMap>(
+            &object_ids_with_states));
+}
+
 // static
 ProfileSyncServiceAndroid*
     ProfileSyncServiceAndroid::GetProfileSyncServiceAndroid() {
diff --git a/chrome/browser/sync/profile_sync_service_android.h b/chrome/browser/sync/profile_sync_service_android.h
index b8027b4..a269e9d 100644
--- a/chrome/browser/sync/profile_sync_service_android.h
+++ b/chrome/browser/sync/profile_sync_service_android.h
@@ -14,8 +14,8 @@
 #include "base/time/time.h"
 #include "chrome/browser/sync/profile_sync_service_observer.h"
 #include "chrome/browser/sync/sync_prefs.h"
+#include "google/cacheinvalidation/include/types.h"
 #include "google_apis/gaia/google_service_auth_error.h"
-#include "sync/internal_api/public/base/model_type.h"
 
 class Profile;
 class ProfileSyncService;
@@ -27,15 +27,6 @@
 // This class should only be accessed from the UI thread.
 class ProfileSyncServiceAndroid : public ProfileSyncServiceObserver {
  public:
-  // Callback from FetchOAuth2Token.
-  // Arguments:
-  // - the error, or NONE if the token fetch was successful.
-  // - the OAuth2 access token.
-  // - the expiry time of the token (may be null, indicating that the expiry
-  //   time is unknown.
-  typedef base::Callback<void(
-      const GoogleServiceAuthError&,const std::string&,const base::Time&)>
-          FetchOAuth2TokenCallback;
 
   ProfileSyncServiceAndroid(JNIEnv* env, jobject obj);
 
@@ -50,6 +41,10 @@
                    jlong version,
                    jstring payload);
 
+  // Called from Java when we need to nudge native syncer but have lost state on
+  // which types have changed.
+  void NudgeSyncerForAllTypes(JNIEnv* env, jobject obj);
+
   void TokenAvailable(JNIEnv*, jobject, jstring username, jstring auth_token);
 
   // Called from Java when the user manually enables sync
@@ -58,12 +53,8 @@
   // Called from Java when the user manually disables sync
   void DisableSync(JNIEnv* env, jobject obj);
 
-  // Called from Java when the user signs in to Chrome. Starts up sync, and
-  // if auth credentials are required, uses the passed |auth_token|. If
-  // |auth_token| is empty, a new |auth_token| is requested from the UI thread
-  // via a call to InvalidateAuthToken().
-  void SignInSync(JNIEnv* env, jobject obj, jstring username,
-                  jstring auth_token);
+  // Called from Java when the user signs in to Chrome. Starts up sync.
+  void SignInSync(JNIEnv* env, jobject obj);
 
   // Called from Java when the user signs out of Chrome
   void SignOutSync(JNIEnv* env, jobject obj);
@@ -199,25 +190,6 @@
   // (GoogleServiceAuthError.State).
   jint GetAuthError(JNIEnv* env, jobject obj);
 
-  // Called by native to invalidate an OAuth2 token, e.g. after a 401 response
-  // from the server. This should be done before fetching a new token.
-  void InvalidateOAuth2Token(const std::string& scope,
-                             const std::string& invalid_auth_token);
-
-  // Called by native when an OAuth2 token is required. |invalid_auth_token|
-  // is an old auth token to be invalidated (may be empty). |callback| will be
-  // invoked asynchronously after a new token has been fetched.
-  void FetchOAuth2Token(const std::string& scope,
-                        const FetchOAuth2TokenCallback& callback);
-
-  // Called from Java when fetching of an OAuth2 token is finished. The
-  // |authToken| param is only valid when |result| is true.
-  void OAuth2TokenFetched(JNIEnv* env,
-                          jobject obj,
-                          int callback,
-                          jstring auth_token,
-                          jboolean result);
-
   // ProfileSyncServiceObserver:
   virtual void OnStateChanged() OVERRIDE;
 
@@ -227,10 +199,13 @@
   static bool Register(JNIEnv* env);
 
  private:
+  typedef std::map<invalidation::ObjectId,
+                   int64,
+                   syncer::ObjectIdLessThan> ObjectIdVersionMap;
+
   virtual ~ProfileSyncServiceAndroid();
   // Remove observers to profile sync service.
   void RemoveObserver();
-  void InvalidateAuthToken();
   // Called from Java when we need to nudge native syncer. The |objectId|,
   // |version| and |payload| values should come from an invalidation.
   void SendNudgeNotification(const std::string& str_object_id,
@@ -249,7 +224,7 @@
   // The invalidation API spec allows for the possibility of redundant
   // invalidations, so keep track of the max versions and drop
   // invalidations with old versions.
-  std::map<syncer::ModelType, int64> max_invalidation_versions_;
+  ObjectIdVersionMap max_invalidation_versions_;
 
   DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceAndroid);
 };
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc
index d41da39..a6fb984 100644
--- a/chrome/browser/sync/profile_sync_service_factory.cc
+++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/sessions/tab_restore_service_factory.h"
 #include "chrome/browser/signin/about_signin_internals_factory.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/sync/profile_sync_components_factory_impl.h"
@@ -52,20 +53,21 @@
   // The ProfileSyncService depends on various SyncableServices being around
   // when it is shut down.  Specify those dependencies here to build the proper
   // destruction order.
-  DependsOn(TemplateURLServiceFactory::GetInstance());
+  DependsOn(AboutSigninInternalsFactory::GetInstance());
   DependsOn(autofill::PersonalDataManagerFactory::GetInstance());
+  DependsOn(BookmarkModelFactory::GetInstance());
+  DependsOn(extensions::ExtensionSystemFactory::GetInstance());
+  DependsOn(GlobalErrorServiceFactory::GetInstance());
+  DependsOn(HistoryServiceFactory::GetInstance());
+  DependsOn(invalidation::InvalidationServiceFactory::GetInstance());
+  DependsOn(PasswordStoreFactory::GetInstance());
+  DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
+  DependsOn(SigninManagerFactory::GetInstance());
+  DependsOn(TemplateURLServiceFactory::GetInstance());
 #if defined(ENABLE_THEMES)
   DependsOn(ThemeServiceFactory::GetInstance());
 #endif
-  DependsOn(GlobalErrorServiceFactory::GetInstance());
-  DependsOn(SigninManagerFactory::GetInstance());
-  DependsOn(PasswordStoreFactory::GetInstance());
-  DependsOn(extensions::ExtensionSystemFactory::GetInstance());
   DependsOn(WebDataServiceFactory::GetInstance());
-  DependsOn(HistoryServiceFactory::GetInstance());
-  DependsOn(BookmarkModelFactory::GetInstance());
-  DependsOn(AboutSigninInternalsFactory::GetInstance());
-  DependsOn(invalidation::InvalidationServiceFactory::GetInstance());
 
   // The following have not been converted to BrowserContextKeyedServices yet,
   // and for now they are explicitly destroyed after the
diff --git a/chrome/browser/sync/profile_sync_service_harness.cc b/chrome/browser/sync/profile_sync_service_harness.cc
index 47b7434..b0dc699 100644
--- a/chrome/browser/sync/profile_sync_service_harness.cc
+++ b/chrome/browser/sync/profile_sync_service_harness.cc
@@ -21,6 +21,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/message_loop.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/invalidation/p2p_invalidation_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/signin_manager_base.h"
@@ -29,7 +30,6 @@
 #include "chrome/browser/sync/about_sync_util.h"
 #include "chrome/browser/sync/glue/data_type_controller.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/sync/profile_sync_service_password_unittest.cc b/chrome/browser/sync/profile_sync_service_password_unittest.cc
index 22686b4..b9a3fac 100644
--- a/chrome/browser/sync/profile_sync_service_password_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_password_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/test/test_timeouts.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/invalidation/invalidation_service_factory.h"
 #include "chrome/browser/password_manager/mock_password_store.h"
 #include "chrome/browser/password_manager/password_store.h"
@@ -30,7 +31,6 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/profile_sync_test_util.h"
 #include "chrome/browser/sync/test_profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/profile_mock.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/sync/profile_sync_service_session_unittest.cc b/chrome/browser/sync/profile_sync_service_session_unittest.cc
index c42edc2..ea8447f 100644
--- a/chrome/browser/sync/profile_sync_service_session_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_session_unittest.cc
@@ -10,13 +10,16 @@
 #include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/guid.h"
 #include "base/location.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/invalidation/invalidation_service_factory.h"
+#include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/signin/token_service_factory.h"
@@ -33,13 +36,16 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/profile_sync_test_util.h"
 #include "chrome/browser/sync/test_profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/test/test_browser_thread.h"
 #include "google_apis/gaia/gaia_constants.h"
 #include "sync/internal_api/public/base/model_type.h"
@@ -61,6 +67,7 @@
 using browser_sync::SessionModelAssociator;
 using browser_sync::SyncBackendHost;
 using content::BrowserThread;
+using content::WebContents;
 using syncer::ChangeRecord;
 using testing::_;
 using testing::Return;
@@ -85,7 +92,8 @@
   virtual ~FakeProfileSyncService() {}
 
   virtual scoped_ptr<DeviceInfo> GetLocalDeviceInfo() const OVERRIDE {
-    return scoped_ptr<DeviceInfo>(new DeviceInfo("client_name",
+    return scoped_ptr<DeviceInfo>(new DeviceInfo(base::GenerateGUID(),
+                                                 "client_name",
                                                  std::string(),
                                                  std::string(),
                                                  sync_pb::SyncEnums::TYPE_WIN));
@@ -755,24 +763,26 @@
   ASSERT_TRUE(create_root.success());
 
   std::vector<int64> node_ids;
-  ASSERT_EQ(0U, model_associator_->tab_pool_.capacity());
-  ASSERT_TRUE(model_associator_->tab_pool_.empty());
-  ASSERT_TRUE(model_associator_->tab_pool_.full());
+  ASSERT_EQ(0U, model_associator_->tab_pool_.Capacity());
+  ASSERT_TRUE(model_associator_->tab_pool_.Empty());
+  ASSERT_TRUE(model_associator_->tab_pool_.Full());
   const size_t num_ids = 10;
   for (size_t i = 0; i < num_ids; ++i) {
     int64 id = model_associator_->tab_pool_.GetFreeTabNode();
     ASSERT_GT(id, -1);
     node_ids.push_back(id);
+    // Associate with a tab node.
+    model_associator_->tab_pool_.AssociateTabNode(id, i + 1);
   }
-  ASSERT_EQ(num_ids, model_associator_->tab_pool_.capacity());
-  ASSERT_TRUE(model_associator_->tab_pool_.empty());
-  ASSERT_FALSE(model_associator_->tab_pool_.full());
+  ASSERT_EQ(num_ids, model_associator_->tab_pool_.Capacity());
+  ASSERT_TRUE(model_associator_->tab_pool_.Empty());
+  ASSERT_FALSE(model_associator_->tab_pool_.Full());
   for (size_t i = 0; i < num_ids; ++i) {
     model_associator_->tab_pool_.FreeTabNode(node_ids[i]);
   }
-  ASSERT_EQ(num_ids, model_associator_->tab_pool_.capacity());
-  ASSERT_FALSE(model_associator_->tab_pool_.empty());
-  ASSERT_TRUE(model_associator_->tab_pool_.full());
+  ASSERT_EQ(num_ids, model_associator_->tab_pool_.Capacity());
+  ASSERT_FALSE(model_associator_->tab_pool_.Empty());
+  ASSERT_TRUE(model_associator_->tab_pool_.Full());
 }
 
 // TODO(jhorwich): Re-enable when crbug.com/121487 addressed
@@ -782,29 +792,34 @@
   ASSERT_TRUE(create_root.success());
 
   const size_t num_starting_nodes = 3;
+  SessionID session_id;
   for (size_t i = 0; i < num_starting_nodes; ++i) {
-    model_associator_->tab_pool_.AddTabNode(i);
+    session_id.set_id(i + 1);
+    model_associator_->tab_pool_.AddTabNode(i + 1, session_id, i);
   }
 
+  model_associator_->tab_pool_.FreeUnusedTabNodes(std::set<int64>());
   std::vector<int64> node_ids;
-  ASSERT_EQ(num_starting_nodes, model_associator_->tab_pool_.capacity());
-  ASSERT_FALSE(model_associator_->tab_pool_.empty());
-  ASSERT_TRUE(model_associator_->tab_pool_.full());
+  ASSERT_EQ(num_starting_nodes, model_associator_->tab_pool_.Capacity());
+  ASSERT_FALSE(model_associator_->tab_pool_.Empty());
+  ASSERT_TRUE(model_associator_->tab_pool_.Full());
   const size_t num_ids = 10;
   for (size_t i = 0; i < num_ids; ++i) {
     int64 id = model_associator_->tab_pool_.GetFreeTabNode();
     ASSERT_GT(id, -1);
     node_ids.push_back(id);
+    // Associate with a tab node.
+    model_associator_->tab_pool_.AssociateTabNode(id, i + 1);
   }
-  ASSERT_EQ(num_ids, model_associator_->tab_pool_.capacity());
-  ASSERT_TRUE(model_associator_->tab_pool_.empty());
-  ASSERT_FALSE(model_associator_->tab_pool_.full());
+  ASSERT_EQ(num_ids, model_associator_->tab_pool_.Capacity());
+  ASSERT_TRUE(model_associator_->tab_pool_.Empty());
+  ASSERT_FALSE(model_associator_->tab_pool_.Full());
   for (size_t i = 0; i < num_ids; ++i) {
     model_associator_->tab_pool_.FreeTabNode(node_ids[i]);
   }
-  ASSERT_EQ(num_ids, model_associator_->tab_pool_.capacity());
-  ASSERT_FALSE(model_associator_->tab_pool_.empty());
-  ASSERT_TRUE(model_associator_->tab_pool_.full());
+  ASSERT_EQ(num_ids, model_associator_->tab_pool_.Capacity());
+  ASSERT_FALSE(model_associator_->tab_pool_.Empty());
+  ASSERT_TRUE(model_associator_->tab_pool_.Full());
 }
 
 // Write a foreign session to a node, and then delete it.
@@ -1168,7 +1183,7 @@
   ASSERT_FALSE(error.IsSet());
   {
     // Delete the first sync tab node.
-    std::string tab_tag = TabNodePool::TabIdToTag(local_tag, 0);
+    std::string tab_tag = TabNodePool::TabIdToTag(local_tag, 1);
 
     syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
     syncer::ReadNode root(&trans);
@@ -1257,4 +1272,60 @@
   ASSERT_FALSE(error.IsSet());
 }
 
+TEST_F(ProfileSyncServiceSessionTest, CheckPrerenderedWebContentsSwap) {
+  AddTab(browser(), GURL("http://foo1"));
+  NavigateAndCommitActiveTab(GURL("http://foo2"));
+  CreateRootHelper create_root(this);
+  // Test setup.
+  ASSERT_TRUE(StartSyncService(create_root.callback(), false));
+
+  syncer::SyncError error;
+  // Initial association.
+  EXPECT_TRUE(model_associator_->AssociateWindows(true, &error));
+  ASSERT_FALSE(error.IsSet());
+
+  // To simulate WebContents swap during prerendering, create new WebContents
+  // and swap with old WebContents.
+  content::WebContents* old_web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  // Create new WebContents, with the required tab helpers.
+  WebContents* new_web_contents = WebContents::CreateWithSessionStorage(
+      WebContents::CreateParams(profile()),
+      old_web_contents->GetController().GetSessionStorageNamespaceMap());
+  SessionTabHelper::CreateForWebContents(new_web_contents);
+  TabContentsSyncedTabDelegate::CreateForWebContents(new_web_contents);
+  new_web_contents->GetController()
+      .CopyStateFrom(old_web_contents->GetController());
+
+  // Swap the WebContents.
+  int index =
+      browser()->tab_strip_model()->GetIndexOfWebContents(old_web_contents);
+  browser()->tab_strip_model()->ReplaceWebContentsAt(index, new_web_contents);
+
+  EXPECT_TRUE(model_associator_->AssociateWindows(true, &error));
+  ASSERT_FALSE(error.IsSet());
+  // Navigate away.
+  NavigateAndCommitActiveTab(GURL("http://bar2"));
+  EXPECT_TRUE(model_associator_->AssociateWindows(true, &error));
+  ASSERT_FALSE(error.IsSet());
+
+  // Delete old WebContents. This should not crash.
+  delete old_web_contents;
+  EXPECT_TRUE(model_associator_->AssociateWindows(true, &error));
+  ASSERT_FALSE(error.IsSet());
+
+  // Try more navigations to make sure everything if fine.
+  NavigateAndCommitActiveTab(GURL("http://bar3"));
+  EXPECT_TRUE(model_associator_->AssociateWindows(true, &error));
+  ASSERT_FALSE(error.IsSet());
+
+  AddTab(browser(), GURL("http://bar4"));
+  EXPECT_TRUE(model_associator_->AssociateWindows(true, &error));
+  ASSERT_FALSE(error.IsSet());
+  NavigateAndCommitActiveTab(GURL("http://bar5"));
+  EXPECT_TRUE(model_associator_->AssociateWindows(true, &error));
+  ASSERT_FALSE(error.IsSet());
+}
+
 }  // namespace browser_sync
diff --git a/chrome/browser/sync/profile_sync_service_startup_unittest.cc b/chrome/browser/sync/profile_sync_service_startup_unittest.cc
index dc58aa8..18a0a72 100644
--- a/chrome/browser/sync/profile_sync_service_startup_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_startup_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/signin/fake_signin_manager.h"
 #include "chrome/browser/signin/oauth2_token_service.h"
 #include "chrome/browser/signin/profile_oauth2_token_service.h"
@@ -22,7 +23,6 @@
 #include "chrome/browser/sync/profile_sync_test_util.h"
 #include "chrome/browser/sync/sync_prefs.h"
 #include "chrome/browser/sync/test_profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc b/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc
index aedffb0..e933442 100644
--- a/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_db_task.h"
 #include "chrome/browser/history/history_notifications.h"
@@ -37,7 +38,6 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/profile_sync_test_util.h"
 #include "chrome/browser/sync/test_profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/profile_mock.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/browser_context_keyed_service/refcounted_browser_context_keyed_service.h"
diff --git a/chrome/browser/sync/profile_sync_service_unittest.cc b/chrome/browser/sync/profile_sync_service_unittest.cc
index 6e7bbe7..c257449 100644
--- a/chrome/browser/sync/profile_sync_service_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_unittest.cc
@@ -63,6 +63,8 @@
     profile->CreateRequestContext();
     invalidation::InvalidationServiceFactory::GetInstance()->
         SetBuildOnlyFakeInvalidatorsForTest(true);
+    ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
+        profile.get(), FakeOAuth2TokenService::BuildTokenService);
   }
 
   void TearDown() {
@@ -126,8 +128,6 @@
   }
 
   void IssueTestTokens() {
-    ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
-        profile.get(), FakeOAuth2TokenService::BuildTokenService);
     TokenService* token_service =
         TokenServiceFactory::GetForProfile(profile.get());
     token_service->IssueAuthTokenForTest(
@@ -433,11 +433,11 @@
   harness_.service.reset();
 
   // This file should have been deleted when the whole directory was nuked.
-  ASSERT_FALSE(file_util::PathExists(sync_file3));
-  ASSERT_FALSE(file_util::PathExists(sync_file1));
+  ASSERT_FALSE(base::PathExists(sync_file3));
+  ASSERT_FALSE(base::PathExists(sync_file1));
 
   // This will still exist, but the text should have changed.
-  ASSERT_TRUE(file_util::PathExists(sync_file2));
+  ASSERT_TRUE(base::PathExists(sync_file2));
   std::string file2text;
   ASSERT_TRUE(file_util::ReadFileToString(sync_file2, &file2text));
   ASSERT_NE(file2text.compare(nonsense2), 0);
diff --git a/chrome/browser/sync/sync_prefs.cc b/chrome/browser/sync/sync_prefs.cc
index 66fd680..a36d8b9 100644
--- a/chrome/browser/sync/sync_prefs.cc
+++ b/chrome/browser/sync/sync_prefs.cc
@@ -11,9 +11,9 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_io_data.h"
 #include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -45,8 +45,8 @@
 }
 
 // static
-void SyncPrefs::RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
-  // TODO(joi): Remove |prefs| parameter.
+void SyncPrefs::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kSyncHasSetupCompleted,
       false,
@@ -111,12 +111,6 @@
       std::string(),
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 
-  // Keeps track whether server experiments have been switched on for that user.
-  registry->RegisterBooleanPref(
-      prefs::kSyncFaviconsEnabled,
-      false,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-
   // We will start prompting people about new data types after the launch of
   // SESSIONS - all previously launched data types are treated as if they are
   // already acknowledged.
diff --git a/chrome/browser/sync/sync_prefs.h b/chrome/browser/sync/sync_prefs.h
index 21ae4e8..2be501a 100644
--- a/chrome/browser/sync/sync_prefs.h
+++ b/chrome/browser/sync/sync_prefs.h
@@ -57,7 +57,7 @@
 
   virtual ~SyncPrefs();
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   void AddSyncPrefObserver(SyncPrefObserver* sync_pref_observer);
   void RemoveSyncPrefObserver(SyncPrefObserver* sync_pref_observer);
diff --git a/chrome/browser/sync/sync_prefs_unittest.cc b/chrome/browser/sync/sync_prefs_unittest.cc
index 2320726..c6e9a8e 100644
--- a/chrome/browser/sync/sync_prefs_unittest.cc
+++ b/chrome/browser/sync/sync_prefs_unittest.cc
@@ -24,7 +24,7 @@
 class SyncPrefsTest : public testing::Test {
  protected:
   virtual void SetUp() OVERRIDE {
-    SyncPrefs::RegisterUserPrefs(pref_service_.registry());
+    SyncPrefs::RegisterProfilePrefs(pref_service_.registry());
   }
 
   TestingPrefServiceSyncable pref_service_;
diff --git a/chrome/browser/sync/sync_startup_tracker_unittest.cc b/chrome/browser/sync/sync_startup_tracker_unittest.cc
index 6511f43..a6d5de9 100644
--- a/chrome/browser/sync/sync_startup_tracker_unittest.cc
+++ b/chrome/browser/sync/sync_startup_tracker_unittest.cc
@@ -6,6 +6,7 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/profile_sync_service_mock.h"
 #include "chrome/browser/sync/sync_startup_tracker.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -37,12 +38,15 @@
         ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
             profile_.get(),
             ProfileSyncServiceMock::BuildMockProfileSyncService));
-    mock_pss_->Initialize();
 
     // Make gmock not spam the output with information about these uninteresting
     // calls.
     EXPECT_CALL(*mock_pss_, AddObserver(_)).Times(AnyNumber());
     EXPECT_CALL(*mock_pss_, RemoveObserver(_)).Times(AnyNumber());
+    EXPECT_CALL(*mock_pss_, GetAuthError()).
+        WillRepeatedly(ReturnRef(no_error_));
+
+    mock_pss_->Initialize();
   }
 
   virtual void TearDown() OVERRIDE {
@@ -59,6 +63,7 @@
         .WillRepeatedly(Return(true));
   }
 
+  content::TestBrowserThreadBundle thread_bundle_;
   GoogleServiceAuthError no_error_;
   scoped_ptr<TestingProfile> profile_;
   ProfileSyncServiceMock* mock_pss_;
diff --git a/chrome/browser/sync/sync_ui_util.cc b/chrome/browser/sync/sync_ui_util.cc
index 645bc4c..3eea19e 100644
--- a/chrome/browser/sync/sync_ui_util.cc
+++ b/chrome/browser/sync/sync_ui_util.cc
@@ -151,11 +151,13 @@
     }
 
     // No auth in progress check for an auth error.
-    AuthError auth_error = signin.signin_global_error()->GetLastAuthError();
+    AuthError auth_error =
+          SigninGlobalError::GetForProfile(service->profile())->
+              GetLastAuthError();
     if (auth_error.state() != AuthError::NONE) {
       if (status_label && link_label)
         signin_ui_util::GetStatusLabelsForAuthError(
-            signin, status_label, link_label);
+            service->profile(), signin, status_label, link_label);
       return SYNC_ERROR;
     }
 
@@ -215,7 +217,9 @@
       result_type = PRE_SYNCED;
       ProfileSyncService::Status status;
       service->QueryDetailedSyncStatus(&status);
-      AuthError auth_error = signin.signin_global_error()->GetLastAuthError();
+      AuthError auth_error =
+          SigninGlobalError::GetForProfile(
+              service->profile())->GetLastAuthError();
       if (status_label) {
         status_label->assign(
             l10n_util::GetStringUTF16(IDS_SYNC_NTP_SETUP_IN_PROGRESS));
@@ -230,7 +234,7 @@
         if (status_label && link_label) {
           status_label->clear();
           signin_ui_util::GetStatusLabelsForAuthError(
-              signin, status_label, link_label);
+              service->profile(), signin, status_label, link_label);
         }
         result_type = SYNC_ERROR;
       }
diff --git a/chrome/browser/sync/sync_ui_util_unittest.cc b/chrome/browser/sync/sync_ui_util_unittest.cc
index 00d0073..7246f8f 100644
--- a/chrome/browser/sync/sync_ui_util_unittest.cc
+++ b/chrome/browser/sync/sync_ui_util_unittest.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/sync/profile_sync_service_mock.h"
 #include "chrome/browser/sync/sync_ui_util.h"
 #include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "grit/generated_resources.h"
 #include "testing/gmock/include/gmock/gmock-actions.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -66,11 +67,14 @@
 } // namespace
 
 
+class SyncUIUtilTest : public testing::Test {
+ private:
+  content::TestBrowserThreadBundle thread_bundle_;
+};
+
 // Test that GetStatusLabelsForSyncGlobalError returns an error if a
 // passphrase is required.
-TEST(SyncUIUtilTest, PassphraseGlobalError) {
-  base::MessageLoopForUI message_loop;
-  content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
+TEST_F(SyncUIUtilTest, PassphraseGlobalError) {
   scoped_ptr<Profile> profile(
       ProfileSyncServiceMock::MakeSignedInTestingProfile());
   NiceMock<ProfileSyncServiceMock> service(profile.get());
@@ -88,9 +92,7 @@
 
 // Test that GetStatusLabelsForSyncGlobalError returns an error if a
 // passphrase is required and not for auth errors.
-TEST(SyncUIUtilTest, AuthAndPassphraseGlobalError) {
-  base::MessageLoopForUI message_loop;
-  content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
+TEST_F(SyncUIUtilTest, AuthAndPassphraseGlobalError) {
   scoped_ptr<Profile> profile(
       ProfileSyncServiceMock::MakeSignedInTestingProfile());
   NiceMock<ProfileSyncServiceMock> service(profile.get());
@@ -120,9 +122,7 @@
 
 // Test that GetStatusLabelsForSyncGlobalError does not indicate errors for
 // auth errors (these are reported through SigninGlobalError).
-TEST(SyncUIUtilTest, AuthStateGlobalError) {
-  base::MessageLoopForUI message_loop;
-  content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
+TEST_F(SyncUIUtilTest, AuthStateGlobalError) {
   scoped_ptr<Profile> profile(
       ProfileSyncServiceMock::MakeSignedInTestingProfile());
   NiceMock<ProfileSyncServiceMock> service(profile.get());
@@ -319,15 +319,18 @@
 // This test ensures that a each distinctive ProfileSyncService statuses
 // will return a unique combination of status and link messages from
 // GetStatusLabels().
-TEST(SyncUIUtilTest, DistinctCasesReportUniqueMessageSets) {
+TEST_F(SyncUIUtilTest, DistinctCasesReportUniqueMessageSets) {
   std::set<string16> messages;
   for (int idx = 0; idx != NUMBER_OF_STATUS_CASES; idx++) {
     scoped_ptr<Profile> profile(new TestingProfile());
     ProfileSyncServiceMock service(profile.get());
+    GoogleServiceAuthError error = GoogleServiceAuthError::AuthErrorNone();
+    EXPECT_CALL(service, GetAuthError()).WillRepeatedly(ReturnRef(error));
     FakeSigninManagerForSyncUIUtilTest signin(profile.get());
     signin.SetAuthenticatedUsername("test_user@test.com");
     scoped_ptr<FakeAuthStatusProvider> provider(
-        new FakeAuthStatusProvider(signin.signin_global_error()));
+        new FakeAuthStatusProvider(
+            SigninGlobalError::GetForProfile(profile.get())));
     GetDistinctCase(service, &signin, provider.get(), idx);
     string16 status_label;
     string16 link_label;
@@ -348,6 +351,7 @@
     messages.insert(combined_label);
     testing::Mock::VerifyAndClearExpectations(&service);
     testing::Mock::VerifyAndClearExpectations(&signin);
+    EXPECT_CALL(service, GetAuthError()).WillRepeatedly(ReturnRef(error));
     provider.reset();
     signin.Shutdown();
   }
@@ -355,15 +359,18 @@
 
 // This test ensures that the html_links parameter on GetStatusLabels() is
 // honored.
-TEST(SyncUIUtilTest, HtmlNotIncludedInStatusIfNotRequested) {
+TEST_F(SyncUIUtilTest, HtmlNotIncludedInStatusIfNotRequested) {
   for (int idx = 0; idx != NUMBER_OF_STATUS_CASES; idx++) {
     scoped_ptr<Profile> profile(
         ProfileSyncServiceMock::MakeSignedInTestingProfile());
     ProfileSyncServiceMock service(profile.get());
+    GoogleServiceAuthError error = GoogleServiceAuthError::AuthErrorNone();
+    EXPECT_CALL(service, GetAuthError()).WillRepeatedly(ReturnRef(error));
     FakeSigninManagerForSyncUIUtilTest signin(profile.get());
     signin.SetAuthenticatedUsername("test_user@test.com");
     scoped_ptr<FakeAuthStatusProvider> provider(
-        new FakeAuthStatusProvider(signin.signin_global_error()));
+        new FakeAuthStatusProvider(
+            SigninGlobalError::GetForProfile(profile.get())));
     GetDistinctCase(service, &signin, provider.get(), idx);
     string16 status_label;
     string16 link_label;
@@ -381,6 +388,7 @@
               string16::npos);
     testing::Mock::VerifyAndClearExpectations(&service);
     testing::Mock::VerifyAndClearExpectations(&signin);
+    EXPECT_CALL(service, GetAuthError()).WillRepeatedly(ReturnRef(error));
     provider.reset();
     signin.Shutdown();
   }
diff --git a/chrome/browser/sync/test/integration/autofill_helper.cc b/chrome/browser/sync/test/integration/autofill_helper.cc
index bc9bf3e..43359c6 100644
--- a/chrome/browser/sync/test/integration/autofill_helper.cc
+++ b/chrome/browser/sync/test/integration/autofill_helper.cc
@@ -5,12 +5,12 @@
 #include "chrome/browser/sync/test/integration/autofill_helper.h"
 
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_test_util.h"
 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "components/autofill/core/browser/autofill_common_test.h"
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/autofill_type.h"
diff --git a/chrome/browser/sync/test/integration/enable_disable_test.cc b/chrome/browser/sync/test/integration/enable_disable_test.cc
index 9e902c7..45a2cea 100644
--- a/chrome/browser/sync/test/integration/enable_disable_test.cc
+++ b/chrome/browser/sync/test/integration/enable_disable_test.cc
@@ -59,6 +59,8 @@
     // AUTOFILL_PROFILE is lumped together with AUTOFILL.
     // SESSIONS is lumped together with PROXY_TABS and
     // HISTORY_DELETE_DIRECTIVES.
+    // Favicons are lumped together with PROXY_TABS and
+    // HISTORY_DELETE_DIRECTIVES.
     if (it.Get() == syncer::AUTOFILL_PROFILE || it.Get() == syncer::SESSIONS) {
       continue;
     }
@@ -118,10 +120,14 @@
     // SESSIONS is lumped together with PROXY_TABS and TYPED_URLS.
     // HISTORY_DELETE_DIRECTIVES is lumped together with TYPED_URLS.
     // PRIORITY_PREFERENCES is lumped together with PREFERENCES.
+    // Favicons are lumped together with PROXY_TABS and
+    // HISTORY_DELETE_DIRECTIVES.
     if (it.Get() == syncer::AUTOFILL_PROFILE ||
         it.Get() == syncer::SESSIONS ||
         it.Get() == syncer::HISTORY_DELETE_DIRECTIVES ||
-        it.Get() == syncer::PRIORITY_PREFERENCES) {
+        it.Get() == syncer::PRIORITY_PREFERENCES ||
+        it.Get() == syncer::FAVICON_IMAGES ||
+        it.Get() == syncer::FAVICON_TRACKING) {
       continue;
     }
 
diff --git a/chrome/browser/sync/test/integration/sync_extension_helper.cc b/chrome/browser/sync/test/integration/sync_extension_helper.cc
index 151020b..62204bf 100644
--- a/chrome/browser/sync/test/integration/sync_extension_helper.cc
+++ b/chrome/browser/sync/test/integration/sync_extension_helper.cc
@@ -305,7 +305,7 @@
   }
   const base::FilePath sub_dir = base::FilePath().AppendASCII(name);
   base::FilePath extension_dir;
-  if (!file_util::PathExists(base_dir) &&
+  if (!base::PathExists(base_dir) &&
       !file_util::CreateDirectory(base_dir)) {
     ADD_FAILURE();
     return NULL;
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index 8d75d64..02fe845 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -220,7 +220,7 @@
   PathService::Get(chrome::DIR_USER_DATA, &path);
   path = path.Append(name);
 
-  if (!file_util::PathExists(path))
+  if (!base::PathExists(path))
     CHECK(file_util::CreateDirectory(path));
 
   Profile* profile =
diff --git a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc
index 8ed733c5..2acfb10 100644
--- a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc
@@ -163,16 +163,6 @@
   ASSERT_TRUE(BooleanPrefMatches(prefs::kShowBookmarkBar));
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest, kEnableInstant) {
-  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
-  ASSERT_TRUE(BooleanPrefMatches(prefs::kSearchInstantEnabled));
-
-  ChangeBooleanPref(0, prefs::kSearchInstantEnabled);
-
-  ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
-  ASSERT_TRUE(BooleanPrefMatches(prefs::kSearchInstantEnabled));
-}
-
 // TCM ID - 3611311.
 IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest, kCheckDefaultBrowser) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
diff --git a/chrome/browser/sync/test_profile_sync_service.cc b/chrome/browser/sync/test_profile_sync_service.cc
index dac67f2..2fefd29 100644
--- a/chrome/browser/sync/test_profile_sync_service.cc
+++ b/chrome/browser/sync/test_profile_sync_service.cc
@@ -4,13 +4,13 @@
 
 #include "chrome/browser/sync/test_profile_sync_service.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/sync/glue/data_type_controller.h"
 #include "chrome/browser/sync/glue/sync_backend_host.h"
 #include "chrome/browser/sync/profile_sync_components_factory.h"
 #include "chrome/browser/sync/test/test_http_bridge_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "sync/internal_api/public/sessions/sync_session_snapshot.h"
 #include "sync/internal_api/public/test/test_user_share.h"
 #include "sync/internal_api/public/user_share.h"
diff --git a/chrome/browser/sync_file_system/drive_backend/api_util.cc b/chrome/browser/sync_file_system/drive_backend/api_util.cc
index e131b82..84cb34a 100644
--- a/chrome/browser/sync_file_system/drive_backend/api_util.cc
+++ b/chrome/browser/sync_file_system/drive_backend/api_util.cc
@@ -19,7 +19,7 @@
 #include "chrome/browser/drive/gdata_wapi_service.h"
 #include "chrome/browser/google_apis/drive_api_parser.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_util.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h"
 #include "chrome/browser/sync_file_system/logger.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/sync_file_system/drive_backend/api_util_unittest.cc b/chrome/browser/sync_file_system/drive_backend/api_util_unittest.cc
index af75d06..1407ab9 100644
--- a/chrome/browser/sync_file_system/drive_backend/api_util_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/api_util_unittest.cc
@@ -14,7 +14,8 @@
 #include "chrome/browser/google_apis/drive_api_parser.h"
 #include "chrome/browser/google_apis/gdata_errorcode.h"
 #include "chrome/browser/google_apis/test_util.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_util.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h"
+#include "chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -40,9 +41,16 @@
 const char kOrigin[] = "chrome-extension://example";
 const char kOriginDirectoryName[] = "example";
 
-void DidRemoveResourceFromDirectory(GDataErrorCode error) {
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
-}
+struct Output {
+  GDataErrorCode error;
+  std::string resource_id;
+  std::string file_md5;
+  int64 largest_changestamp;
+
+  Output() : error(google_apis::GDATA_OTHER_ERROR),
+             largest_changestamp(-1) {
+  }
+};
 
 void DidAddFileOrDirectoryForMakingConflict(GDataErrorCode error,
                                             scoped_ptr<ResourceEntry> entry) {
@@ -50,27 +58,6 @@
   ASSERT_TRUE(entry);
 }
 
-void DidAddNewDirectory(std::string* resource_id_out,
-                        GDataErrorCode error,
-                        scoped_ptr<ResourceEntry> entry) {
-  ASSERT_TRUE(resource_id_out);
-  ASSERT_EQ(google_apis::HTTP_CREATED, error);
-  ASSERT_TRUE(entry);
-  *resource_id_out = entry->resource_id();
-}
-
-void DidAddNewFile(std::string* resource_id_out,
-                   std::string* file_md5_out,
-                   GDataErrorCode error,
-                   scoped_ptr<ResourceEntry> entry) {
-  ASSERT_TRUE(resource_id_out);
-  ASSERT_TRUE(file_md5_out);
-  ASSERT_EQ(google_apis::HTTP_CREATED, error);
-  ASSERT_TRUE(entry);
-  *resource_id_out = entry->resource_id();
-  *file_md5_out = entry->file_md5();
-}
-
 void DidAddFileForUploadNew(
     const UploadCompletionCallback& callback,
     GDataErrorCode error,
@@ -99,45 +86,10 @@
                  base::Passed(&entry)));
 }
 
-void VerifyTitleUniqueness(const tracked_objects::Location& from_here,
-                           const std::string& resource_id,
-                           google_apis::DriveEntryKind kind,
-                           GDataErrorCode error,
-                           scoped_ptr<ResourceList> resource_list) {
-  std::string location(" failed at " + from_here.ToString());
-  ASSERT_FALSE(resource_id.empty()) << location;
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error) << location;
-  ASSERT_TRUE(resource_list) << location;
-
-  const ScopedVector<ResourceEntry>& entries = resource_list->entries();
-  ASSERT_EQ(1u, entries.size());
-  EXPECT_EQ(resource_id, entries[0]->resource_id());
-  switch (kind) {
-    case google_apis::ENTRY_KIND_FOLDER:
-      EXPECT_TRUE(entries[0]->is_folder()) << location;
-      return;
-    case google_apis::ENTRY_KIND_FILE:
-      EXPECT_TRUE(entries[0]->is_file()) << location;
-      return;
-    default:
-      NOTREACHED() << "Unexpected DriveEntryKind: " << kind << location;
-      return;
-  }
-}
-
-void VerifyFileDeletion(const tracked_objects::Location& from_here,
-                        GDataErrorCode error,
-                        scoped_ptr<ResourceList> resource_list) {
-  std::string location(" failed at " + from_here.ToString());
-  ASSERT_EQ(google_apis::HTTP_SUCCESS, error) << location;
-  ASSERT_TRUE(resource_list) << location;
-  EXPECT_TRUE(resource_list->entries().empty()) << location;
-}
-
 class FakeDriveServiceWrapper : public FakeDriveService {
  public:
-  FakeDriveServiceWrapper() : make_directory_conflict_(false) {};
-  virtual ~FakeDriveServiceWrapper() {};
+  FakeDriveServiceWrapper() : make_directory_conflict_(false) {}
+  virtual ~FakeDriveServiceWrapper() {}
 
   // DriveServiceInterface overrides.
   virtual google_apis::CancelCallback AddNewDirectory(
@@ -259,6 +211,9 @@
     fake_drive_service_ = new FakeDriveServiceWrapper;
     fake_drive_uploader_ = new FakeDriveUploader(fake_drive_service_);
 
+    fake_drive_helper_.reset(new FakeDriveServiceHelper(
+        fake_drive_service_, fake_drive_uploader_));
+
     api_util_ = APIUtil::CreateForTesting(
         &profile_,
         scoped_ptr<DriveServiceInterface>(fake_drive_service_),
@@ -273,55 +228,68 @@
   }
 
  protected:
-  void SetUpSyncRootDirectory() {
-    fake_drive_service()->AddNewDirectory(
-        fake_drive_service_->GetRootResourceId(),
-        APIUtil::GetSyncRootDirectoryName(),
-        base::Bind(&DidAddNewDirectory, &sync_root_resource_id_));
-    base::MessageLoop::current()->RunUntilIdle();
-
-    ASSERT_TRUE(!sync_root_resource_id_.empty());
-    fake_drive_service()->RemoveResourceFromDirectory(
-        fake_drive_service_->GetRootResourceId(),
-        sync_root_resource_id_,
-        base::Bind(&DidRemoveResourceFromDirectory));
-    base::MessageLoop::current()->RunUntilIdle();
+  std::string SetUpSyncRootDirectory() {
+    std::string sync_root_id;
+    EXPECT_EQ(google_apis::HTTP_CREATED,
+              fake_drive_helper_->AddOrphanedFolder(
+                  APIUtil::GetSyncRootDirectoryName(),
+                  &sync_root_id));
+    return sync_root_id;
   }
 
-  void SetUpOriginRootDirectory() {
-    ASSERT_TRUE(!sync_root_resource_id_.empty());
-    fake_drive_service()->AddNewDirectory(
-        GetSyncRootResourceId(),
-        kOriginDirectoryName,
-        base::Bind(&DidAddNewDirectory, &origin_root_resource_id_));
-    base::MessageLoop::current()->RunUntilIdle();
+  std::string SetUpOriginRootDirectory(const std::string& sync_root_id) {
+    std::string origin_root_id;
+    EXPECT_EQ(google_apis::HTTP_CREATED,
+              fake_drive_helper_->AddFolder(
+                  sync_root_id,
+                  kOriginDirectoryName,
+                  &origin_root_id));
+    return origin_root_id;
   }
 
-  void SetUpFile(const std::string& content_data,
+  void SetUpFile(const std::string& origin_root_id,
+                 const std::string& content_data,
                  const std::string& title,
-                 std::string* resource_id_out,
-                 std::string* file_md5_out) {
-    ASSERT_TRUE(!origin_root_resource_id_.empty());
-    ASSERT_TRUE(resource_id_out);
-    ASSERT_TRUE(file_md5_out);
-    fake_drive_service()->AddNewFile(
-        "text/plain",
-        content_data,
-        origin_root_resource_id_,
-        title,
-        false,  // shared_with_me
-        base::Bind(&DidAddNewFile, resource_id_out, file_md5_out));
-    base::MessageLoop::current()->RunUntilIdle();
+                 scoped_ptr<ResourceEntry>* entry) {
+    ASSERT_TRUE(entry);
+    std::string file_resource_id;
+    EXPECT_EQ(google_apis::HTTP_SUCCESS,
+              fake_drive_helper_->AddFile(
+                  origin_root_id,
+                  title,
+                  content_data,
+                  &file_resource_id));
+    EXPECT_EQ(google_apis::HTTP_SUCCESS,
+              fake_drive_helper_->GetResourceEntry(
+                  file_resource_id,
+                  entry));
   }
 
-  std::string GetSyncRootResourceId() {
-    DCHECK(!sync_root_resource_id_.empty());
-    return sync_root_resource_id_;
+  void LoadAccountMetadata() {
+    fake_drive_service_->LoadAccountMetadataForWapi(
+        "sync_file_system/account_metadata.json");
   }
 
-  std::string GetOriginRootResourceId() {
-    DCHECK(!origin_root_resource_id_.empty());
-    return origin_root_resource_id_;
+  void VerifyTitleUniqueness(const std::string& parent_resource_id,
+                             const std::string& title,
+                             const std::string& resource_id,
+                             google_apis::DriveEntryKind kind) {
+    ScopedVector<ResourceEntry> entries;
+    EXPECT_EQ(google_apis::HTTP_SUCCESS,
+              fake_drive_helper_->SearchByTitle(
+                  parent_resource_id, title, &entries));
+    ASSERT_EQ(1u, entries.size());
+    EXPECT_EQ(resource_id, entries[0]->resource_id());
+    EXPECT_EQ(kind, entries[0]->kind());
+  }
+
+  void VerifyFileDeletion(const std::string& parent_resource_id,
+                          const std::string& title) {
+    ScopedVector<ResourceEntry> entries;
+    EXPECT_EQ(google_apis::HTTP_SUCCESS,
+              fake_drive_helper_->SearchByTitle(
+                  parent_resource_id, title, &entries));
+    EXPECT_TRUE(entries.empty());
   }
 
   APIUtil* api_util() { return api_util_.get(); }
@@ -356,324 +324,254 @@
  private:
   content::TestBrowserThreadBundle thread_bundle_;
 
-  std::string sync_root_resource_id_;
-  std::string origin_root_resource_id_;
-
   TestingProfile profile_;
   scoped_ptr<APIUtil> api_util_;
   FakeDriveServiceWrapper* fake_drive_service_;
   FakeDriveUploader* fake_drive_uploader_;
+  scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
 
   DISALLOW_COPY_AND_ASSIGN(APIUtilTest);
 };
 
-void DidGetResourceID(bool* done_out,
-                      GDataErrorCode* error_out,
-                      std::string* resource_id_out,
+void DidGetResourceID(Output* output,
                       GDataErrorCode error,
                       const std::string& resource_id) {
-  EXPECT_FALSE(*done_out);
-  *done_out = true;
-  *error_out = error;
-  *resource_id_out = resource_id;
+  ASSERT_TRUE(output);
+  output->error = error;
+  output->resource_id = resource_id;
 }
 
-#if !defined(OS_ANDROID)
-
-void DidGetLargestChangeStamp(bool* done_out,
-                              GDataErrorCode* error_out,
-                              int64* largest_changestamp_out,
+void DidGetLargestChangeStamp(Output* output,
                               GDataErrorCode error,
                               int64 largest_changestamp) {
-  EXPECT_FALSE(*done_out);
-  *done_out = true;
-  *error_out = error;
-  *largest_changestamp_out = largest_changestamp;
+  ASSERT_TRUE(output);
+  output->error = error;
+  output->largest_changestamp = largest_changestamp;
 }
 
-void DidGetResourceList(bool* done_out,
-                        GDataErrorCode* error_out,
+void DidGetResourceList(GDataErrorCode* error_out,
                         scoped_ptr<ResourceList>* document_feed_out,
                         GDataErrorCode error,
                         scoped_ptr<ResourceList> document_feed) {
-  EXPECT_FALSE(*done_out);
-  *done_out = true;
+  ASSERT_TRUE(error_out);
+  ASSERT_TRUE(document_feed_out);
   *error_out = error;
   *document_feed_out = document_feed.Pass();
 }
 
-void DidDownloadFile(bool* done_out,
-                     std::string* expected_file_md5_out,
-                     GDataErrorCode* error_out,
+void DidDownloadFile(Output* output,
                      GDataErrorCode error,
                      const std::string& file_md5,
                      int64 file_size,
                      const base::Time& updated_time) {
-  EXPECT_FALSE(*done_out);
-  *done_out = true;
-  *error_out = error;
-  *expected_file_md5_out = file_md5;
+  ASSERT_TRUE(output);
+  output->error = error;
+  output->file_md5 = file_md5;
 }
 
-void DidUploadFile(bool* done_out,
-                   GDataErrorCode* error_out,
-                   std::string* resource_id_out,
+void DidUploadFile(Output* output,
                    GDataErrorCode error,
                    const std::string& resource_id,
                    const std::string& file_md5) {
-  EXPECT_FALSE(*done_out);
-  *done_out = true;
-  *error_out = error;
-  *resource_id_out = resource_id;
+  ASSERT_TRUE(output);
+  output->error = error;
+  output->resource_id = resource_id;
+  output->file_md5 = file_md5;
 }
 
-void DidDeleteFile(bool* done_out,
-                   GDataErrorCode* error_out,
+void DidDeleteFile(GDataErrorCode* error_out,
                    GDataErrorCode error) {
-  EXPECT_FALSE(*done_out);
-  *done_out = true;
+  ASSERT_TRUE(error);
   *error_out = error;
 }
 
 void APIUtilTest::TestGetSyncRoot() {
-  fake_drive_service()->LoadAccountMetadataForWapi(
-      "sync_file_system/account_metadata.json");
-  SetUpSyncRootDirectory();
+  LoadAccountMetadata();
+  const std::string sync_root_id = SetUpSyncRootDirectory();
 
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
+  Output output;
   api_util()->GetDriveDirectoryForSyncRoot(
-      base::Bind(&DidGetResourceID, &done, &error, &resource_id));
+      base::Bind(&DidGetResourceID, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
-  EXPECT_EQ(GetSyncRootResourceId(), resource_id);
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
+  EXPECT_EQ(sync_root_id, output.resource_id);
 }
 
 void APIUtilTest::TestCreateSyncRoot() {
-  fake_drive_service()->LoadAccountMetadataForWapi(
-      "sync_file_system/account_metadata.json");
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
+  LoadAccountMetadata();
+
+  Output output;
   api_util()->GetDriveDirectoryForSyncRoot(
-      base::Bind(&DidGetResourceID, &done, &error, &resource_id));
+      base::Bind(&DidGetResourceID, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_CREATED, error);
-  EXPECT_FALSE(resource_id.empty());
+  EXPECT_EQ(google_apis::HTTP_CREATED, output.error);
+  EXPECT_FALSE(output.resource_id.empty());
 
-  fake_drive_service()->SearchByTitle(
-      APIUtil::GetSyncRootDirectoryName(),
-      std::string(),  // directory_resource_id
-      base::Bind(&VerifyTitleUniqueness,
-                 FROM_HERE,
-                 resource_id,
-                 google_apis::ENTRY_KIND_FOLDER));
-  base::MessageLoop::current()->RunUntilIdle();
+  VerifyTitleUniqueness(std::string(),  // directory_resource_id
+                        APIUtil::GetSyncRootDirectoryName(),
+                        output.resource_id,
+                        google_apis::ENTRY_KIND_FOLDER);
 }
 
 void APIUtilTest::TestCreateSyncRoot_Conflict() {
-  fake_drive_service()->LoadAccountMetadataForWapi(
-      "sync_file_system/account_metadata.json");
+  LoadAccountMetadata();
   fake_drive_service()->set_make_directory_conflict(true);
 
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
+  Output output;
   api_util()->GetDriveDirectoryForSyncRoot(
-      base::Bind(&DidGetResourceID, &done, &error, &resource_id));
+      base::Bind(&DidGetResourceID, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
-  EXPECT_FALSE(resource_id.empty());
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
+  EXPECT_FALSE(output.resource_id.empty());
 
   // Verify that there is no duplicated directory on the remote side.
-  fake_drive_service()->SearchByTitle(
-      APIUtil::GetSyncRootDirectoryName(),
-      std::string(),  // directory_resource_id
-      base::Bind(&VerifyTitleUniqueness,
-                 FROM_HERE,
-                 resource_id,
-                 google_apis::ENTRY_KIND_FOLDER));
-  base::MessageLoop::current()->RunUntilIdle();
+  VerifyTitleUniqueness(std::string(),  // directory_resource_id
+                        APIUtil::GetSyncRootDirectoryName(),
+                        output.resource_id,
+                        google_apis::ENTRY_KIND_FOLDER);
 }
 
 void APIUtilTest::TestGetOriginDirectory() {
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
+  Output output;
   api_util()->GetDriveDirectoryForOrigin(
-      GetSyncRootResourceId(),
+      sync_root_id,
       GURL(kOrigin),
-      base::Bind(&DidGetResourceID, &done, &error, &resource_id));
+      base::Bind(&DidGetResourceID, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
-  EXPECT_EQ(GetOriginRootResourceId(), resource_id);
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
+  EXPECT_EQ(origin_root_id, output.resource_id);
 }
 
 void APIUtilTest::TestCreateOriginDirectory() {
-  SetUpSyncRootDirectory();
+  const std::string& sync_root_id = SetUpSyncRootDirectory();
 
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
+  Output output;
   api_util()->GetDriveDirectoryForOrigin(
-      GetSyncRootResourceId(),
+      sync_root_id,
       GURL(kOrigin),
-      base::Bind(&DidGetResourceID, &done, &error, &resource_id));
+      base::Bind(&DidGetResourceID, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_CREATED, error);
-  EXPECT_FALSE(resource_id.empty());
+  EXPECT_EQ(google_apis::HTTP_CREATED, output.error);
+  EXPECT_FALSE(output.resource_id.empty());
 
-  fake_drive_service()->SearchByTitle(
-      kOriginDirectoryName,
-      GetSyncRootResourceId(),
-      base::Bind(&VerifyTitleUniqueness,
-                 FROM_HERE,
-                 resource_id,
-                 google_apis::ENTRY_KIND_FOLDER));
-  base::MessageLoop::current()->RunUntilIdle();
+  VerifyTitleUniqueness(sync_root_id,
+                        kOriginDirectoryName,
+                        output.resource_id,
+                        google_apis::ENTRY_KIND_FOLDER);
 }
 
 void APIUtilTest::TestCreateOriginDirectory_Conflict() {
-  SetUpSyncRootDirectory();
   fake_drive_service()->set_make_directory_conflict(true);
+  const std::string sync_root_id = SetUpSyncRootDirectory();
 
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
+  Output output;
   api_util()->GetDriveDirectoryForOrigin(
-      GetSyncRootResourceId(),
+      sync_root_id,
       GURL(kOrigin),
-      base::Bind(&DidGetResourceID, &done, &error, &resource_id));
+      base::Bind(&DidGetResourceID, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
-  EXPECT_FALSE(resource_id.empty());
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
+  EXPECT_FALSE(output.resource_id.empty());
 
   // Verify that there is no duplicated directory on the remote side.
-  fake_drive_service()->SearchByTitle(
-      kOriginDirectoryName,
-      GetSyncRootResourceId(),
-      base::Bind(&VerifyTitleUniqueness,
-                 FROM_HERE,
-                 resource_id,
-                 google_apis::ENTRY_KIND_FOLDER));
-  base::MessageLoop::current()->RunUntilIdle();
+  VerifyTitleUniqueness(sync_root_id,
+                        kOriginDirectoryName,
+                        output.resource_id,
+                        google_apis::ENTRY_KIND_FOLDER);
 }
 
 void APIUtilTest::TestGetLargestChangeStamp() {
-  fake_drive_service()->LoadAccountMetadataForWapi(
-      "sync_file_system/account_metadata.json");
+  LoadAccountMetadata();
 
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  int64 largest_changestamp = -1;
-  api_util()->GetLargestChangeStamp(base::Bind(
-      &DidGetLargestChangeStamp, &done, &error, &largest_changestamp));
+  Output output;
+  api_util()->GetLargestChangeStamp(
+      base::Bind(&DidGetLargestChangeStamp, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
-  EXPECT_EQ(654321, largest_changestamp);
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
+  EXPECT_EQ(654321, output.largest_changestamp);
 }
 
 void APIUtilTest::TestListFiles() {
   fake_drive_service()->set_default_max_results(3);
-
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
   int kNumberOfFiles = 5;
   for (int i = 0; i < kNumberOfFiles; ++i) {
-    std::string file_resource_id;
-    std::string file_md5;
+    scoped_ptr<ResourceEntry> file;
     std::string file_content = base::StringPrintf("test content %d", i);
     std::string file_title = base::StringPrintf("test_%d.txt", i);
-    SetUpFile(file_content, file_title, &file_resource_id, &file_md5);
+    SetUpFile(origin_root_id, file_content, file_title, &file);
   }
 
-  bool done = false;
   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
   scoped_ptr<ResourceList> document_feed;
   api_util()->ListFiles(
-      GetOriginRootResourceId(),
-      base::Bind(&DidGetResourceList, &done, &error, &document_feed));
+      origin_root_id,
+      base::Bind(&DidGetResourceList, &error, &document_feed));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
   EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
   EXPECT_EQ(3U, document_feed->entries().size());
 
   GURL feed_url;
   ASSERT_TRUE(document_feed->GetNextFeedURL(&feed_url));
 
-  done = false;
   error = google_apis::GDATA_OTHER_ERROR;
   document_feed.reset();
 
   api_util()->ContinueListing(
-      feed_url, base::Bind(&DidGetResourceList, &done, &error, &document_feed));
+      feed_url, base::Bind(&DidGetResourceList, &error, &document_feed));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
   EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
   EXPECT_EQ(2U, document_feed->entries().size());
 }
 
 void APIUtilTest::TestListChanges() {
   const int64 kStartChangestamp = 6;
-
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
   // Files should have changestamp #4+ since creating the sync root directory is
   // #1, moving it out of 'My Drive' is #2, and creating the origin root
   // directory is #3.
   const int kNumberOfFiles = 5;
   for (int i = 0; i < kNumberOfFiles; ++i) {
-    std::string file_resource_id;
-    std::string file_md5;
+    scoped_ptr<ResourceEntry> file;
     std::string file_content = base::StringPrintf("test content %d", i);
     std::string file_title = base::StringPrintf("test_%d.txt", i);
-    SetUpFile(file_content, file_title, &file_resource_id, &file_md5);
+    SetUpFile(origin_root_id, file_content, file_title, &file);
   }
 
-  bool done = false;
   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
   scoped_ptr<ResourceList> document_feed;
   api_util()->ListFiles(
-      GetOriginRootResourceId(),
-      base::Bind(&DidGetResourceList, &done, &error, &document_feed));
+      origin_root_id,
+      base::Bind(&DidGetResourceList, &error, &document_feed));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
   EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
   EXPECT_EQ(5U, document_feed->entries().size());
 
-  done = false;
   error = google_apis::GDATA_OTHER_ERROR;
   document_feed.reset();
   api_util()->ListChanges(
       kStartChangestamp,
-      base::Bind(&DidGetResourceList, &done, &error, &document_feed));
+      base::Bind(&DidGetResourceList, &error, &document_feed));
   base::MessageLoop::current()->RunUntilIdle();
 
   // There should be 3 files which have changestamp #6+.
-  EXPECT_TRUE(done);
   EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
   EXPECT_EQ(3U, document_feed->entries().size());
 }
@@ -681,298 +579,231 @@
 void APIUtilTest::TestDownloadFile() {
   const std::string kFileContent = "test content";
   const std::string kFileTitle = "test.txt";
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
-  std::string file_resource_id;
-  std::string file_md5;
-  SetUpFile(kFileContent, kFileTitle, &file_resource_id, &file_md5);
+  scoped_ptr<ResourceEntry> file;
+  SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
 
   base::ScopedTempDir temp_dir;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-  const base::FilePath kOutputFilePath =
-      temp_dir.path().AppendASCII(kFileTitle);
+  base::FilePath output_file_path = temp_dir.path().AppendASCII(file->title());
 
-  bool done = false;
-  std::string downloaded_file_md5;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
+  Output output;
   api_util()->DownloadFile(
-      file_resource_id,
+      file->resource_id(),
       "",  // local_file_md5
-      kOutputFilePath,
-      base::Bind(&DidDownloadFile, &done, &downloaded_file_md5, &error));
+      output_file_path,
+      base::Bind(&DidDownloadFile, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(file_md5, downloaded_file_md5);
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
+  EXPECT_EQ(file->file_md5(), output.file_md5);
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
 }
 
 void APIUtilTest::TestDownloadFileInNotModified() {
   const std::string kFileContent = "test content";
   const std::string kFileTitle = "test.txt";
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
-  std::string file_resource_id;
-  std::string file_md5;
-  SetUpFile(kFileContent, kFileTitle, &file_resource_id, &file_md5);
+  scoped_ptr<ResourceEntry> file;
+  SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
 
   base::ScopedTempDir temp_dir;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-  const base::FilePath kOutputFilePath =
-      temp_dir.path().AppendASCII(kFileTitle);
-
-  bool done = false;
-  std::string downloaded_file_md5;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
+  base::FilePath output_file_path = temp_dir.path().AppendASCII(file->title());
 
   // Since local file's hash value is equal to remote file's one, it is expected
   // to cancel download the file and to return NOT_MODIFIED status code.
+  Output output;
   api_util()->DownloadFile(
-      file_resource_id,
-      file_md5,
-      kOutputFilePath,
-      base::Bind(&DidDownloadFile, &done, &downloaded_file_md5, &error));
+      file->resource_id(),
+      file->file_md5(),
+      output_file_path,
+      base::Bind(&DidDownloadFile, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_NOT_MODIFIED, error);
-  // TODO(nhiroki): Compare |file_md5| and |downloaded_file_md5| after making
-  // FakeDriveService::AddNewEntry set the correct MD5.
+  EXPECT_EQ(file->file_md5(), output.file_md5);
+  EXPECT_EQ(google_apis::HTTP_NOT_MODIFIED, output.error);
 }
 
 void APIUtilTest::TestUploadNewFile() {
   const std::string kFileTitle = "test.txt";
   const base::FilePath kLocalFilePath(FPL("/tmp/dir/file"));
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
-
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
+  Output output;
   api_util()->UploadNewFile(
-      GetOriginRootResourceId(),
+      origin_root_id,
       kLocalFilePath,
       kFileTitle,
-      base::Bind(&DidUploadFile, &done, &error, &resource_id));
+      base::Bind(&DidUploadFile, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_CREATED, error);
-  EXPECT_TRUE(!resource_id.empty());
+  EXPECT_EQ(google_apis::HTTP_CREATED, output.error);
+  EXPECT_TRUE(!output.resource_id.empty());
 
-  fake_drive_service()->SearchByTitle(
-      kFileTitle,
-      GetOriginRootResourceId(),
-      base::Bind(&VerifyTitleUniqueness,
-                 FROM_HERE,
-                 resource_id,
-                 google_apis::ENTRY_KIND_FILE));
-  base::MessageLoop::current()->RunUntilIdle();
+  VerifyTitleUniqueness(origin_root_id,
+                        kFileTitle,
+                        output.resource_id,
+                        google_apis::ENTRY_KIND_FILE);
 }
 
 void APIUtilTest::TestUploadNewFile_ConflictWithFile() {
   const std::string kFileTitle = "test.txt";
   const base::FilePath kLocalFilePath(FPL("/tmp/dir/file"));
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
   fake_drive_uploader()->set_make_file_conflict(true);
 
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
-
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
+  Output output;
   api_util()->UploadNewFile(
-      GetOriginRootResourceId(),
+      origin_root_id,
       kLocalFilePath,
       kFileTitle,
-      base::Bind(&DidUploadFile, &done, &error, &resource_id));
+      base::Bind(&DidUploadFile, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
   // HTTP_CONFLICT error must be returned with empty resource_id.
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_CONFLICT, error);
-  EXPECT_TRUE(!resource_id.empty());
+  EXPECT_EQ(google_apis::HTTP_CONFLICT, output.error);
+  EXPECT_TRUE(!output.resource_id.empty());
 
   // Verify that there is no duplicated file on the remote side.
-  fake_drive_service()->SearchByTitle(
-      kFileTitle,
-      GetOriginRootResourceId(),
-      base::Bind(&VerifyTitleUniqueness,
-                 FROM_HERE,
-                 resource_id,
-                 google_apis::ENTRY_KIND_FILE));
-  base::MessageLoop::current()->RunUntilIdle();
+  VerifyTitleUniqueness(origin_root_id,
+                        kFileTitle,
+                        output.resource_id,
+                        google_apis::ENTRY_KIND_FILE);
 }
 
 void APIUtilTest::TestUploadExistingFile() {
   const base::FilePath kLocalFilePath(FPL("/tmp/dir/file"));
   const std::string kFileContent = "test content";
   const std::string kFileTitle = "test.txt";
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
-  std::string file_resource_id;
-  std::string file_md5;
-  SetUpFile(kFileContent, kFileTitle, &file_resource_id, &file_md5);
+  scoped_ptr<ResourceEntry> file;
+  SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
 
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
+  Output output;
   api_util()->UploadExistingFile(
-      file_resource_id,
-      file_md5,
+      file->resource_id(),
+      file->file_md5(),
       kLocalFilePath,
-      base::Bind(&DidUploadFile, &done, &error, &resource_id));
+      base::Bind(&DidUploadFile, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
-  EXPECT_EQ(file_resource_id, resource_id);
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
+  EXPECT_EQ(file->resource_id(), output.resource_id);
 
-  fake_drive_service()->SearchByTitle(
-      kFileTitle,
-      GetOriginRootResourceId(),
-      base::Bind(&VerifyTitleUniqueness,
-                 FROM_HERE,
-                 file_resource_id,
-                 google_apis::ENTRY_KIND_FILE));
-  base::MessageLoop::current()->RunUntilIdle();
+  VerifyTitleUniqueness(origin_root_id,
+                        file->title(),
+                        file->resource_id(),
+                        file->kind());
 }
 
 void APIUtilTest::TestUploadExistingFileInConflict() {
   const base::FilePath kLocalFilePath(FPL("/tmp/dir/file"));
   const std::string kFileContent = "test content";
   const std::string kFileTitle = "test.txt";
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
-  std::string file_resource_id;
-  std::string file_md5;
-  SetUpFile(kFileContent, kFileTitle, &file_resource_id, &file_md5);
+  scoped_ptr<ResourceEntry> file;
+  SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
 
   // Since remote file's hash value is different from the expected one, it is
   // expected to cancel upload the file and to return CONFLICT status code.
   const std::string kExpectedRemoteFileMD5 = "123456";
 
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
+  Output output;
   api_util()->UploadExistingFile(
-      file_resource_id,
+      file->resource_id(),
       kExpectedRemoteFileMD5,
       kLocalFilePath,
-      base::Bind(&DidUploadFile, &done, &error, &resource_id));
+      base::Bind(&DidUploadFile, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_CONFLICT, error);
-  EXPECT_TRUE(resource_id.empty());
+  EXPECT_EQ(google_apis::HTTP_CONFLICT, output.error);
+  EXPECT_TRUE(output.resource_id.empty());
 
   // Verify that there is no duplicated file on the remote side.
-  fake_drive_service()->SearchByTitle(
-      kFileTitle,
-      GetOriginRootResourceId(),
-      base::Bind(&VerifyTitleUniqueness,
-                 FROM_HERE,
-                 file_resource_id,
-                 google_apis::ENTRY_KIND_FILE));
-  base::MessageLoop::current()->RunUntilIdle();
+  VerifyTitleUniqueness(origin_root_id,
+                        file->title(),
+                        file->resource_id(),
+                        file->kind());
 }
 
 void APIUtilTest::TestDeleteFile() {
   const std::string kFileContent = "test content";
   const std::string kFileTitle = "test.txt";
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
-  std::string file_resource_id;
-  std::string file_md5;
-  SetUpFile(kFileContent, kFileTitle, &file_resource_id, &file_md5);
+  scoped_ptr<ResourceEntry> file;
+  SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
 
-  bool done = false;
   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
-  api_util()->DeleteFile(file_resource_id,
-                         file_md5,
-                         base::Bind(&DidDeleteFile, &done, &error));
+  api_util()->DeleteFile(file->resource_id(),
+                         file->file_md5(),
+                         base::Bind(&DidDeleteFile, &error));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
   EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
 
-  fake_drive_service()->SearchByTitle(
-      kFileTitle,
-      GetOriginRootResourceId(),
-      base::Bind(&VerifyFileDeletion, FROM_HERE));
-  base::MessageLoop::current()->RunUntilIdle();
+  VerifyFileDeletion(origin_root_id, kFileTitle);
 }
 
 void APIUtilTest::TestDeleteFileInConflict() {
   const std::string kFileContent = "test content";
   const std::string kFileTitle = "test.txt";
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
-  std::string file_resource_id;
-  std::string file_md5;
-  SetUpFile(kFileContent, kFileTitle, &file_resource_id, &file_md5);
+  scoped_ptr<ResourceEntry> file;
+  SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
 
   // Since remote file's hash value is different from the expected one, it is
   // expected to cancel delete the file and to return CONFLICT status code.
   const std::string kExpectedRemoteFileMD5 = "123456";
 
-  bool done = false;
   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  api_util()->DeleteFile(file_resource_id,
+  api_util()->DeleteFile(file->resource_id(),
                          kExpectedRemoteFileMD5,
-                         base::Bind(&DidDeleteFile, &done, &error));
+                         base::Bind(&DidDeleteFile, &error));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
   EXPECT_EQ(google_apis::HTTP_CONFLICT, error);
 
   // Verify that the conflict file was not deleted on the remote side.
-  fake_drive_service()->SearchByTitle(
-      kFileTitle,
-      GetOriginRootResourceId(),
-      base::Bind(&VerifyTitleUniqueness,
-                 FROM_HERE,
-                 file_resource_id,
-                 google_apis::ENTRY_KIND_FILE));
-  base::MessageLoop::current()->RunUntilIdle();
+  VerifyTitleUniqueness(origin_root_id,
+                        file->title(),
+                        file->resource_id(),
+                        file->kind());
 }
 
 void APIUtilTest::TestCreateDirectory() {
   const std::string kDirectoryTitle("directory");
+  const std::string sync_root_id = SetUpSyncRootDirectory();
+  const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
 
-  SetUpSyncRootDirectory();
-  SetUpOriginRootDirectory();
-
-  bool done = false;
-  GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
-  std::string resource_id;
+  Output output;
   api_util()->CreateDirectory(
-      GetOriginRootResourceId(),
+      origin_root_id,
       kDirectoryTitle,
-      base::Bind(&DidGetResourceID, &done, &error, &resource_id));
+      base::Bind(&DidGetResourceID, &output));
   base::MessageLoop::current()->RunUntilIdle();
 
-  EXPECT_TRUE(done);
-  EXPECT_EQ(google_apis::HTTP_CREATED, error);
-  EXPECT_FALSE(resource_id.empty());
+  EXPECT_EQ(google_apis::HTTP_CREATED, output.error);
+  EXPECT_FALSE(output.resource_id.empty());
 
-  fake_drive_service()->SearchByTitle(
-      kDirectoryTitle,
-      GetOriginRootResourceId(),
-      base::Bind(&VerifyTitleUniqueness,
-                 FROM_HERE,
-                 resource_id,
-                 google_apis::ENTRY_KIND_FOLDER));
-  base::MessageLoop::current()->RunUntilIdle();
+  VerifyTitleUniqueness(origin_root_id,
+                        kDirectoryTitle,
+                        output.resource_id,
+                        google_apis::ENTRY_KIND_FOLDER);
 }
 
 TEST_F(APIUtilTest, GetSyncRoot) {
@@ -1155,7 +986,5 @@
   TestCreateDirectory();
 }
 
-#endif  // !defined(OS_ANDROID)
-
 }  // namespace drive_backend
 }  // namespace sync_file_system
diff --git a/chrome/browser/sync_file_system/drive_file_sync_service.cc b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.cc
similarity index 97%
rename from chrome/browser/sync_file_system/drive_file_sync_service.cc
rename to chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.cc
index ce50f1c..4ff04d8 100644
--- a/chrome/browser/sync_file_system/drive_file_sync_service.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
 
 #include <algorithm>
 #include <string>
@@ -22,13 +22,12 @@
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync_file_system/drive_backend/api_util.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h"
 #include "chrome/browser/sync_file_system/drive_backend/local_sync_delegate.h"
 #include "chrome/browser/sync_file_system/drive_backend/remote_sync_delegate.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_util.h"
-#include "chrome/browser/sync_file_system/drive_metadata_store.h"
 #include "chrome/browser/sync_file_system/file_status_observer.h"
 #include "chrome/browser/sync_file_system/logger.h"
-#include "chrome/browser/sync_file_system/remote_change_handler.h"
 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/browser_thread.h"
@@ -86,8 +85,8 @@
   if (api_util_)
     api_util_->RemoveObserver(this);
 
-  ::drive::DriveNotificationManager* drive_notification_manager =
-      ::drive::DriveNotificationManagerFactory::GetForProfile(profile_);
+  drive::DriveNotificationManager* drive_notification_manager =
+      drive::DriveNotificationManagerFactory::GetForProfile(profile_);
   if (drive_notification_manager)
     drive_notification_manager->RemoveObserver(this);
 }
@@ -235,11 +234,9 @@
     (*status_map)[itr->first] = "Disabled";
 }
 
-void DriveFileSyncService::GetFileMetadataMap(
-    const GURL& origin,
-    FileMetadataMap* metadata_map) {
-  DCHECK(metadata_map);
-  metadata_store_->GetFileMetadataMap(origin, metadata_map);
+scoped_ptr<base::ListValue> DriveFileSyncService::DumpFiles(
+    const GURL& origin) {
+  return metadata_store_->DumpFiles(origin);
 }
 
 void DriveFileSyncService::SetSyncEnabled(bool enabled) {
@@ -403,8 +400,8 @@
   callback.Run(status);
   may_have_unfetched_changes_ = true;
 
-  ::drive::DriveNotificationManager* drive_notification_manager =
-      ::drive::DriveNotificationManagerFactory::GetForProfile(profile_);
+  drive::DriveNotificationManager* drive_notification_manager =
+      drive::DriveNotificationManagerFactory::GetForProfile(profile_);
   if (drive_notification_manager)
     drive_notification_manager->AddObserver(this);
 }
@@ -1203,7 +1200,7 @@
       continue;
 
     std::string resource_id(
-        ::drive::util::ExtractResourceIdFromUrl((*itr)->href()));
+        drive::util::ExtractResourceIdFromUrl((*itr)->href()));
     if (resource_id.empty())
       continue;
 
diff --git a/chrome/browser/sync_file_system/drive_file_sync_service.h b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h
similarity index 94%
rename from chrome/browser/sync_file_system/drive_file_sync_service.h
rename to chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h
index d892ed4..bd53021 100644
--- a/chrome/browser/sync_file_system/drive_file_sync_service.h
+++ b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_FILE_SYNC_SERVICE_H_
-#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_FILE_SYNC_SERVICE_H_
+#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_DRIVE_FILE_SYNC_SERVICE_H_
+#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_DRIVE_FILE_SYNC_SERVICE_H_
 
 #include <deque>
 #include <map>
@@ -19,10 +19,10 @@
 #include "chrome/browser/drive/drive_notification_observer.h"
 #include "chrome/browser/sync_file_system/conflict_resolution_resolver.h"
 #include "chrome/browser/sync_file_system/drive_backend/api_util_interface.h"
-#include "chrome/browser/sync_file_system/drive_metadata_store.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h"
+#include "chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver.h"
+#include "chrome/browser/sync_file_system/drive_backend/remote_change_handler.h"
 #include "chrome/browser/sync_file_system/local_change_processor.h"
-#include "chrome/browser/sync_file_system/local_sync_operation_resolver.h"
-#include "chrome/browser/sync_file_system/remote_change_handler.h"
 #include "chrome/browser/sync_file_system/remote_file_sync_service.h"
 #include "chrome/browser/sync_file_system/sync_action.h"
 #include "chrome/browser/sync_file_system/sync_direction.h"
@@ -59,7 +59,7 @@
                              public SyncTaskManager::Client,
                              public base::NonThreadSafe,
                              public base::SupportsWeakPtr<DriveFileSyncService>,
-                             public ::drive::DriveNotificationObserver {
+                             public drive::DriveNotificationObserver {
  public:
   typedef base::Callback<void(const SyncStatusCallback& callback)> Task;
 
@@ -109,8 +109,7 @@
   virtual bool IsConflicting(const fileapi::FileSystemURL& url) OVERRIDE;
   virtual RemoteServiceState GetCurrentState() const OVERRIDE;
   virtual void GetOriginStatusMap(OriginStatusMap* status_map) OVERRIDE;
-  virtual void GetFileMetadataMap(const GURL& origin,
-                                  FileMetadataMap* metadata_map) OVERRIDE;
+  virtual scoped_ptr<base::ListValue> DumpFiles(const GURL& origin) OVERRIDE;
   virtual void SetSyncEnabled(bool enabled) OVERRIDE;
   virtual SyncStatusCode SetConflictResolutionPolicy(
       ConflictResolutionPolicy policy) OVERRIDE;
@@ -128,7 +127,7 @@
   virtual void OnAuthenticated() OVERRIDE;
   virtual void OnNetworkConnected() OVERRIDE;
 
-  // ::drive::DriveNotificationObserver implementation.
+  // drive::DriveNotificationObserver implementation.
   virtual void OnNotificationReceived() OVERRIDE;
   virtual void OnPushNotificationEnabled(bool enabled) OVERRIDE;
 
@@ -379,4 +378,4 @@
 
 }  // namespace sync_file_system
 
-#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_FILE_SYNC_SERVICE_H_
+#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_DRIVE_FILE_SYNC_SERVICE_H_
diff --git a/chrome/browser/sync_file_system/drive_file_sync_service_fake_unittest.cc b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_service_fake_unittest.cc
similarity index 98%
rename from chrome/browser/sync_file_system/drive_file_sync_service_fake_unittest.cc
rename to chrome/browser/sync_file_system/drive_backend/drive_file_sync_service_fake_unittest.cc
index 4eb71c7..2d1e8a2 100644
--- a/chrome/browser/sync_file_system/drive_file_sync_service_fake_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_service_fake_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
 
 #include <utility>
 
@@ -18,9 +18,9 @@
 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
 #include "chrome/browser/google_apis/test_util.h"
 #include "chrome/browser/sync_file_system/drive_backend/api_util.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h"
 #include "chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_util.h"
-#include "chrome/browser/sync_file_system/drive_metadata_store.h"
 #include "chrome/browser/sync_file_system/file_status_observer.h"
 #include "chrome/browser/sync_file_system/mock_remote_change_processor.h"
 #include "chrome/browser/sync_file_system/sync_direction.h"
@@ -48,9 +48,10 @@
 using ::testing::StrictMock;
 using ::testing::_;
 
-using ::drive::DriveServiceInterface;
-using ::drive::DriveUploaderInterface;
-using ::drive::FakeDriveService;
+using drive::DriveServiceInterface;
+using drive::DriveUploader;
+using drive::DriveUploaderInterface;
+using drive::FakeDriveService;
 
 using extensions::Extension;
 using extensions::DictionaryBuilder;
@@ -198,7 +199,7 @@
     RegisterSyncableFileSystem();
 
     fake_drive_service_ = new FakeDriveService;
-    DriveUploaderInterface* drive_uploader = new ::drive::DriveUploader(
+    DriveUploaderInterface* drive_uploader = new DriveUploader(
         fake_drive_service_, base::MessageLoopProxy::current().get());
 
     fake_drive_helper_.reset(new FakeDriveServiceHelper(
diff --git a/chrome/browser/sync_file_system/drive_file_sync_service_sync_unittest.cc b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_service_sync_unittest.cc
similarity index 97%
rename from chrome/browser/sync_file_system/drive_file_sync_service_sync_unittest.cc
rename to chrome/browser/sync_file_system/drive_backend/drive_file_sync_service_sync_unittest.cc
index 60eb89f..bdcc9e1 100644
--- a/chrome/browser/sync_file_system/drive_file_sync_service_sync_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_service_sync_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
 
 #include <algorithm>
 
@@ -15,9 +15,9 @@
 #include "chrome/browser/drive/drive_uploader.h"
 #include "chrome/browser/drive/fake_drive_service.h"
 #include "chrome/browser/sync_file_system/drive_backend/api_util.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h"
 #include "chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_util.h"
-#include "chrome/browser/sync_file_system/drive_metadata_store.h"
 #include "chrome/browser/sync_file_system/fake_remote_change_processor.h"
 #include "chrome/browser/sync_file_system/local_file_sync_service.h"
 #include "chrome/test/base/testing_profile.h"
@@ -90,14 +90,14 @@
     RegisterSyncableFileSystem();
     local_sync_service_.reset(new LocalFileSyncService(&profile_));
 
-    fake_drive_service_ = new ::drive::FakeDriveService();
+    fake_drive_service_ = new drive::FakeDriveService();
     fake_drive_service_->Initialize(&profile_);
     ASSERT_TRUE(fake_drive_service_->LoadAccountMetadataForWapi(
         "sync_file_system/account_metadata.json"));
     ASSERT_TRUE(fake_drive_service_->LoadResourceListForWapi(
         "gdata/root_feed.json"));
 
-    drive_uploader_ = new ::drive::DriveUploader(
+    drive_uploader_ = new drive::DriveUploader(
         fake_drive_service_, base::MessageLoopProxy::current().get());
 
     fake_drive_helper_.reset(new FakeDriveServiceHelper(
@@ -118,8 +118,8 @@
 
     scoped_ptr<APIUtil> api_util(APIUtil::CreateForTesting(
         &profile_,
-        scoped_ptr< ::drive::DriveServiceInterface>(fake_drive_service_),
-        scoped_ptr< ::drive::DriveUploaderInterface>(drive_uploader_)));
+        scoped_ptr<drive::DriveServiceInterface>(fake_drive_service_),
+        scoped_ptr<drive::DriveUploaderInterface>(drive_uploader_)));
 
     remote_sync_service_ = DriveFileSyncService::CreateForTesting(
         &profile_,
@@ -414,14 +414,15 @@
 
   TestingProfile profile_;
 
-  ::drive::FakeDriveService* fake_drive_service_;
-  ::drive::DriveUploader* drive_uploader_;
+  drive::FakeDriveService* fake_drive_service_;
+  drive::DriveUploader* drive_uploader_;
   scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
   std::map<GURL, CannedSyncableFileSystem*> file_systems_;
 
   scoped_ptr<DriveFileSyncService> remote_sync_service_;
   scoped_ptr<LocalFileSyncService> local_sync_service_;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(DriveFileSyncServiceSyncTest);
 };
 
diff --git a/chrome/browser/sync_file_system/drive_file_sync_service_unittest.cc b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_service_unittest.cc
similarity index 97%
rename from chrome/browser/sync_file_system/drive_file_sync_service_unittest.cc
rename to chrome/browser/sync_file_system/drive_backend/drive_file_sync_service_unittest.cc
index a95685e..1b53de2 100644
--- a/chrome/browser/sync_file_system/drive_file_sync_service_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_service_unittest.cc
@@ -1,13 +1,13 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
 
 #include "base/message_loop/message_loop.h"
 #include "base/message_loop/message_loop_proxy.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h"
 #include "chrome/browser/sync_file_system/drive_backend/fake_api_util.h"
-#include "chrome/browser/sync_file_system/drive_metadata_store.h"
 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread.h"
diff --git a/chrome/browser/sync_file_system/drive_file_sync_util.cc b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.cc
similarity index 95%
rename from chrome/browser/sync_file_system/drive_file_sync_util.cc
rename to chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.cc
index 8999771..6bf2533 100644
--- a/chrome/browser/sync_file_system/drive_file_sync_util.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/sync_file_system/drive_file_sync_util.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h"
 
 #include "base/command_line.h"
 #include "base/logging.h"
diff --git a/chrome/browser/sync_file_system/drive_file_sync_util.h b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h
similarity index 79%
rename from chrome/browser/sync_file_system/drive_file_sync_util.h
rename to chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h
index 5df4ce5..e67c34e 100644
--- a/chrome/browser/sync_file_system/drive_file_sync_util.h
+++ b/chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_FILE_SYNC_UTIL_H_
-#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_FILE_SYNC_UTIL_H_
+#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_DRIVE_FILE_SYNC_UTIL_H_
+#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_DRIVE_FILE_SYNC_UTIL_H_
 
 #include "chrome/browser/google_apis/gdata_errorcode.h"
 #include "webkit/browser/fileapi/syncable/sync_status_code.h"
@@ -39,4 +39,4 @@
 
 }  // namespace sync_file_system
 
-#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_FILE_SYNC_UTIL_H_
+#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_DRIVE_FILE_SYNC_UTIL_H_
diff --git a/chrome/browser/sync_file_system/drive_metadata_store.cc b/chrome/browser/sync_file_system/drive_backend/drive_metadata_store.cc
similarity index 94%
rename from chrome/browser/sync_file_system/drive_metadata_store.cc
rename to chrome/browser/sync_file_system/drive_backend/drive_metadata_store.cc
index 65f125b..e2b9cf9 100644
--- a/chrome/browser/sync_file_system/drive_metadata_store.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_metadata_store.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/sync_file_system/drive_metadata_store.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h"
 
 #include <utility>
 #include <vector>
@@ -18,10 +18,10 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/task_runner_util.h"
+#include "base/values.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h"
 #include "chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_util.h"
-#include "chrome/browser/sync_file_system/file_metadata.h"
 #include "chrome/browser/sync_file_system/logger.h"
 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
 #include "third_party/leveldatabase/src/include/leveldb/db.h"
@@ -134,6 +134,7 @@
   DCHECK(created);
 
   leveldb::Options options;
+  options.max_open_files = 0;  // Use minimum.
   options.create_if_missing = true;
   leveldb::DB* db = NULL;
   leveldb::Status db_status = leveldb::DB::Open(
@@ -342,16 +343,16 @@
     batch->Delete(OriginAndPathToMetadataKey(origin, itr->first));
 }
 
-FileType DriveTypeToFileMetadataType(DriveMetadata_ResourceType drive_type) {
+std::string DriveTypeToString(DriveMetadata_ResourceType drive_type) {
   switch (drive_type) {
     case DriveMetadata_ResourceType_RESOURCE_TYPE_FILE:
-      return TYPE_FILE;
+      return "file";
     case DriveMetadata_ResourceType_RESOURCE_TYPE_FOLDER:
-      return TYPE_FOLDER;
+      return "folder";
   }
 
   NOTREACHED();
-  return TYPE_FILE;
+  return "unknown";
 }
 
 }  // namespace
@@ -768,31 +769,36 @@
   return true;
 }
 
-void DriveMetadataStore::GetFileMetadataMap(
-    const GURL& origin,
-    FileMetadataMap* output_map) {
+scoped_ptr<base::ListValue> DriveMetadataStore::DumpFiles(const GURL& origin) {
   DCHECK(CalledOnValidThread());
-  DCHECK(!origin.is_empty());
-  DCHECK(output_map);
 
-  MetadataMap::const_iterator origin_itr = metadata_map_.find(origin);
-  if (origin_itr == metadata_map_.end())
-    return;
+  scoped_ptr<base::ListValue> files(new base::ListValue);
 
-  for (PathToMetadata::const_iterator itr = origin_itr->second.begin();
-       itr != origin_itr->second.end();
+  MetadataMap::const_iterator found = metadata_map_.find(origin);
+  if (found == metadata_map_.end())
+    return make_scoped_ptr(new base::ListValue);
+
+  for (PathToMetadata::const_iterator itr = found->second.begin();
+       itr != found->second.end();
        ++itr) {
     // Convert Drive specific metadata to Common File metadata object.
-    const std::string title = itr->first.BaseName().AsUTF8Unsafe();
     const DriveMetadata& metadata = itr->second;
-    const FileType type = DriveTypeToFileMetadataType(metadata.type());
-    std::ostringstream details;
-    details << "resource_id=" << metadata.resource_id() << ", "
-            << "md5_checksum=" << metadata.md5_checksum() << ", "
-            << "to_be_fetched=" << metadata.to_be_fetched();
-    FileMetadata file_metadata(title, type, details.str());
-    (*output_map)[itr->first] = file_metadata;
+
+    base::DictionaryValue* file = new DictionaryValue;
+    file->SetString("path", itr->first.AsUTF8Unsafe());
+    file->SetString("title", itr->first.BaseName().AsUTF8Unsafe());
+    file->SetString("type", DriveTypeToString(metadata.type()));
+
+    base::DictionaryValue* details = new DictionaryValue;
+    details->SetString("resource_id", metadata.resource_id());
+    details->SetString("md5", metadata.md5_checksum());
+    details->SetString("dirty", metadata.to_be_fetched() ? "true" : "false");
+
+    file->Set("details", details);
+    files->Append(file);
   }
+
+  return files.Pass();
 }
 
 }  // namespace sync_file_system
diff --git a/chrome/browser/sync_file_system/drive_metadata_store.h b/chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h
similarity index 93%
rename from chrome/browser/sync_file_system/drive_metadata_store.h
rename to chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h
index b243a5e..472f288 100644
--- a/chrome/browser/sync_file_system/drive_metadata_store.h
+++ b/chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_METADATA_STORE_H_
-#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_METADATA_STORE_H_
+#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_DRIVE_METADATA_STORE_H_
+#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_DRIVE_METADATA_STORE_H_
 
 #include <map>
 #include <string>
@@ -21,6 +21,7 @@
 #include "webkit/browser/fileapi/syncable/sync_status_code.h"
 
 namespace base {
+class ListValue;
 class SequencedTaskRunner;
 }
 
@@ -148,8 +149,7 @@
                                         GURL* origin);
 
   // Returns all file metadata for the given origin.
-  typedef std::map<base::FilePath, FileMetadata> FileMetadataMap;
-  void GetFileMetadataMap(const GURL& origin, FileMetadataMap* output_map);
+  scoped_ptr<base::ListValue> DumpFiles(const GURL& origin);
 
  private:
   friend class DriveMetadataStoreTest;
@@ -186,4 +186,4 @@
 
 }  // namespace sync_file_system
 
-#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_METADATA_STORE_H_
+#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_DRIVE_METADATA_STORE_H_
diff --git a/chrome/browser/sync_file_system/drive_metadata_store_unittest.cc b/chrome/browser/sync_file_system/drive_backend/drive_metadata_store_unittest.cc
similarity index 95%
rename from chrome/browser/sync_file_system/drive_metadata_store_unittest.cc
rename to chrome/browser/sync_file_system/drive_backend/drive_metadata_store_unittest.cc
index dc119bb..7a6ed6a 100644
--- a/chrome/browser/sync_file_system/drive_metadata_store_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_metadata_store_unittest.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/sync_file_system/drive_metadata_store.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h"
 
 #include <utility>
 
@@ -14,10 +14,10 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/threading/thread.h"
+#include "base/values.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h"
 #include "chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_util.h"
-#include "chrome/browser/sync_file_system/file_metadata.h"
 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
 #include "content/public/browser/browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -611,19 +611,21 @@
 
   // Check that DriveMetadata objects get mapped back to generalized
   // FileMetadata objects.
-  DriveMetadataStore::FileMetadataMap metadata_map;
-  metadata_store()->GetFileMetadataMap(origin, &metadata_map);
-  ASSERT_EQ(2U, metadata_map.size());
+  scoped_ptr<base::ListValue> files = metadata_store()->DumpFiles(origin);
+  ASSERT_EQ(2u, files->GetSize());
 
-  FileMetadata metadata_0 = metadata_map[file_path];
-  EXPECT_EQ("file_0", metadata_0.title);
-  EXPECT_EQ(TYPE_FILE, metadata_0.type);
-  EXPECT_TRUE(!metadata_0.service_specific_metadata.empty());
+  base::DictionaryValue* file = NULL;
+  std::string str;
 
-  FileMetadata metadata_1 = metadata_map[folder_path];
-  EXPECT_EQ("folder_0", metadata_1.title);
-  EXPECT_EQ(TYPE_FOLDER, metadata_1.type);
-  EXPECT_TRUE(!metadata_1.service_specific_metadata.empty());
+  ASSERT_TRUE(files->GetDictionary(0, &file));
+  EXPECT_TRUE(file->GetString("title", &str) && str == "file_0");
+  EXPECT_TRUE(file->GetString("type", &str) && str == "file");
+  EXPECT_TRUE(file->HasKey("details"));
+
+  ASSERT_TRUE(files->GetDictionary(1, &file));
+  EXPECT_TRUE(file->GetString("title", &str) && str == "folder_0");
+  EXPECT_TRUE(file->GetString("type", &str) && str == "folder");
+  EXPECT_TRUE(file->HasKey("details"));
 }
 
 TEST_F(DriveMetadataStoreTest, Initialization) {
diff --git a/chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.cc b/chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.cc
index 89924b9..fb09025 100644
--- a/chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.cc
+++ b/chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.cc
@@ -164,7 +164,7 @@
   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
   fake_drive_service_->DeleteResource(
       file_id,
-      std::string(), // etag
+      std::string(),  // etag
       base::Bind(&GDataErrorResultCallback, &error));
   FlushMessageLoop();
   return error;
diff --git a/chrome/browser/sync_file_system/drive_backend/local_sync_delegate.cc b/chrome/browser/sync_file_system/drive_backend/local_sync_delegate.cc
index b85adcd..8faeebf 100644
--- a/chrome/browser/sync_file_system/drive_backend/local_sync_delegate.cc
+++ b/chrome/browser/sync_file_system/drive_backend/local_sync_delegate.cc
@@ -8,8 +8,7 @@
 #include "base/callback.h"
 #include "chrome/browser/sync_file_system/conflict_resolution_resolver.h"
 #include "chrome/browser/sync_file_system/drive_backend/api_util.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
-#include "chrome/browser/sync_file_system/drive_metadata_store.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h"
 #include "chrome/browser/sync_file_system/logger.h"
 #include "webkit/browser/fileapi/syncable/syncable_file_system_util.h"
 
@@ -431,14 +430,6 @@
   metadata_store()->UpdateEntry(url_, drive_metadata_, callback);
 }
 
-void LocalSyncDelegate::SetMetadataConflict(
-    const SyncStatusCallback& callback) {
-  has_drive_metadata_ = true;
-  drive_metadata_.set_conflicted(true);
-  drive_metadata_.set_to_be_fetched(false);
-  metadata_store()->UpdateEntry(url_, drive_metadata_, callback);
-}
-
 void LocalSyncDelegate::DeleteMetadata(const SyncStatusCallback& callback) {
   metadata_store()->DeleteEntry(url_, callback);
 }
@@ -522,23 +513,16 @@
     return;
   }
 
-  SetMetadataConflict(base::Bind(&LocalSyncDelegate::NotifyConflict,
-                                 weak_factory_.GetWeakPtr(), callback));
+  has_drive_metadata_ = true;
+  sync_service_->MarkConflict(
+      url_, &drive_metadata_,
+      base::Bind(&LocalSyncDelegate::DidMarkConflict,
+                 weak_factory_.GetWeakPtr(), callback));
 }
 
-void LocalSyncDelegate::NotifyConflict(const SyncStatusCallback& callback,
-                                       SyncStatusCode status) {
-  if (status != SYNC_STATUS_OK) {
-    callback.Run(status);
-    return;
-  }
-
-  sync_service_->NotifyObserversFileStatusChanged(
-      url_,
-      SYNC_FILE_STATUS_CONFLICTING,
-      SYNC_ACTION_NONE,
-      SYNC_DIRECTION_NONE);
-
+void LocalSyncDelegate::DidMarkConflict(
+    const SyncStatusCallback& callback,
+    SyncStatusCode status) {
   DidApplyLocalChange(callback, google_apis::HTTP_CONFLICT, status);
 }
 
diff --git a/chrome/browser/sync_file_system/drive_backend/local_sync_delegate.h b/chrome/browser/sync_file_system/drive_backend/local_sync_delegate.h
index 6ba2089..347b5f5 100644
--- a/chrome/browser/sync_file_system/drive_backend/local_sync_delegate.h
+++ b/chrome/browser/sync_file_system/drive_backend/local_sync_delegate.h
@@ -5,9 +5,11 @@
 #ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_LOCAL_SYNC_DELEGATE_H_
 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_LOCAL_SYNC_DELEGATE_H_
 
+#include <string>
+
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
 #include "webkit/browser/fileapi/file_system_url.h"
 #include "webkit/browser/fileapi/syncable/file_change.h"
@@ -102,8 +104,8 @@
       scoped_ptr<google_apis::ResourceEntry> entry);
 
   void HandleManualResolutionCase(const SyncStatusCallback& callback);
-  void NotifyConflict(const SyncStatusCallback& callback,
-                      SyncStatusCode status);
+  void DidMarkConflict(const SyncStatusCallback& callback,
+                       SyncStatusCode status);
 
   void HandleLocalWinCase(const SyncStatusCallback& callback);
   void HandleRemoteWinCase(const SyncStatusCallback& callback,
diff --git a/chrome/browser/sync_file_system/local_sync_operation_resolver.cc b/chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver.cc
similarity index 96%
rename from chrome/browser/sync_file_system/local_sync_operation_resolver.cc
rename to chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver.cc
index c0c410a..79461ce 100644
--- a/chrome/browser/sync_file_system/local_sync_operation_resolver.cc
+++ b/chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver.cc
@@ -1,11 +1,11 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/sync_file_system/local_sync_operation_resolver.h"
+#include "chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver.h"
 
 #include "base/logging.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
 
 namespace sync_file_system {
diff --git a/chrome/browser/sync_file_system/local_sync_operation_resolver.h b/chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver.h
similarity index 86%
rename from chrome/browser/sync_file_system/local_sync_operation_resolver.h
rename to chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver.h
index 95d71ac..d191205 100644
--- a/chrome/browser/sync_file_system/local_sync_operation_resolver.h
+++ b/chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_SYNC_OPERATION_RESOLVER_H_
-#define CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_SYNC_OPERATION_RESOLVER_H_
+#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_LOCAL_SYNC_OPERATION_RESOLVER_H_
+#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_LOCAL_SYNC_OPERATION_RESOLVER_H_
 
 #include "base/gtest_prod_util.h"
 #include "chrome/browser/sync_file_system/sync_operation_type.h"
@@ -56,4 +56,4 @@
 
 }  // namespace sync_file_system
 
-#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_SYNC_OPERATION_RESOLVER_H_
+#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_LOCAL_SYNC_OPERATION_RESOLVER_H_
diff --git a/chrome/browser/sync_file_system/local_sync_operation_resolver_unittest.cc b/chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver_unittest.cc
similarity index 97%
rename from chrome/browser/sync_file_system/local_sync_operation_resolver_unittest.cc
rename to chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver_unittest.cc
index f0903da..605de72 100644
--- a/chrome/browser/sync_file_system/local_sync_operation_resolver_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -7,7 +7,7 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
-#include "chrome/browser/sync_file_system/local_sync_operation_resolver.h"
+#include "chrome/browser/sync_file_system/drive_backend/local_sync_operation_resolver.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "webkit/browser/fileapi/syncable/file_change.h"
 #include "webkit/browser/fileapi/syncable/sync_file_type.h"
@@ -88,6 +88,7 @@
   typedef LocalSyncOperationResolver Resolver;
   typedef std::vector<SyncOperationType> ExpectedTypes;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(LocalSyncOperationResolverTest);
 };
 
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database.cc
index 6e52b51..468632e 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database.cc
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database.cc
@@ -4,59 +4,405 @@
 
 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
 
+#include <stack>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/location.h"
+#include "base/memory/scoped_vector.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/sequenced_task_runner.h"
+#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/task_runner_util.h"
+#include "base/threading/thread_restrictions.h"
 #include "chrome/browser/google_apis/drive_api_parser.h"
+#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
+#include "chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util.h"
+#include "chrome/browser/sync_file_system/logger.h"
+#include "third_party/leveldatabase/src/include/leveldb/db.h"
+#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
+#include "webkit/browser/fileapi/syncable/syncable_file_system_util.h"
+#include "webkit/common/fileapi/file_system_util.h"
 
 namespace sync_file_system {
 namespace drive_backend {
 
-MetadataDatabase::MetadataDatabase(base::SequencedTaskRunner* task_runner) {
-  NOTIMPLEMENTED();
+typedef MetadataDatabase::FileByAppID FileByAppID;
+typedef MetadataDatabase::FileByFileID FileByFileID;
+typedef MetadataDatabase::FileByParentAndTitle FileByParentAndTitle;
+typedef MetadataDatabase::FileSet FileSet;
+typedef MetadataDatabase::FilesByParent FilesByParent;
+
+const char kDatabaseVersionKey[] = "VERSION";
+const int64 kCurrentDatabaseVersion = 3;
+const char kServiceMetadataKey[] = "SERVICE";
+const char kFileMetadataKeyPrefix[] = "FILE: ";
+
+struct DatabaseContents {
+  scoped_ptr<ServiceMetadata> service_metadata;
+  ScopedVector<DriveFileMetadata> file_metadata;
+};
+
+namespace {
+
+std::string RemovePrefix(const std::string& str, const std::string& prefix) {
+  if (StartsWithASCII(str, prefix, true))
+    return str.substr(prefix.size());
+  return str;
+}
+
+void AdaptLevelDBStatusToSyncStatusCode(const SyncStatusCallback& callback,
+                                        const leveldb::Status& status) {
+  callback.Run(LevelDBStatusToSyncStatusCode(status));
+}
+
+void PutFileToBatch(const DriveFileMetadata& file, leveldb::WriteBatch* batch) {
+  std::string value;
+  bool success = file.SerializeToString(&value);
+  DCHECK(success);
+  batch->Put(kFileMetadataKeyPrefix + file.file_id(), value);
+}
+
+void PushChildrenToStack(const FilesByParent& files_by_parent,
+                         const std::string& folder_id,
+                         std::stack<std::string>* stack) {
+  FilesByParent::const_iterator found = files_by_parent.find(folder_id);
+  if (found == files_by_parent.end())
+    return;
+  const FileSet& children = found->second;
+  for (FileSet::const_iterator itr = children.begin();
+       itr != children.end(); ++itr)
+    stack->push((*itr)->file_id());
+}
+
+// Returns true if |db| has no content.
+bool IsDatabaseEmpty(leveldb::DB* db) {
+  DCHECK(db);
+  scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions()));
+  itr->SeekToFirst();
+  return !itr->Valid();
+}
+
+SyncStatusCode OpenDatabase(const base::FilePath& path,
+                            scoped_ptr<leveldb::DB>* db_out,
+                            bool* created) {
+  base::ThreadRestrictions::AssertIOAllowed();
+  DCHECK(db_out);
+  DCHECK(created);
+
+  leveldb::Options options;
+  options.max_open_files = 0;  // Use minimum.
+  options.create_if_missing = true;
+  leveldb::DB* db = NULL;
+  leveldb::Status db_status =
+      leveldb::DB::Open(options, path.AsUTF8Unsafe(), &db);
+  SyncStatusCode status = LevelDBStatusToSyncStatusCode(db_status);
+  if (status != SYNC_STATUS_OK) {
+    delete db;
+    return status;
+  }
+
+  *created = IsDatabaseEmpty(db);
+  db_out->reset(db);
+  return status;
+}
+
+SyncStatusCode MigrateDatabaseIfNeeded(leveldb::DB* db) {
+  base::ThreadRestrictions::AssertIOAllowed();
+  DCHECK(db);
+  std::string value;
+  leveldb::Status status =
+      db->Get(leveldb::ReadOptions(), kDatabaseVersionKey, &value);
+  int64 version = 0;
+  if (status.ok()) {
+    if (!base::StringToInt64(value, &version))
+      return SYNC_DATABASE_ERROR_FAILED;
+  } else {
+    if (!status.IsNotFound())
+      return SYNC_DATABASE_ERROR_FAILED;
+  }
+
+  switch (version) {
+    case 0:
+      drive_backend::MigrateDatabaseFromV0ToV1(db);
+      // fall-through
+    case 1:
+      drive_backend::MigrateDatabaseFromV1ToV2(db);
+      // fall-through
+    case 2:
+      // TODO(tzik): Migrate database from version 2 to 3.
+      //   * Add sync-root folder as active, dirty and needs_folder_listing
+      //     folder.
+      //   * Add app-root folders for each origins.  Each app-root folder for
+      //     an enabled origin should be a active, dirty and
+      //     needs_folder_listing folder.  And Each app-root folder for a
+      //     disabled origin should be an inactive, dirty and
+      //     non-needs_folder_listing folder.
+      //   * Add a file metadata for each file in previous version.
+      NOTIMPLEMENTED();
+      return SYNC_DATABASE_ERROR_FAILED;
+      // fall-through
+    case 3:
+      DCHECK_EQ(3, kCurrentDatabaseVersion);
+      return SYNC_STATUS_OK;
+    default:
+      return SYNC_DATABASE_ERROR_FAILED;
+  }
+}
+
+SyncStatusCode WriteVersionInfo(leveldb::DB* db) {
+  base::ThreadRestrictions::AssertIOAllowed();
+  DCHECK(db);
+  return LevelDBStatusToSyncStatusCode(
+      db->Put(leveldb::WriteOptions(),
+              kDatabaseVersionKey,
+              base::Int64ToString(kCurrentDatabaseVersion)));
+}
+
+SyncStatusCode ReadDatabaseContents(leveldb::DB* db,
+                                    DatabaseContents* contents) {
+  base::ThreadRestrictions::AssertIOAllowed();
+  DCHECK(db);
+  DCHECK(contents);
+
+  scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions()));
+  for (itr->SeekToFirst(); itr->Valid(); itr->Next()) {
+    std::string key = itr->key().ToString();
+    std::string value = itr->value().ToString();
+    if (key == kServiceMetadataKey) {
+      scoped_ptr<ServiceMetadata> service_metadata(new ServiceMetadata);
+      if (!service_metadata->ParseFromString(value)) {
+        util::Log(logging::LOG_WARNING, FROM_HERE,
+                  "Failed to parse SyncServiceMetadata");
+        continue;
+      }
+
+      contents->service_metadata = service_metadata.Pass();
+      continue;
+    }
+
+    if (StartsWithASCII(key, kFileMetadataKeyPrefix, true)) {
+      std::string file_id = RemovePrefix(key, kFileMetadataKeyPrefix);
+
+      scoped_ptr<DriveFileMetadata> metadata(new DriveFileMetadata);
+      if (!metadata->ParseFromString(itr->value().ToString())) {
+        util::Log(logging::LOG_WARNING, FROM_HERE,
+                  "Failed to parse a Metadata");
+        continue;
+      }
+
+      contents->file_metadata.push_back(metadata.release());
+      continue;
+    }
+  }
+
+  return SYNC_STATUS_OK;
+}
+
+SyncStatusCode InitializeServiceMetadata(DatabaseContents* contents,
+                                         leveldb::WriteBatch* batch) {
+
+  if (!contents->service_metadata) {
+    contents->service_metadata.reset(new ServiceMetadata);
+
+    std::string value;
+    contents->service_metadata->SerializeToString(&value);
+    batch->Put(kServiceMetadataKey, value);
+  }
+  return SYNC_STATUS_OK;
+}
+
+SyncStatusCode RemoveUnreachableFiles(DatabaseContents* contents,
+                                      leveldb::WriteBatch* batch) {
+  FileByFileID unvisited_files;
+  FilesByParent files_by_parent;
+
+  for (ScopedVector<DriveFileMetadata>::iterator itr =
+           contents->file_metadata.begin();
+       itr != contents->file_metadata.end();
+       ++itr) {
+    DriveFileMetadata* metadata = *itr;
+    DCHECK(!ContainsKey(unvisited_files, metadata->file_id()));
+    unvisited_files[metadata->file_id()] = metadata;
+    files_by_parent[metadata->parent_folder_id()].insert(metadata);
+  }
+
+  // Traverse synced metadata tree. Take only active items and their children.
+  // Drop unreachable items.
+  ScopedVector<DriveFileMetadata> reachable_files;
+  std::stack<std::string> pending;
+  if (!contents->service_metadata->sync_root_folder_id().empty())
+    pending.push(contents->service_metadata->sync_root_folder_id());
+
+  while (!pending.empty()) {
+    std::string file_id = pending.top();
+    pending.pop();
+
+    {
+      FileByFileID::iterator found = unvisited_files.find(file_id);
+      if (found == unvisited_files.end())
+        continue;
+
+      DriveFileMetadata* metadata = found->second;
+      unvisited_files.erase(found);
+      reachable_files.push_back(metadata);
+
+      if (!metadata->active())
+        continue;
+    }
+
+    FilesByParent::iterator found = files_by_parent.find(file_id);
+    if (found == files_by_parent.end())
+      continue;
+
+    for (FileSet::const_iterator itr = found->second.begin();
+         itr != found->second.end();
+         ++itr)
+      pending.push((*itr)->file_id());
+  }
+
+  for (FileByFileID::iterator itr = unvisited_files.begin();
+       itr != unvisited_files.end();
+       ++itr) {
+    DriveFileMetadata* metadata = itr->second;
+    batch->Delete(metadata->file_id());
+    delete metadata;
+  }
+  unvisited_files.clear();
+
+  // |reachable_files| contains all files/folders reachable from sync-root
+  // folder via active folders.
+  contents->file_metadata.weak_clear();
+  contents->file_metadata.swap(reachable_files);
+
+  return SYNC_STATUS_OK;
+}
+
+template <typename Container, typename Key, typename Value>
+bool FindItem(const Container& container, const Key& key, Value* value) {
+  typename Container::const_iterator found = container.find(key);
+  if (found == container.end())
+    return false;
+  if (value)
+    *value = *found->second;
+  return true;
+}
+
+void RunSoon(const tracked_objects::Location& from_here,
+             const base::Closure& closure) {
+  base::MessageLoopProxy::current()->PostTask(from_here, closure);
+}
+
+}  // namespace
+
+bool MetadataDatabase::FileIDComparator::operator()(
+    DriveFileMetadata* left,
+    DriveFileMetadata* right) const {
+  return left->file_id() < right->file_id();
+}
+
+// static
+void MetadataDatabase::Create(base::SequencedTaskRunner* task_runner,
+                              const base::FilePath& database_path,
+                              const CreateCallback& callback) {
+  task_runner->PostTask(FROM_HERE, base::Bind(
+      &CreateOnTaskRunner,
+      base::MessageLoopProxy::current(),
+      make_scoped_refptr(task_runner),
+      database_path, callback));
 }
 
 MetadataDatabase::~MetadataDatabase() {
-}
-
-void MetadataDatabase::Initialize(const base::FilePath& database_dir,
-                                  const SyncStatusCallback& callback) {
-  NOTIMPLEMENTED();
+  task_runner_->DeleteSoon(FROM_HERE, db_.release());
+  STLDeleteContainerPairSecondPointers(
+      file_by_file_id_.begin(), file_by_file_id_.end());
 }
 
 int64 MetadataDatabase::GetLargestChangeID() const {
-  NOTIMPLEMENTED();
-  return 0;
+  return service_metadata_->largest_change_id();
 }
 
 void MetadataDatabase::RegisterApp(const std::string& app_id,
                                    const std::string& folder_id,
                                    const SyncStatusCallback& callback) {
-  NOTIMPLEMENTED();
+  if (FindAppRootFolder(app_id, NULL)) {
+    RunSoon(FROM_HERE, base::Bind(callback, SYNC_STATUS_OK));
+    return;
+  }
+
+  DriveFileMetadata folder;
+  if (!FindFileByFileID(folder_id, &folder)) {
+    RunSoon(FROM_HERE, base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND));
+    return;
+  }
+
+  DCHECK(!folder.active());
+  scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
+  RegisterFolderAsAppRoot(app_id, folder.file_id(), batch.get());
+  WriteToDatabase(batch.Pass(), callback);
 }
 
 void MetadataDatabase::DisableApp(const std::string& app_id,
-                                 const SyncStatusCallback& callback) {
-  NOTIMPLEMENTED();
+                                  const SyncStatusCallback& callback) {
+  DriveFileMetadata folder;
+  if (!FindAppRootFolder(app_id, &folder)) {
+    RunSoon(FROM_HERE, base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND));
+    return;
+  }
+
+  if (!folder.active()) {
+    RunSoon(FROM_HERE, base::Bind(callback, SYNC_STATUS_OK));
+    return;
+  }
+
+  scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
+  MakeFileInactive(folder.file_id(), batch.get());
+  WriteToDatabase(batch.Pass(), callback);
 }
 
 void MetadataDatabase::EnableApp(const std::string& app_id,
                                  const SyncStatusCallback& callback) {
-  NOTIMPLEMENTED();
+  DriveFileMetadata folder;
+  if (!FindAppRootFolder(app_id, &folder)) {
+    RunSoon(FROM_HERE, base::Bind(callback, SYNC_DATABASE_ERROR_NOT_FOUND));
+    return;
+  }
+
+  if (folder.active()) {
+    RunSoon(FROM_HERE, base::Bind(callback, SYNC_STATUS_OK));
+    return;
+  }
+
+  scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
+  MakeFileActive(folder.file_id(), batch.get());
+  WriteToDatabase(batch.Pass(), callback);
 }
 
 void MetadataDatabase::UnregisterApp(const std::string& app_id,
                                      const SyncStatusCallback& callback) {
-  NOTIMPLEMENTED();
+  DriveFileMetadata folder;
+  if (!FindAppRootFolder(app_id, &folder)) {
+    RunSoon(FROM_HERE, base::Bind(callback, SYNC_STATUS_OK));
+    return;
+  }
+
+  scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
+  UnregisterFolderAsAppRoot(app_id, batch.get());
+  WriteToDatabase(batch.Pass(), callback);
 }
 
 bool MetadataDatabase::FindAppRootFolder(const std::string& app_id,
                                          DriveFileMetadata* folder) const {
-  NOTIMPLEMENTED();
-  return false;
+  return FindItem(app_root_by_app_id_, app_id, folder);
 }
 
 bool MetadataDatabase::FindFileByFileID(const std::string& file_id,
                                         DriveFileMetadata* metadata) const {
-  NOTIMPLEMENTED();
-  return false;
+  return FindItem(file_by_file_id_, file_id, metadata);
 }
 
 size_t MetadataDatabase::FindFilesByParentAndTitle(
@@ -71,19 +417,38 @@
     const std::string& folder_id,
     const std::string& title,
     DriveFileMetadata* file) const {
-  NOTIMPLEMENTED();
-  return false;
+  return FindItem(active_file_by_parent_and_title_,
+                  std::make_pair(folder_id, title),
+                  file);
 }
 
 bool MetadataDatabase::FindActiveFileByPath(const std::string& app_id,
                                             const base::FilePath& path,
                                             DriveFileMetadata* file) const {
-  NOTIMPLEMENTED();
-  return false;
+  DriveFileMetadata current;
+  if (!FindAppRootFolder(app_id, &current))
+    return false;
+
+  std::vector<base::FilePath::StringType> components;
+  path.GetComponents(&components);
+
+  std::string parent_folder_id = current.file_id();
+  for (std::vector<base::FilePath::StringType>::iterator itr =
+           components.begin();
+       itr != components.end();
+       ++itr) {
+    std::string current_folder_id = current.file_id();
+    if (!FindActiveFileByParentAndTitle(
+            current_folder_id, base::FilePath(*itr).AsUTF8Unsafe(), &current))
+      return false;
+  }
+  if (file)
+    *file = current;
+  return true;
 }
 
-bool MetadataDatabase::ConstructPathForFile(const std::string& file_id,
-                                            base::FilePath* path) const {
+bool MetadataDatabase::BuildPathForFile(const std::string& file_id,
+                                        base::FilePath* path) const {
   NOTIMPLEMENTED();
   return false;
 }
@@ -101,5 +466,247 @@
   NOTIMPLEMENTED();
 }
 
+MetadataDatabase::MetadataDatabase(base::SequencedTaskRunner* task_runner)
+    : task_runner_(task_runner), weak_ptr_factory_(this) {
+  DCHECK(task_runner);
+}
+
+// static
+void MetadataDatabase::CreateOnTaskRunner(
+    base::SingleThreadTaskRunner* callback_runner,
+    base::SequencedTaskRunner* task_runner,
+    const base::FilePath& database_path,
+    const CreateCallback& callback) {
+  scoped_ptr<MetadataDatabase> metadata_database(
+      new MetadataDatabase(task_runner));
+  SyncStatusCode status =
+      metadata_database->InitializeOnTaskRunner(database_path);
+  if (status != SYNC_STATUS_OK)
+    metadata_database.reset();
+
+  callback_runner->PostTask(FROM_HERE, base::Bind(
+      callback, status, base::Passed(&metadata_database)));
+}
+
+// static
+SyncStatusCode MetadataDatabase::CreateForTesting(
+    scoped_ptr<leveldb::DB> db,
+    scoped_ptr<MetadataDatabase>* metadata_database_out) {
+  scoped_ptr<MetadataDatabase> metadata_database(
+      new MetadataDatabase(base::MessageLoopProxy::current()));
+  metadata_database->db_ = db.Pass();
+  SyncStatusCode status =
+      metadata_database->InitializeOnTaskRunner(base::FilePath());
+  if (status == SYNC_STATUS_OK)
+    *metadata_database_out = metadata_database.Pass();
+  return status;
+}
+
+SyncStatusCode MetadataDatabase::InitializeOnTaskRunner(
+    const base::FilePath& database_path) {
+  base::ThreadRestrictions::AssertIOAllowed();
+  DCHECK(task_runner_->RunsTasksOnCurrentThread());
+
+  SyncStatusCode status = SYNC_STATUS_UNKNOWN;
+  bool created = false;
+  // Open database unless |db_| is overridden for testing.
+  if (!db_) {
+    status = OpenDatabase(database_path, &db_, &created);
+    if (status != SYNC_STATUS_OK)
+      return status;
+  }
+
+  if (created) {
+    status = WriteVersionInfo(db_.get());
+    if (status != SYNC_STATUS_OK)
+      return status;
+  } else {
+    status = MigrateDatabaseIfNeeded(db_.get());
+    if (status != SYNC_STATUS_OK)
+      return status;
+  }
+
+  DatabaseContents contents;
+  status = ReadDatabaseContents(db_.get(), &contents);
+  if (status != SYNC_STATUS_OK)
+    return status;
+
+  leveldb::WriteBatch batch;
+  status = InitializeServiceMetadata(&contents, &batch);
+  if (status != SYNC_STATUS_OK)
+    return status;
+
+  status = RemoveUnreachableFiles(&contents, &batch);
+  if (status != SYNC_STATUS_OK)
+    return status;
+
+  status = LevelDBStatusToSyncStatusCode(
+      db_->Write(leveldb::WriteOptions(), &batch));
+  if (status != SYNC_STATUS_OK)
+    return status;
+
+  BuildIndexes(&contents);
+  return status;
+}
+
+void MetadataDatabase::BuildIndexes(DatabaseContents* contents) {
+  for (ScopedVector<DriveFileMetadata>::iterator itr =
+           contents->file_metadata.begin();
+       itr != contents->file_metadata.end();
+       ++itr) {
+    DriveFileMetadata* file = *itr;
+    file_by_file_id_[file->file_id()] = file;
+
+    if (file->is_app_root())
+      app_root_by_app_id_[file->app_id()] = file;
+
+    if (file->active() && file->has_synced_details()) {
+      FileByParentAndTitle::key_type key(
+          file->parent_folder_id(), file->synced_details().title());
+      active_file_by_parent_and_title_[key] = file;
+    }
+
+    if (!file->parent_folder_id().empty())
+      files_by_parent_[file->parent_folder_id()].insert(file);
+
+    if (file->dirty())
+      dirty_files_.insert(file);
+  }
+
+  contents->file_metadata.weak_clear();
+}
+
+void MetadataDatabase::RegisterFolderAsAppRoot(
+    const std::string& app_id,
+    const std::string& folder_id,
+    leveldb::WriteBatch* batch) {
+  DriveFileMetadata* folder = file_by_file_id_[folder_id];
+  if (!folder || folder->active() || folder->is_app_root() ||
+      !folder->app_id().empty()) {
+    NOTREACHED();
+    return;
+  }
+
+  folder->set_is_app_root(true);
+  folder->set_app_id(app_id);
+  folder->set_active(true);
+  folder->set_dirty(true);
+  folder->set_needs_folder_listing(true);
+  PutFileToBatch(*folder, batch);
+
+  app_root_by_app_id_[app_id] = folder;
+  if (folder->has_synced_details()) {
+    FileByParentAndTitle::key_type key(
+        folder->parent_folder_id(), folder->synced_details().title());
+    DCHECK(!ContainsKey(active_file_by_parent_and_title_, key));
+    active_file_by_parent_and_title_[key] = folder;
+  }
+  dirty_files_.insert(folder);
+}
+
+void MetadataDatabase::UnregisterFolderAsAppRoot(
+    const std::string& app_id,
+    leveldb::WriteBatch* batch) {
+  DriveFileMetadata* folder = app_root_by_app_id_[app_id];
+  if (!folder || !folder->active() ||
+      folder->app_id() != app_id || !folder->is_app_root()) {
+    NOTREACHED();
+    return;
+  }
+
+  folder->set_active(false);
+  folder->set_is_app_root(false);
+  folder->set_app_id(std::string());
+  PutFileToBatch(*folder, batch);
+
+  // Remove child entries recursively.
+  std::stack<std::string> pending_files;
+  PushChildrenToStack(files_by_parent_, folder->file_id(), &pending_files);
+  while (!pending_files.empty()) {
+    std::string file_id = pending_files.top();
+    pending_files.pop();
+    PushChildrenToStack(files_by_parent_, file_id, &pending_files);
+    RemoveFile(file_id, batch);
+  }
+
+  app_root_by_app_id_.erase(app_id);
+  if (folder->has_synced_details()) {
+    FileByParentAndTitle::key_type key(
+        folder->parent_folder_id(), folder->synced_details().title());
+    active_file_by_parent_and_title_.erase(key);
+  }
+}
+
+void MetadataDatabase::MakeFileActive(const std::string& file_id,
+                                      leveldb::WriteBatch* batch) {
+  DriveFileMetadata* file = file_by_file_id_[file_id];
+  if (!file || file->active()) {
+    NOTREACHED();
+    return;
+  }
+
+  file->set_active(true);
+  if (file->has_synced_details() &&
+      file->synced_details().kind() == KIND_FOLDER)
+    file->set_needs_folder_listing(true);
+  PutFileToBatch(*file, batch);
+
+  if (file->has_synced_details()) {
+    FileByParentAndTitle::key_type key(
+        file->parent_folder_id(), file->synced_details().title());
+    DCHECK(!ContainsKey(active_file_by_parent_and_title_, key));
+    active_file_by_parent_and_title_[key] = file;
+  }
+}
+
+void MetadataDatabase::MakeFileInactive(const std::string& file_id,
+                                        leveldb::WriteBatch* batch) {
+  DriveFileMetadata* file = file_by_file_id_[file_id];
+  if (!file || !file->active()) {
+    NOTREACHED();
+    return;
+  }
+
+  file->set_active(false);
+  PutFileToBatch(*file, batch);
+
+  if (file->has_synced_details()) {
+    FileByParentAndTitle::key_type key(
+        file->parent_folder_id(), file->synced_details().title());
+    DCHECK(ContainsKey(active_file_by_parent_and_title_, key));
+    active_file_by_parent_and_title_.erase(key);
+  }
+}
+
+void MetadataDatabase::RemoveFile(const std::string& file_id,
+                                  leveldb::WriteBatch* batch) {
+  scoped_ptr<DriveFileMetadata> file(file_by_file_id_[file_id]);
+  file_by_file_id_.erase(file_id);
+
+  batch->Delete(file->file_id());
+
+  files_by_parent_[file->parent_folder_id()].erase(file.get());
+  if (file->is_app_root())
+    app_root_by_app_id_.erase(file->app_id());
+  if (file->active() && file->has_synced_details()) {
+    FileByParentAndTitle::key_type key(
+        file->parent_folder_id(), file->synced_details().title());
+    active_file_by_parent_and_title_.erase(key);
+  }
+  dirty_files_.erase(file.get());
+}
+
+void MetadataDatabase::WriteToDatabase(scoped_ptr<leveldb::WriteBatch> batch,
+                                       const SyncStatusCallback& callback) {
+  base::PostTaskAndReplyWithResult(
+      task_runner_.get(),
+      FROM_HERE,
+      base::Bind(&leveldb::DB::Write,
+                 base::Unretained(db_.get()),
+                 leveldb::WriteOptions(),
+                 base::Owned(batch.release())),
+      base::Bind(&AdaptLevelDBStatusToSyncStatusCode, callback));
+}
+
 }  // namespace drive_backend
 }  // namespace sync_file_system
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database.h b/chrome/browser/sync_file_system/drive_backend/metadata_database.h
index 967950a..a248f9a 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database.h
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database.h
@@ -5,15 +5,20 @@
 #ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_
 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_
 
+#include <map>
+#include <string>
+
 #include "base/callback_forward.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
+#include "base/memory/weak_ptr.h"
 #include "webkit/browser/fileapi/syncable/sync_callbacks.h"
 #include "webkit/browser/fileapi/syncable/sync_status_code.h"
 
 namespace base {
 class FilePath;
 class SequencedTaskRunner;
+class SingleThreadTaskRunner;
 }
 
 namespace leveldb {
@@ -32,18 +37,63 @@
 
 class ServiceMetadata;
 class DriveFileMetadata;
-struct InitializeInfo;
+struct DatabaseContents;
 
-// This class holds a snapshot of the server side metadata.
+// MetadataDatabase instance holds and maintains database and its indexes.  The
+// database holds metadata of the server-side files/folders as
+// DriveFileMetadata instances.
+// The term "file" includes files, folders and other resources on Drive.
+//
+// Files have following state:
+//   - Unknown file
+//     - Is initial state of the files, only file_id and parent_folder_id field
+//       are known.
+//     - Has empty synced_details, must be active and dirty.
+//   - Folder
+//     - Is either one of sync-root folder, app-root folder or a regular folder.
+//     - Sync-root folder holds app-root folders as its direct children, and
+//       holds entire SyncFileSystem files as its descentants.  Its file_id is
+//       stored in ServiceMetadata.
+//     - App-root folder holds all files for an application as its descendants.
+//   - File
+//   - Unsupported file
+//     - Represents unsupported files such as hosted documents. Must be
+//       inactive.
+//
+// Invariants:
+//   - Any file in the database must either:
+//     - be sync-root,
+//     - have an app-root as its parent folder, or
+//     - have an active folder as its parent.
+//   That is, all files must be reachable from sync-root via app-root folders
+//   and active folders.
+//
+//   - Any active folder must either:
+//     - have needs_folder_listing flag and dirty flag, or
+//     - have all children at the stored largest change id.
+//
 class MetadataDatabase {
- public:
-  explicit MetadataDatabase(base::SequencedTaskRunner* task_runner);
-  ~MetadataDatabase();
+ private:
+  struct FileIDComparator {
+    bool operator()(DriveFileMetadata* left, DriveFileMetadata* right) const;
+  };
 
-  // Initializes the internal database and loads its content to memory.
-  // This function works asynchronously.
-  void Initialize(const base::FilePath& database_path,
-                  const SyncStatusCallback& callback);
+ public:
+  typedef std::set<DriveFileMetadata*, FileIDComparator> FileSet;
+  typedef std::map<std::string, DriveFileMetadata*> FileByFileID;
+  typedef std::map<std::string, FileSet> FilesByParent;
+  typedef std::map<std::pair<std::string, std::string>, DriveFileMetadata*>
+      FileByParentAndTitle;
+  typedef std::map<std::string, DriveFileMetadata*> FileByAppID;
+
+  typedef base::Callback<
+      void(SyncStatusCode status, scoped_ptr<MetadataDatabase> instance)>
+      CreateCallback;
+
+  static void Create(base::SequencedTaskRunner* task_runner,
+                     const base::FilePath& database_path,
+                     const CreateCallback& callback);
+  ~MetadataDatabase();
 
   int64 GetLargestChangeID() const;
 
@@ -64,8 +114,8 @@
   void EnableApp(const std::string& app_id,
                  const SyncStatusCallback& callback);
 
-  // Unregister the folder as the app-root for |app_id|.  If |app_id| does not
-  // exist, does nothing.
+  // Unregisters the folder as the app-root for |app_id|.  If |app_id| does not
+  // exist, does nothing.  The folder is left as an inactive normal folder.
   void UnregisterApp(const std::string& app_id,
                      const SyncStatusCallback& callback);
 
@@ -107,8 +157,8 @@
 
   // Looks up FilePath from FileID.  Returns true on success.
   // |path| must be non-NULL.
-  bool ConstructPathForFile(const std::string& file_id,
-                            base::FilePath* path) const;
+  bool BuildPathForFile(const std::string& file_id,
+                        base::FilePath* path) const;
 
   // Updates database by |changes|.
   // Marks dirty for each changed file if the file has the metadata in the
@@ -124,6 +174,48 @@
                       const SyncStatusCallback& callback);
 
  private:
+  friend class MetadataDatabaseTest;
+
+  explicit MetadataDatabase(base::SequencedTaskRunner* task_runner);
+  static void CreateOnTaskRunner(base::SingleThreadTaskRunner* callback_runner,
+                                 base::SequencedTaskRunner* task_runner,
+                                 const base::FilePath& database_path,
+                                 const CreateCallback& callback);
+  static SyncStatusCode CreateForTesting(
+      scoped_ptr<leveldb::DB> db,
+      scoped_ptr<MetadataDatabase>* metadata_database_out);
+  SyncStatusCode InitializeOnTaskRunner(const base::FilePath& database_path);
+  void BuildIndexes(DatabaseContents* contents);
+
+  // Database manipulation methods.
+  void RegisterFolderAsAppRoot(const std::string& app_id,
+                               const std::string& folder,
+                               leveldb::WriteBatch* batch);
+  void MakeFileActive(const std::string& file,
+                      leveldb::WriteBatch* batch);
+  void MakeFileInactive(const std::string& file,
+                        leveldb::WriteBatch* batch);
+  void UnregisterFolderAsAppRoot(const std::string& app_id,
+                                 leveldb::WriteBatch* batch);
+  void RemoveFile(const std::string& file,
+                  leveldb::WriteBatch* batch);
+
+  void WriteToDatabase(scoped_ptr<leveldb::WriteBatch> batch,
+                       const SyncStatusCallback& callback);
+
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
+  scoped_ptr<leveldb::DB> db_;
+
+  scoped_ptr<ServiceMetadata> service_metadata_;
+  FileByFileID file_by_file_id_;  // Owned.
+
+  FilesByParent files_by_parent_;  // Not owned.
+  FileByAppID app_root_by_app_id_;  // Not owned.
+  FileByParentAndTitle active_file_by_parent_and_title_;  // Not owned.
+  FileSet dirty_files_;  // Not owned.
+
+  base::WeakPtrFactory<MetadataDatabase> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(MetadataDatabase);
 };
 
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database.proto b/chrome/browser/sync_file_system/drive_backend/metadata_database.proto
index 05a9c81..aee00fd 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database.proto
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database.proto
@@ -17,7 +17,7 @@
 }
 
 message ServiceMetadata {
-  optional int64 largest_change_id = 1 [default = 0];
+  optional int64 largest_change_id = 1;
   optional string sync_root_folder_id = 2;
 }
 
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
new file mode 100644
index 0000000..d8fa77d
--- /dev/null
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
@@ -0,0 +1,397 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
+
+#include "base/bind.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/strings/string_number_conversions.h"
+#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/leveldatabase/src/include/leveldb/db.h"
+#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
+
+namespace sync_file_system {
+namespace drive_backend {
+
+typedef MetadataDatabase::FileSet FileSet;
+typedef MetadataDatabase::FileByFileID FileByFileID;
+typedef MetadataDatabase::FilesByParent FilesByParent;
+typedef MetadataDatabase::FileByParentAndTitle FileByParentAndTitle;
+typedef MetadataDatabase::FileByAppID FileByAppID;
+
+namespace {
+
+const int64 kInitialChangeID = 1234;
+const char kSyncRootFolderID[] = "sync_root_folder_id";
+
+bool AreEquivalentMessages(const google::protobuf::MessageLite& left,
+                           const google::protobuf::MessageLite& right);
+bool AreEquivalent(const google::protobuf::MessageLite* left,
+                   const google::protobuf::MessageLite* right) {
+  return AreEquivalentMessages(*left, *right);
+}
+
+template <typename Container>
+bool AreEquivalentMaps(const Container& left, const Container& right);
+template <typename Key, typename Value, typename Compare>
+bool AreEquivalent(const std::map<Key, Value, Compare>& left,
+                   const std::map<Key, Value, Compare>& right) {
+  return AreEquivalentMaps(left, right);
+}
+
+template <typename Container>
+bool AreEquivalentSets(const Container& left, const Container& right);
+template <typename Value, typename Compare>
+bool AreEquivalent(const std::set<Value, Compare>& left,
+                   const std::set<Value, Compare>& right) {
+  return AreEquivalentSets(left, right);
+}
+
+bool AreEquivalentMessages(const google::protobuf::MessageLite& left,
+                           const google::protobuf::MessageLite& right) {
+  std::string serialized_left;
+  std::string serialized_right;
+  left.SerializeToString(&serialized_left);
+  right.SerializeToString(&serialized_right);
+  return serialized_left == serialized_right;
+}
+
+template <typename Container>
+bool AreEquivalentMaps(const Container& left, const Container& right) {
+  if (left.size() != right.size())
+    return false;
+
+  typedef typename Container::const_iterator const_iterator;
+  const_iterator left_itr = left.begin();
+  const_iterator right_itr = right.begin();
+
+  while (left_itr != left.end()) {
+    if (left_itr->first != right_itr->first)
+      return false;
+    if (!AreEquivalent(left_itr->second, right_itr->second))
+      return false;
+
+    ++left_itr;
+    ++right_itr;
+  }
+  return true;
+}
+
+template <typename Container>
+bool AreEquivalentSets(const Container& left, const Container& right) {
+  if (left.size() != right.size())
+    return false;
+
+  typedef typename Container::const_iterator const_iterator;
+  const_iterator left_itr = left.begin();
+  const_iterator right_itr = right.begin();
+  while (left_itr != left.end()) {
+    if (!AreEquivalent(*left_itr, *right_itr))
+      return false;
+    ++left_itr;
+    ++right_itr;
+  }
+  return true;
+}
+
+void SyncStatusResultCallback(SyncStatusCode* status_out,
+                              SyncStatusCode status) {
+  EXPECT_EQ(SYNC_STATUS_UNKNOWN, *status_out);
+  *status_out = status;
+}
+
+void DatabaseCreateResultCallback(SyncStatusCode* status_out,
+                                  scoped_ptr<MetadataDatabase>* database_out,
+                                  SyncStatusCode status,
+                                  scoped_ptr<MetadataDatabase> database) {
+  EXPECT_EQ(SYNC_STATUS_UNKNOWN, *status_out);
+  *status_out = status;
+  *database_out = database.Pass();
+}
+
+}  // namespace
+
+class MetadataDatabaseTest : public testing::Test {
+ public:
+  MetadataDatabaseTest() : next_file_id_number_(1) {}
+
+  virtual ~MetadataDatabaseTest() {}
+
+  virtual void SetUp() OVERRIDE {
+    ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
+  }
+
+  virtual void TearDown() OVERRIDE { DropDatabase(); }
+
+ protected:
+  std::string GenerateFileID() {
+    return "file_id_" + base::Int64ToString(next_file_id_number_++);
+  }
+
+  SyncStatusCode InitializeDatabase() {
+    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
+    MetadataDatabase::Create(base::MessageLoopProxy::current(),
+                             database_dir_.path(),
+                             base::Bind(&DatabaseCreateResultCallback,
+                                        &status, &metadata_database_));
+    message_loop_.RunUntilIdle();
+    return status;
+  }
+
+  void DropDatabase() {
+    metadata_database_.reset();
+    message_loop_.RunUntilIdle();
+  }
+
+  MetadataDatabase* metadata_database() { return metadata_database_.get(); }
+
+  leveldb::DB* db() {
+    if (!metadata_database_)
+      return NULL;
+    return metadata_database_->db_.get();
+  }
+
+  scoped_ptr<leveldb::DB> OpenLevelDB() {
+    leveldb::DB* db = NULL;
+    leveldb::Options options;
+    options.create_if_missing = true;
+    options.max_open_files = 0;  // Use minimum.
+    leveldb::Status status =
+        leveldb::DB::Open(options, database_dir_.path().AsUTF8Unsafe(), &db);
+    EXPECT_TRUE(status.ok());
+    return make_scoped_ptr(db);
+  }
+
+  void SetUpServiceMetadata(leveldb::DB* db) {
+    ServiceMetadata service_metadata;
+    service_metadata.set_largest_change_id(kInitialChangeID);
+    service_metadata.set_sync_root_folder_id(kSyncRootFolderID);
+    std::string value;
+    ASSERT_TRUE(service_metadata.SerializeToString(&value));
+    db->Put(leveldb::WriteOptions(), "SERVICE", value);
+  }
+
+  DriveFileMetadata CreateSyncRoot() {
+    DriveFileMetadata metadata;
+    metadata.set_file_id(kSyncRootFolderID);
+    metadata.set_parent_folder_id(std::string());
+    metadata.mutable_synced_details()->set_title("Chrome Syncable FileSystem");
+    metadata.mutable_synced_details()->set_kind(KIND_FOLDER);
+    metadata.set_active(true);
+    metadata.set_dirty(false);
+    return metadata;
+  }
+
+  DriveFileMetadata CreateUnknownFile(const std::string& app_id,
+                                      const std::string& parent_folder_id) {
+    DriveFileMetadata metadata;
+    metadata.set_file_id(GenerateFileID());
+    metadata.set_parent_folder_id(parent_folder_id);
+    metadata.set_app_id(app_id);
+    metadata.set_is_app_root(
+        !app_id.empty() && parent_folder_id == kSyncRootFolderID);
+    return metadata;
+  }
+
+  DriveFileMetadata CreateFile(const std::string& app_id,
+                               const std::string& parent_folder_id,
+                               const std::string& title) {
+    DriveFileMetadata file(CreateUnknownFile(app_id, parent_folder_id));
+    file.mutable_synced_details()->add_parent_folder_id(parent_folder_id);
+    file.mutable_synced_details()->set_title(title);
+    file.mutable_synced_details()->set_kind(KIND_FILE);
+    file.set_active(true);
+    file.set_dirty(false);
+    return file;
+  }
+
+  DriveFileMetadata CreateFolder(const std::string& app_id,
+                                 const std::string& parent_folder_id,
+                                 const std::string& title) {
+    DriveFileMetadata folder(CreateUnknownFile(app_id, parent_folder_id));
+    folder.mutable_synced_details()->add_parent_folder_id(parent_folder_id);
+    folder.mutable_synced_details()->set_title(title);
+    folder.mutable_synced_details()->set_kind(KIND_FOLDER);
+    folder.set_active(true);
+    folder.set_dirty(false);
+    return folder;
+  }
+
+  leveldb::Status PutFileToDB(leveldb::DB* db, const DriveFileMetadata& file) {
+    std::string key = "FILE: " + file.file_id();
+    std::string value;
+    file.SerializeToString(&value);
+    return db->Put(leveldb::WriteOptions(), key, value);
+  }
+
+  void VerifyReloadConsistency() {
+    scoped_ptr<MetadataDatabase> metadata_database_2;
+    ASSERT_EQ(SYNC_STATUS_OK,
+              MetadataDatabase::CreateForTesting(
+                  metadata_database_->db_.Pass(),
+                  &metadata_database_2));
+    metadata_database_->db_ = metadata_database_2->db_.Pass();
+
+    EXPECT_TRUE(AreEquivalent(metadata_database_->file_by_file_id_,
+                              metadata_database_2->file_by_file_id_));
+    EXPECT_TRUE(AreEquivalent(metadata_database_->files_by_parent_,
+                              metadata_database_2->files_by_parent_));
+    EXPECT_TRUE(AreEquivalent(metadata_database_->app_root_by_app_id_,
+                              metadata_database_2->app_root_by_app_id_));
+    EXPECT_TRUE(AreEquivalent(
+        metadata_database_->active_file_by_parent_and_title_,
+        metadata_database_2->active_file_by_parent_and_title_));
+    EXPECT_TRUE(AreEquivalent(metadata_database_->dirty_files_,
+                              metadata_database_2->dirty_files_));
+  }
+
+  void VerifyFile(const DriveFileMetadata& file) {
+    DriveFileMetadata file_in_metadata_db;
+    ASSERT_TRUE(metadata_database()->FindFileByFileID(
+        file.file_id(), &file_in_metadata_db));
+    EXPECT_TRUE(AreEquivalentMessages(file, file_in_metadata_db));
+  }
+
+  SyncStatusCode RegisterApp(const std::string& app_id,
+                             const std::string& folder_id) {
+    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
+    metadata_database_->RegisterApp(
+        app_id, folder_id,
+        base::Bind(&SyncStatusResultCallback, &status));
+    message_loop_.RunUntilIdle();
+    return status;
+  }
+
+  SyncStatusCode DisableApp(const std::string& app_id) {
+    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
+    metadata_database_->DisableApp(
+        app_id, base::Bind(&SyncStatusResultCallback, &status));
+    message_loop_.RunUntilIdle();
+    return status;
+  }
+
+  SyncStatusCode EnableApp(const std::string& app_id) {
+    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
+    metadata_database_->EnableApp(
+        app_id, base::Bind(&SyncStatusResultCallback, &status));
+    message_loop_.RunUntilIdle();
+    return status;
+  }
+
+  SyncStatusCode UnregisterApp(const std::string& app_id) {
+    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
+    metadata_database_->UnregisterApp(
+        app_id, base::Bind(&SyncStatusResultCallback, &status));
+    message_loop_.RunUntilIdle();
+    return status;
+  }
+
+ private:
+  base::ScopedTempDir database_dir_;
+  base::MessageLoop message_loop_;
+
+  scoped_ptr<MetadataDatabase> metadata_database_;
+
+  int64 next_file_id_number_;
+
+  DISALLOW_COPY_AND_ASSIGN(MetadataDatabaseTest);
+};
+
+TEST_F(MetadataDatabaseTest, InitializationTest_Empty) {
+  EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase());
+  DropDatabase();
+  EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase());
+}
+
+TEST_F(MetadataDatabaseTest, InitializationTest_SimpleTree) {
+  std::string app_id = "app_id";
+  DriveFileMetadata sync_root(CreateSyncRoot());
+  DriveFileMetadata app_root(CreateFolder(app_id, kSyncRootFolderID, app_id));
+  DriveFileMetadata file(CreateFile(app_id, app_root.file_id(), "file"));
+  DriveFileMetadata folder(CreateFolder(app_id, app_root.file_id(), "folder"));
+  DriveFileMetadata file_in_folder(
+      CreateFile(app_id, folder.file_id(), "file_in_folder"));
+  DriveFileMetadata orphaned(CreateUnknownFile(std::string(), "root"));
+
+  {
+    scoped_ptr<leveldb::DB> db = OpenLevelDB();
+    ASSERT_TRUE(db);
+    db->Put(leveldb::WriteOptions(), "VERSION", base::Int64ToString(3));
+    SetUpServiceMetadata(db.get());
+
+    EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok());
+    EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok());
+    EXPECT_TRUE(PutFileToDB(db.get(), file).ok());
+    EXPECT_TRUE(PutFileToDB(db.get(), folder).ok());
+    EXPECT_TRUE(PutFileToDB(db.get(), file_in_folder).ok());
+    EXPECT_TRUE(PutFileToDB(db.get(), orphaned).ok());
+  }
+
+  EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase());
+
+  VerifyFile(sync_root);
+  VerifyFile(app_root);
+  VerifyFile(file);
+  VerifyFile(folder);
+  VerifyFile(file_in_folder);
+  EXPECT_FALSE(metadata_database()->FindFileByFileID(orphaned.file_id(), NULL));
+}
+
+TEST_F(MetadataDatabaseTest, AppManagementTest) {
+  DriveFileMetadata sync_root(CreateSyncRoot());
+  DriveFileMetadata app_root(
+      CreateFolder("app_id", kSyncRootFolderID, "app_id"));
+  DriveFileMetadata folder(
+      CreateFolder(std::string(), kSyncRootFolderID, "folder"));
+  folder.set_active(false);
+
+  {
+    scoped_ptr<leveldb::DB> db = OpenLevelDB();
+    ASSERT_TRUE(db);
+    db->Put(leveldb::WriteOptions(), "VERSION", base::Int64ToString(3));
+    SetUpServiceMetadata(db.get());
+
+    EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok());
+    EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok());
+    EXPECT_TRUE(PutFileToDB(db.get(), folder).ok());
+  }
+
+  EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase());
+  VerifyFile(sync_root);
+  VerifyFile(app_root);
+  VerifyFile(folder);
+
+  folder.set_app_id("foo");
+  EXPECT_EQ(SYNC_STATUS_OK, RegisterApp(folder.app_id(), folder.file_id()));
+
+  folder.set_is_app_root(true);
+  folder.set_active(true);
+  folder.set_dirty(true);
+  folder.set_needs_folder_listing(true);
+  VerifyFile(folder);
+  VerifyReloadConsistency();
+
+  EXPECT_EQ(SYNC_STATUS_OK, DisableApp(folder.app_id()));
+  folder.set_active(false);
+  VerifyFile(folder);
+  VerifyReloadConsistency();
+
+  EXPECT_EQ(SYNC_STATUS_OK, EnableApp(folder.app_id()));
+  folder.set_active(true);
+  VerifyFile(folder);
+  VerifyReloadConsistency();
+
+  EXPECT_EQ(SYNC_STATUS_OK, UnregisterApp(folder.app_id()));
+  folder.set_app_id(std::string());
+  folder.set_is_app_root(false);
+  folder.set_active(false);
+  VerifyFile(folder);
+  VerifyReloadConsistency();
+}
+
+}  // namespace drive_backend
+}  // namespace sync_file_system
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util_unittest.cc b/chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util_unittest.cc
index 71099ff..56b9c7f 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
-#include "chrome/browser/sync_file_system/drive_metadata_store.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/leveldatabase/src/include/leveldb/db.h"
 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
@@ -107,6 +107,7 @@
 
   leveldb::Options options;
   options.create_if_missing = true;
+  options.max_open_files = 0;  // Use minimum.
   leveldb::DB* db_ptr = NULL;
   std::string db_dir = fileapi::FilePathToString(
       base_dir.path().Append(DriveMetadataStore::kDatabaseName));
diff --git a/chrome/browser/sync_file_system/remote_change_handler.cc b/chrome/browser/sync_file_system/drive_backend/remote_change_handler.cc
similarity index 98%
rename from chrome/browser/sync_file_system/remote_change_handler.cc
rename to chrome/browser/sync_file_system/drive_backend/remote_change_handler.cc
index 8db1d77..d1dbabc 100644
--- a/chrome/browser/sync_file_system/remote_change_handler.cc
+++ b/chrome/browser/sync_file_system/drive_backend/remote_change_handler.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/sync_file_system/remote_change_handler.h"
+#include "chrome/browser/sync_file_system/drive_backend/remote_change_handler.h"
 
 #include "base/logging.h"
 #include "webkit/common/fileapi/file_system_util.h"
diff --git a/chrome/browser/sync_file_system/remote_change_handler.h b/chrome/browser/sync_file_system/drive_backend/remote_change_handler.h
similarity index 92%
rename from chrome/browser/sync_file_system/remote_change_handler.h
rename to chrome/browser/sync_file_system/drive_backend/remote_change_handler.h
index 96be8c3..98d053d 100644
--- a/chrome/browser/sync_file_system/remote_change_handler.h
+++ b/chrome/browser/sync_file_system/drive_backend/remote_change_handler.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_REMOTE_CHANGE_HANDLER_H_
-#define CHROME_BROWSER_SYNC_FILE_SYSTEM_REMOTE_CHANGE_HANDLER_H_
+#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_CHANGE_HANDLER_H_
+#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_CHANGE_HANDLER_H_
 
 #include <map>
 #include <set>
@@ -106,4 +106,4 @@
 
 }  // namespace sync_file_system
 
-#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_REMOTE_CHANGE_HANDLER_H_
+#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_CHANGE_HANDLER_H_
diff --git a/chrome/browser/sync_file_system/drive_backend/remote_sync_delegate.cc b/chrome/browser/sync_file_system/drive_backend/remote_sync_delegate.cc
index 511b3d8..fa1cbc9 100644
--- a/chrome/browser/sync_file_system/drive_backend/remote_sync_delegate.cc
+++ b/chrome/browser/sync_file_system/drive_backend/remote_sync_delegate.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/sync_file_system/drive_backend/remote_sync_delegate.h"
 
 #include "base/file_util.h"
+#include "chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver.h"
 #include "chrome/browser/sync_file_system/logger.h"
 #include "chrome/browser/sync_file_system/remote_change_processor.h"
-#include "chrome/browser/sync_file_system/remote_sync_operation_resolver.h"
 #include "content/public/browser/browser_thread.h"
 #include "webkit/browser/fileapi/syncable/syncable_file_system_util.h"
 
diff --git a/chrome/browser/sync_file_system/drive_backend/remote_sync_delegate.h b/chrome/browser/sync_file_system/drive_backend/remote_sync_delegate.h
index 3037c90..5d8ccda 100644
--- a/chrome/browser/sync_file_system/drive_backend/remote_sync_delegate.h
+++ b/chrome/browser/sync_file_system/drive_backend/remote_sync_delegate.h
@@ -5,11 +5,13 @@
 #ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_SYNC_DELEGATE_H_
 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_SYNC_DELEGATE_H_
 
+#include <string>
+
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/sync_file_system/drive_backend/api_util.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
-#include "chrome/browser/sync_file_system/drive_metadata_store.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_metadata_store.h"
 #include "chrome/browser/sync_file_system/sync_action.h"
 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
 #include "webkit/browser/fileapi/file_system_url.h"
diff --git a/chrome/browser/sync_file_system/remote_sync_operation_resolver.cc b/chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver.cc
similarity index 97%
rename from chrome/browser/sync_file_system/remote_sync_operation_resolver.cc
rename to chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver.cc
index 1dc83d1..0fd5eea 100644
--- a/chrome/browser/sync_file_system/remote_sync_operation_resolver.cc
+++ b/chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/sync_file_system/remote_sync_operation_resolver.h"
+#include "chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver.h"
 
 #include "base/logging.h"
 
diff --git a/chrome/browser/sync_file_system/remote_sync_operation_resolver.h b/chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver.h
similarity index 88%
rename from chrome/browser/sync_file_system/remote_sync_operation_resolver.h
rename to chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver.h
index 00d4714..68c809d 100644
--- a/chrome/browser/sync_file_system/remote_sync_operation_resolver.h
+++ b/chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef  CHROME_BROWSER_SYNC_FILE_SYSTEM_REMOTE_SYNC_OPERATION_RESOLVER_H_
-#define  CHROME_BROWSER_SYNC_FILE_SYSTEM_REMOTE_SYNC_OPERATION_RESOLVER_H_
+#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_SYNC_OPERATION_RESOLVER_H_
+#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_SYNC_OPERATION_RESOLVER_H_
 
 #include "base/gtest_prod_util.h"
 #include "chrome/browser/sync_file_system/sync_operation_type.h"
@@ -66,4 +66,4 @@
 
 }  // namespace sync_file_system
 
-#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_REMOTE_SYNC_OPERATION_RESOLVER_H_
+#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_SYNC_OPERATION_RESOLVER_H_
diff --git a/chrome/browser/sync_file_system/remote_sync_operation_resolver_unittest.cc b/chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver_unittest.cc
similarity index 98%
rename from chrome/browser/sync_file_system/remote_sync_operation_resolver_unittest.cc
rename to chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver_unittest.cc
index 2dc246f..67bc22c 100644
--- a/chrome/browser/sync_file_system/remote_sync_operation_resolver_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -6,7 +6,7 @@
 #include <string>
 #include <vector>
 
-#include "chrome/browser/sync_file_system/remote_sync_operation_resolver.h"
+#include "chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "webkit/browser/fileapi/syncable/file_change.h"
 #include "webkit/browser/fileapi/syncable/sync_file_type.h"
@@ -97,6 +97,7 @@
   typedef RemoteSyncOperationResolver Resolver;
   typedef std::vector<SyncOperationType> ExpectedTypes;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(RemoteSyncOperationResolverTest);
 };
 
diff --git a/chrome/browser/sync_file_system/file_metadata.h b/chrome/browser/sync_file_system/file_metadata.h
deleted file mode 100644
index 745d8e5..0000000
--- a/chrome/browser/sync_file_system/file_metadata.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_FILE_METADATA_H_
-#define CHROME_BROWSER_SYNC_FILE_SYSTEM_FILE_METADATA_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "webkit/browser/fileapi/syncable/sync_file_status.h"
-
-namespace sync_file_system {
-
-enum FileType {
-  TYPE_FILE = 0,
-  TYPE_FOLDER = 1
-};
-
-// Abstraction of FileMetadata to structure common elements that all service
-// specific metadata should be able to map to. e.g. DriveMetadata.
-struct FileMetadata {
-  FileMetadata() {}
-
-  // sync_status is not known until SyncFileSystemService because
-  // local_file_sync_service has to be checked for pending changes.
-  FileMetadata(const std::string& title,
-               FileType type,
-               const std::string& service_specific_metadata)
-     : title(title),
-       type(type),
-       sync_status(SYNC_FILE_STATUS_UNKNOWN),
-       service_specific_metadata(service_specific_metadata) {}
-
-
-  // Common information.
-  std::string title;
-  FileType type;
-  SyncFileStatus sync_status;
-
-  // Sync service specific information.
-  std::string service_specific_metadata;
-};
-
-}  // namespace sync_file_system
-
-#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_FILE_METADATA_H_
diff --git a/chrome/browser/sync_file_system/logger.cc b/chrome/browser/sync_file_system/logger.cc
index 9c825e8..7e5e628 100644
--- a/chrome/browser/sync_file_system/logger.cc
+++ b/chrome/browser/sync_file_system/logger.cc
@@ -36,7 +36,7 @@
 }  // namespace
 
 void ClearLog() {
-  g_logger.Pointer()->SetHistorySize(::drive::kDefaultHistorySize);
+  g_logger.Pointer()->SetHistorySize(drive::kDefaultHistorySize);
 }
 
 void Log(logging::LogSeverity severity,
diff --git a/chrome/browser/sync_file_system/logger.h b/chrome/browser/sync_file_system/logger.h
index fbd3d4c..0bea1ca 100644
--- a/chrome/browser/sync_file_system/logger.h
+++ b/chrome/browser/sync_file_system/logger.h
@@ -30,7 +30,7 @@
 
 // Returns the log history.
 // This function can be called from any thread.
-std::vector< ::drive::EventLogger::Event> GetLogHistory();
+std::vector<drive::EventLogger::Event> GetLogHistory();
 
 }  // namespace util
 }  // namespace sync_file_system
diff --git a/chrome/browser/sync_file_system/mock_remote_file_sync_service.cc b/chrome/browser/sync_file_system/mock_remote_file_sync_service.cc
index 0f41b15..a537454 100644
--- a/chrome/browser/sync_file_system/mock_remote_file_sync_service.cc
+++ b/chrome/browser/sync_file_system/mock_remote_file_sync_service.cc
@@ -50,6 +50,11 @@
 MockRemoteFileSyncService::~MockRemoteFileSyncService() {
 }
 
+scoped_ptr<base::ListValue> MockRemoteFileSyncService::DumpFiles(
+    const GURL& origin) {
+  return scoped_ptr<base::ListValue>();
+}
+
 void MockRemoteFileSyncService::NotifyRemoteChangeQueueUpdated(
     int64 pending_changes) {
   FOR_EACH_OBSERVER(Observer, service_observers_,
diff --git a/chrome/browser/sync_file_system/mock_remote_file_sync_service.h b/chrome/browser/sync_file_system/mock_remote_file_sync_service.h
index e1df6a7..3a77c3c 100644
--- a/chrome/browser/sync_file_system/mock_remote_file_sync_service.h
+++ b/chrome/browser/sync_file_system/mock_remote_file_sync_service.h
@@ -9,6 +9,7 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "base/observer_list.h"
+#include "base/values.h"
 #include "chrome/browser/sync_file_system/file_status_observer.h"
 #include "chrome/browser/sync_file_system/mock_local_change_processor.h"
 #include "chrome/browser/sync_file_system/remote_change_processor.h"
@@ -51,15 +52,14 @@
                      RemoteServiceState());
   MOCK_METHOD1(GetOriginStatusMap,
                void(RemoteFileSyncService::OriginStatusMap* status_map));
-  MOCK_METHOD2(GetFileMetadataMap,
-               void(const GURL& origin,
-                    RemoteFileSyncService::FileMetadataMap* metadata_map));
   MOCK_METHOD1(SetSyncEnabled, void(bool));
   MOCK_METHOD1(SetConflictResolutionPolicy,
                SyncStatusCode(ConflictResolutionPolicy));
   MOCK_CONST_METHOD0(GetConflictResolutionPolicy,
                      ConflictResolutionPolicy());
 
+  virtual scoped_ptr<base::ListValue> DumpFiles(const GURL& origin) OVERRIDE;
+
   // Send notifications to the observers.
   // Can be used in the mock implementation.
   void NotifyRemoteChangeQueueUpdated(int64 pending_changes);
diff --git a/chrome/browser/sync_file_system/remote_file_sync_service.h b/chrome/browser/sync_file_system/remote_file_sync_service.h
index c4f32b7..231aa4f 100644
--- a/chrome/browser/sync_file_system/remote_file_sync_service.h
+++ b/chrome/browser/sync_file_system/remote_file_sync_service.h
@@ -10,12 +10,15 @@
 
 #include "base/basictypes.h"
 #include "chrome/browser/sync_file_system/conflict_resolution_policy.h"
-#include "chrome/browser/sync_file_system/file_metadata.h"
 #include "webkit/browser/fileapi/file_system_url.h"
 #include "webkit/browser/fileapi/syncable/sync_callbacks.h"
 
 class GURL;
 
+namespace base {
+class ListValue;
+}
+
 namespace sync_file_system {
 
 class FileStatusObserver;
@@ -145,10 +148,8 @@
   typedef std::map<GURL, std::string> OriginStatusMap;
   virtual void GetOriginStatusMap(OriginStatusMap* status_map) = 0;
 
-  // Returns file metadata for one origin.
-  typedef std::map<base::FilePath, FileMetadata> FileMetadataMap;
-  virtual void GetFileMetadataMap(const GURL& origin,
-                                  FileMetadataMap* metadata_map) = 0;
+  // Returns file metadata for |origin|.
+  virtual scoped_ptr<base::ListValue> DumpFiles(const GURL& origin) = 0;
 
   // Enables or disables the background sync.
   // Setting this to false should disable the synchronization (and make
diff --git a/chrome/browser/sync_file_system/sync_file_system_service.cc b/chrome/browser/sync_file_system/sync_file_system_service.cc
index 0278b36..4d24660 100644
--- a/chrome/browser/sync_file_system/sync_file_system_service.cc
+++ b/chrome/browser/sync_file_system/sync_file_system_service.cc
@@ -11,21 +11,23 @@
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer.h"
+#include "chrome/browser/extensions/api/sync_file_system/sync_file_system_api_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
 #include "chrome/browser/sync_file_system/local_file_sync_service.h"
 #include "chrome/browser/sync_file_system/logger.h"
 #include "chrome/browser/sync_file_system/sync_direction.h"
 #include "chrome/browser/sync_file_system/sync_event_observer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/browser/storage_partition.h"
 #include "url/gurl.h"
 #include "webkit/browser/fileapi/file_system_context.h"
 #include "webkit/browser/fileapi/syncable/sync_file_metadata.h"
@@ -99,34 +101,31 @@
               origin.spec().c_str());
 }
 
+std::string SyncFileStatusToString(SyncFileStatus sync_file_status) {
+  return extensions::api::sync_file_system::ToString(
+      extensions::SyncFileStatusToExtensionEnum(sync_file_status));
+}
+
 // Gets called repeatedly until every SyncFileStatus has been mapped.
-void DidGetFileSyncStatus(
-    const SyncStatusCallback& callback,
-    FileMetadata* metadata,
-    size_t expected_results,
+void DidGetFileSyncStatusForDump(
+    base::ListValue* files,
     size_t* num_results,
+    const SyncFileSystemService::DumpFilesCallback& callback,
+    base::DictionaryValue* file,
     SyncStatusCode sync_status_code,
     SyncFileStatus sync_file_status) {
-  DCHECK(metadata);
+  DCHECK(files);
   DCHECK(num_results);
 
-  // TODO(calvinlo): Unfortunately the sync_status_code will only be OK if
-  // the app that matches the url.origin() is actually running. Otherwise
-  // the FileSystemContext isn't loaded into the map in
-  // LocalFileSyncService::HasPendingLocalChanges() and the contains key check
-  // fails. This causes SYNC_FILE_ERROR_INVALID_URL to be returned.
-  // With this check in, the SyncFileStatus will therefore show nothing (for
-  // SYNC_FILE_STATUS_UNKNOWN) for syncFS apps which aren't running.
-  metadata->sync_status = (sync_status_code == SYNC_STATUS_OK) ?
-      sync_file_status : SYNC_FILE_STATUS_UNKNOWN;
+  if (file)
+    file->SetString("status", SyncFileStatusToString(sync_file_status));
 
   // Once all results have been received, run the callback to signal end.
-  DCHECK_LE(*num_results, expected_results);
-  (*num_results)++;
-  if (*num_results < expected_results)
+  DCHECK_LE(*num_results, files->GetSize());
+  if (++*num_results < files->GetSize())
     return;
 
-  callback.Run(SYNC_STATUS_OK);
+  callback.Run(files);
 }
 
 }  // namespace
@@ -179,33 +178,18 @@
   remote_file_service_->GetOriginStatusMap(status_map);
 }
 
-void SyncFileSystemService::GetFileMetadataMap(
-    const GURL& origin,
-    RemoteFileSyncService::FileMetadataMap* metadata_map,
-    size_t* num_results,
-    const SyncStatusCallback& callback) {
-  DCHECK(metadata_map);
+void SyncFileSystemService::DumpFiles(const GURL& origin,
+                                      const DumpFilesCallback& callback) {
   DCHECK(!origin.is_empty());
-  DCHECK(num_results);
-  remote_file_service_->GetFileMetadataMap(origin, metadata_map);
 
-  // Figure out how many results have to be waited on before callback.
-  size_t expected_results = metadata_map->size();
-
-  // After all metadata loaded, sync status can be added to each entry.
-  RemoteFileSyncService::FileMetadataMap::iterator file_path_itr;
-  for (file_path_itr = metadata_map->begin();
-       file_path_itr != metadata_map->end();
-       ++file_path_itr) {
-    const base::FilePath& file_path = file_path_itr->first;
-    const FileSystemURL url = CreateSyncableFileSystemURL(origin, file_path);
-    FileMetadata& metadata = file_path_itr->second;
-    GetFileSyncStatus(url, base::Bind(&DidGetFileSyncStatus,
-                                      callback,
-                                      &metadata,
-                                      expected_results,
-                                      num_results));
-  }
+  content::StoragePartition* storage_partition =
+      content::BrowserContext::GetStoragePartitionForSite(profile_, origin);
+  fileapi::FileSystemContext* file_system_context =
+      storage_partition->GetFileSystemContext();
+  local_file_service_->MaybeInitializeFileSystemContext(
+      origin, file_system_context,
+      base::Bind(&SyncFileSystemService::DidInitializeFileSystemForDump,
+                 AsWeakPtr(), origin, callback));
 }
 
 void SyncFileSystemService::GetFileSyncStatus(
@@ -330,6 +314,48 @@
   callback.Run(status);
 }
 
+void SyncFileSystemService::DidInitializeFileSystemForDump(
+    const GURL& origin,
+    const DumpFilesCallback& callback,
+    SyncStatusCode status) {
+  DCHECK(!origin.is_empty());
+
+  if (status != SYNC_STATUS_OK) {
+    base::ListValue empty_result;
+    callback.Run(&empty_result);
+    return;
+  }
+
+  base::ListValue* files = remote_file_service_->DumpFiles(origin).release();
+  if (!files->GetSize()) {
+    callback.Run(files);
+    return;
+  }
+
+  base::Callback<void(base::DictionaryValue* file,
+                      SyncStatusCode sync_status,
+                      SyncFileStatus sync_file_status)> completion_callback =
+      base::Bind(&DidGetFileSyncStatusForDump, base::Owned(files),
+                 base::Owned(new size_t(0)), callback);
+
+  // After all metadata loaded, sync status can be added to each entry.
+  for (size_t i = 0; i < files->GetSize(); ++i) {
+    base::DictionaryValue* file = NULL;
+    std::string path_string;
+    if (!files->GetDictionary(i, &file) ||
+        !file->GetString("path", &path_string)) {
+      NOTREACHED();
+      completion_callback.Run(
+          NULL, SYNC_FILE_ERROR_FAILED, SYNC_FILE_STATUS_UNKNOWN);
+      continue;
+    }
+
+    base::FilePath file_path = base::FilePath::FromUTF8Unsafe(path_string);
+    FileSystemURL url = CreateSyncableFileSystemURL(origin, file_path);
+    GetFileSyncStatus(url, base::Bind(completion_callback, file));
+  }
+}
+
 void SyncFileSystemService::SetSyncEnabledForTesting(bool enabled) {
   sync_enabled_ = enabled;
   remote_file_service_->SetSyncEnabled(sync_enabled_);
diff --git a/chrome/browser/sync_file_system/sync_file_system_service.h b/chrome/browser/sync_file_system/sync_file_system_service.h
index fbcadb9..0e015c9 100644
--- a/chrome/browser/sync_file_system/sync_file_system_service.h
+++ b/chrome/browser/sync_file_system/sync_file_system_service.h
@@ -45,6 +45,8 @@
       public content::NotificationObserver,
       public base::SupportsWeakPtr<SyncFileSystemService> {
  public:
+  typedef base::Callback<void(const base::ListValue* files)> DumpFilesCallback;
+
   // BrowserContextKeyedService overrides.
   virtual void Shutdown() OVERRIDE;
 
@@ -55,11 +57,7 @@
 
   SyncServiceState GetSyncServiceState();
   void GetExtensionStatusMap(std::map<GURL, std::string>* status_map);
-  void GetFileMetadataMap(
-      const GURL& origin,
-      RemoteFileSyncService::FileMetadataMap* metadata_map,
-      size_t* num_results,
-      const SyncStatusCallback& callback);
+  void DumpFiles(const GURL& origin, const DumpFilesCallback& callback);
 
   // Returns the file |url|'s sync status.
   void GetFileSyncStatus(
@@ -91,6 +89,10 @@
                          const SyncStatusCallback& callback,
                          SyncStatusCode status);
 
+  void DidInitializeFileSystemForDump(const GURL& app_origin,
+                                      const DumpFilesCallback& callback,
+                                      SyncStatusCode status);
+
   // Overrides sync_enabled_ setting. This should be called only by tests.
   void SetSyncEnabledForTesting(bool enabled);
 
diff --git a/chrome/browser/sync_file_system/sync_file_system_service_factory.cc b/chrome/browser/sync_file_system/sync_file_system_service_factory.cc
index d01b5e4..bb6b7f9 100644
--- a/chrome/browser/sync_file_system/sync_file_system_service_factory.cc
+++ b/chrome/browser/sync_file_system/sync_file_system_service_factory.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/drive/drive_notification_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
 #include "chrome/browser/sync_file_system/sync_file_system_service.h"
 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
 #include "webkit/browser/fileapi/syncable/syncable_file_system_util.h"
@@ -40,7 +40,7 @@
     : BrowserContextKeyedServiceFactory(
         "SyncFileSystemService",
         BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(::drive::DriveNotificationManagerFactory::GetInstance());
+  DependsOn(drive::DriveNotificationManagerFactory::GetInstance());
 }
 
 SyncFileSystemServiceFactory::~SyncFileSystemServiceFactory() {}
diff --git a/chrome/browser/tab_contents/background_contents.cc b/chrome/browser/tab_contents/background_contents.cc
index 106351c..a569d4e 100644
--- a/chrome/browser/tab_contents/background_contents.cc
+++ b/chrome/browser/tab_contents/background_contents.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/tab_contents/background_contents.h"
 
 #include "chrome/browser/background/background_contents_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/renderer_preferences_util.h"
 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/notification_service.h"
@@ -110,7 +110,7 @@
       new_contents, disposition, initial_pos, user_gesture, was_blocked);
 }
 
-void BackgroundContents::RenderViewGone(base::TerminationStatus status) {
+void BackgroundContents::RenderProcessGone(base::TerminationStatus status) {
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED,
       content::Source<Profile>(profile_),
diff --git a/chrome/browser/tab_contents/background_contents.h b/chrome/browser/tab_contents/background_contents.h
index be2c71f..e6b817c 100644
--- a/chrome/browser/tab_contents/background_contents.h
+++ b/chrome/browser/tab_contents/background_contents.h
@@ -63,7 +63,7 @@
                               bool* was_blocked) OVERRIDE;
 
   // content::WebContentsObserver implementation:
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
 
   // content::NotificationObserver
   virtual void Observe(int type,
diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc
index eb4b728..ee6ebed 100644
--- a/chrome/browser/tab_contents/render_view_context_menu.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -24,6 +24,7 @@
 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/download/download_service.h"
@@ -44,7 +45,6 @@
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/browser/speech/chrome_speech_recognition_preferences.h"
 #include "chrome/browser/spellchecker/spellcheck_host_metrics.h"
 #include "chrome/browser/spellchecker/spellcheck_service.h"
 #include "chrome/browser/tab_contents/retargeting_details.h"
@@ -59,7 +59,6 @@
 #include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/net/url_util.h"
@@ -80,6 +79,7 @@
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_restriction.h"
+#include "content/public/common/menu_item.h"
 #include "content/public/common/ssl_status.h"
 #include "content/public/common/url_utils.h"
 #include "extensions/browser/view_type_utils.h"
@@ -92,7 +92,6 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/text/text_elider.h"
 #include "ui/gfx/favicon_size.h"
-#include "webkit/common/webmenuitem.h"
 
 using WebKit::WebContextMenuData;
 using WebKit::WebMediaPlayerAction;
@@ -259,14 +258,14 @@
   return disposition == CURRENT_TAB ? NEW_FOREGROUND_TAB : disposition;
 }
 
-bool IsCustomItemEnabled(const std::vector<WebMenuItem>& items, int id) {
+bool IsCustomItemEnabled(const std::vector<content::MenuItem>& items, int id) {
   DCHECK(id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
          id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST);
   for (size_t i = 0; i < items.size(); ++i) {
     int action_id = IDC_CONTENT_CONTEXT_CUSTOM_FIRST + items[i].action;
     if (action_id == id)
       return items[i].enabled;
-    if (items[i].type == WebMenuItem::SUBMENU) {
+    if (items[i].type == content::MenuItem::SUBMENU) {
       if (IsCustomItemEnabled(items[i].submenu, id))
         return true;
     }
@@ -274,14 +273,14 @@
   return false;
 }
 
-bool IsCustomItemChecked(const std::vector<WebMenuItem>& items, int id) {
+bool IsCustomItemChecked(const std::vector<content::MenuItem>& items, int id) {
   DCHECK(id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
          id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST);
   for (size_t i = 0; i < items.size(); ++i) {
     int action_id = IDC_CONTENT_CONTEXT_CUSTOM_FIRST + items[i].action;
     if (action_id == id)
       return items[i].checked;
-    if (items[i].type == WebMenuItem::SUBMENU) {
+    if (items[i].type == content::MenuItem::SUBMENU) {
       if (IsCustomItemChecked(items[i].submenu, id))
         return true;
     }
@@ -292,7 +291,7 @@
 const size_t kMaxCustomMenuDepth = 5;
 const size_t kMaxCustomMenuTotalItems = 1000;
 
-void AddCustomItemsToMenu(const std::vector<WebMenuItem>& items,
+void AddCustomItemsToMenu(const std::vector<content::MenuItem>& items,
                           size_t depth,
                           size_t* total_items,
                           ui::SimpleMenuModel::Delegate* delegate,
@@ -313,24 +312,24 @@
     }
     (*total_items)++;
     switch (items[i].type) {
-      case WebMenuItem::OPTION:
+      case content::MenuItem::OPTION:
         menu_model->AddItem(
             items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
             items[i].label);
         break;
-      case WebMenuItem::CHECKABLE_OPTION:
+      case content::MenuItem::CHECKABLE_OPTION:
         menu_model->AddCheckItem(
             items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
             items[i].label);
         break;
-      case WebMenuItem::GROUP:
+      case content::MenuItem::GROUP:
         // TODO(viettrungluu): I don't know what this is supposed to do.
         NOTREACHED();
         break;
-      case WebMenuItem::SEPARATOR:
+      case content::MenuItem::SEPARATOR:
         menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
         break;
-      case WebMenuItem::SUBMENU: {
+      case content::MenuItem::SUBMENU: {
         ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(delegate);
         AddCustomItemsToMenu(items[i].submenu, depth + 1, total_items, delegate,
                              submenu);
@@ -1450,8 +1449,8 @@
 #if defined(ENABLE_INPUT_SPEECH)
   // Check box for menu item 'Block offensive words'.
   if (id == IDC_CONTENT_CONTEXT_SPEECH_INPUT_FILTER_PROFANITIES) {
-    return ChromeSpeechRecognitionPreferences::GetForProfile(profile_)->
-        FilterProfanities();
+    return profile_->GetPrefs()->GetBoolean(
+        prefs::kSpeechRecognitionFilterProfanities);
   }
 #endif
 
@@ -1753,8 +1752,7 @@
       Browser* browser =
           chrome::FindBrowserWithWebContents(source_web_contents_);
       chrome::ShowWebsiteSettings(browser, source_web_contents_,
-                                  nav_entry->GetURL(), nav_entry->GetSSL(),
-                                  true);
+                                  nav_entry->GetURL(), nav_entry->GetSSL());
       break;
     }
 
@@ -1795,8 +1793,7 @@
       Browser* browser = chrome::FindBrowserWithWebContents(
           source_web_contents_);
       chrome::ShowWebsiteSettings(browser, source_web_contents_,
-                                  params_.frame_url, params_.security_info,
-                                  false);
+                                  params_.frame_url, params_.security_info);
       break;
     }
 
@@ -1891,8 +1888,10 @@
 
 #if defined(ENABLE_INPUT_SPEECH)
     case IDC_CONTENT_CONTEXT_SPEECH_INPUT_FILTER_PROFANITIES: {
-      ChromeSpeechRecognitionPreferences::GetForProfile(profile_)->
-          ToggleFilterProfanities();
+      profile_->GetPrefs()->SetBoolean(
+          prefs::kSpeechRecognitionFilterProfanities,
+          !profile_->GetPrefs()->GetBoolean(
+              prefs::kSpeechRecognitionFilterProfanities));
       break;
     }
 #endif
diff --git a/chrome/browser/tab_contents/render_view_context_menu_browsertest.cc b/chrome/browser/tab_contents/render_view_context_menu_browsertest.cc
index efc0d2b..3248b72 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_browsertest.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu_browsertest.cc
@@ -8,12 +8,12 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/tab_contents/render_view_context_menu.h"
 #include "chrome/browser/tab_contents/render_view_context_menu_browsertest_util.h"
 #include "chrome/browser/tab_contents/render_view_context_menu_test_util.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/navigation_controller.h"
diff --git a/chrome/browser/tab_contents/render_view_context_menu_browsertest_util.cc b/chrome/browser/tab_contents/render_view_context_menu_browsertest_util.cc
index 864e589..a19d1fb 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_browsertest_util.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu_browsertest_util.cc
@@ -6,8 +6,8 @@
 
 #include "base/message_loop.h"
 #include "base/bind.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/tab_contents/render_view_context_menu.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 
 ContextMenuNotificationObserver::ContextMenuNotificationObserver(
diff --git a/chrome/browser/task_manager/background_resource_provider.cc b/chrome/browser/task_manager/background_resource_provider.cc
index 371af28..6bbf757 100644
--- a/chrome/browser/task_manager/background_resource_provider.cc
+++ b/chrome/browser/task_manager/background_resource_provider.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/background/background_contents_service.h"
 #include "chrome/browser/background/background_contents_service_factory.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/task_manager/renderer_resource.h"
 #include "chrome/browser/task_manager/resource_provider.h"
 #include "chrome/browser/task_manager/task_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
diff --git a/chrome/browser/task_manager/child_process_resource_provider.cc b/chrome/browser/task_manager/child_process_resource_provider.cc
index 03bea05..0c48d6c 100644
--- a/chrome/browser/task_manager/child_process_resource_provider.cc
+++ b/chrome/browser/task_manager/child_process_resource_provider.cc
@@ -8,10 +8,10 @@
 
 #include "base/i18n/rtl.h"
 #include "base/strings/string16.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/task_manager/resource_provider.h"
 #include "chrome/browser/task_manager/task_manager.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/chrome_process_type.h"
+#include "components/nacl/common/nacl_process_type.h"
 #include "content/public/browser/browser_child_process_host_iterator.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_data.h"
diff --git a/chrome/browser/task_manager/extension_process_resource_provider.cc b/chrome/browser/task_manager/extension_process_resource_provider.cc
index 219d311..121ae0f 100644
--- a/chrome/browser/task_manager/extension_process_resource_provider.cc
+++ b/chrome/browser/task_manager/extension_process_resource_provider.cc
@@ -7,6 +7,7 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
@@ -16,7 +17,6 @@
 #include "chrome/browser/task_manager/resource_provider.h"
 #include "chrome/browser/task_manager/task_manager.h"
 #include "chrome/browser/task_manager/task_manager_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/task_manager/guest_resource_provider.cc b/chrome/browser/task_manager/guest_resource_provider.cc
index 5dcedf1..b8bda92 100644
--- a/chrome/browser/task_manager/guest_resource_provider.cc
+++ b/chrome/browser/task_manager/guest_resource_provider.cc
@@ -5,13 +5,13 @@
 #include "chrome/browser/task_manager/guest_resource_provider.h"
 
 #include "base/strings/string16.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/task_manager/renderer_resource.h"
 #include "chrome/browser/task_manager/resource_provider.h"
 #include "chrome/browser/task_manager/task_manager.h"
 #include "chrome/browser/task_manager/task_manager_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
diff --git a/chrome/browser/task_manager/notification_resource_provider.cc b/chrome/browser/task_manager/notification_resource_provider.cc
index b8a78bc..886b5c6 100644
--- a/chrome/browser/task_manager/notification_resource_provider.cc
+++ b/chrome/browser/task_manager/notification_resource_provider.cc
@@ -6,11 +6,11 @@
 
 #include "base/strings/string16.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/notifications/balloon_host.h"
 #include "chrome/browser/notifications/balloon_notification_ui_manager.h"
 #include "chrome/browser/task_manager/task_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/task_manager/panel_resource_provider.cc b/chrome/browser/task_manager/panel_resource_provider.cc
index 2c66fd3..c078ba3 100644
--- a/chrome/browser/task_manager/panel_resource_provider.cc
+++ b/chrome/browser/task_manager/panel_resource_provider.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/task_manager/panel_resource_provider.h"
 
 #include "base/i18n/rtl.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/task_manager/renderer_resource.h"
@@ -13,7 +14,6 @@
 #include "chrome/browser/task_manager/task_manager_util.h"
 #include "chrome/browser/ui/panels/panel.h"
 #include "chrome/browser/ui/panels/panel_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
diff --git a/chrome/browser/task_manager/tab_contents_resource_provider.cc b/chrome/browser/task_manager/tab_contents_resource_provider.cc
index de3a008..f4c1370 100644
--- a/chrome/browser/task_manager/tab_contents_resource_provider.cc
+++ b/chrome/browser/task_manager/tab_contents_resource_provider.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/task_manager/tab_contents_resource_provider.h"
 
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/favicon/favicon_tab_helper.h"
 #include "chrome/browser/prerender/prerender_manager.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/ui/browser_instant_controller.h"
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc
index a4f2a93..d3e3a52 100644
--- a/chrome/browser/task_manager/task_manager_browsertest.cc
+++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -8,6 +8,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/ui/panels/panel_manager.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -457,7 +457,8 @@
 
 // Checks that task manager counts a worker thread JS heap size.
 // http://crbug.com/241066
-IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, WebWorkerJSHeapMemory) {
+// Flaky, http://crbug.com/259368
+IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, DISABLED_WebWorkerJSHeapMemory) {
   GURL url(ui_test_utils::GetTestUrl(base::FilePath(
       base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File)));
   ui_test_utils::NavigateToURL(browser(), url);
diff --git a/chrome/browser/task_manager/task_manager_browsertest_util.cc b/chrome/browser/task_manager/task_manager_browsertest_util.cc
index 327b31a..0b050e3 100644
--- a/chrome/browser/task_manager/task_manager_browsertest_util.cc
+++ b/chrome/browser/task_manager/task_manager_browsertest_util.cc
@@ -6,6 +6,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/task_manager/resource_provider.h"
 #include "chrome/browser/task_manager/task_manager.h"
@@ -13,7 +14,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/task_manager/worker_resource_provider.cc b/chrome/browser/task_manager/worker_resource_provider.cc
index 7cfc2ca..2d90a40 100644
--- a/chrome/browser/task_manager/worker_resource_provider.cc
+++ b/chrome/browser/task_manager/worker_resource_provider.cc
@@ -13,11 +13,11 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/task_manager/resource_provider.h"
 #include "chrome/browser/task_manager/task_manager.h"
-#include "chrome/common/chrome_process_type.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_data.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/worker_service.h"
+#include "content/public/common/process_type.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc
index fb594d8..d7fe33b 100644
--- a/chrome/browser/themes/theme_service.cc
+++ b/chrome/browser/themes/theme_service.cc
@@ -10,6 +10,7 @@
 #include "base/sequenced_task_runner.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/themes/theme_syncable_service.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
@@ -200,6 +200,11 @@
   if (theme_pack_.get())
     return theme_pack_->HasCustomImage(id);
 
+  if (IsManagedUser() &&
+      (id == IDR_THEME_FRAME || id == IDR_THEME_FRAME_INACTIVE ||
+       id == IDR_THEME_TAB_BACKGROUND || id == IDR_THEME_TAB_BACKGROUND_V))
+    return true;
+
   return false;
 }
 
diff --git a/chrome/browser/themes/theme_service_factory.cc b/chrome/browser/themes/theme_service_factory.cc
index adc424b..92fe85c 100644
--- a/chrome/browser/themes/theme_service_factory.cc
+++ b/chrome/browser/themes/theme_service_factory.cc
@@ -66,7 +66,7 @@
   return provider;
 }
 
-void ThemeServiceFactory::RegisterUserPrefs(
+void ThemeServiceFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
   bool default_uses_system_theme = false;
diff --git a/chrome/browser/themes/theme_service_factory.h b/chrome/browser/themes/theme_service_factory.h
index a61abc7..2c7df11 100644
--- a/chrome/browser/themes/theme_service_factory.h
+++ b/chrome/browser/themes/theme_service_factory.h
@@ -42,7 +42,7 @@
   // BrowserContextKeyedServiceFactory:
   virtual BrowserContextKeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const OVERRIDE;
diff --git a/chrome/browser/themes/theme_syncable_service_unittest.cc b/chrome/browser/themes/theme_syncable_service_unittest.cc
index 5931a17..bf91861 100644
--- a/chrome/browser/themes/theme_syncable_service_unittest.cc
+++ b/chrome/browser/themes/theme_syncable_service_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/browser/profiles/profile.h"
@@ -436,10 +437,11 @@
   sync_pb::EntitySpecifics entity_specifics;
   entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
   syncer::SyncChangeList change_list;
-  change_list.push_back(syncer::SyncChange(FROM_HERE,
-                                           syncer::SyncChange::ACTION_UPDATE,
-                                           syncer::SyncData::CreateRemoteData(
-                                               1, entity_specifics)));
+  change_list.push_back(syncer::SyncChange(
+      FROM_HERE,
+      syncer::SyncChange::ACTION_UPDATE,
+      syncer::SyncData::CreateRemoteData(
+          1, entity_specifics, base::Time())));
   error = theme_sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
   EXPECT_FALSE(error.IsSet()) << error.message();
   EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
diff --git a/chrome/browser/three_d_api_observer.cc b/chrome/browser/three_d_api_observer.cc
index 61b39cf..f3976bf 100644
--- a/chrome/browser/three_d_api_observer.cc
+++ b/chrome/browser/three_d_api_observer.cc
@@ -26,17 +26,16 @@
                      content::ThreeDAPIType requester);
 
  private:
-  enum ThreeDInfobarDismissalHistogram {
-    THREE_D_INFOBAR_IGNORED,
-    THREE_D_INFOBAR_RELOADED,
-    THREE_D_INFOBAR_CLOSED_WITHOUT_ACTION,
-    THREE_D_INFOBAR_DISMISSAL_MAX
+  enum DismissalHistogram {
+    IGNORED,
+    RELOADED,
+    CLOSED_WITHOUT_ACTION,
+    DISMISSAL_MAX
   };
 
-  ThreeDAPIInfoBarDelegate(
-      InfoBarService* owner,
-      const GURL& url,
-      content::ThreeDAPIType requester);
+  ThreeDAPIInfoBarDelegate(InfoBarService* owner,
+                           const GURL& url,
+                           content::ThreeDAPIType requester);
   virtual ~ThreeDAPIInfoBarDelegate();
 
   // ConfirmInfoBarDelegate:
@@ -83,23 +82,20 @@
 ThreeDAPIInfoBarDelegate::~ThreeDAPIInfoBarDelegate() {
   if (message_text_queried_ && !action_taken_) {
     UMA_HISTOGRAM_ENUMERATION("GPU.ThreeDAPIInfoBarDismissal",
-                              THREE_D_INFOBAR_CLOSED_WITHOUT_ACTION,
-                              THREE_D_INFOBAR_DISMISSAL_MAX);
+                              CLOSED_WITHOUT_ACTION, DISMISSAL_MAX);
   }
 }
 
 bool ThreeDAPIInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const {
-  ThreeDAPIInfoBarDelegate* three_d_delegate =
-      delegate->AsThreeDAPIInfoBarDelegate();
   // For the time being, if a given web page is actually using both
   // WebGL and Pepper 3D and both APIs are blocked, just leave the
   // first infobar up. If the user selects "try again", both APIs will
   // be unblocked and the web page reload will succeed.
-  return (three_d_delegate != NULL);
+  return (delegate->AsThreeDAPIInfoBarDelegate() != NULL);
 }
 
 ThreeDAPIInfoBarDelegate*
-ThreeDAPIInfoBarDelegate::AsThreeDAPIInfoBarDelegate() {
+    ThreeDAPIInfoBarDelegate::AsThreeDAPIInfoBarDelegate() {
   return this;
 }
 
@@ -129,17 +125,15 @@
 
 bool ThreeDAPIInfoBarDelegate::Accept() {
   action_taken_ = true;
-  UMA_HISTOGRAM_ENUMERATION("GPU.ThreeDAPIInfoBarDismissal",
-                            THREE_D_INFOBAR_IGNORED,
-                            THREE_D_INFOBAR_DISMISSAL_MAX);
+  UMA_HISTOGRAM_ENUMERATION("GPU.ThreeDAPIInfoBarDismissal", IGNORED,
+                            DISMISSAL_MAX);
   return true;
 }
 
 bool ThreeDAPIInfoBarDelegate::Cancel() {
   action_taken_ = true;
-  UMA_HISTOGRAM_ENUMERATION("GPU.ThreeDAPIInfoBarDismissal",
-                            THREE_D_INFOBAR_RELOADED,
-                            THREE_D_INFOBAR_DISMISSAL_MAX);
+  UMA_HISTOGRAM_ENUMERATION("GPU.ThreeDAPIInfoBarDismissal", RELOADED,
+                            DISMISSAL_MAX);
   content::GpuDataManager::GetInstance()->UnblockDomainFrom3DAPIs(url_);
   web_contents()->GetController().Reload(true);
   return true;
diff --git a/chrome/browser/toolkit_extra_parts.h b/chrome/browser/toolkit_extra_parts.h
deleted file mode 100644
index 802c080..0000000
--- a/chrome/browser/toolkit_extra_parts.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_TOOLKIT_EXTRA_PARTS_H_
-#define CHROME_BROWSER_TOOLKIT_EXTRA_PARTS_H_
-
-#include "build/build_config.h"
-
-class ChromeBrowserMainParts;
-
-namespace chrome {
-
-#if defined(TOOLKIT_GTK)
-void AddGtkToolkitExtraParts(ChromeBrowserMainParts* main_parts);
-#endif
-
-#if defined(TOOLKIT_VIEWS)
-void AddViewsToolkitExtraParts(ChromeBrowserMainParts* main_parts);
-#endif
-
-#if defined(USE_ASH)
-void AddAshToolkitExtraParts(ChromeBrowserMainParts* main_parts);
-#endif
-
-#if defined(USE_AURA)
-void AddAuraToolkitExtraParts(ChromeBrowserMainParts* main_parts);
-#endif
-
-}  // namespace chrome
-
-#endif  // CHROME_BROWSER_TOOLKIT_EXTRA_PARTS_H_
diff --git a/chrome/browser/translate/translate_accept_languages.cc b/chrome/browser/translate/translate_accept_languages.cc
index df2f4cc..5a098be 100644
--- a/chrome/browser/translate/translate_accept_languages.cc
+++ b/chrome/browser/translate/translate_accept_languages.cc
@@ -11,9 +11,9 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/translate/translate_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/translate/translate_util.h"
diff --git a/chrome/browser/translate/translate_browsertest.cc b/chrome/browser/translate/translate_browsertest.cc
index f65093f..440d5c4 100644
--- a/chrome/browser/translate/translate_browsertest.cc
+++ b/chrome/browser/translate/translate_browsertest.cc
@@ -8,11 +8,11 @@
 #include "base/files/file_path.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/translate/translate_infobar_delegate.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/translate/translate_infobar_delegate.cc b/chrome/browser/translate/translate_infobar_delegate.cc
index b1f1345..20a5b0a 100644
--- a/chrome/browser/translate/translate_infobar_delegate.cc
+++ b/chrome/browser/translate/translate_infobar_delegate.cc
@@ -114,8 +114,8 @@
 }
 
 void TranslateInfoBarDelegate::ReportLanguageDetectionError() {
-  TranslateManager::GetInstance()->
-      ReportLanguageDetectionError(web_contents());
+  TranslateManager::GetInstance()->ReportLanguageDetectionError(
+      web_contents());
 }
 
 void TranslateInfoBarDelegate::TranslationDeclined() {
@@ -129,9 +129,8 @@
   // translations when getting a LANGUAGE_DETERMINED from the page, which
   // happens when a load stops. That could happen multiple times, including
   // after the user already declined the translation.)
-  TranslateTabHelper* translate_tab_helper =
-      TranslateTabHelper::FromWebContents(web_contents());
-  translate_tab_helper->language_state().set_translation_declined(true);
+  TranslateTabHelper::FromWebContents(web_contents())->
+      language_state().set_translation_declined(true);
 
   UMA_HISTOGRAM_BOOLEAN(kDeclineTranslate, true);
 }
@@ -343,7 +342,7 @@
       error_type_(error_type),
       prefs_(prefs),
       shortcut_config_(shortcut_config) {
-  DCHECK_NE((infobar_type == TRANSLATION_ERROR),
+  DCHECK_NE((infobar_type_ == TRANSLATION_ERROR),
             (error_type_ == TranslateErrors::NONE));
 
   std::vector<std::string> language_codes;
diff --git a/chrome/browser/translate/translate_infobar_delegate.h b/chrome/browser/translate/translate_infobar_delegate.h
index 066df9b..b934d32 100644
--- a/chrome/browser/translate/translate_infobar_delegate.h
+++ b/chrome/browser/translate/translate_infobar_delegate.h
@@ -183,7 +183,6 @@
                                        bool autodetermined_source_language);
 
  protected:
-  // For testing.
   TranslateInfoBarDelegate(Type infobar_type,
                            TranslateErrors::Type error_type,
                            InfoBarService* infobar_service,
@@ -191,7 +190,6 @@
                            ShortcutConfiguration shortcut_config,
                            const std::string& original_language,
                            const std::string& target_language);
-  Type infobar_type_;
 
  private:
   typedef std::pair<std::string, string16> LanguageNamePair;
@@ -209,6 +207,8 @@
   // associated with the current page.
   std::string GetPageHost();
 
+  Type infobar_type_;
+
   // The type of fading animation if any that should be used when showing this
   // infobar.
   BackgroundAnimationType background_animation_;
diff --git a/chrome/browser/translate/translate_language_list.cc b/chrome/browser/translate/translate_language_list.cc
index 88f0701..d5b13c0 100644
--- a/chrome/browser/translate/translate_language_list.cc
+++ b/chrome/browser/translate/translate_language_list.cc
@@ -103,10 +103,7 @@
 const char kAlphaLanguageQueryName[] = "alpha";
 const char kAlphaLanguageQueryValue[] = "1";
 
-// Assign following IDs to URLFetchers so that tests can distinguish each
-// request in order to simiulate respectively.
-const int kFetcherIdForLanguageList = 1;
-const int kFetcherIdForAlphaLanguageList = 2;
+const int kFetcherId = 1;
 
 // Represent if the language list updater is disabled.
 bool update_is_disabled = false;
@@ -126,12 +123,19 @@
 // Parses |language_list| containing the list of languages that the translate
 // server can translate to and from, and fills |set| with them.
 void SetSupportedLanguages(const std::string& language_list,
-                           std::set<std::string>* set) {
-  DCHECK(set);
+                           std::set<std::string>* target_language_set,
+                           std::set<std::string>* alpha_language_set) {
+  DCHECK(target_language_set);
+  DCHECK(alpha_language_set);
+
   // The format is:
-  // sl({"sl": {"XX": "LanguageName", ...}, "tl": {"XX": "LanguageName", ...}})
-  // Where "sl(" is set in kLanguageListCallbackName
-  // and "tl" is kTargetLanguagesKey
+  // sl({
+  //   "sl": {"XX": "LanguageName", ...},
+  //   "tl": {"XX": "LanguageName", ...},
+  //   "al": {"XX": 1, ...}
+  // })
+  // Where "sl(" is set in kLanguageListCallbackName, "tl" is
+  // kTargetLanguagesKey and "al" kAlphaLanguagesKey.
   if (!StartsWithASCII(language_list,
                        TranslateLanguageList::kLanguageListCallbackName,
                        false) ||
@@ -152,8 +156,9 @@
     NOTREACHED();
     return;
   }
-  // The first level dictionary contains two sub-dict, one for source languages
-  // and the other for target languages, we want to use the target languages.
+  // The first level dictionary contains three sub-dict, first for source
+  // languages and second for target languages, we want to use the target
+  // languages. The last is for alpha languages.
   DictionaryValue* language_dict =
       static_cast<DictionaryValue*>(json_value.get());
   DictionaryValue* target_languages = NULL;
@@ -167,7 +172,7 @@
   const std::string& locale = g_browser_process->GetApplicationLocale();
 
   // Now we can clear language list.
-  set->clear();
+  target_language_set->clear();
   std::string message;
   // ... and replace it with the values we just fetched from the server.
   for (DictionaryValue::Iterator iter(*target_languages);
@@ -178,28 +183,32 @@
       TranslateBrowserMetrics::ReportUndisplayableLanguage(lang);
       continue;
     }
-    set->insert(lang);
+    target_language_set->insert(lang);
     if (message.empty())
       message += lang;
     else
       message += ", " + lang;
   }
   NotifyEvent(__LINE__, message);
-}
 
-// Returns URL to fetch the language list.
-GURL GetLanguageListFetchURL(bool include_alpha_languages) {
-  GURL url = GURL(kLanguageListFetchURL);
-  url = TranslateURLUtil::AddHostLocaleToUrl(url);
-  url = TranslateURLUtil::AddApiKeyToUrl(url);
-
-  if (include_alpha_languages) {
-    url = net::AppendQueryParameter(url,
-                                    kAlphaLanguageQueryName,
-                                    kAlphaLanguageQueryValue);
+  // Get the alpha languages. The "al" parameter could be abandoned.
+  DictionaryValue* alpha_languages = NULL;
+  if (!language_dict->GetDictionary(TranslateLanguageList::kAlphaLanguagesKey,
+                                    &alpha_languages) ||
+      alpha_languages == NULL) {
+    return;
   }
 
-  return url;
+  // We assume that the alpha languages are included in the above target
+  // languages, and don't use UMA or NotifyEvent.
+  alpha_language_set->clear();
+  for (DictionaryValue::Iterator iter(*alpha_languages);
+       !iter.IsAtEnd(); iter.Advance()) {
+    const std::string& lang = iter.key();
+    if (!l10n_util::IsLocaleNameTranslated(lang.c_str(), locale))
+      continue;
+    alpha_language_set->insert(lang);
+  }
 }
 
 }  // namespace
@@ -207,25 +216,20 @@
 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL.
 const char TranslateLanguageList::kLanguageListCallbackName[] = "sl(";
 const char TranslateLanguageList::kTargetLanguagesKey[] = "tl";
+const char TranslateLanguageList::kAlphaLanguagesKey[] = "al";
 
 TranslateLanguageList::TranslateLanguageList() {
   // We default to our hard coded list of languages in
   // |kDefaultSupportedLanguages|. This list will be overriden by a server
   // providing supported langauges list.
   for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i)
-    supported_languages_.insert(kDefaultSupportedLanguages[i]);
-  UpdateSupportedLanguages();
+    all_supported_languages_.insert(kDefaultSupportedLanguages[i]);
 
   if (update_is_disabled)
     return;
 
-  language_list_fetcher_.reset(
-      new TranslateURLFetcher(kFetcherIdForLanguageList));
+  language_list_fetcher_.reset(new TranslateURLFetcher(kFetcherId));
   language_list_fetcher_->set_max_retry_on_5xx(kMaxRetryOn5xx);
-
-  alpha_language_list_fetcher_.reset(
-      new TranslateURLFetcher(kFetcherIdForAlphaLanguageList));
-  alpha_language_list_fetcher_->set_max_retry_on_5xx(kMaxRetryOn5xx);
 }
 
 TranslateLanguageList::~TranslateLanguageList() {
@@ -240,7 +244,7 @@
 
   // Update language lists if they are not updated after Chrome was launched
   // for later requests.
-  if (language_list_fetcher_.get() || alpha_language_list_fetcher_.get())
+  if (language_list_fetcher_.get())
     RequestLanguageList();
 }
 
@@ -262,9 +266,7 @@
 }
 
 bool TranslateLanguageList::IsAlphaLanguage(const std::string& language) {
-  // |language| should exist only in the alpha language list.
-  return supported_alpha_languages_.count(language) != 0 &&
-         supported_languages_.count(language) == 0;
+  return alpha_languages_.count(language) != 0;
 }
 
 void TranslateLanguageList::RequestLanguageList() {
@@ -277,10 +279,15 @@
   if (language_list_fetcher_.get() &&
       (language_list_fetcher_->state() == TranslateURLFetcher::IDLE ||
        language_list_fetcher_->state() == TranslateURLFetcher::FAILED)) {
-    GURL url = GetLanguageListFetchURL(false);
+    GURL url = GURL(kLanguageListFetchURL);
+    url = TranslateURLUtil::AddHostLocaleToUrl(url);
+    url = TranslateURLUtil::AddApiKeyToUrl(url);
+    url = net::AppendQueryParameter(url,
+                                    kAlphaLanguageQueryName,
+                                    kAlphaLanguageQueryValue);
 
     std::string message = base::StringPrintf(
-        "Language list fetch starts (URL: %s)",
+        "Language list includeing alpha languages fetch starts (URL: %s)",
         url.spec().c_str());
     NotifyEvent(__LINE__, message);
 
@@ -291,24 +298,6 @@
     if (!result)
       NotifyEvent(__LINE__, "Request is omitted due to retry limit");
   }
-
-  if (alpha_language_list_fetcher_.get() &&
-      (alpha_language_list_fetcher_->state() == TranslateURLFetcher::IDLE ||
-       alpha_language_list_fetcher_->state() == TranslateURLFetcher::FAILED)) {
-    GURL url = GetLanguageListFetchURL(true);
-
-    std::string message = base::StringPrintf(
-        "Alpha language list fetch starts (URL: %s)",
-        url.spec().c_str());
-    NotifyEvent(__LINE__, message);
-
-    bool result = alpha_language_list_fetcher_->Request(
-        url,
-        base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete,
-                   base::Unretained(this)));
-    if (!result)
-      NotifyEvent(__LINE__, "Request is omitted due to retry limit");
-  }
 }
 
 // static
@@ -327,47 +316,16 @@
     // The TranslateURLFetcher has a limit for retried requests and aborts
     // re-try not to invoke OnLanguageListFetchComplete anymore if it's asked to
     // re-try too many times.
-    GURL url = GetLanguageListFetchURL(id == kFetcherIdForAlphaLanguageList);
-    std::string message = base::StringPrintf(
-        "Failed to Fetch languages from: %s", url.spec().c_str());
-    NotifyEvent(__LINE__, message);
+    NotifyEvent(__LINE__, "Failed to fetch languages");
     return;
   }
 
-  std::string message = base::StringPrintf(
-      "%s list is updated",
-      id == kFetcherIdForLanguageList ? "Language" : "Alpha language");
-  NotifyEvent(__LINE__, message);
+  NotifyEvent(__LINE__, "Language list is updated");
 
-  switch (id) {
-    case kFetcherIdForLanguageList:
-      SetSupportedLanguages(data, &supported_languages_);
-      language_list_fetcher_.reset();
-      break;
-    case kFetcherIdForAlphaLanguageList:
-      SetSupportedLanguages(data, &supported_alpha_languages_);
-      alpha_language_list_fetcher_.reset();
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-  UpdateSupportedLanguages();
+  DCHECK_EQ(kFetcherId, id);
+
+  SetSupportedLanguages(data, &all_supported_languages_, &alpha_languages_);
+  language_list_fetcher_.reset();
 
   last_updated_ = base::Time::Now();
 }
-
-void TranslateLanguageList::UpdateSupportedLanguages() {
-  all_supported_languages_.clear();
-  std::set<std::string>::const_iterator iter;
-  for (iter = supported_languages_.begin();
-       iter != supported_languages_.end();
-       ++iter) {
-    all_supported_languages_.insert(*iter);
-  }
-  for (iter = supported_alpha_languages_.begin();
-       iter != supported_alpha_languages_.end();
-       ++iter) {
-    all_supported_languages_.insert(*iter);
-  }
-}
diff --git a/chrome/browser/translate/translate_language_list.h b/chrome/browser/translate/translate_language_list.h
index a443817..5e818c0 100644
--- a/chrome/browser/translate/translate_language_list.h
+++ b/chrome/browser/translate/translate_language_list.h
@@ -57,6 +57,7 @@
   // static const values shared with our browser tests.
   static const char kLanguageListCallbackName[];
   static const char kTargetLanguagesKey[];
+  static const char kAlphaLanguagesKey[];
 
  private:
   // Callback function called when TranslateURLFetcher::Request() is finished.
@@ -64,27 +65,15 @@
                                    bool success,
                                    const std::string& data);
 
-  // Updates |all_supported_languages_| to contain the union of
-  // |supported_languages_| and |supported_alpha_languages_|.
-  void UpdateSupportedLanguages();
-
-  // The languages supported by the translation server.
-  std::set<std::string> supported_languages_;
-
-  // The alpha languages supported by the translation server.
-  std::set<std::string> supported_alpha_languages_;
-
-  // All the languages supported by the translation server. It contains the
-  // union of |supported_languages_| and |supported_alpha_languages_|.
+  // All the languages supported by the translation server.
   std::set<std::string> all_supported_languages_;
 
-  // A LanguageListFetcher instance to fetch a server providing supported
-  // language list.
-  scoped_ptr<TranslateURLFetcher> language_list_fetcher_;
+  // Alpha languages supported by the translation server.
+  std::set<std::string> alpha_languages_;
 
-  // A LanguageListFetcher instance to fetch a server providing supported alpha
-  // language list.
-  scoped_ptr<TranslateURLFetcher> alpha_language_list_fetcher_;
+  // A LanguageListFetcher instance to fetch a server providing supported
+  // language list including alpha languages.
+  scoped_ptr<TranslateURLFetcher> language_list_fetcher_;
 
   // The last-updated time when the language list is sent.
   base::Time last_updated_;
diff --git a/chrome/browser/translate/translate_manager.cc b/chrome/browser/translate/translate_manager.cc
index f071e4c..99fcf12 100644
--- a/chrome/browser/translate/translate_manager.cc
+++ b/chrome/browser/translate/translate_manager.cc
@@ -6,16 +6,14 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/compiler_specific.h"
 #include "base/memory/singleton.h"
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
-#include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/tab_contents/language_state.h"
@@ -36,7 +34,6 @@
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/render_messages.h"
@@ -52,10 +49,8 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "net/base/load_flags.h"
 #include "net/base/url_util.h"
 #include "net/http/http_status_code.h"
-#include "ui/base/l10n/l10n_util.h"
 
 #ifdef FILE_MANAGER_EXTENSION
 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h"
@@ -418,7 +413,6 @@
       TranslateTabHelper::FromWebContents(web_contents);
   if (!translate_tab_helper)
     return;
-
   std::string auto_translate_to =
       translate_tab_helper->language_state().AutoTranslateTo();
   if (!auto_translate_to.empty()) {
@@ -439,8 +433,10 @@
       language_code, target_lang);
 }
 
-void TranslateManager::InitiateTranslationPosted(
-    int process_id, int render_id, const std::string& page_lang, int attempt) {
+void TranslateManager::InitiateTranslationPosted(int process_id,
+                                                 int render_id,
+                                                 const std::string& page_lang,
+                                                 int attempt) {
   // The tab might have been closed.
   WebContents* web_contents =
       tab_util::GetWebContentsByID(process_id, render_id);
@@ -605,9 +601,8 @@
     details->error_type = TranslateErrors::UNSUPPORTED_LANGUAGE;
   }
 
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents->GetBrowserContext());
-  PrefService* prefs = profile->GetPrefs();
+  PrefService* prefs = Profile::FromBrowserContext(
+      web_contents->GetBrowserContext())->GetPrefs();
   TranslateInfoBarDelegate::Create(
       InfoBarService::FromWebContents(web_contents), true,
       (details->error_type == TranslateErrors::NONE) ?
diff --git a/chrome/browser/translate/translate_manager_browsertest.cc b/chrome/browser/translate/translate_manager_browsertest.cc
index d38b409..ee3d7ff 100644
--- a/chrome/browser/translate/translate_manager_browsertest.cc
+++ b/chrome/browser/translate/translate_manager_browsertest.cc
@@ -15,6 +15,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/browser/infobars/infobar.h"
 #include "chrome/browser/infobars/infobar_service.h"
@@ -27,7 +28,6 @@
 #include "chrome/browser/translate/translate_tab_helper.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/common/translate/language_detection_details.h"
@@ -44,7 +44,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/mock_notification_observer.h"
 #include "content/public/test/mock_render_process_host.h"
-#include "content/public/test/render_view_test.h"
 #include "content/public/test/test_renderer_host.h"
 #include "grit/generated_resources.h"
 #include "ipc/ipc_test_sink.h"
@@ -52,7 +51,6 @@
 #include "net/url_request/url_fetcher_delegate.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "third_party/WebKit/public/web/WebContextMenuData.h"
-#include "third_party/WebKit/public/web/WebKit.h"
 #include "third_party/cld/languages/public/languages.h"
 
 using content::NavigationController;
@@ -225,7 +223,6 @@
 
  protected:
   virtual void SetUp() {
-    WebKit::initialize(webkit_platform_support_.Get());
     // Access the TranslateManager singleton so it is created before we call
     // ChromeRenderViewHostTestHarness::SetUp() to match what's done in Chrome,
     // where the TranslateManager is created before the WebContents.  This
@@ -256,10 +253,10 @@
         content::Source<InfoBarService>(infobar_service()));
 
     ChromeRenderViewHostTestHarness::TearDown();
-    WebKit::shutdown();
   }
 
   void SimulateTranslateScriptURLFetch(bool success) {
+    // TODO(hajimehoshi): 0 is a magic number.
     net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
     ASSERT_TRUE(fetcher);
     net::URLRequestStatus status;
@@ -272,7 +269,10 @@
   }
 
   void SimulateSupportedLanguagesURLFetch(
-      bool success, const std::vector<std::string>& languages) {
+      bool success,
+      const std::vector<std::string>& languages,
+      bool use_alpha_languages,
+      const std::vector<std::string>& alpha_languages) {
     net::URLRequestStatus status;
     status.set_status(success ? net::URLRequestStatus::SUCCESS :
                                 net::URLRequestStatus::FAILED);
@@ -290,17 +290,29 @@
         if (i == 0)
           comma = ",";
       }
+
+      if (use_alpha_languages) {
+        data += base::StringPrintf("},\"%s\": {",
+                                   TranslateLanguageList::kAlphaLanguagesKey);
+        comma = "";
+        for (size_t i = 0; i < alpha_languages.size(); ++i) {
+          data += base::StringPrintf("%s\"%s\": 1", comma,
+                                     alpha_languages[i].c_str());
+          if (i == 0)
+            comma = ",";
+        }
+      }
+
       data += "}})";
     }
-    for (int id = 1; id <= 2; ++id) {
-      net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(id);
-      ASSERT_TRUE(fetcher);
-      fetcher->set_url(fetcher->GetOriginalURL());
-      fetcher->set_status(status);
-      fetcher->set_response_code(success ? 200 : 500);
-      fetcher->SetResponseString(data);
-      fetcher->delegate()->OnURLFetchComplete(fetcher);
-    }
+    // TODO(hajimehoshi): 1 is a magic number.
+    net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(1);
+    ASSERT_TRUE(fetcher != NULL);
+    fetcher->set_url(fetcher->GetOriginalURL());
+    fetcher->set_status(status);
+    fetcher->set_response_code(success ? 200 : 500);
+    fetcher->SetResponseString(data);
+    fetcher->delegate()->OnURLFetchComplete(fetcher);
   }
 
   void SetPrefObserverExpectation(const char* path) {
@@ -312,8 +324,6 @@
  private:
   content::NotificationRegistrar notification_registrar_;
   net::TestURLFetcherFactory url_fetcher_factory_;
-  content::RenderViewTest::RendererWebKitPlatformSupportImplNoSandbox
-      webkit_platform_support_;
 
   // The infobars that have been removed.
   // WARNING: the pointers point to deleted objects, use only for comparison.
@@ -633,6 +643,10 @@
   server_languages.push_back("fr-FR");
   server_languages.push_back("xx");
 
+  std::vector<std::string> alpha_languages;
+  alpha_languages.push_back("aa");
+  alpha_languages.push_back("yi");
+
   // First, get the default languages list. Note that calling
   // GetSupportedLanguages() invokes RequestLanguageList() internally.
   std::vector<std::string> default_supported_languages;
@@ -646,47 +660,76 @@
   EXPECT_EQ(default_supported_languages, current_supported_languages);
 
   // Also check that it didn't change if we failed the URL fetch.
-  SimulateSupportedLanguagesURLFetch(false, std::vector<std::string>());
+  SimulateSupportedLanguagesURLFetch(false, std::vector<std::string>(),
+                                     true, std::vector<std::string>());
   current_supported_languages.clear();
   TranslateManager::GetSupportedLanguages(&current_supported_languages);
   EXPECT_EQ(default_supported_languages, current_supported_languages);
 
   // Now check that we got the appropriate set of languages from the server.
-  SimulateSupportedLanguagesURLFetch(true, server_languages);
+  SimulateSupportedLanguagesURLFetch(true, server_languages,
+                                     true, alpha_languages);
   current_supported_languages.clear();
   TranslateManager::GetSupportedLanguages(&current_supported_languages);
   // "xx" can't be displayed in the Translate inforbar, so this is eliminated.
   EXPECT_EQ(server_languages.size() - 1, current_supported_languages.size());
   // Not sure we need to guarantee the order of languages, so we find them.
   for (size_t i = 0; i < server_languages.size(); ++i) {
-    if (server_languages[i] == "xx")
+    const std::string& lang = server_languages[i];
+    if (lang == "xx")
       continue;
     EXPECT_NE(current_supported_languages.end(),
               std::find(current_supported_languages.begin(),
                         current_supported_languages.end(),
-                        server_languages[i]));
+                        lang));
+    bool is_alpha = std::find(alpha_languages.begin(),
+                              alpha_languages.end(),
+                              lang) != alpha_languages.end();
+    EXPECT_EQ(TranslateManager::IsAlphaLanguage(lang), is_alpha);
   }
 }
 
-std::string GetLanguageListString(
-    const std::vector<std::string>& language_list) {
-  // The translate manager is expecting a JSON string like:
-  // sl({'sl': {'XX': 'LanguageName', ...}, 'tl': {'XX': 'LanguageName', ...}})
-  // We only need to set the tl (target languages) dictionary.
-  scoped_ptr<DictionaryValue> target_languages_dict(new DictionaryValue);
-  for (size_t i = 0; i < language_list.size(); ++i) {
-    // The value is ignored, we only use the key.
-    target_languages_dict->Set(language_list[i], Value::CreateNullValue());
-  }
+// Test the fetching of languages from the translate server without 'al'
+// parameter.
+TEST_F(TranslateManagerBrowserTest,
+       FetchLanguagesFromTranslateServerWithoutAlpha) {
+  std::vector<std::string> server_languages;
+  server_languages.push_back("aa");
+  server_languages.push_back("ak");
+  server_languages.push_back("ab");
+  server_languages.push_back("en-CA");
+  server_languages.push_back("zh");
+  server_languages.push_back("yi");
+  server_languages.push_back("fr-FR");
+  server_languages.push_back("xx");
 
-  DictionaryValue language_list_dict;
-  language_list_dict.Set("tl", target_languages_dict.release());
-  std::string language_list_json_str;
-  base::JSONWriter::Write(&language_list_dict, &language_list_json_str);
-  std::string language_list_str("sl(");
-  language_list_str += language_list_json_str;
-  language_list_str += ")";
-  return language_list_str;
+  std::vector<std::string> alpha_languages;
+  alpha_languages.push_back("aa");
+  alpha_languages.push_back("yi");
+
+  // call GetSupportedLanguages to call RequestLanguageList internally.
+  std::vector<std::string> default_supported_languages;
+  TranslateManager::GetSupportedLanguages(&default_supported_languages);
+
+  SimulateSupportedLanguagesURLFetch(true, server_languages,
+                                     false, alpha_languages);
+
+  std::vector<std::string> current_supported_languages;
+  TranslateManager::GetSupportedLanguages(&current_supported_languages);
+
+  // "xx" can't be displayed in the Translate inforbar, so this is eliminated.
+  EXPECT_EQ(server_languages.size() - 1, current_supported_languages.size());
+
+  for (size_t i = 0; i < server_languages.size(); ++i) {
+    const std::string& lang = server_languages[i];
+    if (lang == "xx")
+      continue;
+    EXPECT_NE(current_supported_languages.end(),
+              std::find(current_supported_languages.begin(),
+                        current_supported_languages.end(),
+                        lang));
+    EXPECT_FALSE(TranslateManager::IsAlphaLanguage(lang));
+  }
 }
 
 // Tests auto-translate on page.
diff --git a/chrome/browser/translate/translate_prefs.cc b/chrome/browser/translate/translate_prefs.cc
index 8ec9736..303fb21 100644
--- a/chrome/browser/translate/translate_prefs.cc
+++ b/chrome/browser/translate/translate_prefs.cc
@@ -285,7 +285,7 @@
 }
 
 // static
-void TranslatePrefs::RegisterUserPrefs(
+void TranslatePrefs::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(kPrefTranslateLanguageBlacklist,
                              user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
diff --git a/chrome/browser/translate/translate_prefs.h b/chrome/browser/translate/translate_prefs.h
index f1ce6d4..2d77124 100644
--- a/chrome/browser/translate/translate_prefs.h
+++ b/chrome/browser/translate/translate_prefs.h
@@ -83,7 +83,7 @@
       Profile* profile, const std::string& language);
   static bool ShouldAutoTranslate(PrefService* user_prefs,
       const std::string& original_language, std::string* target_language);
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
   static void MigrateUserPrefs(PrefService* user_prefs);
 
  private:
diff --git a/chrome/browser/translate/translate_tab_helper.cc b/chrome/browser/translate/translate_tab_helper.cc
index b8de0e5..4cf6dda 100644
--- a/chrome/browser/translate/translate_tab_helper.cc
+++ b/chrome/browser/translate/translate_tab_helper.cc
@@ -4,8 +4,8 @@
 
 #include "chrome/browser/translate/translate_tab_helper.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/translate/page_translated_details.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/common/translate/language_detection_details.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/active_tab_tracker.h b/chrome/browser/ui/active_tab_tracker.h
index f58528c..f7d18e4 100644
--- a/chrome/browser/ui/active_tab_tracker.h
+++ b/chrome/browser/ui/active_tab_tracker.h
@@ -15,7 +15,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Browser;
 
diff --git a/chrome/browser/ui/alternate_error_tab_observer.cc b/chrome/browser/ui/alternate_error_tab_observer.cc
index f381d86..e9ed442 100644
--- a/chrome/browser/ui/alternate_error_tab_observer.cc
+++ b/chrome/browser/ui/alternate_error_tab_observer.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/ui/alternate_error_tab_observer.h"
 
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/notification_service.h"
@@ -41,7 +41,7 @@
 }
 
 // static
-void AlternateErrorPageTabObserver::RegisterUserPrefs(
+void AlternateErrorPageTabObserver::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* prefs) {
   prefs->RegisterBooleanPref(prefs::kAlternateErrorPagesEnabled,
                              true,
diff --git a/chrome/browser/ui/alternate_error_tab_observer.h b/chrome/browser/ui/alternate_error_tab_observer.h
index 475505c..79ea6c1 100644
--- a/chrome/browser/ui/alternate_error_tab_observer.h
+++ b/chrome/browser/ui/alternate_error_tab_observer.h
@@ -25,7 +25,7 @@
  public:
   virtual ~AlternateErrorPageTabObserver();
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  private:
   explicit AlternateErrorPageTabObserver(content::WebContents* web_contents);
diff --git a/chrome/browser/ui/android/autofill/autofill_dialog_view_android.cc b/chrome/browser/ui/android/autofill/autofill_dialog_view_android.cc
index 4b06e11..22a7dfc 100644
--- a/chrome/browser/ui/android/autofill/autofill_dialog_view_android.cc
+++ b/chrome/browser/ui/android/autofill/autofill_dialog_view_android.cc
@@ -210,6 +210,10 @@
   NOTIMPLEMENTED();
 }
 
+TestableAutofillDialogView* AutofillDialogViewAndroid::GetTestableView() {
+  return NULL;
+}
+
 // TODO(aruslan): bind to the list of accounts population.
 std::vector<std::string> AutofillDialogViewAndroid::GetAvailableUserAccounts() {
   std::vector<std::string> account_names;
diff --git a/chrome/browser/ui/android/autofill/autofill_dialog_view_android.h b/chrome/browser/ui/android/autofill/autofill_dialog_view_android.h
index 5a68739..b44f7fe 100644
--- a/chrome/browser/ui/android/autofill/autofill_dialog_view_android.h
+++ b/chrome/browser/ui/android/autofill/autofill_dialog_view_android.h
@@ -42,6 +42,7 @@
   virtual void UpdateProgressBar(double value) OVERRIDE;
   virtual void ModelChanged() OVERRIDE;
   virtual void OnSignInResize(const gfx::Size& pref_size) OVERRIDE;
+  virtual TestableAutofillDialogView* GetTestableView() OVERRIDE;
 
   // Java to C++ calls
   void ItemSelected(JNIEnv* env, jobject obj, jint section, jint index);
diff --git a/chrome/browser/ui/android/navigation_popup.cc b/chrome/browser/ui/android/navigation_popup.cc
index 69ef1df..4033b31 100644
--- a/chrome/browser/ui/android/navigation_popup.cc
+++ b/chrome/browser/ui/android/navigation_popup.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/url_constants.h"
-#include "googleurl/src/gurl.h"
 #include "grit/ui_resources.h"
 #include "jni/NavigationPopup_jni.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -22,6 +21,7 @@
 #include "ui/gfx/android/java_bitmap.h"
 #include "ui/gfx/favicon_size.h"
 #include "ui/gfx/image/image.h"
+#include "url/gurl.h"
 
 using base::android::ConvertUTF8ToJavaString;
 using base::android::ScopedJavaLocalRef;
diff --git a/chrome/browser/ui/android/tab_model/tab_model.cc b/chrome/browser/ui/android/tab_model/tab_model.cc
index 9ecf372..4840fde 100644
--- a/chrome/browser/ui/android/tab_model/tab_model.cc
+++ b/chrome/browser/ui/android/tab_model/tab_model.cc
@@ -6,11 +6,11 @@
 
 #include "base/logging.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/search_terms_data.h"
 #include "chrome/browser/sync/glue/synced_window_delegate_android.h"
 #include "chrome/browser/ui/toolbar/toolbar_model_impl.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 
 using content::NotificationService;
diff --git a/chrome/browser/ui/android/tab_model/tab_model_unittest.cc b/chrome/browser/ui/android/tab_model/tab_model_unittest.cc
index 9a8509c..96d2086 100644
--- a/chrome/browser/ui/android/tab_model/tab_model_unittest.cc
+++ b/chrome/browser/ui/android/tab_model/tab_model_unittest.cc
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/android/tab_model/tab_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/ui/app_list/app_list_service.h b/chrome/browser/ui/app_list/app_list_service.h
index 97b8ef6..ebb8f68 100644
--- a/chrome/browser/ui/app_list/app_list_service.h
+++ b/chrome/browser/ui/app_list/app_list_service.h
@@ -60,7 +60,7 @@
 
   // Enable the app list. What this does specifically will depend on the host
   // operating system and shell.
-  virtual void EnableAppList() = 0;
+  virtual void EnableAppList(Profile* initial_profile) = 0;
 
   // Get the window the app list is in, or NULL if the app list isn't visible.
   virtual gfx::NativeWindow GetAppListWindow() = 0;
diff --git a/chrome/browser/ui/app_list/app_list_service_disabled.cc b/chrome/browser/ui/app_list/app_list_service_disabled.cc
index 8122e97..5b46a16 100644
--- a/chrome/browser/ui/app_list/app_list_service_disabled.cc
+++ b/chrome/browser/ui/app_list/app_list_service_disabled.cc
@@ -37,7 +37,7 @@
 
   virtual Profile* GetCurrentAppListProfile() OVERRIDE { return NULL; }
   virtual bool IsAppListVisible() const OVERRIDE { return false; }
-  virtual void EnableAppList() OVERRIDE {}
+  virtual void EnableAppList(Profile* initial_profile) OVERRIDE {}
 
   virtual AppListControllerDelegate* CreateControllerDelegate() OVERRIDE {
     return NULL;
diff --git a/chrome/browser/ui/app_list/app_list_service_impl.cc b/chrome/browser/ui/app_list/app_list_service_impl.cc
index c763cdd..0dcee73 100644
--- a/chrome/browser/ui/app_list/app_list_service_impl.cc
+++ b/chrome/browser/ui/app_list/app_list_service_impl.cc
@@ -8,9 +8,9 @@
 #include "base/prefs/pref_service.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
@@ -184,6 +184,8 @@
                  content::Source<Profile>(profile_));
   registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED,
                  content::Source<Profile>(profile_));
+  registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
+                 content::Source<Profile>(profile_));
 }
 
 void AppListServiceImpl::InvalidatePendingProfileLoads() {
diff --git a/chrome/browser/ui/app_list/app_list_service_mac.mm b/chrome/browser/ui/app_list/app_list_service_mac.mm
index 2637424..88ee1ab 100644
--- a/chrome/browser/ui/app_list/app_list_service_mac.mm
+++ b/chrome/browser/ui/app_list/app_list_service_mac.mm
@@ -63,11 +63,14 @@
   virtual void ShowAppList(Profile* requested_profile) OVERRIDE;
   virtual void DismissAppList() OVERRIDE;
   virtual bool IsAppListVisible() const OVERRIDE;
-  virtual void EnableAppList() OVERRIDE;
+  virtual void EnableAppList(Profile* initial_profile) OVERRIDE;
   virtual gfx::NativeWindow GetAppListWindow() OVERRIDE;
 
+  // AppListServiceImpl override:
+  virtual void OnSigninStatusChanged() OVERRIDE;
+
   // AppShimHandler overrides:
-  virtual bool OnShimLaunch(apps::AppShimHandler::Host* host,
+  virtual void OnShimLaunch(apps::AppShimHandler::Host* host,
                             apps::AppShimLaunchType launch_type) OVERRIDE;
   virtual void OnShimClose(apps::AppShimHandler::Host* host) OVERRIDE;
   virtual void OnShimFocus(apps::AppShimHandler::Host* host,
@@ -178,7 +181,7 @@
       CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAppListShim);
   base::FilePath install_path = web_app::GetAppInstallPath(
       GetAppListShortcutInfo(profile_path));
-  if (enable == file_util::PathExists(install_path))
+  if (enable == base::PathExists(install_path))
     return;
 
   if (enable) {
@@ -190,7 +193,7 @@
 
   // Sanity check because deleting things recursively is scary.
   CHECK(install_path.MatchesExtension(".app"));
-  base::Delete(install_path, true /* recursive */);
+  base::DeleteFile(install_path, true /* recursive */);
 }
 
 void CreateShortcutsInDefaultLocation(
@@ -317,7 +320,7 @@
   return [[window_controller_ window] isVisible];
 }
 
-void AppListServiceMac::EnableAppList() {
+void AppListServiceMac::EnableAppList(Profile* initial_profile) {
   // TODO(tapted): Implement enable logic here for OSX.
 }
 
@@ -325,11 +328,15 @@
   return [window_controller_ window];
 }
 
-bool AppListServiceMac::OnShimLaunch(apps::AppShimHandler::Host* host,
+void AppListServiceMac::OnSigninStatusChanged() {
+  [[window_controller_ appListViewController] onSigninStatusChanged];
+}
+
+void AppListServiceMac::OnShimLaunch(apps::AppShimHandler::Host* host,
                                      apps::AppShimLaunchType launch_type) {
   ShowForSavedProfile();
   observers_.AddObserver(host);
-  return true;
+  host->OnAppLaunchComplete(apps::APP_SHIM_LAUNCH_SUCCESS);
 }
 
 void AppListServiceMac::OnShimClose(apps::AppShimHandler::Host* host) {
diff --git a/chrome/browser/ui/app_list/app_list_service_mac_browsertest.mm b/chrome/browser/ui/app_list/app_list_service_mac_browsertest.mm
index f198d2b..8e96c70 100644
--- a/chrome/browser/ui/app_list/app_list_service_mac_browsertest.mm
+++ b/chrome/browser/ui/app_list/app_list_service_mac_browsertest.mm
@@ -18,15 +18,16 @@
 class AppListServiceMacBrowserTest : public InProcessBrowserTest,
                                      public AppShimHandler::Host {
  public:
-  AppListServiceMacBrowserTest() : close_count_(0), running_(false) {}
+  AppListServiceMacBrowserTest() : launch_count_(0),
+                                   close_count_(0),
+                                   running_(false) {}
 
  protected:
   void LaunchShim() {
     DCHECK(!running_);
     // AppList shims should always succced showing the app list.
-    EXPECT_TRUE(AppShimHandler::GetForAppMode(
-        app_mode::kAppListModeId)->OnShimLaunch(this,
-                                                apps::APP_SHIM_LAUNCH_NORMAL));
+    AppShimHandler::GetForAppMode(app_mode::kAppListModeId)->
+        OnShimLaunch(this, apps::APP_SHIM_LAUNCH_NORMAL);
     running_ = true;
   }
 
@@ -43,6 +44,9 @@
   }
 
   // AppShimHandler::Host overrides:
+  virtual void OnAppLaunchComplete(apps::AppShimLaunchResult) OVERRIDE {
+    ++launch_count_;
+  }
   virtual void OnAppClosed() OVERRIDE {
     ++close_count_;
     QuitShim();
@@ -55,6 +59,7 @@
     return app_mode::kAppListModeId;
   }
 
+  int launch_count_;
   int close_count_;
   bool running_;
 
@@ -76,6 +81,7 @@
   service->ShowForSavedProfile();
   EXPECT_EQ(browser()->profile(), service->GetCurrentAppListProfile());
   EXPECT_TRUE(service->IsAppListVisible());
+  EXPECT_EQ(0, launch_count_);
   EXPECT_EQ(0, close_count_);
   service->DismissAppList();
   EXPECT_FALSE(service->IsAppListVisible());
@@ -88,6 +94,7 @@
   // not the app list.
   LaunchShim();
   EXPECT_TRUE(service->IsAppListVisible());
+  EXPECT_EQ(1, launch_count_);
   QuitShim();
   EXPECT_FALSE(service->IsAppListVisible());
   EXPECT_EQ(0, close_count_);
@@ -96,6 +103,7 @@
   // icon again, which should close it.
   LaunchShim();
   EXPECT_TRUE(service->IsAppListVisible());
+  EXPECT_EQ(2, launch_count_);
   FocusShim();
   EXPECT_FALSE(service->IsAppListVisible());
   EXPECT_EQ(1, close_count_);
@@ -103,6 +111,7 @@
   // Test showing the app list via the shim, then dismissing the app list.
   LaunchShim();
   EXPECT_TRUE(service->IsAppListVisible());
+  EXPECT_EQ(3, launch_count_);
   service->DismissAppList();
   EXPECT_FALSE(service->IsAppListVisible());
   EXPECT_EQ(2, close_count_);
@@ -111,6 +120,7 @@
   // is unchanged when the app list is dismissed again.
   service->ShowAppList(browser()->profile());
   EXPECT_TRUE(service->IsAppListVisible());
+  EXPECT_EQ(3, launch_count_);
   service->DismissAppList();
   EXPECT_FALSE(service->IsAppListVisible());
   EXPECT_EQ(2, close_count_);
diff --git a/chrome/browser/ui/app_list/apps_model_builder.cc b/chrome/browser/ui/app_list/apps_model_builder.cc
index 2176d6f..b662b45 100644
--- a/chrome/browser/ui/app_list/apps_model_builder.cc
+++ b/chrome/browser/ui/app_list/apps_model_builder.cc
@@ -8,6 +8,7 @@
 
 #include "base/auto_reset.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_sorting.h"
@@ -16,7 +17,6 @@
 #include "chrome/browser/extensions/install_tracker_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/extension_app_item.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
@@ -110,7 +110,7 @@
   model_->DeleteAt(i);
 }
 
-void AppsModelBuilder::OnExtensionInstalled(const Extension* extension) {
+void AppsModelBuilder::OnExtensionLoaded(const Extension* extension) {
   if (!extension->ShouldDisplayInAppLauncher())
     return;
 
@@ -129,6 +129,13 @@
   UpdateHighlight();
 }
 
+void AppsModelBuilder::OnExtensionUnloaded(const Extension* extension) {
+  int index = FindApp(extension->id());
+  if (index < 0)
+    return;
+  GetAppAt(index)->UpdateIcon();
+}
+
 void AppsModelBuilder::OnExtensionUninstalled(const Extension* extension) {
   int index = FindApp(extension->id());
   if (index < 0)
@@ -136,13 +143,6 @@
   model_->DeleteAt(index);
 }
 
-void AppsModelBuilder::OnExtensionDisabled(const Extension* extension) {
-  int index = FindApp(extension->id());
-  if (index < 0)
-    return;
-  GetAppAt(index)->UpdateIcon();
-}
-
 void AppsModelBuilder::OnAppsReordered() {
   ResortApps();
 }
@@ -194,14 +194,24 @@
 }
 
 void AppsModelBuilder::ResortApps() {
+  // Scan app items in |model_| and put the apps that do not have valid ordinals
+  // into |invalid_ordinal_apps|. This is needed to handle uninstalling a
+  // terminated app case, where there is no unload notification and uninstall
+  // notification comes in after the app's ordinals are cleared.
+  // See http://crbug.com/256749.
   Apps apps;
-  for (size_t i = 0; i < model_->item_count(); ++i)
-    apps.push_back(GetAppAt(i));
-
-  if (apps.empty())
-    return;
+  Apps invalid_ordinal_apps;
+  for (size_t i = 0; i < model_->item_count(); ++i) {
+    ExtensionAppItem* app = GetAppAt(i);
+    if (app->GetPageOrdinal().IsValid() && app->GetAppLaunchOrdinal().IsValid())
+      apps.push_back(app);
+    else
+      invalid_ordinal_apps.push_back(app);
+  }
 
   std::sort(apps.begin(), apps.end(), &AppPrecedes);
+  apps.insert(
+      apps.end(), invalid_ordinal_apps.begin(), invalid_ordinal_apps.end());
 
   base::AutoReset<bool> auto_reset(&ignore_changes_, true);
 
diff --git a/chrome/browser/ui/app_list/apps_model_builder.h b/chrome/browser/ui/app_list/apps_model_builder.h
index 29e0bc9..0898dd9 100644
--- a/chrome/browser/ui/app_list/apps_model_builder.h
+++ b/chrome/browser/ui/app_list/apps_model_builder.h
@@ -56,11 +56,13 @@
 
   virtual void OnInstallFailure(const std::string& extension_id) OVERRIDE;
   virtual void OnExtensionInstalled(
+      const extensions::Extension* extension) OVERRIDE {}
+  virtual void OnExtensionLoaded(
+      const extensions::Extension* extension) OVERRIDE;
+  virtual void OnExtensionUnloaded(
       const extensions::Extension* extension) OVERRIDE;
   virtual void OnExtensionUninstalled(
       const extensions::Extension* extension) OVERRIDE;
-  virtual void OnExtensionDisabled(
-      const extensions::Extension* extension) OVERRIDE;
   virtual void OnAppsReordered() OVERRIDE;
   virtual void OnAppInstalledToAppList(
       const std::string& extension_id) OVERRIDE;
diff --git a/chrome/browser/ui/app_list/apps_model_builder_unittest.cc b/chrome/browser/ui/app_list/apps_model_builder_unittest.cc
index 3325db3..3781da0 100644
--- a/chrome/browser/ui/app_list/apps_model_builder_unittest.cc
+++ b/chrome/browser/ui/app_list/apps_model_builder_unittest.cc
@@ -163,6 +163,26 @@
   loop_.RunUntilIdle();
 }
 
+TEST_F(AppsModelBuilderTest, UninstallTerminatedApp) {
+  scoped_ptr<app_list::AppListModel::Apps> model(
+      new app_list::AppListModel::Apps);
+  AppsModelBuilder builder(profile_.get(), model.get(), NULL);
+  builder.Build();
+
+  const extensions::Extension* app =
+      service_->GetInstalledExtension(kPackagedApp2Id);
+  ASSERT_TRUE(app != NULL);
+
+  // Simulate an app termination.
+  service_->TrackTerminatedExtensionForTest(app);
+
+  service_->UninstallExtension(kPackagedApp2Id, false, NULL);
+  EXPECT_EQ(std::string("Packaged App 1,Hosted App"),
+            GetModelContent(model.get()));
+
+  loop_.RunUntilIdle();
+}
+
 TEST_F(AppsModelBuilderTest, OrdinalPrefsChange) {
   scoped_ptr<app_list::AppListModel::Apps> model(
       new app_list::AppListModel::Apps);
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.cc b/chrome/browser/ui/app_list/search/app_search_provider.cc
index b3cd83b..992d250 100644
--- a/chrome/browser/ui/app_list/search/app_search_provider.cc
+++ b/chrome/browser/ui/app_list/search/app_search_provider.cc
@@ -7,13 +7,13 @@
 #include <string>
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/search/app_result.h"
 #include "chrome/browser/ui/app_list/search/tokenized_string.h"
 #include "chrome/browser/ui/app_list/search/tokenized_string_match.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 
diff --git a/chrome/browser/ui/app_list/search/search_webstore_result.h b/chrome/browser/ui/app_list/search/search_webstore_result.h
index 4a0052e..0f494b8 100644
--- a/chrome/browser/ui/app_list/search/search_webstore_result.h
+++ b/chrome/browser/ui/app_list/search/search_webstore_result.h
@@ -9,7 +9,7 @@
 
 #include "base/basictypes.h"
 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Profile;
 
diff --git a/chrome/browser/ui/app_list/search/webstore_provider.cc b/chrome/browser/ui/app_list/search/webstore_provider.cc
index 16c2d30..0a0d14f 100644
--- a/chrome/browser/ui/app_list/search/webstore_provider.cc
+++ b/chrome/browser/ui/app_list/search/webstore_provider.cc
@@ -15,7 +15,7 @@
 #include "chrome/browser/ui/app_list/search/webstore_result.h"
 #include "chrome/browser/ui/app_list/search/webstore_search_fetcher.h"
 #include "chrome/common/extensions/extension_constants.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace app_list {
 
diff --git a/chrome/browser/ui/app_list/search/webstore_result.cc b/chrome/browser/ui/app_list/search/webstore_result.cc
index 1ceb310..f2f36de 100644
--- a/chrome/browser/ui/app_list/search/webstore_result.cc
+++ b/chrome/browser/ui/app_list/search/webstore_result.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
 #include "chrome/browser/ui/app_list/search/webstore_installer.h"
 #include "chrome/browser/ui/app_list/search/webstore_result_icon_source.h"
+#include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/common/extensions/extension.h"
 #include "grit/chromium_strings.h"
@@ -64,15 +65,13 @@
 }
 
 void WebstoreResult::Open(int event_flags) {
-  const extensions::Extension* extension =
-      extensions::ExtensionSystem::Get(profile_)->extension_service()
-          ->GetInstalledExtension(app_id_);
-  if (extension) {
-    controller_->ActivateApp(profile_, extension, event_flags);
-    return;
-  }
-
-  StartInstall();
+  const GURL store_url(extension_urls::GetWebstoreItemDetailURLPrefix() +
+                       app_id_);
+  chrome::NavigateParams params(profile_,
+                                store_url,
+                                content::PAGE_TRANSITION_LINK);
+  params.disposition = ui::DispositionFromEventFlags(event_flags);
+  chrome::Navigate(&params);
 }
 
 void WebstoreResult::InvokeAction(int action_index, int event_flags) {
@@ -186,10 +185,13 @@
   UpdateActions();
 }
 
-void WebstoreResult::OnExtensionUninstalled(
+void WebstoreResult::OnExtensionLoaded(
     const extensions::Extension* extension) {}
 
-void WebstoreResult::OnExtensionDisabled(
+void WebstoreResult::OnExtensionUnloaded(
+    const extensions::Extension* extension) {}
+
+void WebstoreResult::OnExtensionUninstalled(
     const extensions::Extension* extension) {}
 
 void WebstoreResult::OnAppsReordered() {}
diff --git a/chrome/browser/ui/app_list/search/webstore_result.h b/chrome/browser/ui/app_list/search/webstore_result.h
index 8743cd5..3bea408 100644
--- a/chrome/browser/ui/app_list/search/webstore_result.h
+++ b/chrome/browser/ui/app_list/search/webstore_result.h
@@ -11,7 +11,7 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/extensions/install_observer.h"
 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class AppListControllerDelegate;
 class Profile;
@@ -60,9 +60,11 @@
   virtual void OnInstallFailure(const std::string& extension_id) OVERRIDE;
   virtual void OnExtensionInstalled(
       const extensions::Extension* extension) OVERRIDE;
-  virtual void OnExtensionUninstalled(
+  virtual void OnExtensionLoaded(
       const extensions::Extension* extension) OVERRIDE;
-  virtual void OnExtensionDisabled(
+  virtual void OnExtensionUnloaded(
+      const extensions::Extension* extension) OVERRIDE;
+  virtual void OnExtensionUninstalled(
       const extensions::Extension* extension) OVERRIDE;
   virtual void OnAppsReordered() OVERRIDE;
   virtual void OnAppInstalledToAppList(
diff --git a/chrome/browser/ui/app_list/search/webstore_result_icon_source.h b/chrome/browser/ui/app_list/search/webstore_result_icon_source.h
index 06b4fed..3b43335 100644
--- a/chrome/browser/ui/app_list/search/webstore_result_icon_source.h
+++ b/chrome/browser/ui/app_list/search/webstore_result_icon_source.h
@@ -10,10 +10,10 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/image_decoder.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_source.h"
+#include "url/gurl.h"
 
 namespace net {
 class URLFetcher;
diff --git a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.cc b/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.cc
index 8f6fc13..77e9133 100644
--- a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.cc
+++ b/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
 
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
diff --git a/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc b/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc
index 8c3f76c..fc3cc46 100644
--- a/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc
+++ b/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc
@@ -8,6 +8,7 @@
 #include "base/i18n/rtl.h"
 #include "base/memory/singleton.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
@@ -16,7 +17,6 @@
 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/apps/OWNERS b/chrome/browser/ui/apps/OWNERS
new file mode 100644
index 0000000..8391787
--- /dev/null
+++ b/chrome/browser/ui/apps/OWNERS
@@ -0,0 +1,6 @@
+# Apps team members
+asargent@chromium.org
+benwells@chromium.org
+koz@chromium.org
+miket@chromium.org
+tapted@chromium.org
diff --git a/chrome/browser/ui/apps/chrome_shell_window_delegate.cc b/chrome/browser/ui/apps/chrome_shell_window_delegate.cc
index 255c416..80b810f 100644
--- a/chrome/browser/ui/apps/chrome_shell_window_delegate.cc
+++ b/chrome/browser/ui/apps/chrome_shell_window_delegate.cc
@@ -9,6 +9,8 @@
 #include "chrome/browser/file_select_helper.h"
 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
 #include "chrome/browser/platform_util.h"
+#include "chrome/browser/printing/print_preview_message_handler.h"
+#include "chrome/browser/printing/print_view_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_finder.h"
@@ -29,20 +31,12 @@
 
 bool disable_external_open_for_testing_ = false;
 
-class ShellWindowLinkDelegate : public content::WebContentsDelegate {
- public:
-  ShellWindowLinkDelegate();
-
- private:
-  virtual content::WebContents* OpenURLFromTab(
-      content::WebContents* source,
-      const content::OpenURLParams& params) OVERRIDE;
-
-  DISALLOW_COPY_AND_ASSIGN(ShellWindowLinkDelegate);
-};
+}  // namespace
 
 ShellWindowLinkDelegate::ShellWindowLinkDelegate() {}
 
+ShellWindowLinkDelegate::~ShellWindowLinkDelegate() {}
+
 // TODO(rockot): Add a test that exercises this code. See
 // http://crbug.com/254260.
 content::WebContents* ShellWindowLinkDelegate::OpenURLFromTab(
@@ -53,8 +47,6 @@
   return NULL;
 }
 
-}  // namespace
-
 ChromeShellWindowDelegate::ChromeShellWindowDelegate() {}
 
 ChromeShellWindowDelegate::~ChromeShellWindowDelegate() {}
@@ -66,6 +58,11 @@
 void ChromeShellWindowDelegate::InitWebContents(
     content::WebContents* web_contents) {
   FaviconTabHelper::CreateForWebContents(web_contents);
+
+#if defined(ENABLE_PRINTING)
+  printing::PrintPreviewMessageHandler::CreateForWebContents(web_contents);
+  printing::PrintViewManager::CreateForWebContents(web_contents);
+#endif
 }
 
 content::WebContents* ChromeShellWindowDelegate::OpenURLFromTab(
@@ -92,7 +89,9 @@
     bool user_gesture,
     bool* was_blocked) {
   if (!disable_external_open_for_testing_) {
-    new_contents->SetDelegate(new ShellWindowLinkDelegate());
+    if (!shell_window_link_delegate_.get())
+      shell_window_link_delegate_.reset(new ShellWindowLinkDelegate());
+    new_contents->SetDelegate(shell_window_link_delegate_.get());
     return;
   }
   Browser* browser =
diff --git a/chrome/browser/ui/apps/chrome_shell_window_delegate.h b/chrome/browser/ui/apps/chrome_shell_window_delegate.h
index 4bad8b2..a0e971d 100644
--- a/chrome/browser/ui/apps/chrome_shell_window_delegate.h
+++ b/chrome/browser/ui/apps/chrome_shell_window_delegate.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_APPS_CHROME_SHELL_WINDOW_DELEGATE_H_
 
 #include "apps/shell_window.h"
+#include "base/memory/scoped_ptr.h"
 #include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
@@ -14,6 +15,19 @@
 
 namespace chrome {
 
+class ShellWindowLinkDelegate : public content::WebContentsDelegate {
+ public:
+  ShellWindowLinkDelegate();
+  virtual ~ShellWindowLinkDelegate();
+
+ private:
+  virtual content::WebContents* OpenURLFromTab(
+      content::WebContents* source,
+      const content::OpenURLParams& params) OVERRIDE;
+
+  DISALLOW_COPY_AND_ASSIGN(ShellWindowLinkDelegate);
+};
+
 class ChromeShellWindowDelegate : public apps::ShellWindow::Delegate {
  public:
   ChromeShellWindowDelegate();
@@ -51,6 +65,8 @@
   virtual bool IsWebContentsVisible(
       content::WebContents* web_contents) OVERRIDE;
 
+  scoped_ptr<ShellWindowLinkDelegate> shell_window_link_delegate_;
+
   DISALLOW_COPY_AND_ASSIGN(ChromeShellWindowDelegate);
 };
 
diff --git a/chrome/browser/ui/ash/app_list/app_list_service_ash.cc b/chrome/browser/ui/ash/app_list/app_list_service_ash.cc
index 64ad3fe..4303770 100644
--- a/chrome/browser/ui/ash/app_list/app_list_service_ash.cc
+++ b/chrome/browser/ui/ash/app_list/app_list_service_ash.cc
@@ -31,7 +31,7 @@
   virtual void ShowAppList(Profile* default_profile) OVERRIDE;
   virtual bool IsAppListVisible() const OVERRIDE;
   virtual void DismissAppList() OVERRIDE;
-  virtual void EnableAppList() OVERRIDE;
+  virtual void EnableAppList(Profile* initial_profile) OVERRIDE;
   virtual gfx::NativeWindow GetAppListWindow() OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(AppListServiceAsh);
@@ -59,7 +59,7 @@
     ash::Shell::GetInstance()->ToggleAppList(NULL);
 }
 
-void AppListServiceAsh::EnableAppList() {}
+void AppListServiceAsh::EnableAppList(Profile* initial_profile) {}
 
 gfx::NativeWindow AppListServiceAsh::GetAppListWindow() {
   if (ash::Shell::HasInstance())
diff --git a/chrome/browser/ui/ash/app_sync_ui_state.cc b/chrome/browser/ui/ash/app_sync_ui_state.cc
index 43d52da..686b061 100644
--- a/chrome/browser/ui/ash/app_sync_ui_state.cc
+++ b/chrome/browser/ui/ash/app_sync_ui_state.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/ash/app_sync_ui_state.h"
 
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/pending_extension_manager.h"
@@ -13,7 +14,6 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/ash/app_sync_ui_state_factory.h"
 #include "chrome/browser/ui/ash/app_sync_ui_state_observer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc
index c285804..c2d6888 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate.cc
+++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -19,6 +19,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/app_mode/app_mode_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/shell_window_registry.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -39,7 +40,6 @@
 #include "chrome/browser/ui/extensions/native_app_window.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/immersive_fullscreen_configuration.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/time_format.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc
index 09becbb..7c5bb0b 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc
@@ -8,6 +8,7 @@
 #include "ash/wm/window_util.h"
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
 #include "chrome/browser/chromeos/background/ash_user_wallpaper_delegate.h"
@@ -30,7 +31,6 @@
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/extensions/native_app_window.h"
 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate_views.cc b/chrome/browser/ui/ash/chrome_shell_delegate_views.cc
index c2bcb8e..c7075b2 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate_views.cc
+++ b/chrome/browser/ui/ash/chrome_shell_delegate_views.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "ash/magnifier/magnifier_constants.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/ash/caps_lock_delegate_views.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/notification_service.h"
 
diff --git a/chrome/browser/ui/ash/event_rewriter_unittest.cc b/chrome/browser/ui/ash/event_rewriter_unittest.cc
index cabe94a..26b442e 100644
--- a/chrome/browser/ui/ash/event_rewriter_unittest.cc
+++ b/chrome/browser/ui/ash/event_rewriter_unittest.cc
@@ -495,7 +495,7 @@
 TEST_F(EventRewriterTest, TestRewriteCommandToControlWithControlRemapped) {
   // Remap Control to Alt.
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   IntegerPrefMember control;
   control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
   control.SetValue(chromeos::input_method::kAltKey);
@@ -1124,7 +1124,7 @@
 TEST_F(EventRewriterTest, TestRewriteModifiersDisableSome) {
   // Disable Search and Control keys.
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   IntegerPrefMember search;
   search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
   search.SetValue(chromeos::input_method::kVoidKey);
@@ -1262,7 +1262,7 @@
 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToControl) {
   // Remap Search to Control.
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   IntegerPrefMember search;
   search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
   search.SetValue(chromeos::input_method::kControlKey);
@@ -1382,7 +1382,7 @@
 TEST_F(EventRewriterTest, TestRewriteModifiersRemapMany) {
   // Remap Search to Alt.
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   IntegerPrefMember search;
   search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
   search.SetValue(chromeos::input_method::kAltKey);
@@ -1494,7 +1494,7 @@
 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToCapsLock) {
   // Remap Search to Caps Lock.
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   IntegerPrefMember search;
   search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
   search.SetValue(chromeos::input_method::kCapsLockKey);
@@ -1610,7 +1610,7 @@
   // TODO(yusukes): Reenable the test once build servers are upgraded.
 
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
 
   chromeos::input_method::MockXKeyboard xkeyboard;
   EventRewriter rewriter;
@@ -1638,7 +1638,7 @@
   // TODO(yusukes): Reenable the test once build servers are upgraded.
 
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
 
   chromeos::input_method::MockXKeyboard xkeyboard;
   EventRewriter rewriter;
@@ -1683,7 +1683,7 @@
       chromeos::switches::kHasChromeOSDiamondKey, "");
 
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
 
   chromeos::input_method::MockXKeyboard xkeyboard;
   EventRewriter rewriter;
@@ -1771,7 +1771,7 @@
 
 TEST_F(EventRewriterTest, TestRewriteCapsLockToControl) {
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   IntegerPrefMember control;
   control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
   control.SetValue(chromeos::input_method::kControlKey);
@@ -1826,7 +1826,7 @@
 TEST_F(EventRewriterTest, TestRewriteCapsLockMod3InUse) {
   // Remap CapsLock to Control.
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   IntegerPrefMember control;
   control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
   control.SetValue(chromeos::input_method::kControlKey);
@@ -1855,7 +1855,7 @@
 
 TEST_F(EventRewriterTest, TestRewriteExtendedKeys) {
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   EventRewriter rewriter;
   rewriter.set_pref_service_for_testing(&prefs);
 
@@ -1998,7 +1998,7 @@
 
 TEST_F(EventRewriterTest, TestRewriteFunctionKeys) {
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   EventRewriter rewriter;
   rewriter.set_pref_service_for_testing(&prefs);
 
@@ -2217,7 +2217,7 @@
 
   // Remap Search to Control.
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   IntegerPrefMember search;
   search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
   search.SetValue(chromeos::input_method::kControlKey);
@@ -2262,7 +2262,7 @@
 TEST_F(EventRewriterTest, TestRewriteKeyEventSentByXSendEvent) {
   // Remap Control to Alt.
   TestingPrefServiceSyncable prefs;
-  chromeos::Preferences::RegisterUserPrefs(prefs.registry());
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   IntegerPrefMember control;
   control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
   control.SetValue(chromeos::input_method::kAltKey);
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.cc
index 9569b69..a2c4907 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.cc
@@ -5,12 +5,12 @@
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.h"
 
 #include "ash/wm/window_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 
 ChromeLauncherAppMenuItemBrowser::ChromeLauncherAppMenuItemBrowser(
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
index 8bcd379..9a0845a 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
@@ -16,6 +16,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/automation/automation_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_function_test_utils.h"
@@ -32,7 +33,6 @@
 #include "chrome/browser/ui/extensions/native_app_window.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.cc
index 8c1220d..1bdacb4 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.cc
@@ -20,6 +20,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/app_mode/app_mode_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/extensions/app_icon_loader_impl.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -54,7 +55,6 @@
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
@@ -625,14 +625,9 @@
 }
 
 void ChromeLauncherControllerPerApp::OnAutoHideBehaviorChanged(
+    aura::RootWindow* root_window,
     ash::ShelfAutoHideBehavior new_behavior) {
-  ash::Shell::RootWindowList root_windows = ash::Shell::GetAllRootWindows();
-
-  for (ash::Shell::RootWindowList::const_iterator iter =
-           root_windows.begin();
-       iter != root_windows.end(); ++iter) {
-    SetShelfAutoHideBehaviorPrefs(new_behavior, *iter);
-  }
+  SetShelfAutoHideBehaviorPrefs(new_behavior, root_window);
 }
 
 void ChromeLauncherControllerPerApp::SetLauncherItemImage(
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.h b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.h
index 06069b0..951589c 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.h
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app.h
@@ -313,6 +313,7 @@
 
   // ash::ShelfLayoutManagerObserver overrides:
   virtual void OnAutoHideBehaviorChanged(
+      aura::RootWindow* root_window,
       ash::ShelfAutoHideBehavior new_behavior) OVERRIDE;
 
   // Get the list of all running incarnations of this item.
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app_browsertest.cc
index 621d225..18baf0e 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app_browsertest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_app_browsertest.cc
@@ -17,6 +17,7 @@
 #include "ash/wm/window_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/automation/automation_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_function_test_utils.h"
@@ -38,7 +39,6 @@
 #include "chrome/browser/ui/extensions/native_app_window.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc
index 447ab1d..abd2bf1 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc
@@ -18,6 +18,7 @@
 #include "base/values.h"
 #include "chrome/browser/app_mode/app_mode_utils.h"
 #include "chrome/browser/defaults.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/app_icon_loader_impl.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -43,7 +44,6 @@
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
@@ -658,15 +658,9 @@
 }
 
 void ChromeLauncherControllerPerBrowser::OnAutoHideBehaviorChanged(
+    aura::RootWindow* root_window,
     ash::ShelfAutoHideBehavior new_behavior) {
-    std::string behavior_string;
-  ash::Shell::RootWindowList root_windows = ash::Shell::GetAllRootWindows();
-
-  for (ash::Shell::RootWindowList::const_iterator iter =
-           root_windows.begin();
-       iter != root_windows.end(); ++iter) {
-    SetShelfAutoHideBehaviorPrefs(new_behavior, *iter);
-  }
+  SetShelfAutoHideBehaviorPrefs(new_behavior, root_window);
 }
 
 void ChromeLauncherControllerPerBrowser::SetLauncherItemImage(
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.h b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.h
index 1a6c8be..0204501 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.h
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.h
@@ -301,6 +301,7 @@
 
   // ash::ShelfLayoutManagerObserver overrides:
   virtual void OnAutoHideBehaviorChanged(
+      aura::RootWindow* root_window,
       ash::ShelfAutoHideBehavior new_behavior) OVERRIDE;
 
  protected:
diff --git a/chrome/browser/ui/ash/launcher/launcher_favicon_loader.cc b/chrome/browser/ui/ash/launcher/launcher_favicon_loader.cc
index ce196e4..442e458 100644
--- a/chrome/browser/ui/ash/launcher/launcher_favicon_loader.cc
+++ b/chrome/browser/ui/ash/launcher/launcher_favicon_loader.cc
@@ -10,8 +10,8 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "googleurl/src/gurl.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "url/gurl.h"
 
 namespace internal {
 
diff --git a/chrome/browser/ui/ash/screenshot_taker_unittest.cc b/chrome/browser/ui/ash/screenshot_taker_unittest.cc
index d91ef4a..a73eb37 100644
--- a/chrome/browser/ui/ash/screenshot_taker_unittest.cc
+++ b/chrome/browser/ui/ash/screenshot_taker_unittest.cc
@@ -129,7 +129,7 @@
   EXPECT_EQ(ScreenshotTakerObserver::SCREENSHOT_SUCCESS, screenshot_result_);
 
   if (ScreenshotTakerObserver::SCREENSHOT_SUCCESS == screenshot_result_)
-    EXPECT_TRUE(file_util::PathExists(screenshot_path_));
+    EXPECT_TRUE(base::PathExists(screenshot_path_));
 }
 
 }  // namespace test
diff --git a/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc b/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc
index eb922f9..ad1ec3f 100644
--- a/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc
+++ b/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.h"
 
 #include "chrome/browser/chrome_browser_main.h"
-#include "chrome/browser/toolkit_extra_parts.h"
 #include "chrome/browser/ui/aura/active_desktop_monitor.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "ui/aura/env.h"
@@ -73,11 +72,3 @@
   // aura::Env instance is deleted in BrowserProcessImpl::StartTearDown
   // after the metrics service is deleted.
 }
-
-namespace chrome {
-
-void AddAuraToolkitExtraParts(ChromeBrowserMainParts* main_parts) {
-  main_parts->AddParts(new ChromeBrowserMainExtraPartsAura());
-}
-
-}  // namespace chrome
diff --git a/chrome/browser/ui/auto_login_infobar_delegate.cc b/chrome/browser/ui/auto_login_infobar_delegate.cc
index 2cb853a..89c845a 100644
--- a/chrome/browser/ui/auto_login_infobar_delegate.cc
+++ b/chrome/browser/ui/auto_login_infobar_delegate.cc
@@ -11,13 +11,12 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_util.h"
-#include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/ubertoken_fetcher.h"
 #include "chrome/browser/ui/sync/sync_promo_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -138,11 +137,6 @@
 }  // namespace
 
 
-// AutoLoginInfoBarDelegate::Params -------------------------------------------
-
-AutoLoginInfoBarDelegate::Params::Params() {}
-AutoLoginInfoBarDelegate::Params::~Params() {}
-
 
 // AutoLoginInfoBarDelegate ---------------------------------------------------
 
@@ -164,20 +158,19 @@
     : ConfirmInfoBarDelegate(owner),
       params_(params),
       button_pressed_(false) {
-  RecordHistogramAction(HISTOGRAM_SHOWN);
-  registrar_.Add(this,
-                 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
+  RecordHistogramAction(SHOWN);
+  registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
                  content::Source<Profile>(Profile::FromBrowserContext(
                      web_contents()->GetBrowserContext())));
 }
 
 AutoLoginInfoBarDelegate::~AutoLoginInfoBarDelegate() {
   if (!button_pressed_)
-    RecordHistogramAction(HISTOGRAM_IGNORED);
+    RecordHistogramAction(IGNORED);
 }
 
 void AutoLoginInfoBarDelegate::InfoBarDismissed() {
-  RecordHistogramAction(HISTOGRAM_DISMISSED);
+  RecordHistogramAction(DISMISSED);
   button_pressed_ = true;
 }
 
@@ -209,17 +202,16 @@
   // AutoLoginRedirector deletes itself.
   new AutoLoginRedirector(&web_contents()->GetController(),
                           params_.header.args);
-  RecordHistogramAction(HISTOGRAM_ACCEPTED);
+  RecordHistogramAction(ACCEPTED);
   button_pressed_ = true;
   return true;
 }
 
 bool AutoLoginInfoBarDelegate::Cancel() {
-  Profile* profile = Profile::FromBrowserContext(
-      web_contents()->GetBrowserContext());
-  PrefService* pref_service = profile->GetPrefs();
+  PrefService* pref_service = Profile::FromBrowserContext(
+      web_contents()->GetBrowserContext())->GetPrefs();
   pref_service->SetBoolean(prefs::kAutologinEnabled, false);
-  RecordHistogramAction(HISTOGRAM_REJECTED);
+  RecordHistogramAction(REJECTED);
   button_pressed_ = true;
   return true;
 }
@@ -235,5 +227,6 @@
 }
 
 void AutoLoginInfoBarDelegate::RecordHistogramAction(Actions action) {
-  UMA_HISTOGRAM_ENUMERATION("AutoLogin.Regular", action, HISTOGRAM_MAX);
+  UMA_HISTOGRAM_ENUMERATION("AutoLogin.Regular", action,
+                            HISTOGRAM_BOUNDING_VALUE);
 }
diff --git a/chrome/browser/ui/auto_login_infobar_delegate.h b/chrome/browser/ui/auto_login_infobar_delegate.h
index 823fb6b..96bebb7 100644
--- a/chrome/browser/ui/auto_login_infobar_delegate.h
+++ b/chrome/browser/ui/auto_login_infobar_delegate.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_UI_AUTO_LOGIN_INFOBAR_DELEGATE_H_
 #define CHROME_BROWSER_UI_AUTO_LOGIN_INFOBAR_DELEGATE_H_
 
+#include <string>
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "components/auto_login_parser/auto_login_parser.h"
 #include "content/public/browser/notification_observer.h"
@@ -22,9 +23,6 @@
                                  public content::NotificationObserver {
  public:
   struct Params {
-    Params();
-    ~Params();
-
     // Information from a parsed header.
     auto_login_parser::HeaderData header;
 
@@ -47,13 +45,13 @@
  private:
   // Enum values used for UMA histograms.
   enum Actions {
-    HISTOGRAM_SHOWN,       // The infobar was shown to the user.
-    HISTOGRAM_ACCEPTED,    // The user pressed the accept button.
-    HISTOGRAM_REJECTED,    // The user pressed the reject button.
-    HISTOGRAM_DISMISSED,   // The user pressed the close button.
-    HISTOGRAM_IGNORED,     // The user ignored the infobar.
-    HISTOGRAM_LEARN_MORE,  // The user clicked on the learn more link.
-    HISTOGRAM_MAX
+    SHOWN,       // The infobar was shown to the user.
+    ACCEPTED,    // The user pressed the accept button.
+    REJECTED,    // The user pressed the reject button.
+    DISMISSED,   // The user pressed the close button.
+    IGNORED,     // The user ignored the infobar.
+    LEARN_MORE,  // The user clicked on the learn more link.
+    HISTOGRAM_BOUNDING_VALUE
   };
 
   // ConfirmInfoBarDelegate:
diff --git a/chrome/browser/ui/auto_login_prompter.cc b/chrome/browser/ui/auto_login_prompter.cc
index 4dc3999..f77cbb1 100644
--- a/chrome/browser/ui/auto_login_prompter.cc
+++ b/chrome/browser/ui/auto_login_prompter.cc
@@ -23,8 +23,8 @@
 #include "components/auto_login_parser/auto_login_parser.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_request.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 using content::WebContents;
diff --git a/chrome/browser/ui/auto_login_prompter.h b/chrome/browser/ui/auto_login_prompter.h
index fdf4d5d..27f28d7 100644
--- a/chrome/browser/ui/auto_login_prompter.h
+++ b/chrome/browser/ui/auto_login_prompter.h
@@ -10,7 +10,7 @@
 #include "base/compiler_specific.h"
 #include "chrome/browser/ui/auto_login_infobar_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace content {
 class RenderViewHost;
diff --git a/chrome/browser/ui/autofill/autocheckout_bubble_controller.cc b/chrome/browser/ui/autofill/autocheckout_bubble_controller.cc
index da502a7..d12b3b8 100644
--- a/chrome/browser/ui/autofill/autocheckout_bubble_controller.cc
+++ b/chrome/browser/ui/autofill/autocheckout_bubble_controller.cc
@@ -18,7 +18,7 @@
     const gfx::RectF& anchor_rect,
     const gfx::NativeWindow& native_window,
     bool is_google_user,
-    const base::Callback<void(bool)>& callback)
+    const base::Callback<void(AutocheckoutBubbleState)>& callback)
     : anchor_rect_(gfx::ToEnclosingRect(anchor_rect)),
       native_window_(native_window),
       is_google_user_(is_google_user),
@@ -65,14 +65,14 @@
 void AutocheckoutBubbleController::BubbleAccepted() {
   had_user_interaction_ = true;
   metric_logger_->LogAutocheckoutBubbleMetric(AutofillMetrics::BUBBLE_ACCEPTED);
-  callback_.Run(true);
+  callback_.Run(AUTOCHECKOUT_BUBBLE_ACCEPTED);
 }
 
 void AutocheckoutBubbleController::BubbleCanceled() {
   had_user_interaction_ = true;
   metric_logger_->LogAutocheckoutBubbleMetric(
       AutofillMetrics::BUBBLE_DISMISSED);
-  callback_.Run(false);
+  callback_.Run(AUTOCHECKOUT_BUBBLE_CANCELED);
 }
 
 void AutocheckoutBubbleController::BubbleCreated() const {
@@ -83,7 +83,7 @@
   if (!had_user_interaction_) {
     metric_logger_->LogAutocheckoutBubbleMetric(
         AutofillMetrics::BUBBLE_IGNORED);
-    callback_.Run(false);
+    callback_.Run(AUTOCHECKOUT_BUBBLE_IGNORED);
   }
 }
 
diff --git a/chrome/browser/ui/autofill/autocheckout_bubble_controller.h b/chrome/browser/ui/autofill/autocheckout_bubble_controller.h
index 7bd4637..dbb8a23 100644
--- a/chrome/browser/ui/autofill/autocheckout_bubble_controller.h
+++ b/chrome/browser/ui/autofill/autocheckout_bubble_controller.h
@@ -8,6 +8,7 @@
 #include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string16.h"
+#include "components/autofill/core/browser/autocheckout_bubble_state.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/rect.h"
 
@@ -30,10 +31,11 @@
   // been logged into accounts.google.com. |callback| is invoked if the bubble
   // is accepted. It brings up the requestAutocomplete dialog to collect user
   // input for Autocheckout.
-  AutocheckoutBubbleController(const gfx::RectF& anchor_rect,
-                               const gfx::NativeWindow& native_window,
-                               bool  is_google_user,
-                               const base::Callback<void(bool)>& callback);
+  AutocheckoutBubbleController(
+      const gfx::RectF& anchor_rect,
+      const gfx::NativeWindow& native_window,
+      bool  is_google_user,
+      const base::Callback<void(AutocheckoutBubbleState)>& callback);
   ~AutocheckoutBubbleController();
 
   static base::string16 AcceptText();
@@ -75,7 +77,7 @@
   bool is_google_user_;
 
   // |callback_| is invoked if the bubble is accepted.
-  base::Callback<void(bool)> callback_;
+  base::Callback<void(AutocheckoutBubbleState)> callback_;
 
   // For logging UMA metrics. Overridden by metrics tests.
   scoped_ptr<const AutofillMetrics> metric_logger_;
diff --git a/chrome/browser/ui/autofill/autocheckout_bubble_controller_unittest.cc b/chrome/browser/ui/autofill/autocheckout_bubble_controller_unittest.cc
index ca353ad..bfc07e6 100644
--- a/chrome/browser/ui/autofill/autocheckout_bubble_controller_unittest.cc
+++ b/chrome/browser/ui/autofill/autocheckout_bubble_controller_unittest.cc
@@ -35,8 +35,8 @@
   TestCallback() : accepted_count_(0), dismissed_count_(0) {}
   ~TestCallback() {}
 
-  void Run(bool accepted) {
-    if (accepted)
+  void Run(AutocheckoutBubbleState state) {
+    if (state == AUTOCHECKOUT_BUBBLE_ACCEPTED)
       accepted_count_++;
     else
       dismissed_count_++;
@@ -50,7 +50,7 @@
     return dismissed_count_;
   }
 
-  base::Callback<void(bool)> GetCallback() {
+  base::Callback<void(AutocheckoutBubbleState)> GetCallback() {
     return base::Bind(&TestCallback::Run, base::Unretained(this));
   }
 
@@ -63,7 +63,7 @@
   public autofill::AutocheckoutBubbleController {
  public:
   explicit TestAutocheckoutBubbleController(
-      const base::Callback<void(bool)>& callback)
+      const base::Callback<void(AutocheckoutBubbleState)>& callback)
       : AutocheckoutBubbleController(gfx::RectF(),
                                      gfx::NativeWindow(),
                                      true /* is_google_user */,
diff --git a/chrome/browser/ui/autofill/autofill_credit_card_bubble.cc b/chrome/browser/ui/autofill/autofill_credit_card_bubble.cc
new file mode 100644
index 0000000..133de0a
--- /dev/null
+++ b/chrome/browser/ui/autofill/autofill_credit_card_bubble.cc
@@ -0,0 +1,23 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble.h"
+
+namespace autofill {
+
+// static
+const int AutofillCreditCardBubble::kContentWidth = 300;
+
+AutofillCreditCardBubble::~AutofillCreditCardBubble() {}
+
+#if !defined(TOOLKIT_VIEWS)
+// static
+base::WeakPtr<AutofillCreditCardBubble> AutofillCreditCardBubble::Create(
+    const base::WeakPtr<AutofillCreditCardBubbleController>& controller) {
+  // TODO(dbeam): make a bubble on all applicable platforms.
+  return base::WeakPtr<AutofillCreditCardBubble>();
+}
+#endif
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/autofill/autofill_credit_card_bubble.h b/chrome/browser/ui/autofill/autofill_credit_card_bubble.h
new file mode 100644
index 0000000..ba91afe
--- /dev/null
+++ b/chrome/browser/ui/autofill/autofill_credit_card_bubble.h
@@ -0,0 +1,49 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_CREDIT_CARD_BUBBLE_H_
+#define CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_CREDIT_CARD_BUBBLE_H_
+
+#include "base/memory/weak_ptr.h"
+
+namespace autofill {
+
+class AutofillCreditCardBubbleController;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// AutofillCreditCardBubble
+//
+//  An interface to be implemented on each platform to show a bubble after the
+//  Autofill dialog is sucessfully submitted. Shows anchored to an icon that
+//  looks like a credit card or the Google Wallet logo in the omnibox. Hidden
+//  when focus is lost.
+//
+////////////////////////////////////////////////////////////////////////////////
+class AutofillCreditCardBubble {
+ public:
+  // The preferred size of the bubble's contents.
+  static const int kContentWidth;
+
+  virtual ~AutofillCreditCardBubble();
+
+  // Visually reveal the dialog bubble.
+  virtual void Show() = 0;
+
+  // Hide the bubble from view.
+  virtual void Hide() = 0;
+
+  // Whether the bubble is currently in the process of hiding itself.
+  virtual bool IsHiding() const = 0;
+
+  // Create a bubble view that's operated by |controller| and owned by the
+  // platform's widget or view management framework. |controller| is invalid
+  // while the bubble is closing.
+  static base::WeakPtr<AutofillCreditCardBubble> Create(
+      const base::WeakPtr<AutofillCreditCardBubbleController>& controller);
+};
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_CREDIT_CARD_BUBBLE_H_
diff --git a/chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.cc b/chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.cc
new file mode 100644
index 0000000..0d85561
--- /dev/null
+++ b/chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.cc
@@ -0,0 +1,303 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/message_loop/message_loop.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/string_split.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble.h"
+#include "chrome/browser/ui/autofill/tab_autofill_manager_delegate.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/omnibox/location_bar.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/pref_names.h"
+#include "components/user_prefs/pref_registry_syncable.h"
+#include "content/public/browser/navigation_details.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/web_contents.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "grit/webkit_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/range/range.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/image/image.h"
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::AutofillCreditCardBubbleController);
+
+namespace autofill {
+
+namespace {
+
+static const int kMaxGeneratedCardTimesToShow = 4;
+static const char kWalletGeneratedCardLearnMoreLink[] =
+    "http://support.google.com/wallet/bin/answer.py?hl=en&answer=2740044";
+
+AutofillCreditCardBubbleController* GetOrCreate(content::WebContents* wc) {
+  AutofillCreditCardBubbleController::CreateForWebContents(wc);
+  return AutofillCreditCardBubbleController::FromWebContents(wc);
+}
+
+}  // namespace
+
+AutofillCreditCardBubbleController::AutofillCreditCardBubbleController(
+    content::WebContents* web_contents)
+    : WebContentsObserver(web_contents),
+      web_contents_(web_contents),
+      should_show_anchor_(true),
+      weak_ptr_factory_(this) {}
+
+AutofillCreditCardBubbleController::~AutofillCreditCardBubbleController() {
+  Hide();
+}
+
+// static
+void AutofillCreditCardBubbleController::RegisterUserPrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  registry->RegisterIntegerPref(
+      ::prefs::kAutofillGeneratedCardBubbleTimesShown,
+      0,
+      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+}
+
+// static
+bool AutofillCreditCardBubbleController::ShouldShowGeneratedCardBubble(
+    Profile* profile) {
+  int times_shown = profile->GetPrefs()->GetInteger(
+      ::prefs::kAutofillGeneratedCardBubbleTimesShown);
+  return times_shown < kMaxGeneratedCardTimesToShow;
+}
+
+// static
+void AutofillCreditCardBubbleController::ShowGeneratedCardBubble(
+    content::WebContents* contents,
+    const base::string16& fronting_card_name,
+    const base::string16& backing_card_name) {
+  GetOrCreate(contents)->ShowAsGeneratedCardBubble(fronting_card_name,
+                                                   backing_card_name);
+}
+
+// static
+void AutofillCreditCardBubbleController::ShowNewCardSavedBubble(
+    content::WebContents* contents,
+    const base::string16& new_card_name) {
+  GetOrCreate(contents)->ShowAsNewCardSavedBubble(new_card_name);
+}
+
+void AutofillCreditCardBubbleController::DidNavigateMainFrame(
+    const content::LoadCommittedDetails& details,
+    const content::FrameNavigateParams& params) {
+  if (details.entry &&
+      !content::PageTransitionIsRedirect(details.entry->GetTransitionType())) {
+    should_show_anchor_ = false;
+    UpdateAnchor();
+    web_contents()->RemoveUserData(UserDataKey());
+    // |this| is now deleted.
+  }
+}
+
+bool AutofillCreditCardBubbleController::IsHiding() const {
+  return bubble_ && bubble_->IsHiding();
+}
+
+gfx::Image AutofillCreditCardBubbleController::AnchorIcon() const {
+  if (!should_show_anchor_)
+    return gfx::Image();
+
+  return ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+      IsGeneratedCardBubble() ? IDR_WALLET_ICON : IDR_AUTOFILL_CC_GENERIC);
+}
+
+base::string16 AutofillCreditCardBubbleController::BubbleTitle() const {
+  return !IsGeneratedCardBubble() ? ASCIIToUTF16("Lorem ipsum, savum cardum") :
+      l10n_util::GetStringUTF16(
+          IDS_AUTOFILL_CREDIT_CARD_BUBBLE_GENERATED_TITLE);
+}
+
+base::string16 AutofillCreditCardBubbleController::BubbleText() const {
+  DCHECK(IsSetup());
+  return bubble_text_;
+}
+
+const std::vector<ui::Range>& AutofillCreditCardBubbleController::
+    BubbleTextRanges() const {
+  DCHECK(IsSetup());
+  return bubble_text_ranges_;
+}
+
+base::string16 AutofillCreditCardBubbleController::LinkText() const {
+  return l10n_util::GetStringUTF16(IsGeneratedCardBubble() ?
+      IDS_LEARN_MORE : IDS_AUTOFILL_CREDIT_CARD_BUBBLE_MANAGE_CARDS);
+}
+
+void AutofillCreditCardBubbleController::OnAnchorClicked() {
+  Show(true);
+}
+
+void AutofillCreditCardBubbleController::OnLinkClicked() {
+  if (IsGeneratedCardBubble()) {
+#if !defined(OS_ANDROID)
+    chrome::NavigateParams params(
+        chrome::FindBrowserWithWebContents(web_contents()),
+        GURL(kWalletGeneratedCardLearnMoreLink),
+        content::PAGE_TRANSITION_AUTO_BOOKMARK);
+    params.disposition = NEW_FOREGROUND_TAB;
+    chrome::Navigate(&params);
+#else
+  // TODO(dbeam): implement.
+#endif
+  } else {
+    TabAutofillManagerDelegate::FromWebContents(web_contents())->
+        ShowAutofillSettings();
+  }
+  Hide();
+}
+
+base::WeakPtr<AutofillCreditCardBubbleController>
+    AutofillCreditCardBubbleController::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
+base::WeakPtr<AutofillCreditCardBubble> AutofillCreditCardBubbleController::
+    CreateBubble() {
+  return AutofillCreditCardBubble::Create(GetWeakPtr());
+}
+
+bool AutofillCreditCardBubbleController::CanShow() const {
+#if !defined(OS_ANDROID)
+  Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
+  return web_contents() == browser->tab_strip_model()->GetActiveWebContents();
+#else
+  return true;
+#endif
+}
+
+void AutofillCreditCardBubbleController::ShowAsGeneratedCardBubble(
+    const base::string16& fronting_card_name,
+    const base::string16& backing_card_name) {
+  Reset();
+
+  DCHECK(!fronting_card_name.empty());
+  DCHECK(!backing_card_name.empty());
+  fronting_card_name_ = fronting_card_name;
+  backing_card_name_ = backing_card_name;
+
+  SetUp();
+  Show(false);
+}
+
+void AutofillCreditCardBubbleController::ShowAsNewCardSavedBubble(
+    const base::string16& new_card_name) {
+  Reset();
+
+  DCHECK(!new_card_name.empty());
+  new_card_name_ = new_card_name;
+
+  SetUp();
+  Show(false);
+}
+
+void AutofillCreditCardBubbleController::Reset() {
+  Hide();
+
+  fronting_card_name_.clear();
+  backing_card_name_.clear();
+  new_card_name_.clear();
+  bubble_text_.clear();
+  bubble_text_ranges_.clear();
+
+  DCHECK(!IsSetup());
+}
+
+void AutofillCreditCardBubbleController::SetUp() {
+  base::string16 full_text;
+  if (IsGeneratedCardBubble()) {
+    full_text = l10n_util::GetStringFUTF16(
+        IDS_AUTOFILL_CREDIT_CARD_BUBBLE_GENERATED_TEXT,
+        fronting_card_name_,
+        backing_card_name_);
+  } else {
+    full_text = ReplaceStringPlaceholders(
+        ASCIIToUTF16("Lorem ipsum, savum cardem |$1|. Replacem before launch."),
+        new_card_name_,
+        NULL);
+  }
+
+  base::char16 separator('|');
+  std::vector<base::string16> pieces;
+  base::SplitStringDontTrim(full_text, separator, &pieces);
+
+  while (!pieces.empty()) {
+    base::string16 piece = pieces.front();
+    if (!piece.empty() && pieces.size() % 2 == 0) {
+      const size_t start = bubble_text_.size();
+      bubble_text_ranges_.push_back(ui::Range(start, start + piece.size()));
+    }
+    bubble_text_.append(piece);
+    pieces.erase(pieces.begin(), pieces.begin() + 1);
+  }
+
+  UpdateAnchor();
+  DCHECK(IsSetup());
+}
+
+bool AutofillCreditCardBubbleController::IsSetup() const {
+  DCHECK_EQ(bubble_text_.empty(), bubble_text_ranges_.empty());
+  return !bubble_text_.empty();
+}
+
+bool AutofillCreditCardBubbleController::IsGeneratedCardBubble() const {
+  DCHECK_EQ(fronting_card_name_.empty(), backing_card_name_.empty());
+  DCHECK_NE(backing_card_name_.empty(), new_card_name_.empty());
+  return !fronting_card_name_.empty();
+}
+
+void AutofillCreditCardBubbleController::Show(bool was_anchor_click) {
+  if (!CanShow())
+    return;
+
+  bubble_ = CreateBubble();
+  bubble_->Show();
+
+  if (IsGeneratedCardBubble() && !was_anchor_click) {
+    // If the bubble was an automatically created "you generated a card" bubble,
+    // count it as a show. If the user clicked the omnibox icon, don't count it.
+    PrefService* prefs = Profile::FromBrowserContext(
+        web_contents()->GetBrowserContext())->GetPrefs();
+    prefs->SetInteger(::prefs::kAutofillGeneratedCardBubbleTimesShown,
+        prefs->GetInteger(::prefs::kAutofillGeneratedCardBubbleTimesShown) + 1);
+  }
+}
+
+void AutofillCreditCardBubbleController::UpdateAnchor() {
+#if !defined(OS_ANDROID)
+  Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
+  if (browser && browser->window() && browser->window()->GetLocationBar())
+    browser->window()->GetLocationBar()->UpdateAutofillCreditCardView();
+#else
+  // TODO(dbeam): implement.
+#endif
+}
+
+void AutofillCreditCardBubbleController::Hide() {
+  // Sever |bubble_|'s reference to the controller and hide (if it exists).
+  weak_ptr_factory_.InvalidateWeakPtrs();
+
+  if (bubble_ && !bubble_->IsHiding())
+    bubble_->Hide();
+
+  DCHECK(!bubble_ || bubble_->IsHiding());
+}
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h b/chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h
new file mode 100644
index 0000000..0021f49
--- /dev/null
+++ b/chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h
@@ -0,0 +1,187 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_CREDIT_CARD_BUBBLE_CONTROLLER_H_
+#define CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_CREDIT_CARD_BUBBLE_CONTROLLER_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "base/strings/string16.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+class Profile;
+
+namespace content {
+class WebContents;
+}
+
+namespace gfx {
+class Image;
+}
+
+namespace ui {
+class Range;
+}
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+namespace autofill {
+
+class AutofillCreditCardBubble;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// AutofillCreditCardBubbleController
+//
+//  A class to show a bubble after successfully submitting the Autofill dialog.
+//  The bubble is shown when a new credit card is saved locally or to explain
+//  generated Online Wallet cards to the user. This class does not own the shown
+//  bubble, but only has a weak reference to it (it is often owned by the native
+//  platform's ui toolkit).
+//
+////////////////////////////////////////////////////////////////////////////////
+class AutofillCreditCardBubbleController
+    : public content::WebContentsObserver,
+      public content::WebContentsUserData<AutofillCreditCardBubbleController> {
+ public:
+  virtual ~AutofillCreditCardBubbleController();
+
+  // Registers preferences this class cares about.
+  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+
+  // Whether the generated card bubble should be shown.
+  static bool ShouldShowGeneratedCardBubble(Profile* profile);
+
+  // Show a bubble to educate the user about generated (fronting) cards and how
+  // they are used to bill their original (backing) card.
+  static void ShowGeneratedCardBubble(content::WebContents* contents,
+                                      const base::string16& backing_card_name,
+                                      const base::string16& fronting_card_name);
+
+  // Show a bubble notifying the user that new credit card data has been saved.
+  static void ShowNewCardSavedBubble(content::WebContents* contents,
+                                     const base::string16& new_card_name);
+
+  // content::WebContentsObserver implementation.
+  virtual void DidNavigateMainFrame(
+      const content::LoadCommittedDetails& details,
+      const content::FrameNavigateParams& params) OVERRIDE;
+
+  // Whether |bubble_| is currently in the process of hiding.
+  bool IsHiding() const;
+
+  // An image that should be shown as an icon in the omnibox and pointed to by
+  // the bubble.
+  gfx::Image AnchorIcon() const;
+
+  // The title of the bubble. May be empty.
+  base::string16 BubbleTitle() const;
+
+  // The main text of the bubble.
+  base::string16 BubbleText() const;
+
+  // Ranges of text styles in the bubble's main content.
+  const std::vector<ui::Range>& BubbleTextRanges() const;
+
+  // The text of the link shown at the bubble of the bubble.
+  base::string16 LinkText() const;
+
+  // Called when the anchor for this bubble is clicked.
+  void OnAnchorClicked();
+
+  // Called when the link at the bottom of the bubble is clicked.
+  void OnLinkClicked();
+
+  // The web contents that successfully submitted the Autofill dialog (causing
+  // this bubble to show).
+  content::WebContents* web_contents() { return web_contents_; }
+  const content::WebContents* web_contents() const { return web_contents_; }
+
+ protected:
+  // Create a bubble connected to |web_contents|. Its content will be based on
+  // which |SetupAs*()| method is called.
+  explicit AutofillCreditCardBubbleController(content::WebContents* contents);
+
+  // Returns a base::WeakPtr that references |this|. Exposed for testing.
+  base::WeakPtr<AutofillCreditCardBubbleController> GetWeakPtr();
+
+  // Creates and returns an Autofill credit card bubble. Exposed for testing.
+  virtual base::WeakPtr<AutofillCreditCardBubble> CreateBubble();
+
+  // Whether the bubble can show currently.
+  virtual bool CanShow() const;
+
+  // Show a bubble to educate the user about generated (fronting) cards and how
+  // they are used to bill their original (backing) card. Exposed for testing.
+  virtual void ShowAsGeneratedCardBubble(
+      const base::string16& backing_card_name,
+      const base::string16& fronting_card_name);
+
+  // Show a bubble notifying the user that new credit card data has been saved.
+  // Exposed for testing.
+  virtual void ShowAsNewCardSavedBubble(const base::string16& new_card_name);
+
+ private:
+  friend class content::WebContentsUserData<AutofillCreditCardBubbleController>;
+
+  // Nukes the state of this controller and hides |bubble_| (if it exists).
+  void Reset();
+
+  // Generate bubble text and ranges now that this class knows which type of
+  // bubble it should be shown as. Called from |ShowAs*()| methods.
+  void SetUp();
+
+  // Whether the controller has been setup as a certain type of bubble.
+  bool IsSetup() const;
+
+  // Whether the bubble is an educational bubble about generated cards.
+  bool IsGeneratedCardBubble() const;
+
+  // An internal helper to show the bubble in response to successful Autofill
+  // dialog submission or anchor click.
+  void Show(bool was_anchor_click);
+
+  // Update the omnibox icon that |bubble_| will be anchored to.
+  void UpdateAnchor();
+
+  // Hides |bubble_| (if it exists and isn't already hiding).
+  void Hide();
+
+  // The web contents associated with this bubble.
+  content::WebContents* const web_contents_;
+
+  // The newly saved credit card.
+  base::string16 new_card_name_;
+
+  // The generated credit card number and associated backing card.
+  base::string16 fronting_card_name_;
+  base::string16 backing_card_name_;
+
+  // Bubble contents text and text ranges generated in |SetUp()|.
+  base::string16 bubble_text_;
+  std::vector<ui::Range> bubble_text_ranges_;
+
+  // A bubble view that's created by calling either |Show*()| method; owned by
+  // the native widget/hierarchy, not this class (though this class must outlive
+  // |bubble_|). NULL in many cases.
+  base::WeakPtr<AutofillCreditCardBubble> bubble_;
+
+  // Whether the anchor should currently be showing.
+  bool should_show_anchor_;
+
+  // A weak pointer factory for |Create()|.
+  base::WeakPtrFactory<AutofillCreditCardBubbleController> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(AutofillCreditCardBubbleController);
+};
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_CREDIT_CARD_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/ui/autofill/autofill_credit_card_bubble_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_credit_card_bubble_controller_unittest.cc
new file mode 100644
index 0000000..89c5cc3
--- /dev/null
+++ b/chrome/browser/ui/autofill/autofill_credit_card_bubble_controller_unittest.cc
@@ -0,0 +1,242 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h"
+#include "chrome/browser/ui/autofill/test_autofill_credit_card_bubble.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/page_transition_types.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/web_contents_tester.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/range/range.h"
+
+#if defined(OS_WIN)
+#include "ui/base/win/scoped_ole_initializer.h"
+#endif
+
+namespace autofill {
+
+namespace {
+
+base::string16 BackingCard() {
+  return ASCIIToUTF16("Visa - 1111");
+}
+base::string16 FrontingCard() {
+  return ASCIIToUTF16("Mastercard - 5888");
+}
+base::string16 NewCard() {
+  return ASCIIToUTF16("Discover - 7582");
+}
+
+base::string16 RangeOfString(const base::string16& string,
+                             const ui::Range& range) {
+  return string.substr(range.start(), range.end() - range.start());
+}
+
+class TestAutofillCreditCardBubbleController
+    : public AutofillCreditCardBubbleController {
+ public:
+  explicit TestAutofillCreditCardBubbleController(
+      content::WebContents* contents)
+      : AutofillCreditCardBubbleController(contents),
+        bubble_(GetWeakPtr()) {
+    contents->SetUserData(UserDataKey(), this);
+    EXPECT_TRUE(IsInstalled());
+  }
+  virtual ~TestAutofillCreditCardBubbleController() {}
+
+  const TestAutofillCreditCardBubble* bubble() const { return &bubble_; }
+
+  bool IsInstalled() const {
+    return web_contents()->GetUserData(UserDataKey()) == this;
+  }
+
+ protected:
+  virtual base::WeakPtr<AutofillCreditCardBubble> CreateBubble() OVERRIDE {
+    return bubble_.GetWeakPtr();
+  }
+
+  virtual bool CanShow() const OVERRIDE {
+    return true;
+  }
+
+ private:
+  TestAutofillCreditCardBubble bubble_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestAutofillCreditCardBubbleController);
+};
+
+class AutofillCreditCardBubbleControllerTest : public testing::Test {
+ public:
+  AutofillCreditCardBubbleControllerTest()
+      : test_web_contents_(
+            content::WebContentsTester::CreateTestWebContents(
+                profile(), NULL)) {}
+
+  virtual void SetUp() OVERRIDE {
+    // Attaches immediately to |test_web_contents_| so a test version will exist
+    // before a non-test version can be created.
+    new TestAutofillCreditCardBubbleController(test_web_contents_.get());
+  }
+
+ protected:
+  TestAutofillCreditCardBubbleController* controller() {
+    return static_cast<TestAutofillCreditCardBubbleController*>(
+        TestAutofillCreditCardBubbleController::FromWebContents(
+            test_web_contents_.get()));
+  }
+
+  int GeneratedCardBubbleTimesShown() {
+    return profile()->GetPrefs()->GetInteger(
+        ::prefs::kAutofillGeneratedCardBubbleTimesShown);
+  }
+
+  bool ShouldShow() {
+    return AutofillCreditCardBubbleController::ShouldShowGeneratedCardBubble(
+        profile());
+  }
+
+  Profile* profile() { return &profile_; }
+
+  content::WebContentsTester* test_web_contents() {
+    return content::WebContentsTester::For(test_web_contents_.get());
+  }
+
+  void ShowGeneratedCardBubble() {
+    EXPECT_TRUE(controller()->IsInstalled());
+    controller()->ShowGeneratedCardBubble(
+        test_web_contents_.get(), BackingCard(), FrontingCard());
+  }
+
+  void ShowNewCardSavedBubble() {
+    EXPECT_TRUE(controller()->IsInstalled());
+    controller()->ShowNewCardSavedBubble(test_web_contents_.get(), NewCard());
+  }
+
+  void Navigate() {
+    NavigateWithTransition(content::PAGE_TRANSITION_LINK);
+  }
+
+  void Redirect() {
+    NavigateWithTransition(content::PAGE_TRANSITION_CLIENT_REDIRECT);
+  }
+
+ private:
+  void NavigateWithTransition(content::PageTransition trans) {
+    test_web_contents()->TestDidNavigate(
+        test_web_contents_->GetRenderViewHost(), 1, GURL("about:blank"), trans);
+  }
+
+  content::TestBrowserThreadBundle thread_bundle_;
+#if defined(OS_WIN)
+  // Without this there will be drag and drop failures. http://crbug.com/227221
+  ui::ScopedOleInitializer ole_initializer_;
+#endif
+  TestingProfile profile_;
+  scoped_ptr<content::WebContents> test_web_contents_;
+};
+
+}  // namespace
+
+TEST_F(AutofillCreditCardBubbleControllerTest, ShouldShowGeneratedCardBubble) {
+  ASSERT_EQ(0, GeneratedCardBubbleTimesShown());
+  EXPECT_TRUE(ShouldShow());
+
+  ShowGeneratedCardBubble();
+  EXPECT_EQ(1, GeneratedCardBubbleTimesShown());
+  EXPECT_TRUE(ShouldShow());
+
+  ShowGeneratedCardBubble();
+  ShowGeneratedCardBubble();
+  EXPECT_EQ(3, GeneratedCardBubbleTimesShown());
+  EXPECT_TRUE(ShouldShow());
+
+  ShowGeneratedCardBubble();
+  EXPECT_EQ(4, GeneratedCardBubbleTimesShown());
+  EXPECT_FALSE(ShouldShow());
+}
+
+TEST_F(AutofillCreditCardBubbleControllerTest, BubbleText) {
+  ShowGeneratedCardBubble();
+  base::string16 generated_text = controller()->BubbleText();
+  EXPECT_NE(generated_text.find(BackingCard()), base::string16::npos);
+  EXPECT_NE(generated_text.find(FrontingCard()), base::string16::npos);
+  EXPECT_EQ(generated_text.find(NewCard()), base::string16::npos);
+
+  ShowNewCardSavedBubble();
+  base::string16 new_text = controller()->BubbleText();
+  EXPECT_NE(new_text, generated_text);
+  EXPECT_EQ(new_text.find(BackingCard()), base::string16::npos);
+  EXPECT_EQ(new_text.find(FrontingCard()), base::string16::npos);
+  EXPECT_NE(new_text.find(NewCard()), base::string16::npos);
+
+  ShowGeneratedCardBubble();
+  EXPECT_EQ(generated_text, controller()->BubbleText());
+
+  ShowNewCardSavedBubble();
+  EXPECT_EQ(new_text, controller()->BubbleText());
+}
+
+TEST_F(AutofillCreditCardBubbleControllerTest, BubbleTextRanges) {
+  ShowGeneratedCardBubble();
+  base::string16 text = controller()->BubbleText();
+  std::vector<ui::Range> ranges = controller()->BubbleTextRanges();
+
+  ASSERT_EQ(ranges.size(), 2U);
+  EXPECT_EQ(BackingCard(), RangeOfString(text, ranges[0]));
+  EXPECT_EQ(FrontingCard(), RangeOfString(text, ranges[1]));
+
+  ShowNewCardSavedBubble();
+  text = controller()->BubbleText();
+  ranges = controller()->BubbleTextRanges();
+
+  ASSERT_EQ(ranges.size(), 1U);
+  EXPECT_EQ(NewCard(), RangeOfString(text, ranges[0]));
+}
+
+TEST_F(AutofillCreditCardBubbleControllerTest, HideOnNavigate) {
+  EXPECT_FALSE(controller()->bubble()->showing());
+  ShowGeneratedCardBubble();
+  EXPECT_TRUE(controller()->bubble()->showing());
+
+  Navigate();
+  EXPECT_FALSE(controller());
+
+  SetUp();
+
+  EXPECT_FALSE(controller()->bubble()->showing());
+  ShowNewCardSavedBubble();
+  EXPECT_TRUE(controller()->bubble()->showing());
+
+  Navigate();
+  EXPECT_FALSE(controller());
+}
+
+TEST_F(AutofillCreditCardBubbleControllerTest, StayOnRedirect) {
+  EXPECT_FALSE(controller()->bubble()->showing());
+  ShowGeneratedCardBubble();
+  EXPECT_TRUE(controller()->bubble()->showing());
+
+  Redirect();
+  EXPECT_TRUE(controller()->bubble()->showing());
+
+  SetUp();
+
+  EXPECT_FALSE(controller()->bubble()->showing());
+  ShowNewCardSavedBubble();
+  EXPECT_TRUE(controller()->bubble()->showing());
+
+  Redirect();
+  EXPECT_TRUE(controller()->bubble()->showing());
+}
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller.h b/chrome/browser/ui/autofill/autofill_dialog_controller.h
index 6bc0508..7662b81 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller.h
@@ -80,6 +80,10 @@
   // Whether or not the |button| should be enabled.
   virtual bool IsDialogButtonEnabled(ui::DialogButton button) const = 0;
 
+  // Returns a struct full of data concerning what overlay, if any, should be
+  // displayed on top of the dialog.
+  virtual DialogOverlayState GetDialogOverlay() const = 0;
+
   // Returns ranges to linkify in the text returned by |LegalDocumentsText()|.
   virtual const std::vector<ui::Range>& LegalDocumentLinks() = 0;
 
@@ -187,6 +191,9 @@
   // A legal document link has been clicked.
   virtual void LegalDocumentLinkClicked(const ui::Range& range) = 0;
 
+  // A button in the dialog's overlay has been pressed.
+  virtual void OverlayButtonPressed() = 0;
+
   // Called when the view has been cancelled.
   virtual void OnCancel() = 0;
 
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
index 469655f..46fbac0 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
@@ -9,6 +9,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_view.h"
 #include "chrome/browser/ui/autofill/data_model_wrapper.h"
@@ -18,6 +19,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/autofill/content/browser/wallet/mock_wallet_client.h"
 #include "components/autofill/content/browser/wallet/wallet_test_util.h"
 #include "components/autofill/core/browser/autofill_common_test.h"
 #include "components/autofill/core/browser/autofill_metrics.h"
@@ -31,6 +33,7 @@
 #include "content/public/browser/web_contents_delegate.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 
@@ -78,6 +81,9 @@
     return autocheckout_status_;
   }
 
+  MOCK_CONST_METHOD2(LogDialogDismissalState,
+                     void(DialogType dialog_type, DialogDismissalState state));
+
  private:
   DialogType dialog_type_;
   AutofillMetrics::DialogDismissalAction dialog_dismissal_action_;
@@ -99,6 +105,9 @@
                                      dialog_type,
                                      base::Bind(&MockCallback)),
         metric_logger_(metric_logger),
+        mock_wallet_client_(
+            Profile::FromBrowserContext(contents->GetBrowserContext())->
+                GetRequestContext(), this),
         message_loop_runner_(runner),
         use_validation_(false) {}
 
@@ -151,7 +160,6 @@
     return &test_manager_;
   }
 
-  using AutofillDialogControllerImpl::DisableWallet;
   using AutofillDialogControllerImpl::IsEditingExistingData;
   using AutofillDialogControllerImpl::IsManuallyEditingSection;
 
@@ -164,6 +172,10 @@
     return &test_manager_;
   }
 
+  virtual wallet::WalletClient* GetWalletClient() OVERRIDE {
+    return &mock_wallet_client_;
+  }
+
  private:
   // To specify our own metric logger.
   virtual const AutofillMetrics& GetMetricLogger() const OVERRIDE {
@@ -172,6 +184,7 @@
 
   const AutofillMetrics& metric_logger_;
   TestPersonalDataManager test_manager_;
+  testing::NiceMock<wallet::MockWalletClient> mock_wallet_client_;
   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
   bool use_validation_;
 
@@ -304,9 +317,7 @@
   DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerTest);
 };
 
-// TODO(isherman): Enable these tests on other platforms once the UI is
-// implemented on those platforms.
-#if defined(TOOLKIT_VIEWS)
+#if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX)
 // Submit the form data.
 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Submit) {
   InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE);
@@ -343,6 +354,25 @@
   EXPECT_EQ(DIALOG_TYPE_REQUEST_AUTOCOMPLETE, metric_logger().dialog_type());
 }
 
+// Ensure that the expected metric is logged when the dialog is closed during
+// signin.
+IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, CloseDuringSignin) {
+  InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE);
+  controller()->SignInLinkClicked();
+
+  EXPECT_CALL(metric_logger(),
+              LogDialogDismissalState(
+                  DIALOG_TYPE_REQUEST_AUTOCOMPLETE,
+                  AutofillMetrics::DIALOG_CANCELED_DURING_SIGNIN));
+  controller()->GetTestableView()->CancelForTesting();
+
+  RunMessageLoop();
+
+  EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
+            metric_logger().dialog_dismissal_action());
+  EXPECT_EQ(DIALOG_TYPE_REQUEST_AUTOCOMPLETE, metric_logger().dialog_type());
+}
+
 // Test Autocheckout success metrics.
 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AutocheckoutSuccess) {
   InitializeControllerOfType(DIALOG_TYPE_AUTOCHECKOUT);
@@ -407,9 +437,16 @@
   EXPECT_EQ(DIALOG_TYPE_AUTOCHECKOUT, metric_logger().dialog_type());
 }
 
-IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, FillInputFromAutofill) {
+#if defined(OS_MACOSX)
+// TODO(groby): Implement the necessary functionality and enable this test:
+// http://crbug.com/256864
+#define MAYBE_FillInputFromAutofill DISABLED_FillInputFromAutofill
+#else
+#define MAYBE_FillInputFromAutofill FillInputFromAutofill
+#endif
+IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
+                       MAYBE_FillInputFromAutofill) {
   InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE);
-  controller()->DisableWallet(wallet::WalletClient::UNKNOWN_ERROR);
 
   AutofillProfile full_profile(test::GetFullProfile());
   controller()->GetTestingManager()->AddTestingProfile(&full_profile);
@@ -459,8 +496,7 @@
 
 // Test that Autocheckout steps are shown after submitting the
 // dialog for controller with type DIALOG_TYPE_AUTOCHECKOUT.
-IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
-                       AutocheckoutShowsSteps) {
+IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AutocheckoutShowsSteps) {
   InitializeControllerOfType(DIALOG_TYPE_AUTOCHECKOUT);
   controller()->AddAutocheckoutStep(AUTOCHECKOUT_STEP_PROXY_CARD);
 
@@ -474,10 +510,19 @@
   EXPECT_TRUE(controller()->ShouldShowProgressBar());
 }
 
+#if defined(OS_MACOSX)
+// TODO(groby): Implement the necessary functionality and enable this test:
+// http://crbug.com/256864
+#define MAYBE_RequestAutocompleteDoesntShowSteps \
+    DISABLED_RequestAutocompleteDoesntShowSteps
+#else
+#define MAYBE_RequestAutocompleteDoesntShowSteps \
+    RequestAutocompleteDoesntShowSteps
+#endif
 // Test that Autocheckout steps are not showing after submitting the
 // dialog for controller with type DIALOG_TYPE_REQUEST_AUTOCOMPLETE.
 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
-                       RequestAutocompleteDoesntShowSteps) {
+                       MAYBE_RequestAutocompleteDoesntShowSteps) {
   InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE);
   controller()->AddAutocheckoutStep(AUTOCHECKOUT_STEP_PROXY_CARD);
 
@@ -491,11 +536,18 @@
   EXPECT_FALSE(controller()->ShouldShowProgressBar());
 }
 
+#if defined(OS_MACOSX)
+// TODO(groby): Implement the necessary functionality and enable this test:
+// http://crbug.com/256864
+#define MAYBE_FillComboboxFromAutofill DISABLED_FillComboboxFromAutofill
+#else
+#define MAYBE_FillComboboxFromAutofill FillComboboxFromAutofill
+#endif
 // Tests that changing the value of a CC expiration date combobox works as
 // expected when Autofill is used to fill text inputs.
-IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, FillComboboxFromAutofill) {
+IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
+                       MAYBE_FillComboboxFromAutofill) {
   InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE);
-  controller()->DisableWallet(wallet::WalletClient::UNKNOWN_ERROR);
 
   CreditCard card1;
   test::SetCreditCardInfo(&card1, "JJ Smith", "4111111111111111", "12", "2018");
@@ -619,7 +671,6 @@
 // Ensure that expired cards trigger invalid suggestions.
 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ExpiredCard) {
   InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE);
-  controller()->DisableWallet(wallet::WalletClient::UNKNOWN_ERROR);
 
   CreditCard verified_card(test::GetCreditCard());
   verified_card.set_origin("Chrome settings");
@@ -673,7 +724,14 @@
             controller()->GetTestableView()->GetSize().width());
 }
 
-IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AutocompleteEvent) {
+#if defined(OS_MACOSX)
+// TODO(groby): Implement the necessary functionality and enable this test:
+// http://crbug.com/256864
+#define MAYBE_AutocompleteEvent DISABLED_AutocompleteEvent
+#else
+#define MAYBE_AutocompleteEvent AutocompleteEvent
+#endif
+IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, MAYBE_AutocompleteEvent) {
   AutofillDialogControllerImpl* controller =
       SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
 
@@ -687,8 +745,17 @@
   ExpectDomMessage("success");
 }
 
+#if defined(OS_MACOSX)
+// TODO(groby): Implement the necessary functionality and enable this test:
+// http://crbug.com/256864
+#define MAYBE_AutocompleteErrorEventReasonInvalid \
+    DISABLED_AutocompleteErrorEventReasonInvalid
+#else
+#define MAYBE_AutocompleteErrorEventReasonInvalid \
+    AutocompleteErrorEventReasonInvalid
+#endif
 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
-                       AutocompleteErrorEventReasonInvalid) {
+                       MAYBE_AutocompleteErrorEventReasonInvalid) {
   AutofillDialogControllerImpl* controller =
       SetUpHtmlAndInvoke("<input autocomplete='cc-name' pattern='.*zebra.*'>");
 
@@ -706,8 +773,17 @@
   ExpectDomMessage("error: invalid");
 }
 
+#if defined(OS_MACOSX)
+// TODO(groby): Implement the necessary functionality and enable this test:
+// http://crbug.com/256864
+#define MAYBE_AutocompleteErrorEventReasonCancel \
+    DISABLED_AutocompleteErrorEventReasonCancel
+#else
+#define MAYBE_AutocompleteErrorEventReasonCancel \
+    AutocompleteErrorEventReasonCancel
+#endif
 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
-                       AutocompleteErrorEventReasonCancel) {
+                       MAYBE_AutocompleteErrorEventReasonCancel) {
   SetUpHtmlAndInvoke("<input autocomplete='cc-name'>")->GetTestableView()->
       CancelForTesting();
   ExpectDomMessage("error: cancel");
@@ -715,7 +791,6 @@
 
 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, NoCvcSegfault) {
   InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE);
-  controller()->DisableWallet(wallet::WalletClient::UNKNOWN_ERROR);
   controller()->set_use_validation(true);
 
   CreditCard credit_card(test::GetVerifiedCreditCard());
@@ -726,7 +801,14 @@
       controller()->GetTestableView()->SubmitForTesting());
 }
 
-IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, PreservedSections) {
+#if defined(OS_MACOSX)
+// TODO(groby): Implement the necessary functionality and enable this test:
+// http://crbug.com/256864
+#define MAYBE_PreservedSections  DISABLED_PreservedSections
+#else
+#define MAYBE_PreservedSections PreservedSections
+#endif
+IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, MAYBE_PreservedSections) {
   InitializeControllerOfType(DIALOG_TYPE_REQUEST_AUTOCOMPLETE);
   controller()->set_use_validation(true);
 
@@ -763,11 +845,11 @@
   EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_CC_BILLING));
 
   // Create some valid inputted billing data.
-  const DetailInput& cc_name =
-      controller()->RequestedFieldsForSection(SECTION_CC_BILLING)[4];
-  ASSERT_EQ(CREDIT_CARD_NAME, cc_name.type);
+  const DetailInput& cc_number =
+      controller()->RequestedFieldsForSection(SECTION_CC_BILLING)[0];
+  EXPECT_EQ(CREDIT_CARD_NUMBER, cc_number.type);
   TestableAutofillDialogView* view = controller()->GetTestableView();
-  view->SetTextContentsOfInput(cc_name, ASCIIToUTF16("credit card name"));
+  view->SetTextContentsOfInput(cc_number, ASCIIToUTF16("4111111111111111"));
 
   // Select "Add new shipping info..." from suggestions menu.
   ui::MenuModel* shipping_model =
@@ -796,15 +878,15 @@
   EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING));
   EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
 
-  const DetailInput& new_cc_name =
-      controller()->RequestedFieldsForSection(SECTION_CC).back();
-  ASSERT_EQ(cc_name.type, new_cc_name.type);
-  EXPECT_EQ(ASCIIToUTF16("credit card name"),
-            view->GetTextContentsOfInput(new_cc_name));
+  const DetailInput& new_cc_number =
+      controller()->RequestedFieldsForSection(SECTION_CC).front();
+  EXPECT_EQ(cc_number.type, new_cc_number.type);
+  EXPECT_EQ(ASCIIToUTF16("4111111111111111"),
+            view->GetTextContentsOfInput(new_cc_number));
 
   EXPECT_NE(ASCIIToUTF16("shipping name"),
             view->GetTextContentsOfInput(shipping_zip));
 }
-#endif  // defined(TOOLKIT_VIEWS)
+#endif  // defined(TOOLKIT_VIEWS) || defined(OS_MACOSX)
 
 }  // namespace autofill
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
index 5e661c9..6ed07ec 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
@@ -24,6 +24,7 @@
 #include "chrome/browser/extensions/shell_window_registry.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_view.h"
 #include "chrome/browser/ui/autofill/data_model_wrapper.h"
 #include "chrome/browser/ui/browser.h"
@@ -124,9 +125,17 @@
   return input.type == field_type;
 }
 
-// Returns true if |input| should be used for a site-requested |field|.
-bool DetailInputMatchesField(const DetailInput& input,
+// Returns true if |input| in the given |section| should be used for a
+// site-requested |field|.
+bool DetailInputMatchesField(DialogSection section,
+                             const DetailInput& input,
                              const AutofillField& field) {
+  // The credit card name is filled from the billing section's data.
+  if (field.type() == CREDIT_CARD_NAME &&
+      (section == SECTION_BILLING || section == SECTION_CC_BILLING)) {
+    return input.type == NAME_FULL;
+  }
+
   return InputTypeMatchesFieldType(input, field.type());
 }
 
@@ -139,9 +148,6 @@
 // the billing address as the shipping address.
 bool DetailInputMatchesShippingField(const DetailInput& input,
                                      const AutofillField& field) {
-  if (field.type() == NAME_FULL)
-    return input.type == CREDIT_CARD_NAME;
-
   // Equivalent billing field type is used to support UseBillingAsShipping
   // usecase.
   AutofillFieldType field_type =
@@ -196,14 +202,16 @@
         cvc->assign(trimmed);
     } else if (it->first->type == ADDRESS_HOME_COUNTRY ||
                it->first->type == ADDRESS_BILLING_COUNTRY) {
+      if (profile) {
         profile->SetInfo(it->first->type,
                          trimmed,
                          g_browser_process->GetApplicationLocale());
+      }
     } else {
       // Copy the credit card name to |profile| in addition to |card| as
       // wallet::Instrument requires a recipient name for its billing address.
-      if (profile && it->first->type == CREDIT_CARD_NAME)
-        profile->SetRawInfo(NAME_FULL, trimmed);
+      if (card && it->first->type == NAME_FULL)
+        card->SetRawInfo(CREDIT_CARD_NAME, trimmed);
 
       if (IsCreditCardType(it->first->type)) {
         if (card)
@@ -387,12 +395,39 @@
   return base::string16();
 }
 
+gfx::Image GetGeneratedCardImage(const string16& card_number) {
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  const gfx::ImageSkia* card =
+      rb.GetImageSkiaNamed(IDR_AUTOFILL_GENERATED_CARD);
+  gfx::Canvas canvas(card->size(), ui::SCALE_FACTOR_100P, false);
+  canvas.DrawImageInt(*card, 0, 0);
+
+#if !defined(OS_ANDROID)
+  gfx::Rect display_rect(gfx::Point(), card->size());
+  display_rect.Inset(14, 0, 14, 0);
+  // TODO(estade): fallback font for systems that don't have Helvetica?
+  gfx::Font helvetica("Helvetica", 14);
+  gfx::ShadowValues shadows;
+  shadows.push_back(gfx::ShadowValue(gfx::Point(0, 1),
+                    0.0,
+                    SkColorSetARGB(85, 0, 0, 0)));
+  canvas.DrawStringWithShadows(
+      card_number,
+      helvetica,
+      SK_ColorWHITE,
+      display_rect, 0, 0, shadows);
+#endif
+
+  gfx::ImageSkia skia(canvas.ExtractImageRep());
+  return gfx::Image(skia);
+}
+
 }  // namespace
 
 AutofillDialogController::~AutofillDialogController() {}
 
 AutofillDialogControllerImpl::~AutofillDialogControllerImpl() {
-  if (popup_controller_.get())
+  if (popup_controller_)
     popup_controller_->Hide();
 
   GetMetricLogger().LogDialogInitialUserState(
@@ -419,7 +454,7 @@
 }
 
 // static
-void AutofillDialogControllerImpl::RegisterUserPrefs(
+void AutofillDialogControllerImpl::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       ::prefs::kAutofillDialogShowCount,
@@ -467,8 +502,9 @@
   // Determine what field types should be included in the dialog.
   bool has_types = false;
   bool has_sections = false;
-  form_structure_.ParseFieldTypesFromAutocompleteAttributes(&has_types,
-                                                            &has_sections);
+  form_structure_.ParseFieldTypesFromAutocompleteAttributes(
+      FormStructure::PARSE_FOR_AUTOFILL_DIALOG, &has_types, &has_sections);
+
   // Fail if the author didn't specify autocomplete types.
   if (!has_types) {
     callback_.Run(NULL, std::string());
@@ -486,10 +522,10 @@
     { 3, CREDIT_CARD_EXP_4_DIGIT_YEAR },
     { 3, CREDIT_CARD_VERIFICATION_CODE, IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC,
       1.5 },
-    { 4, CREDIT_CARD_NAME, IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARDHOLDER_NAME },
   };
 
   const DetailInput kBillingInputs[] = {
+    { 4, NAME_FULL, IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARDHOLDER_NAME },
     { 5, ADDRESS_BILLING_LINE1,
       IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1 },
     { 6, ADDRESS_BILLING_LINE2,
@@ -547,7 +583,7 @@
   EmptyDataModelWrapper empty_wrapper;
   cares_about_shipping_ = empty_wrapper.FillFormStructure(
       inputs,
-      base::Bind(DetailInputMatchesField),
+      base::Bind(DetailInputMatchesField, SECTION_SHIPPING),
       &form_structure_);
 
   SuggestionsUpdated();
@@ -566,7 +602,9 @@
   // Try to see if the user is already signed-in. If signed-in, fetch the user's
   // Wallet data. Otherwise, see if the user could be signed in passively.
   // TODO(aruslan): UMA metrics for sign-in.
-  GetWalletItems();
+  signin_helper_.reset(new wallet::WalletSigninHelper(
+      this, profile_->GetRequestContext()));
+  signin_helper_->StartWalletCookieValueFetch();
 
   if (!account_chooser_model_.WalletIsSelected())
     LogDialogLatencyToShow();
@@ -744,6 +782,61 @@
          IsSubmitPausedOn(wallet::VERIFY_CVV);
 }
 
+DialogOverlayState AutofillDialogControllerImpl::GetDialogOverlay() const {
+  bool show_wallet_interstitial = IsPayingWithWallet() && is_submitting_ &&
+      !IsSubmitPausedOn(wallet::VERIFY_CVV) &&
+      GetDialogType() == DIALOG_TYPE_REQUEST_AUTOCOMPLETE;
+  if (!show_wallet_interstitial)
+    return DialogOverlayState();
+
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  DialogOverlayState state;
+
+  state.strings.push_back(DialogOverlayString());
+  DialogOverlayString& string = state.strings.back();
+#if !defined(OS_ANDROID)
+  // gfx::Font isn't implemented on Android; DeriveFont() causes a null deref.
+  string.font = rb.GetFont(ui::ResourceBundle::BaseFont).DeriveFont(4);
+#endif
+
+  // First-run, post-submit, Wallet expository page.
+  if (full_wallet_ && full_wallet_->required_actions().empty()) {
+    string16 cc_number = full_wallet_->GetInfo(CREDIT_CARD_NUMBER);
+    DCHECK_EQ(16U, cc_number.size());
+    state.image = GetGeneratedCardImage(
+        ASCIIToUTF16("xxxx xxxx xxxx ") +
+        cc_number.substr(cc_number.size() - 4));
+    string.text = l10n_util::GetStringUTF16(
+        IDS_AUTOFILL_DIALOG_CARD_GENERATION_DONE);
+    // TODO(estade): figure out correct color.
+    string.text_color = SK_ColorGRAY;
+
+    state.strings.push_back(DialogOverlayString());
+    DialogOverlayString& subtext = state.strings.back();
+    subtext.font = rb.GetFont(ui::ResourceBundle::BaseFont);
+    // TODO(estade): figure out correct color.
+    subtext.text_color = SK_ColorGRAY;
+    subtext.text = l10n_util::GetStringUTF16(
+        IDS_AUTOFILL_DIALOG_CARD_GENERATION_EXPLANATION);
+
+    state.button_text = l10n_util::GetStringUTF16(
+        IDS_AUTOFILL_DIALOG_CARD_GENERATION_OK_BUTTON);
+  } else {
+    // TODO(estade): fix this (animation?).
+    state.image =
+        GetGeneratedCardImage(ASCIIToUTF16("xxxx xxxx xx..."));
+
+    // "Submitting" waiting page.
+    string.text = l10n_util::GetStringUTF16(
+        IDS_AUTOFILL_DIALOG_CARD_GENERATION_IN_PROGRESS);
+    // TODO(estade): figure out correct color.
+    string.text_color = SK_ColorGRAY;
+    string.alignment = gfx::ALIGN_CENTER;
+  }
+
+  return state;
+}
+
 const std::vector<ui::Range>& AutofillDialogControllerImpl::
     LegalDocumentLinks() {
   EnsureLegalDocumentsText();
@@ -1133,9 +1226,8 @@
     case SECTION_CC:
       return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_CC);
     case SECTION_BILLING:
-      return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_BILLING);
     case SECTION_CC_BILLING:
-      return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_CC_BILLING);
+      return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_BILLING);
     case SECTION_SHIPPING:
       return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_SHIPPING);
     default:
@@ -1433,15 +1525,6 @@
       break;
     }
 
-    case CREDIT_CARD_NAME:
-      // Wallet requires a first and last name.
-      if (!value.empty() && IsPayingWithWallet() &&
-          !IsCardHolderNameValidForWallet(value)) {
-        return l10n_util::GetStringUTF16(
-            IDS_AUTOFILL_DIALOG_VALIDATION_WALLET_REQUIRES_TWO_NAMES);
-      }
-      break;
-
     case CREDIT_CARD_EXP_MONTH:
     case CREDIT_CARD_EXP_4_DIGIT_YEAR:
       break;
@@ -1464,8 +1547,10 @@
       break;
 
     case ADDRESS_HOME_STATE:
-      if (!value.empty() && !autofill::IsValidState(value))
-        return ASCIIToUTF16("Are you sure this is right?");
+      if (!value.empty() && !autofill::IsValidState(value)) {
+        return l10n_util::GetStringUTF16(
+            IDS_AUTOFILL_DIALOG_VALIDATION_INVALID_REGION);
+      }
       break;
 
     case ADDRESS_HOME_ZIP:
@@ -1475,7 +1560,14 @@
       }
       break;
 
-    case NAME_FULL:  // Used for shipping.
+    case NAME_FULL:
+      // Wallet requires a first and last billing name.
+      if (section == SECTION_CC_BILLING && !value.empty() &&
+          !IsCardHolderNameValidForWallet(value)) {
+        DCHECK(IsPayingWithWallet());
+        return l10n_util::GetStringUTF16(
+            IDS_AUTOFILL_DIALOG_VALIDATION_WALLET_REQUIRES_TWO_NAMES);
+      }
       break;
 
     case PHONE_HOME_WHOLE_NUMBER:  // Used in shipping section.
@@ -1665,6 +1757,10 @@
   // TODO(ahutter): Once a user can cancel Autocheckout mid-flow, log that
   // metric here.
 
+  // Called from here rather than in ~AutofillDialogControllerImpl as this
+  // relies on virtual methods that change to their base class in the dtor.
+  MaybeShowCreditCardBubble();
+
   delete this;
 }
 
@@ -1719,16 +1815,17 @@
   }
 
   if (!wallet_server_validation_recoverable_) {
-    // TODO(ahutter): L10n and UI.
     notifications.push_back(DialogNotification(
         DialogNotification::REQUIRED_ACTION,
-        ASCIIToUTF16("Could not save Wallet data")));
+        l10n_util::GetStringUTF16(
+            IDS_AUTOFILL_DIALOG_FAILED_TO_SAVE_WALLET_DATA)));
   }
 
   if (choose_another_instrument_or_address_) {
     notifications.push_back(DialogNotification(
         DialogNotification::REQUIRED_ACTION,
-        ASCIIToUTF16("We need more information to complete your purchase.")));
+        l10n_util::GetStringUTF16(
+            IDS_AUTOFILL_DIALOG_CHOOSE_DIFFERENT_WALLET_INSTRUMENT)));
   }
 
   if (should_show_wallet_promo_ && ShouldShowDetailArea() &&
@@ -1793,6 +1890,14 @@
   NOTREACHED();
 }
 
+void AutofillDialogControllerImpl::OverlayButtonPressed() {
+  DCHECK(is_submitting_);
+  DCHECK(full_wallet_);
+  profile_->GetPrefs()->SetBoolean(::prefs::kAutofillDialogHasPaidWithWallet,
+                                   true);
+  FinishSubmit();
+}
+
 void AutofillDialogControllerImpl::OnCancel() {
   HidePopup();
   if (autocheckout_state_ == AUTOCHECKOUT_NOT_STARTED && !is_submitting_)
@@ -1912,7 +2017,9 @@
   if (wallet::IsSignInContinueUrl(load_details->entry->GetVirtualURL())) {
     should_show_wallet_promo_ = false;
     account_chooser_model_.SelectActiveWalletAccount();
-    GetWalletItems();
+    signin_helper_.reset(new wallet::WalletSigninHelper(
+        this, profile_->GetRequestContext()));
+    signin_helper_->StartWalletCookieValueFetch();
     HideSignIn();
   }
 }
@@ -1963,6 +2070,10 @@
   return risk_data_;
 }
 
+std::string AutofillDialogControllerImpl::GetWalletCookieValue() const {
+  return wallet_cookie_value_;
+}
+
 void AutofillDialogControllerImpl::OnDidAcceptLegalDocuments() {
   DCHECK(is_submitting_ && IsPayingWithWallet());
   has_accepted_legal_documents_ = true;
@@ -2018,9 +2129,8 @@
 void AutofillDialogControllerImpl::OnPassiveSigninSuccess(
     const std::string& username) {
   const string16 username16 = UTF8ToUTF16(username);
-  signin_helper_.reset();
+  signin_helper_->StartWalletCookieValueFetch();
   account_chooser_model_.SetActiveWalletAccountName(username16);
-  GetWalletItems();
 }
 
 void AutofillDialogControllerImpl::OnUserNameFetchSuccess(
@@ -2031,11 +2141,6 @@
   OnWalletOrSigninUpdate();
 }
 
-void AutofillDialogControllerImpl::OnAutomaticSigninSuccess(
-    const std::string& username) {
-  NOTIMPLEMENTED();
-}
-
 void AutofillDialogControllerImpl::OnPassiveSigninFailure(
     const GoogleServiceAuthError& error) {
   // TODO(aruslan): report an error.
@@ -2050,11 +2155,11 @@
   OnWalletSigninError();
 }
 
-void AutofillDialogControllerImpl::OnAutomaticSigninFailure(
-    const GoogleServiceAuthError& error) {
-  // TODO(aruslan): report an error.
-  LOG(ERROR) << "failed to automatically sign in: " << error.ToString();
-  OnWalletSigninError();
+void AutofillDialogControllerImpl::OnDidFetchWalletCookieValue(
+    const std::string& cookie_value) {
+  wallet_cookie_value_ = cookie_value;
+  signin_helper_.reset();
+  GetWalletItems();
 }
 
 void AutofillDialogControllerImpl::OnDidGetWalletItems(
@@ -2179,9 +2284,7 @@
 }
 
 bool AutofillDialogControllerImpl::TransmissionWillBeSecure() const {
-  return source_url_.SchemeIs(chrome::kHttpsScheme) &&
-         !net::IsCertStatusError(ssl_status_.cert_status) &&
-         !net::IsCertStatusMinorError(ssl_status_.cert_status);
+  return source_url_.SchemeIs(chrome::kHttpsScheme);
 }
 
 AutofillDialogControllerImpl::AutofillDialogControllerImpl(
@@ -2198,7 +2301,6 @@
       form_structure_(form_structure, std::string()),
       invoked_from_same_origin_(true),
       source_url_(source_url),
-      ssl_status_(form_structure.ssl_status),
       callback_(callback),
       account_chooser_model_(this, profile_->GetPrefs(), metric_logger_,
                              dialog_type),
@@ -2406,10 +2508,11 @@
           kAddNewItemKey,
           l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_BILLING_DETAILS));
       if (!wallet_items_->HasRequiredAction(wallet::SETUP_WALLET)) {
-        suggested_cc_billing_.AddKeyedItem(
+        suggested_cc_billing_.AddKeyedItemWithSublabel(
             kManageItemsKey,
             l10n_util::GetStringUTF16(
-                IDS_AUTOFILL_DIALOG_MANAGE_BILLING_DETAILS));
+                IDS_AUTOFILL_DIALOG_MANAGE_BILLING_DETAILS),
+                UTF8ToUTF16(wallet::GetManageInstrumentsUrl().host()));
       }
 
       // Determine which instrument item should be selected.
@@ -2486,11 +2589,15 @@
   suggested_shipping_.AddKeyedItem(
       kAddNewItemKey,
       l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_SHIPPING_ADDRESS));
-  if (!IsPayingWithWallet() ||
-      !wallet_items_->HasRequiredAction(wallet::SETUP_WALLET)) {
+  if (!IsPayingWithWallet()) {
     suggested_shipping_.AddKeyedItem(
         kManageItemsKey,
         l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_SHIPPING_ADDRESS));
+  } else if (!wallet_items_->HasRequiredAction(wallet::SETUP_WALLET)) {
+    suggested_shipping_.AddKeyedItemWithSublabel(
+        kManageItemsKey,
+        l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_SHIPPING_ADDRESS),
+        UTF8ToUTF16(wallet::GetManageAddressesUrl().host()));
   }
 
   if (!IsPayingWithWallet()) {
@@ -2569,8 +2676,15 @@
       card.set_origin(kAutofillDialogOrigin);
       FillFormGroupFromOutputs(output, &card);
 
-      if (ShouldSaveDetailsLocally())
+      // The card holder name comes from the billing address section.
+      card.SetRawInfo(CREDIT_CARD_NAME,
+                      GetValueFromSection(SECTION_BILLING, NAME_FULL));
+
+      if (ShouldSaveDetailsLocally()) {
         GetManager()->SaveImportedCreditCard(card);
+        DCHECK(!profile()->IsOffTheRecord());
+        newly_saved_card_.reset(new CreditCard(card));
+      }
 
       AutofillCreditCardWrapper card_wrapper(&card);
       card_wrapper.FillFormStructure(inputs, compare, &form_structure_);
@@ -2582,10 +2696,8 @@
       profile.set_origin(kAutofillDialogOrigin);
       FillFormGroupFromOutputs(output, &profile);
 
-      // For billing, the profile name has to come from the CC section.
+      // For billing, the email address comes from the separate email section.
       if (section == SECTION_BILLING) {
-        profile.SetRawInfo(NAME_FULL,
-                           GetValueFromSection(SECTION_CC, CREDIT_CARD_NAME));
         profile.SetRawInfo(EMAIL_ADDRESS,
                            GetValueFromSection(SECTION_EMAIL, EMAIL_ADDRESS));
       }
@@ -2600,8 +2712,8 @@
 }
 
 void AutofillDialogControllerImpl::FillOutputForSection(DialogSection section) {
-  FillOutputForSectionWithComparator(section,
-                                     base::Bind(DetailInputMatchesField));
+  FillOutputForSectionWithComparator(
+      section, base::Bind(DetailInputMatchesField, section));
 }
 
 bool AutofillDialogControllerImpl::FormStructureCaresAboutSection(
@@ -3057,6 +3169,24 @@
 }
 
 void AutofillDialogControllerImpl::FinishSubmit() {
+  if (IsPayingWithWallet() &&
+      !profile_->GetPrefs()->GetBoolean(
+          ::prefs::kAutofillDialogHasPaidWithWallet)) {
+    if (GetDialogType() == DIALOG_TYPE_REQUEST_AUTOCOMPLETE) {
+      // To get past this point, the view must call back OverlayButtonPressed.
+#if defined(TOOLKIT_VIEWS)
+      view_->UpdateButtonStrip();
+#else
+      // TODO(estade): implement overlays on other platforms.
+      OverlayButtonPressed();
+#endif
+      return;
+    } else {
+      profile_->GetPrefs()->SetBoolean(
+        ::prefs::kAutofillDialogHasPaidWithWallet, true);
+    }
+  }
+
   FillOutputForSection(SECTION_EMAIL);
   FillOutputForSection(SECTION_CC);
   FillOutputForSection(SECTION_BILLING);
@@ -3076,10 +3206,7 @@
     FillOutputForSection(SECTION_SHIPPING);
   }
 
-  if (IsPayingWithWallet()) {
-    profile_->GetPrefs()->SetBoolean(
-        ::prefs::kAutofillDialogHasPaidWithWallet, true);
-  } else {
+  if (!IsPayingWithWallet()) {
     for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) {
       DialogSection section = static_cast<DialogSection>(i);
       if (!SectionIsActive(section))
@@ -3215,7 +3342,9 @@
       GetDialogType(), AutofillMetrics::DIALOG_UI_CANCELED);
 
   AutofillMetrics::DialogDismissalState dismissal_state;
-  if (!IsManuallyEditingAnySection())
+  if (!signin_registrar_.IsEmpty())
+    dismissal_state = AutofillMetrics::DIALOG_CANCELED_DURING_SIGNIN;
+  else if (!IsManuallyEditingAnySection())
     dismissal_state = AutofillMetrics::DIALOG_CANCELED_NO_EDITS;
   else if (AllSectionsAreValid())
     dismissal_state = AutofillMetrics::DIALOG_CANCELED_NO_INVALID_FIELDS;
@@ -3304,4 +3433,33 @@
       AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_NO_AUTOFILL;
 }
 
+void AutofillDialogControllerImpl::MaybeShowCreditCardBubble() {
+  if (newly_saved_card_) {
+    AutofillCreditCardBubbleController::ShowNewCardSavedBubble(
+        web_contents(), newly_saved_card_->TypeAndLastFourDigits());
+    return;
+  }
+
+  if (!full_wallet_ || !full_wallet_->billing_address() ||
+      !AutofillCreditCardBubbleController::ShouldShowGeneratedCardBubble(
+          profile())) {
+    // If this run of the dialog didn't result in a valid |full_wallet_| or the
+    // generated card bubble shouldn't be shown now, don't show it again.
+    return;
+  }
+
+  base::string16 backing_last_four;
+  if (ActiveInstrument()) {
+    backing_last_four = ActiveInstrument()->TypeAndLastFourDigits();
+  } else {
+    DetailOutputMap output;
+    view_->GetUserInput(SECTION_CC_BILLING, &output);
+    CreditCard card;
+    GetBillingInfoFromOutputs(output, &card, NULL, NULL);
+    backing_last_four = card.TypeAndLastFourDigits();
+  }
+  AutofillCreditCardBubbleController::ShowGeneratedCardBubble(
+      web_contents(), backing_last_four, full_wallet_->TypeAndLastFourDigits());
+}
+
 }  // namespace autofill
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
index 598c6e5..a8c578d 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
@@ -34,9 +34,9 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/common/ssl_status.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/models/simple_menu_model.h"
 #include "ui/base/ui_base_types.h"
+#include "url/gurl.h"
 
 class Profile;
 
@@ -85,7 +85,7 @@
       const base::Callback<void(const FormStructure*,
                                 const std::string&)>& callback);
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   void Show();
   void Hide();
@@ -128,6 +128,7 @@
   virtual bool ShouldShowProgressBar() const OVERRIDE;
   virtual int GetDialogButtons() const OVERRIDE;
   virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE;
+  virtual DialogOverlayState GetDialogOverlay() const OVERRIDE;
   virtual const std::vector<ui::Range>& LegalDocumentLinks() OVERRIDE;
   virtual bool SectionIsActive(DialogSection section) const OVERRIDE;
   virtual const DetailInputs& RequestedFieldsForSection(DialogSection section)
@@ -171,6 +172,7 @@
   virtual void NotificationCheckboxStateChanged(DialogNotification::Type type,
                                                 bool checked) OVERRIDE;
   virtual void LegalDocumentLinkClicked(const ui::Range& range) OVERRIDE;
+  virtual void OverlayButtonPressed() OVERRIDE;
   virtual void OnCancel() OVERRIDE;
   virtual void OnAccept() OVERRIDE;
   virtual Profile* profile() OVERRIDE;
@@ -199,6 +201,7 @@
   virtual const AutofillMetrics& GetMetricLogger() const OVERRIDE;
   virtual DialogType GetDialogType() const OVERRIDE;
   virtual std::string GetRiskData() const OVERRIDE;
+  virtual std::string GetWalletCookieValue() const OVERRIDE;
   virtual void OnDidAcceptLegalDocuments() OVERRIDE;
   virtual void OnDidAuthenticateInstrument(bool success) OVERRIDE;
   virtual void OnDidGetFullWallet(
@@ -240,12 +243,11 @@
   virtual void OnPassiveSigninSuccess(const std::string& username) OVERRIDE;
   virtual void OnPassiveSigninFailure(
       const GoogleServiceAuthError& error) OVERRIDE;
-  virtual void OnAutomaticSigninSuccess(const std::string& username) OVERRIDE;
-  virtual void OnAutomaticSigninFailure(
-      const GoogleServiceAuthError& error) OVERRIDE;
   virtual void OnUserNameFetchSuccess(const std::string& username) OVERRIDE;
   virtual void OnUserNameFetchFailure(
       const GoogleServiceAuthError& error) OVERRIDE;
+  virtual void OnDidFetchWalletCookieValue(
+      const std::string& cookie_value) OVERRIDE;
 
   DialogType dialog_type() const { return dialog_type_; }
 
@@ -321,7 +323,7 @@
   void HideSignIn();
 
   // Handles the SignedInState() on Wallet or sign-in state update.
-  // Triggers the user name fetch and the passive/automatic sign-in.
+  // Triggers the user name fetch and passive sign-in.
   void SignedInStateUpdated();
 
   // Refreshes the model on Wallet or sign-in state update.
@@ -561,6 +563,10 @@
   // interacting with this dialog.
   AutofillMetrics::DialogInitialUserStateMetric GetInitialUserState() const;
 
+  // Shows an educational bubble if a new credit card was saved or the first few
+  // times an Online Wallet fronting card was generated.
+  void MaybeShowCreditCardBubble();
+
   // The |profile| for |contents_|.
   Profile* const profile_;
 
@@ -588,9 +594,6 @@
   // The URL of the invoking site.
   GURL source_url_;
 
-  // The SSL info from the invoking site.
-  content::SSLStatus ssl_status_;
-
   // The callback via which we return the collected data and, if Online Wallet
   // was used, the Google transaction id.
   base::Callback<void(const FormStructure*, const std::string&)> callback_;
@@ -692,7 +695,6 @@
   // recoverable.
   bool wallet_server_validation_recoverable_;
 
-
   typedef std::map<AutofillFieldType,
       std::pair<base::string16, base::string16> > TypeErrorInputMap;
   typedef std::map<DialogSection, TypeErrorInputMap> WalletValidationErrors;
@@ -709,6 +711,15 @@
   // Autocheckout use case.
   std::vector<DialogAutocheckoutStep> steps_;
 
+  // The Google Wallet cookie value, set as an authorization header on requests
+  // to Wallet.
+  std::string wallet_cookie_value_;
+
+  // Populated if the user chose to save a newly inputted credit card. Used to
+  // show a bubble as the dialog closes to confirm a user's new card info was
+  // saved. Never populated while incognito (as nothing's actually saved).
+  scoped_ptr<CreditCard> newly_saved_card_;
+
   DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerImpl);
 };
 
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
index 6249f5d..68903cc 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
@@ -11,16 +11,19 @@
 #include "base/message_loop.h"
 #include "base/prefs/pref_service.h"
 #include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_view.h"
+#include "chrome/browser/ui/autofill/test_autofill_credit_card_bubble.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
 #include "components/autofill/content/browser/wallet/full_wallet.h"
 #include "components/autofill/content/browser/wallet/instrument.h"
+#include "components/autofill/content/browser/wallet/mock_wallet_client.h"
 #include "components/autofill/content/browser/wallet/wallet_address.h"
-#include "components/autofill/content/browser/wallet/wallet_client.h"
 #include "components/autofill/content/browser/wallet/wallet_service_url.h"
 #include "components/autofill/content/browser/wallet/wallet_test_util.h"
 #include "components/autofill/core/browser/autofill_common_test.h"
@@ -133,6 +136,9 @@
       OVERRIDE {
     *output = outputs_[section];
   }
+  virtual TestableAutofillDialogView* GetTestableView() OVERRIDE {
+    return NULL;
+  }
 
   virtual string16 GetCvc() OVERRIDE { return string16(); }
   virtual bool SaveDetailsLocally() OVERRIDE { return true; }
@@ -157,61 +163,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogView);
 };
 
-class TestWalletClient : public wallet::WalletClient {
- public:
-  TestWalletClient(net::URLRequestContextGetter* context,
-                   wallet::WalletClientDelegate* delegate)
-      : wallet::WalletClient(context, delegate) {}
-  virtual ~TestWalletClient() {}
-
-  MOCK_METHOD3(AcceptLegalDocuments,
-      void(const std::vector<wallet::WalletItems::LegalDocument*>& documents,
-           const std::string& google_transaction_id,
-           const GURL& source_url));
-
-  MOCK_METHOD3(AuthenticateInstrument,
-      void(const std::string& instrument_id,
-           const std::string& card_verification_number,
-           const std::string& obfuscated_gaia_id));
-
-  MOCK_METHOD1(GetFullWallet,
-      void(const wallet::WalletClient::FullWalletRequest& request));
-
-  MOCK_METHOD1(GetWalletItems, void(const GURL& source_url));
-
-  MOCK_METHOD2(SaveAddress,
-      void(const wallet::Address& address, const GURL& source_url));
-
-  MOCK_METHOD3(SaveInstrument,
-      void(const wallet::Instrument& instrument,
-           const std::string& obfuscated_gaia_id,
-           const GURL& source_url));
-
-  MOCK_METHOD4(SaveInstrumentAndAddress,
-      void(const wallet::Instrument& instrument,
-           const wallet::Address& address,
-           const std::string& obfuscated_gaia_id,
-           const GURL& source_url));
-
-  MOCK_METHOD2(UpdateAddress,
-      void(const wallet::Address& address, const GURL& source_url));
-
-  virtual void UpdateInstrument(
-      const wallet::WalletClient::UpdateInstrumentRequest& update_request,
-      scoped_ptr<wallet::Address> billing_address) {
-    updated_billing_address_ = billing_address.Pass();
-  }
-
-  const wallet::Address* updated_billing_address() {
-    return updated_billing_address_.get();
-  }
-
- private:
-  scoped_ptr<wallet::Address> updated_billing_address_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestWalletClient);
-};
-
 // Bring over command-ids from AccountChooserModel.
 class TestAccountChooserModel : public AccountChooserModel {
  public:
@@ -247,7 +198,7 @@
                                      dialog_type,
                                      callback),
         metric_logger_(metric_logger),
-        test_wallet_client_(
+        mock_wallet_client_(
             Profile::FromBrowserContext(contents->GetBrowserContext())->
                 GetRequestContext(), this),
         dialog_type_(dialog_type) {}
@@ -269,8 +220,8 @@
     return &test_manager_;
   }
 
-  TestWalletClient* GetTestingWalletClient() {
-    return &test_wallet_client_;
+  wallet::MockWalletClient* GetTestingWalletClient() {
+    return &mock_wallet_client_;
   }
 
   const GURL& open_tab_url() { return open_tab_url_; }
@@ -295,7 +246,7 @@
   }
 
   virtual wallet::WalletClient* GetWalletClient() OVERRIDE {
-    return &test_wallet_client_;
+    return &mock_wallet_client_;
   }
 
   virtual void OpenTabWithUrl(const GURL& url) OVERRIDE {
@@ -316,18 +267,49 @@
 
   const AutofillMetrics& metric_logger_;
   TestPersonalDataManager test_manager_;
-  testing::NiceMock<TestWalletClient> test_wallet_client_;
+  testing::NiceMock<wallet::MockWalletClient> mock_wallet_client_;
   GURL open_tab_url_;
   DialogType dialog_type_;
 
   DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController);
 };
 
+class TestAutofillCreditCardBubbleController :
+    public AutofillCreditCardBubbleController {
+ public:
+  explicit TestAutofillCreditCardBubbleController(
+      content::WebContents* contents)
+      : AutofillCreditCardBubbleController(contents),
+        bubble_(GetWeakPtr()) {
+    contents->SetUserData(UserDataKey(), this);
+    EXPECT_EQ(contents->GetUserData(UserDataKey()), this);
+  }
+  virtual ~TestAutofillCreditCardBubbleController() {}
+
+  MOCK_METHOD2(ShowAsGeneratedCardBubble,
+               void(const base::string16& backing_card_name,
+                    const base::string16& fronting_card_name));
+  MOCK_METHOD1(ShowAsNewCardSavedBubble,
+               void(const base::string16& newly_saved_card_name));
+
+ protected:
+  virtual base::WeakPtr<AutofillCreditCardBubble> CreateBubble() OVERRIDE {
+    return bubble_.GetWeakPtr();
+  }
+
+  virtual bool CanShow() const OVERRIDE {
+    return true;
+  }
+
+ private:
+  TestAutofillCreditCardBubble bubble_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestAutofillCreditCardBubbleController);
+};
+
 class AutofillDialogControllerTest : public testing::Test {
  protected:
-  AutofillDialogControllerTest()
-    : form_structure_(NULL) {
-  }
+  AutofillDialogControllerTest(): form_structure_(NULL) {}
 
   // testing::Test implementation:
   virtual void SetUp() OVERRIDE {
@@ -335,11 +317,19 @@
     test_web_contents_.reset(
         content::WebContentsTester::CreateTestWebContents(profile(), NULL));
 
+    test_bubble_controller_ =
+        new testing::NiceMock<TestAutofillCreditCardBubbleController>(
+            test_web_contents_.get());
+
+    // Don't get stuck on the first run wallet interstitial.
+    profile()->GetPrefs()->SetBoolean(::prefs::kAutofillDialogHasPaidWithWallet,
+                                      true);
+
     SetUpControllerWithFormData(DefaultFormData());
   }
 
   virtual void TearDown() OVERRIDE {
-    if (controller_.get())
+    if (controller_)
       controller_->ViewClosed();
   }
 
@@ -355,7 +345,7 @@
   }
 
   void SetUpControllerWithFormData(const FormData& form_data) {
-    if (controller_.get())
+    if (controller_)
       controller_->ViewClosed();
 
     base::Callback<void(const FormStructure*, const std::string&)> callback =
@@ -378,7 +368,8 @@
     const DetailInputs& cc_inputs =
         controller()->RequestedFieldsForSection(SECTION_CC);
     for (size_t i = 0; i < cc_inputs.size(); ++i) {
-      cc_outputs[&cc_inputs[i]] = ASCIIToUTF16("11");
+      cc_outputs[&cc_inputs[i]] = cc_inputs[i].type == CREDIT_CARD_NUMBER ?
+          ASCIIToUTF16(kTestCCNumberVisa) : ASCIIToUTF16("11");
     }
     controller()->GetView()->SetUserInput(SECTION_CC, cc_outputs);
   }
@@ -442,6 +433,14 @@
 
   const FormStructure* form_structure() { return form_structure_; }
 
+  const content::WebContents* test_web_contents() const {
+    return test_web_contents_.get();
+  }
+
+  TestAutofillCreditCardBubbleController* test_bubble_controller() {
+    return test_bubble_controller_;
+  }
+
  private:
   void FinishedCallback(const FormStructure* form_structure,
                         const std::string& google_transaction_id) {
@@ -470,6 +469,10 @@
 
   // Returned when the dialog closes successfully.
   const FormStructure* form_structure_;
+
+  // Used to monitor if the Autofill credit card bubble is shown. Owned by
+  // |test_web_contents_|.
+  TestAutofillCreditCardBubbleController* test_bubble_controller_;
 };
 
 }  // namespace
@@ -559,30 +562,30 @@
   }
 }
 
-TEST_F(AutofillDialogControllerTest, CardHolderNameValidation) {
+TEST_F(AutofillDialogControllerTest, BillingNameValidation) {
   // Construct DetailOutputMap from AutofillProfile data.
   SwitchToAutofill();
 
   DetailOutputMap outputs;
   const DetailInputs& inputs =
-      controller()->RequestedFieldsForSection(SECTION_CC);
+      controller()->RequestedFieldsForSection(SECTION_BILLING);
 
-  // Input an empty card holder name with VALIDATE_FINAL.
-  SetOutputValue(inputs, &outputs, CREDIT_CARD_NAME, "");
+  // Input an empty billing name with VALIDATE_FINAL.
+  SetOutputValue(inputs, &outputs, NAME_FULL, "");
   ValidityData validity_data =
-      controller()->InputsAreValid(SECTION_CC, outputs, VALIDATE_FINAL);
-  EXPECT_EQ(1U, validity_data.count(CREDIT_CARD_NAME));
+      controller()->InputsAreValid(SECTION_BILLING, outputs, VALIDATE_FINAL);
+  EXPECT_EQ(1U, validity_data.count(NAME_FULL));
 
-  // Input an empty card holder name with VALIDATE_EDIT.
+  // Input an empty billing name with VALIDATE_EDIT.
   validity_data =
-      controller()->InputsAreValid(SECTION_CC, outputs, VALIDATE_EDIT);
-  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
+      controller()->InputsAreValid(SECTION_BILLING, outputs, VALIDATE_EDIT);
+  EXPECT_EQ(0U, validity_data.count(NAME_FULL));
 
-  // Input a non-empty card holder name.
-  SetOutputValue(inputs, &outputs, CREDIT_CARD_NAME, "Bob");
+  // Input a non-empty billing name.
+  SetOutputValue(inputs, &outputs, NAME_FULL, "Bob");
   validity_data =
-      controller()->InputsAreValid(SECTION_CC, outputs, VALIDATE_FINAL);
-  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
+      controller()->InputsAreValid(SECTION_BILLING, outputs, VALIDATE_FINAL);
+  EXPECT_EQ(0U, validity_data.count(NAME_FULL));
 
   // Switch to Wallet which only considers names with with at least two names to
   // be valid.
@@ -596,51 +599,51 @@
   const DetailInputs& wallet_inputs =
       controller()->RequestedFieldsForSection(SECTION_CC_BILLING);
 
-  // Input an empty card holder name with VALIDATE_FINAL. Data source should not
+  // Input an empty billing name with VALIDATE_FINAL. Data source should not
   // change this behavior.
-  SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME, "");
+  SetOutputValue(wallet_inputs, &wallet_outputs, NAME_FULL, "");
   validity_data =
       controller()->InputsAreValid(
           SECTION_CC_BILLING, wallet_outputs, VALIDATE_FINAL);
-  EXPECT_EQ(1U, validity_data.count(CREDIT_CARD_NAME));
+  EXPECT_EQ(1U, validity_data.count(NAME_FULL));
 
-  // Input an empty card holder name with VALIDATE_EDIT. Data source should not
+  // Input an empty billing name with VALIDATE_EDIT. Data source should not
   // change this behavior.
   validity_data =
       controller()->InputsAreValid(
           SECTION_CC_BILLING, wallet_outputs, VALIDATE_EDIT);
-  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
+  EXPECT_EQ(0U, validity_data.count(NAME_FULL));
 
-  // Input a one name card holder name. Wallet does not currently support this.
-  SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME, "Bob");
+  // Input a one name billing name. Wallet does not currently support this.
+  SetOutputValue(wallet_inputs, &wallet_outputs, NAME_FULL, "Bob");
   validity_data =
       controller()->InputsAreValid(
           SECTION_CC_BILLING, wallet_outputs, VALIDATE_FINAL);
-  EXPECT_EQ(1U, validity_data.count(CREDIT_CARD_NAME));
+  EXPECT_EQ(1U, validity_data.count(NAME_FULL));
 
-  // Input a two name card holder name.
-  SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME,
+  // Input a two name billing name.
+  SetOutputValue(wallet_inputs, &wallet_outputs, NAME_FULL,
                  "Bob Barker");
   validity_data =
       controller()->InputsAreValid(
           SECTION_CC_BILLING, wallet_outputs, VALIDATE_FINAL);
-  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
+  EXPECT_EQ(0U, validity_data.count(NAME_FULL));
 
-  // Input a more than two name card holder name.
-  SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME,
+  // Input a more than two name billing name.
+  SetOutputValue(wallet_inputs, &wallet_outputs, NAME_FULL,
                  "John Jacob Jingleheimer Schmidt");
   validity_data =
       controller()->InputsAreValid(
           SECTION_CC_BILLING, wallet_outputs, VALIDATE_FINAL);
-  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
+  EXPECT_EQ(0U, validity_data.count(NAME_FULL));
 
-  // Input a card holder name with lots of crazy whitespace.
-  SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME,
+  // Input a billing name with lots of crazy whitespace.
+  SetOutputValue(wallet_inputs, &wallet_outputs, NAME_FULL,
                  "     \\n\\r John \\n  Jacob Jingleheimer \\t Schmidt  ");
   validity_data =
       controller()->InputsAreValid(
           SECTION_CC_BILLING, wallet_outputs, VALIDATE_FINAL);
-  EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
+  EXPECT_EQ(0U, validity_data.count(NAME_FULL));
 }
 
 TEST_F(AutofillDialogControllerTest, CreditCardNumberValidation) {
@@ -927,7 +930,7 @@
 
   EXPECT_EQ(CREDIT_CARD_NAME, form_structure()->field(1)->type());
   string16 cc_name = form_structure()->field(1)->value;
-  EXPECT_EQ(NAME_FULL, form_structure()->field(6)->type());
+  EXPECT_EQ(CREDIT_CARD_NAME, form_structure()->field(6)->type());
   string16 billing_name = form_structure()->field(6)->value;
   EXPECT_EQ(NAME_FULL, form_structure()->field(13)->type());
   string16 shipping_name = form_structure()->field(13)->value;
@@ -936,8 +939,7 @@
   EXPECT_FALSE(billing_name.empty());
   EXPECT_FALSE(shipping_name.empty());
   // Billing name should always be the same as cardholder name.
-  // TODO(estade): this currently fails. http://crbug.com/246417
-  // EXPECT_EQ(cc_name, billing_name);
+  EXPECT_EQ(cc_name, billing_name);
   EXPECT_NE(cc_name, shipping_name);
 }
 
@@ -965,7 +967,7 @@
 
   EXPECT_EQ(CREDIT_CARD_NAME, form_structure()->field(1)->type());
   string16 cc_name = form_structure()->field(1)->value;
-  EXPECT_EQ(NAME_FULL, form_structure()->field(6)->type());
+  EXPECT_EQ(CREDIT_CARD_NAME, form_structure()->field(6)->type());
   string16 billing_name = form_structure()->field(6)->value;
   EXPECT_EQ(NAME_FULL, form_structure()->field(13)->type());
   string16 shipping_name = form_structure()->field(13)->value;
@@ -1410,10 +1412,12 @@
 
 // Tests that adding an autofill profile and then submitting works.
 TEST_F(AutofillDialogControllerTest, AddAutofillProfile) {
-  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
+  EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(2);
 
   AutofillProfile full_profile(test::GetVerifiedProfile());
+  CreditCard credit_card(test::GetVerifiedCreditCard());
   controller()->GetTestingManager()->AddTestingProfile(&full_profile);
+  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
 
   ui::MenuModel* model = controller()->MenuModelForSection(SECTION_BILLING);
   // Activate the "Add billing address" menu item.
@@ -1430,17 +1434,6 @@
   }
   controller()->GetView()->SetUserInput(SECTION_BILLING, outputs);
 
-  // Fill in some CC info. The name field will be used to fill in the billing
-  // address name in the newly minted AutofillProfile.
-  DetailOutputMap cc_outputs;
-  const DetailInputs& cc_inputs =
-      controller()->RequestedFieldsForSection(SECTION_CC);
-  for (size_t i = 0; i < cc_inputs.size(); ++i) {
-    cc_outputs[&cc_inputs[i]] = cc_inputs[i].type == CREDIT_CARD_NAME ?
-        ASCIIToUTF16("Bill Money") : ASCIIToUTF16("111");
-  }
-  controller()->GetView()->SetUserInput(SECTION_CC, cc_outputs);
-
   controller()->OnAccept();
   const AutofillProfile& added_profile =
       controller()->GetTestingManager()->imported_profile();
@@ -1449,10 +1442,8 @@
       controller()->RequestedFieldsForSection(SECTION_SHIPPING);
   for (size_t i = 0; i < shipping_inputs.size(); ++i) {
     const DetailInput& input = shipping_inputs[i];
-    string16 expected = input.type == NAME_FULL ?
-        ASCIIToUTF16("Bill Money") :
-        full_profile2.GetInfo(input.type, "en-US");
-    EXPECT_EQ(expected, added_profile.GetInfo(input.type, "en-US"));
+    EXPECT_EQ(full_profile2.GetInfo(input.type, "en-US"),
+              added_profile.GetInfo(input.type, "en-US"));
   }
 
   // Also, the currently selected email address should get added to the new
@@ -1643,8 +1634,11 @@
 TEST_F(AutofillDialogControllerTest, WalletBanners) {
   CommandLine* command_line = CommandLine::ForCurrentProcess();
   command_line->AppendSwitch(switches::kWalletServiceUseProd);
-  PrefService* prefs = controller()->profile()->GetPrefs();
-  ASSERT_FALSE(prefs->GetBoolean(::prefs::kAutofillDialogHasPaidWithWallet));
+  PrefService* prefs = profile()->GetPrefs();
+
+  // Simulate first run.
+  prefs->SetBoolean(::prefs::kAutofillDialogHasPaidWithWallet, false);
+  SetUpControllerWithFormData(DefaultFormData());
 
   EXPECT_EQ(0U, NotificationsOfType(
       DialogNotification::EXPLANATORY_MESSAGE).size());
@@ -1752,6 +1746,12 @@
   command_line->AppendSwitch(switches::kWalletServiceUseProd);
   controller()->set_dialog_type(DIALOG_TYPE_AUTOCHECKOUT);
 
+  // Simulate first run.
+  profile()->GetPrefs()->SetBoolean(::prefs::kAutofillDialogHasPaidWithWallet,
+                                    false);
+  SetUpControllerWithFormData(DefaultFormData());
+  controller()->set_dialog_type(DIALOG_TYPE_AUTOCHECKOUT);
+
   // Sign in a user with a completed account.
   controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
 
@@ -1763,11 +1763,13 @@
 
   AcceptAndLoadFakeFingerprint();
   controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
+  EXPECT_TRUE(controller()->GetDialogOverlay().image.IsEmpty());
 
   EXPECT_EQ(0U, NotificationsOfType(
       DialogNotification::EXPLANATORY_MESSAGE).size());
 
   controller()->OnAutocheckoutSuccess();
+  EXPECT_TRUE(controller()->GetDialogOverlay().image.IsEmpty());
 
   EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
   EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
@@ -1777,6 +1779,8 @@
       DialogNotification::AUTOCHECKOUT_ERROR).size());
   EXPECT_EQ(0U, NotificationsOfType(
       DialogNotification::EXPLANATORY_MESSAGE).size());
+  EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
+      ::prefs::kAutofillDialogHasPaidWithWallet));
 }
 
 TEST_F(AutofillDialogControllerTest, ViewCancelDoesntSetPref) {
@@ -1804,6 +1808,51 @@
       ::prefs::kAutofillDialogPayWithoutWallet));
 }
 
+// Tests that there's an overlay shown while waiting for full wallet items,
+// and on first run an additional expository wallet overlay shown after full
+// wallet items are returned.
+// TODO(estade): enable on other platforms when overlays are supported there.
+#if defined(TOOLKIT_VIEWS)
+TEST_F(AutofillDialogControllerTest, WalletFirstRun) {
+  // Simulate first run.
+  PrefService* prefs = profile()->GetPrefs();
+  prefs->SetBoolean(::prefs::kAutofillDialogHasPaidWithWallet, false);
+  SetUpControllerWithFormData(DefaultFormData());
+
+  SwitchToWallet();
+  EXPECT_TRUE(controller()->GetDialogOverlay().image.IsEmpty());
+
+  SubmitWithWalletItems(CompleteAndValidWalletItems());
+  EXPECT_FALSE(controller()->GetDialogOverlay().image.IsEmpty());
+
+  EXPECT_FALSE(prefs->GetBoolean(::prefs::kAutofillDialogHasPaidWithWallet));
+  controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
+  EXPECT_FALSE(prefs->GetBoolean(::prefs::kAutofillDialogHasPaidWithWallet));
+  EXPECT_FALSE(controller()->GetDialogOverlay().image.IsEmpty());
+  EXPECT_FALSE(form_structure());
+
+  controller()->OverlayButtonPressed();
+  EXPECT_TRUE(prefs->GetBoolean(::prefs::kAutofillDialogHasPaidWithWallet));
+  EXPECT_TRUE(form_structure());
+}
+#endif
+
+// On second run, the second overlay doesn't show.
+TEST_F(AutofillDialogControllerTest, WalletSecondRun) {
+  SwitchToWallet();
+  EXPECT_TRUE(controller()->GetDialogOverlay().image.IsEmpty());
+
+  SubmitWithWalletItems(CompleteAndValidWalletItems());
+  EXPECT_FALSE(controller()->GetDialogOverlay().image.IsEmpty());
+
+  EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
+      ::prefs::kAutofillDialogHasPaidWithWallet));
+  controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
+  EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
+      ::prefs::kAutofillDialogHasPaidWithWallet));
+  EXPECT_TRUE(form_structure());
+}
+
 TEST_F(AutofillDialogControllerTest, ViewSubmitSetsPref) {
   ASSERT_FALSE(profile()->GetPrefs()->HasPrefPath(
       ::prefs::kAutofillDialogPayWithoutWallet));
@@ -1887,7 +1936,7 @@
 // Test if autofill types of returned form structure are correct for billing
 // entries.
 TEST_F(AutofillDialogControllerTest, AutofillTypes) {
-  controller()->OnDidGetWalletItems(wallet::GetTestWalletItems());
+  controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
   controller()->OnAccept();
   controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
   ASSERT_EQ(20U, form_structure()->field_count());
@@ -2091,7 +2140,7 @@
 // and updated correctly.
 TEST_F(AutofillDialogControllerTest, DetailedSteps) {
   EXPECT_CALL(*controller()->GetTestingWalletClient(),
-            GetFullWallet(_)).Times(1);
+              GetFullWallet(_)).Times(1);
 
   controller()->set_dialog_type(DIALOG_TYPE_AUTOCHECKOUT);
 
@@ -2178,4 +2227,27 @@
             controller()->CurrentAutocheckoutSteps()[2].status());
 }
 
+
+TEST_F(AutofillDialogControllerTest, NewCardBubbleShown) {
+  EXPECT_CALL(*test_bubble_controller(),
+              ShowAsNewCardSavedBubble(ASCIIToUTF16("Visa - 1111"))).Times(1);
+  EXPECT_CALL(*test_bubble_controller(),
+              ShowAsGeneratedCardBubble(_, _)).Times(0);
+
+  SwitchToAutofill();
+  FillCreditCardInputs();
+  controller()->OnAccept();
+  controller()->ViewClosed();
+}
+
+TEST_F(AutofillDialogControllerTest, GeneratedCardBubbleShown) {
+  EXPECT_CALL(*test_bubble_controller(),
+              ShowAsGeneratedCardBubble(_, _)).Times(1);
+  EXPECT_CALL(*test_bubble_controller(), ShowAsNewCardSavedBubble(_)).Times(0);
+
+  SubmitWithWalletItems(CompleteAndValidWalletItems());
+  controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
+  controller()->ViewClosed();
+}
+
 }  // namespace autofill
diff --git a/chrome/browser/ui/autofill/autofill_dialog_types.cc b/chrome/browser/ui/autofill/autofill_dialog_types.cc
index eb62c15..1230c53 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_types.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_types.cc
@@ -25,6 +25,7 @@
 
 SkColor DialogNotification::GetBackgroundColor() const {
   switch (type_) {
+    case DialogNotification::AUTOCHECKOUT_SUCCESS:
     case DialogNotification::EXPLANATORY_MESSAGE:
     case DialogNotification::WALLET_USAGE_CONFIRMATION:
       return SkColorSetRGB(0x47, 0x89, 0xfa);
@@ -36,7 +37,6 @@
     case DialogNotification::SECURITY_WARNING:
     case DialogNotification::VALIDATION_ERROR:
       return kWarningColor;
-    case DialogNotification::AUTOCHECKOUT_SUCCESS:
     case DialogNotification::NONE:
       return SK_ColorTRANSPARENT;
   }
@@ -47,11 +47,11 @@
 
 SkColor DialogNotification::GetTextColor() const {
   switch (type_) {
-    case DialogNotification::AUTOCHECKOUT_SUCCESS:
     case DialogNotification::REQUIRED_ACTION:
     case DialogNotification::WALLET_ERROR:
     case DialogNotification::AUTOCHECKOUT_ERROR:
       return SK_ColorBLACK;
+    case DialogNotification::AUTOCHECKOUT_SUCCESS:
     case DialogNotification::DEVELOPER_WARNING:
     case DialogNotification::EXPLANATORY_MESSAGE:
     case DialogNotification::WALLET_USAGE_CONFIRMATION:
@@ -221,6 +221,12 @@
       extra_icon(extra_icon) {}
 SuggestionState::~SuggestionState() {}
 
+DialogOverlayString::DialogOverlayString() : alignment(gfx::ALIGN_LEFT) {}
+DialogOverlayString::~DialogOverlayString() {}
+
+DialogOverlayState::DialogOverlayState() {}
+DialogOverlayState::~DialogOverlayState() {}
+
 AutofillMetrics::DialogUiEvent DialogSectionToUiEditEvent(
     DialogSection section) {
   switch (section) {
diff --git a/chrome/browser/ui/autofill/autofill_dialog_types.h b/chrome/browser/ui/autofill/autofill_dialog_types.h
index a65820b..26df627 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_types.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_types.h
@@ -15,6 +15,7 @@
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/font.h"
 #include "ui/gfx/image/image.h"
+#include "ui/gfx/text_constants.h"
 
 namespace autofill {
 
@@ -189,6 +190,31 @@
   gfx::Image extra_icon;
 };
 
+// A struct to describe a textual message within a dialog overlay.
+struct DialogOverlayString {
+  DialogOverlayString();
+  ~DialogOverlayString();
+  // TODO(estade): need to set a color as well.
+  base::string16 text;
+  SkColor text_color;
+  gfx::Font font;
+  gfx::HorizontalAlignment alignment;
+};
+
+// A struct to describe a dialog overlay. If |image| is empty, no overlay should
+// be shown.
+struct DialogOverlayState {
+  DialogOverlayState();
+  ~DialogOverlayState();
+  // If empty, there should not be an overlay. If non-empty, an image that is
+  // more or less front and center.
+  gfx::Image image;
+  // If non-empty, messages to display.
+  std::vector<DialogOverlayString> strings;
+  // If non-empty, holds text that should go on a button.
+  base::string16 button_text;
+};
+
 enum ValidationType {
   VALIDATE_EDIT,   // Validate user edits. Allow for empty fields.
   VALIDATE_FINAL,  // Full form validation. Required fields can't be empty.
diff --git a/chrome/browser/ui/autofill/autofill_dialog_view.cc b/chrome/browser/ui/autofill/autofill_dialog_view.cc
index a4442e4..7d78fc8 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_view.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_view.cc
@@ -20,10 +20,4 @@
 }
 #endif
 
-TestableAutofillDialogView* AutofillDialogView::GetTestableView() {
-  return NULL;
-}
-
-TestableAutofillDialogView::~TestableAutofillDialogView() {}
-
 }  // namespace autofill
diff --git a/chrome/browser/ui/autofill/autofill_dialog_view.h b/chrome/browser/ui/autofill/autofill_dialog_view.h
index 12a7ddb..c2c610d 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_view.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_view.h
@@ -87,9 +87,8 @@
   virtual void ModelChanged() = 0;
 
   // Returns an object that can be used to test that the view is behaving as
-  // expected. This should be implemented on all platforms, but for now returns
-  // NULL on everything but Views.
-  virtual TestableAutofillDialogView* GetTestableView();
+  // expected.
+  virtual TestableAutofillDialogView* GetTestableView() = 0;
 
   // Called by AutofillDialogSignInDelegate when the sign-in page experiences a
   // resize. |pref_size| is the new preferred size of the sign-in page.
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_browsertest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_browsertest.cc
index 35f6ecb..2598972 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_browsertest.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_browsertest.cc
@@ -24,8 +24,10 @@
 class TestAutofillExternalDelegate : public AutofillExternalDelegate {
  public:
   TestAutofillExternalDelegate(content::WebContents* web_contents,
-                               AutofillManager* autofill_manager)
-      : AutofillExternalDelegate(web_contents, autofill_manager),
+                               AutofillManager* autofill_manager,
+                               AutofillDriver* autofill_driver)
+      : AutofillExternalDelegate(web_contents, autofill_manager,
+                                 autofill_driver),
         popup_hidden_(true) {}
   virtual ~TestAutofillExternalDelegate() {}
 
@@ -75,11 +77,13 @@
     ASSERT_TRUE(web_contents_ != NULL);
     Observe(web_contents_);
 
+    AutofillDriverImpl* driver =
+        AutofillDriverImpl::FromWebContents(web_contents_);
     autofill_external_delegate_.reset(
        new TestAutofillExternalDelegate(
            web_contents_,
-           AutofillDriverImpl::FromWebContents(
-               web_contents_)->autofill_manager()));
+           driver->autofill_manager(),
+           driver));
   }
 
   // Normally the WebContents will automatically delete the delegate, but here
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
index a645863..482d838 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
@@ -33,8 +33,10 @@
 class MockAutofillExternalDelegate : public AutofillExternalDelegate {
  public:
   MockAutofillExternalDelegate(content::WebContents* web_contents,
-                               AutofillManager* autofill_manager)
-      : AutofillExternalDelegate(web_contents, autofill_manager) {}
+                               AutofillManager* autofill_manager,
+                               AutofillDriver* autofill_driver)
+      : AutofillExternalDelegate(web_contents, autofill_manager,
+                                 autofill_driver) {}
   virtual ~MockAutofillExternalDelegate() {}
 
   virtual void DidSelectSuggestion(int identifier) OVERRIDE {}
@@ -167,7 +169,8 @@
     external_delegate_.reset(
         new NiceMock<MockAutofillExternalDelegate>(
             web_contents(),
-            driver->autofill_manager()));
+            driver->autofill_manager(),
+            driver));
 
     autofill_popup_controller_ =
         new testing::NiceMock<TestAutofillPopupController>(
@@ -367,7 +370,7 @@
   AutofillDriverImpl* driver =
       AutofillDriverImpl::FromWebContents(web_contents());
   MockAutofillExternalDelegate delegate(
-      web_contents(), driver->autofill_manager());
+      web_contents(), driver->autofill_manager(), driver);
 
   WeakPtr<AutofillPopupControllerImpl> controller =
       AutofillPopupControllerImpl::GetOrCreate(
@@ -526,7 +529,7 @@
     AutofillDriverImpl* driver =
         AutofillDriverImpl::FromWebContents(web_contents());
     NiceMock<MockAutofillExternalDelegate> external_delegate(
-        web_contents(), driver->autofill_manager());
+        web_contents(), driver->autofill_manager(), driver);
     TestAutofillPopupController* autofill_popup_controller =
         new TestAutofillPopupController(external_delegate.GetWeakPtr(),
                                         element_bounds[i]);
diff --git a/chrome/browser/ui/autofill/data_model_wrapper.cc b/chrome/browser/ui/autofill/data_model_wrapper.cc
index 40a0072..3a251b0 100644
--- a/chrome/browser/ui/autofill/data_model_wrapper.cc
+++ b/chrome/browser/ui/autofill/data_model_wrapper.cc
@@ -119,6 +119,21 @@
   }
 }
 
+void AutofillProfileWrapper::FillFormField(AutofillField* field) const {
+  AutofillFieldType field_type = field->type();
+
+  if (field_type == CREDIT_CARD_NAME) {
+    // Requests for the user's credit card are filled from the billing address,
+    // but the AutofillProfile class doesn't know how to fill credit card
+    // fields. So, temporarily set the type to the corresponding profile type.
+    field->set_heuristic_type(NAME_FULL);
+  }
+
+  AutofillDataModelWrapper::FillFormField(field);
+
+  field->set_heuristic_type(field_type);
+}
+
 // AutofillCreditCardWrapper
 
 AutofillCreditCardWrapper::AutofillCreditCardWrapper(const CreditCard* card)
@@ -146,21 +161,6 @@
   return card_->TypeAndLastFourDigits();
 }
 
-void AutofillCreditCardWrapper::FillFormField(AutofillField* field) const {
-  AutofillFieldType field_type = field->type();
-
-  if (field_type == NAME_FULL) {
-    // Requests for the user's full name are filled from the credit card data,
-    // but the CreditCard class only knows how to fill credit card fields.  So,
-    // temporarily set the type to the corresponding credit card type.
-    field->set_heuristic_type(CREDIT_CARD_NAME);
-  }
-
-  AutofillDataModelWrapper::FillFormField(field);
-
-  field->set_heuristic_type(field_type);
-}
-
 // WalletAddressWrapper
 
 WalletAddressWrapper::WalletAddressWrapper(
diff --git a/chrome/browser/ui/autofill/data_model_wrapper.h b/chrome/browser/ui/autofill/data_model_wrapper.h
index 0e54ff8..8fbcd97 100644
--- a/chrome/browser/ui/autofill/data_model_wrapper.h
+++ b/chrome/browser/ui/autofill/data_model_wrapper.h
@@ -108,7 +108,9 @@
   AutofillProfileWrapper(const AutofillProfile* profile, size_t variant);
   virtual ~AutofillProfileWrapper();
 
+ protected:
   virtual void FillInputs(DetailInputs* inputs) OVERRIDE;
+  virtual void FillFormField(AutofillField* field) const OVERRIDE;
 
  private:
   const AutofillProfile* profile_;
@@ -126,9 +128,6 @@
   virtual gfx::Image GetIcon() OVERRIDE;
   virtual string16 GetDisplayText() OVERRIDE;
 
- protected:
-  virtual void FillFormField(AutofillField* field) const OVERRIDE;
-
  private:
   const CreditCard* card_;
 
diff --git a/chrome/browser/ui/autofill/mock_autofill_dialog_controller.cc b/chrome/browser/ui/autofill/mock_autofill_dialog_controller.cc
index 006fa2b..6ca8614 100644
--- a/chrome/browser/ui/autofill/mock_autofill_dialog_controller.cc
+++ b/chrome/browser/ui/autofill/mock_autofill_dialog_controller.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/ui/autofill/mock_autofill_dialog_controller.h"
+#include "grit/generated_resources.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace autofill {
@@ -10,9 +11,26 @@
 MockAutofillDialogController::MockAutofillDialogController() {
   testing::DefaultValue<const DetailInputs&>::Set(default_inputs_);
   testing::DefaultValue<ui::ComboboxModel*>::Set(NULL);
+  testing::DefaultValue<ValidityData>::Set(ValidityData());
+
+  // SECTION_CC *must* have a CREDIT_CARD_VERIFICATION_CODE field.
+  const DetailInput kCreditCardInputs[] = {
+    { 2, CREDIT_CARD_VERIFICATION_CODE, IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC }
+  };
+  cc_default_inputs_.push_back(kCreditCardInputs[0]);
+  ON_CALL(*this, RequestedFieldsForSection(SECTION_CC))
+      .WillByDefault(testing::ReturnRef(cc_default_inputs_));
+
+  // Activate all sections but CC_BILLING - default for the real
+  // controller implementation, too.
+  ON_CALL(*this, SectionIsActive(testing::_))
+      .WillByDefault(testing::Return(true));
+  ON_CALL(*this, SectionIsActive(SECTION_CC_BILLING))
+      .WillByDefault(testing::Return(false));
 }
 
 MockAutofillDialogController::~MockAutofillDialogController() {
+  testing::DefaultValue<ValidityData>::Clear();
   testing::DefaultValue<ui::ComboboxModel*>::Clear();
   testing::DefaultValue<const DetailInputs&>::Clear();
 }
@@ -57,14 +75,14 @@
   return false;
 }
 
-bool MockAutofillDialogController::ShouldOfferToSaveInChrome() const {
-   return false;
-}
-
 gfx::Image MockAutofillDialogController::AccountChooserImage() {
   return gfx::Image();
 }
 
+bool MockAutofillDialogController::ShouldShowDetailArea() const {
+  return false;
+}
+
 bool MockAutofillDialogController::ShouldShowProgressBar() const {
   return false;
 }
@@ -73,25 +91,20 @@
   return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
 }
 
-bool MockAutofillDialogController::ShouldShowDetailArea() const {
-  return false;
-}
-
 bool MockAutofillDialogController::IsDialogButtonEnabled(
     ui::DialogButton button) const {
   return false;
 }
 
+DialogOverlayState MockAutofillDialogController::GetDialogOverlay() const {
+  return DialogOverlayState();
+}
+
 const std::vector<ui::Range>&
     MockAutofillDialogController::LegalDocumentLinks() {
   return range_;
 }
 
-bool MockAutofillDialogController::SectionIsActive(
-    DialogSection section) const {
-  return false;
-}
-
 string16 MockAutofillDialogController::LabelForSection(
     DialogSection section) const {
   return string16();
@@ -124,13 +137,6 @@
   return string16();
 }
 
-ValidityData MockAutofillDialogController::InputsAreValid(
-     DialogSection section,
-     const DetailOutputMap& inputs,
-     ValidationType validation_type) {
-  return ValidityData();
-}
-
 void MockAutofillDialogController::UserEditedOrActivatedInput(
     DialogSection section,
     const DetailInput* input,
@@ -171,6 +177,8 @@
 void MockAutofillDialogController::LegalDocumentLinkClicked(
     const ui::Range& range) {}
 
+void MockAutofillDialogController::OverlayButtonPressed() {}
+
 void MockAutofillDialogController::OnCancel() {}
 
 void MockAutofillDialogController::OnAccept() {}
diff --git a/chrome/browser/ui/autofill/mock_autofill_dialog_controller.h b/chrome/browser/ui/autofill/mock_autofill_dialog_controller.h
index 6da9ce8..61a25d3 100644
--- a/chrome/browser/ui/autofill/mock_autofill_dialog_controller.h
+++ b/chrome/browser/ui/autofill/mock_autofill_dialog_controller.h
@@ -25,15 +25,16 @@
   virtual string16 LegalDocumentsText() OVERRIDE;
   virtual DialogSignedInState SignedInState() const OVERRIDE;
   virtual bool ShouldShowSpinner() const OVERRIDE;
-  virtual bool ShouldOfferToSaveInChrome() const OVERRIDE;
+  MOCK_CONST_METHOD0(ShouldOfferToSaveInChrome, bool());
   MOCK_METHOD0(MenuModelForAccountChooser, ui::MenuModel*());
   virtual gfx::Image AccountChooserImage() OVERRIDE;
   virtual bool ShouldShowProgressBar() const OVERRIDE;
   virtual int GetDialogButtons() const OVERRIDE;
   virtual bool ShouldShowDetailArea() const OVERRIDE;
   virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE;
+  virtual DialogOverlayState GetDialogOverlay() const OVERRIDE;
   virtual const std::vector<ui::Range>& LegalDocumentLinks() OVERRIDE;
-  virtual bool SectionIsActive(DialogSection section) const OVERRIDE;
+  MOCK_CONST_METHOD1(SectionIsActive, bool(DialogSection));
   MOCK_CONST_METHOD1(RequestedFieldsForSection,
                      const DetailInputs&(DialogSection));
   MOCK_METHOD1(ComboboxModelForAutofillType,
@@ -50,10 +51,9 @@
       DialogSection section,
       AutofillFieldType type,
       const string16& value) OVERRIDE;
-  virtual ValidityData InputsAreValid(
-      DialogSection section,
-      const DetailOutputMap& inputs,
-      ValidationType validation_type) OVERRIDE;
+  MOCK_METHOD3(InputsAreValid, ValidityData(DialogSection,
+                                            const DetailOutputMap&,
+                                            ValidationType));
   virtual void UserEditedOrActivatedInput(DialogSection section,
                                           const DetailInput* input,
                                           gfx::NativeView parent_view,
@@ -79,6 +79,7 @@
                                                 bool checked) OVERRIDE;
 
   virtual void LegalDocumentLinkClicked(const ui::Range& range) OVERRIDE;
+  virtual void OverlayButtonPressed() OVERRIDE;
   virtual void OnCancel() OVERRIDE;
   virtual void OnAccept() OVERRIDE;
 
@@ -86,6 +87,7 @@
   virtual content::WebContents* web_contents() OVERRIDE;
  private:
   DetailInputs default_inputs_;
+  DetailInputs cc_default_inputs_;  // Default inputs for SECTION_CC.
   std::vector<ui::Range> range_;
 };
 
diff --git a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc
index c66528c..ffb4546 100644
--- a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc
+++ b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc
@@ -38,7 +38,11 @@
 }
 
 TabAutofillManagerDelegate::~TabAutofillManagerDelegate() {
-  HideAutofillPopup();
+  // NOTE: It is too late to clean up the autofill popup; that cleanup process
+  // requires that the WebContents instance still be valid and it is not at
+  // this point (in particular, the WebContentsImpl destructor has already
+  // finished running and we are now in the base class destructor).
+  DCHECK(!popup_controller_);
 }
 
 PersonalDataManager* TabAutofillManagerDelegate::GetPersonalDataManager() {
@@ -94,9 +98,9 @@
 void TabAutofillManagerDelegate::ShowAutocheckoutBubble(
     const gfx::RectF& bounding_box,
     bool is_google_user,
-    const base::Callback<void(bool)>& callback) {
+    const base::Callback<void(AutocheckoutBubbleState)>& callback) {
 #if !defined(TOOLKIT_VIEWS)
-  callback.Run(false);
+  callback.Run(AUTOCHECKOUT_BUBBLE_CANCELED);
   NOTIMPLEMENTED();
 #else
   HideAutocheckoutBubble();
@@ -205,4 +209,9 @@
   HideAutocheckoutBubble();
 }
 
+void TabAutofillManagerDelegate::WebContentsDestroyed(
+    content::WebContents* web_contents) {
+  HideAutofillPopup();
+}
+
 }  // namespace autofill
diff --git a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h
index bb118bc..446721f 100644
--- a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h
+++ b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h
@@ -11,6 +11,7 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_types.h"
 #include "components/autofill/content/browser/autocheckout_steps.h"
+#include "components/autofill/core/browser/autocheckout_bubble_state.h"
 #include "components/autofill/core/browser/autofill_manager_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
@@ -52,7 +53,7 @@
   virtual void ShowAutocheckoutBubble(
       const gfx::RectF& bounds,
       bool is_google_user,
-      const base::Callback<void(bool)>& callback) OVERRIDE;
+      const base::Callback<void(AutocheckoutBubbleState)>& callback) OVERRIDE;
   virtual void HideAutocheckoutBubble() OVERRIDE;
   virtual void ShowRequestAutocompleteDialog(
       const FormData& form,
@@ -80,6 +81,8 @@
   virtual void DidNavigateMainFrame(
       const content::LoadCommittedDetails& details,
       const content::FrameNavigateParams& params) OVERRIDE;
+  virtual void WebContentsDestroyed(
+      content::WebContents* web_contents) OVERRIDE;
 
   // Exposed for testing.
   AutofillDialogControllerImpl* GetDialogControllerForTesting() {
diff --git a/chrome/browser/ui/autofill/test_autofill_credit_card_bubble.cc b/chrome/browser/ui/autofill/test_autofill_credit_card_bubble.cc
new file mode 100644
index 0000000..00e81f0
--- /dev/null
+++ b/chrome/browser/ui/autofill/test_autofill_credit_card_bubble.cc
@@ -0,0 +1,34 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/autofill/test_autofill_credit_card_bubble.h"
+
+namespace autofill {
+
+TestAutofillCreditCardBubble::TestAutofillCreditCardBubble(
+    const base::WeakPtr<AutofillCreditCardBubbleController>& controller)
+    : showing_(false),
+      weak_ptr_factory_(this) {}
+
+TestAutofillCreditCardBubble::~TestAutofillCreditCardBubble() {}
+
+// AutofillCreditCardBubble:
+void TestAutofillCreditCardBubble::Show() {
+  showing_ = true;
+}
+
+void TestAutofillCreditCardBubble::Hide() {
+  showing_ = false;
+}
+
+bool TestAutofillCreditCardBubble::IsHiding() const {
+  return !showing_;
+}
+
+base::WeakPtr<TestAutofillCreditCardBubble>
+    TestAutofillCreditCardBubble::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/autofill/test_autofill_credit_card_bubble.h b/chrome/browser/ui/autofill/test_autofill_credit_card_bubble.h
new file mode 100644
index 0000000..491eac1
--- /dev/null
+++ b/chrome/browser/ui/autofill/test_autofill_credit_card_bubble.h
@@ -0,0 +1,49 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_AUTOFILL_TEST_AUTOFILL_CREDIT_CARD_BUBBLE_H_
+#define CHROME_BROWSER_UI_AUTOFILL_TEST_AUTOFILL_CREDIT_CARD_BUBBLE_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble.h"
+
+namespace autofill {
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// TestAutofillCreditCardBubble
+//
+//  A cross-platform, headless bubble that doesn't conflict with other top-level
+//  widgets/windows.
+////////////////////////////////////////////////////////////////////////////////
+class TestAutofillCreditCardBubble : public AutofillCreditCardBubble {
+ public:
+  explicit TestAutofillCreditCardBubble(
+      const base::WeakPtr<AutofillCreditCardBubbleController>& controller);
+
+  virtual ~TestAutofillCreditCardBubble();
+
+  // AutofillCreditCardBubble:
+  virtual void Show() OVERRIDE;
+  virtual void Hide() OVERRIDE;
+  virtual bool IsHiding() const OVERRIDE;
+
+  base::WeakPtr<TestAutofillCreditCardBubble> GetWeakPtr();
+
+  bool showing() const { return showing_; }
+
+ private:
+  // Whether the bubble is currently showing or not.
+  bool showing_;
+
+  base::WeakPtrFactory<TestAutofillCreditCardBubble> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestAutofillCreditCardBubble);
+};
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_AUTOFILL_TEST_AUTOFILL_CREDIT_CARD_BUBBLE_H_
diff --git a/chrome/browser/ui/autofill/testable_autofill_dialog_view.h b/chrome/browser/ui/autofill/testable_autofill_dialog_view.h
index 7020e81..c8238a7 100644
--- a/chrome/browser/ui/autofill/testable_autofill_dialog_view.h
+++ b/chrome/browser/ui/autofill/testable_autofill_dialog_view.h
@@ -11,7 +11,7 @@
 // to assist in unit testing.
 class TestableAutofillDialogView {
  public:
-  virtual ~TestableAutofillDialogView();
+  virtual ~TestableAutofillDialogView() {}
 
   // Simulates the user pressing 'Submit' to accept the dialog.
   virtual void SubmitForTesting() = 0;
diff --git a/chrome/browser/ui/blocked_content/blocked_content_tab_helper.cc b/chrome/browser/ui/blocked_content/blocked_content_tab_helper.cc
index 844f210..f10c5d5 100644
--- a/chrome/browser/ui/blocked_content/blocked_content_tab_helper.cc
+++ b/chrome/browser/ui/blocked_content/blocked_content_tab_helper.cc
@@ -5,11 +5,11 @@
 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
 
 #include "base/auto_reset.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/blocked_content/blocked_content_container.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/navigation_entry.h"
diff --git a/chrome/browser/popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
similarity index 73%
rename from chrome/browser/popup_blocker_browsertest.cc
rename to chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
index cfb3190..5ee815c 100644
--- a/chrome/browser/popup_blocker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -8,6 +8,7 @@
 #include "base/path_service.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
 #include "chrome/browser/autocomplete/autocomplete_result.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/profiles/profile.h"
@@ -21,11 +22,11 @@
 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
 #include "chrome/browser/ui/omnibox/omnibox_view.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
@@ -39,6 +40,33 @@
 static const base::FilePath::CharType* kTestDir =
     FILE_PATH_LITERAL("popup_blocker");
 
+// Counts the number of RenderViewHosts created.
+class CountRenderViewHosts : public content::NotificationObserver {
+ public:
+  CountRenderViewHosts()
+      : count_(0) {
+    registrar_.Add(this,
+                   content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
+                   content::NotificationService::AllSources());
+  }
+  virtual ~CountRenderViewHosts() {}
+
+  int GetRenderViewHostCreatedCount() const { return count_; }
+
+ private:
+  virtual void Observe(int type,
+                       const content::NotificationSource& source,
+                       const content::NotificationDetails& details) OVERRIDE {
+    count_++;
+  }
+
+  content::NotificationRegistrar registrar_;
+
+  int count_;
+
+  DISALLOW_COPY_AND_ASSIGN(CountRenderViewHosts);
+};
+
 class PopupBlockerBrowserTest : public InProcessBrowserTest {
  public:
   PopupBlockerBrowserTest() {}
@@ -182,4 +210,49 @@
   EXPECT_EQ(ASCIIToUTF16(search_string), model->CurrentMatch(NULL).contents);
 }
 
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, BlockWebContentsCreation) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableBetterPopupBlocking);
+
+  CountRenderViewHosts counter;
+
+  ui_test_utils::NavigateToURL(browser(), GetTestURL());
+
+  // If the popup blocker blocked the blank post, there should be only one tab.
+  EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
+                                        browser()->host_desktop_type()));
+  EXPECT_EQ(1, browser()->tab_strip_model()->count());
+  WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  EXPECT_EQ(GetTestURL(), web_contents->GetURL());
+
+  // And no new RVH created.
+  EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount());
+}
+
+IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
+                       PopupBlockedFakeClickOnAnchorNoTarget) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableBetterPopupBlocking);
+
+  GURL url(ui_test_utils::GetTestUrl(
+      base::FilePath(kTestDir),
+      base::FilePath(FILE_PATH_LITERAL("popup-fake-click-on-anchor2.html"))));
+
+  CountRenderViewHosts counter;
+
+  ui_test_utils::NavigateToURL(browser(), url);
+
+  // If the popup blocker blocked the blank post, there should be only one tab.
+  EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
+                                        browser()->host_desktop_type()));
+  EXPECT_EQ(1, browser()->tab_strip_model()->count());
+  WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  EXPECT_EQ(url, web_contents->GetURL());
+
+  // And no new RVH created.
+  EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount());
+}
+
 }  // namespace
diff --git a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
index 71217ed..1998fec 100644
--- a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
@@ -10,13 +10,13 @@
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/host_desktop.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/bookmarks/bookmark_prompt_controller.h b/chrome/browser/ui/bookmarks/bookmark_prompt_controller.h
index 7b0d2a4..20e8226 100644
--- a/chrome/browser/ui/bookmarks/bookmark_prompt_controller.h
+++ b/chrome/browser/ui/bookmarks/bookmark_prompt_controller.h
@@ -13,7 +13,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Browser;
 class PrefService;
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 5513be6..aa2e18f 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -37,6 +37,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_shutdown.h"
 #include "chrome/browser/character_encoding.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chrome_page_zoom.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
@@ -137,7 +138,6 @@
 #include "chrome/browser/upgrade_detector.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/custom_handlers/protocol_handler.h"
 #include "chrome/common/extensions/background_info.h"
@@ -443,7 +443,6 @@
   }
 
   fullscreen_controller_.reset(new FullscreenController(this));
-  search_model_->AddObserver(this);
 }
 
 Browser::~Browser() {
@@ -451,7 +450,6 @@
   if (!browser_shutdown::ShuttingDownWithoutClosingBrowsers())
     DCHECK(tab_strip_model_->empty());
 
-  search_model_->RemoveObserver(this);
   tab_strip_model_->RemoveObserver(this);
 
   // Destroy the BrowserCommandController before removing the browser, so that
@@ -847,7 +845,6 @@
       InfoBarService::FromWebContents(web_contents);
   if (!infobar_service)
     return;
-
   SimpleAlertInfoBarDelegate::Create(
       infobar_service, InfoBarDelegate::kNoIconID,
       l10n_util::GetStringUTF16(IDS_JS_OUT_OF_MEMORY_PROMPT), true);
@@ -1273,7 +1270,31 @@
   nav_params.source_contents = source;
   nav_params.tabstrip_add_types = TabStripModel::ADD_NONE;
   nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
-  nav_params.user_gesture = true;
+  nav_params.user_gesture = params.user_gesture;
+
+  BlockedContentTabHelper* blocked_content_helper = NULL;
+  if (source)
+    blocked_content_helper = BlockedContentTabHelper::FromWebContents(source);
+
+  if (CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableBetterPopupBlocking) &&
+      blocked_content_helper) {
+
+    if (blocked_content_helper->all_contents_blocked()) {
+      // TODO(jochen): store information about the blocked pop-up in the
+      // helper.
+      return NULL;
+    }
+
+    if ((params.disposition == NEW_POPUP ||
+         params.disposition == NEW_FOREGROUND_TAB ||
+         params.disposition == NEW_BACKGROUND_TAB) &&
+        !params.user_gesture && !CommandLine::ForCurrentProcess()->HasSwitch(
+                                    switches::kDisablePopupBlocking)) {
+      return NULL;
+    }
+  }
+
   chrome::Navigate(&nav_params);
 
   return nav_params.target_contents;
@@ -1466,13 +1487,37 @@
     int route_id,
     WindowContainerType window_container_type,
     const string16& frame_name,
-    const GURL& target_url) {
+    const GURL& target_url,
+    WindowOpenDisposition disposition,
+    bool user_gesture) {
   if (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
     // If a BackgroundContents is created, suppress the normal WebContents.
     return !MaybeCreateBackgroundContents(
         route_id, web_contents, frame_name, target_url);
   }
 
+  if (!CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableBetterPopupBlocking)) {
+    return true;
+  }
+
+  BlockedContentTabHelper* blocked_content_helper =
+      BlockedContentTabHelper::FromWebContents(web_contents);
+  if (!blocked_content_helper)
+    return true;
+
+  if (blocked_content_helper->all_contents_blocked()) {
+    // TODO(jochen): store information about the blocked pop-up in the helper.
+    return false;
+  }
+
+  if ((disposition == NEW_POPUP || disposition == NEW_FOREGROUND_TAB ||
+       disposition == NEW_BACKGROUND_TAB) && !user_gesture &&
+      !CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kDisablePopupBlocking)) {
+    return false;
+  }
+
   return true;
 }
 
@@ -1812,12 +1857,6 @@
   }
 }
 
-void Browser::ModelChanged(const SearchModel::State& old_state,
-                           const SearchModel::State& new_state) {
-  if (SearchModel::ShouldChangeTopBarsVisibility(old_state, new_state))
-    UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // Browser, Command and state updating (private):
 
@@ -2126,27 +2165,6 @@
       state = BookmarkBar::HIDDEN;
   }
 
-  // Bookmark bar may need to be hidden for |SEARCH_SUGGESTIONS| and
-  // |SEARCH_RESULTS| modes as per SearchBox API or Instant overlay or if it's
-  // detached when origin is not |NTP|.
-  // TODO(sail): remove conditional MACOSX flag when bookmark bar is actually
-  // hidden on mac; for now, mac keeps the bookmark bar shown but changes its
-  // z-order to stack it below contents.
-#if !defined(OS_MACOSX)
-  if (search_model_->mode().is_search() &&
-      ((state == BookmarkBar::DETACHED &&
-        !search_model_->mode().is_origin_ntp()) ||
-      !search_model_->top_bars_visible())) {
-    state = BookmarkBar::HIDDEN;
-  }
-#else
-  // TODO(sail): remove this when the above block is enabled for mac.
-  if (state == BookmarkBar::DETACHED && search_model_->mode().is_search() &&
-      !search_model_->mode().is_origin_ntp()) {
-    state = BookmarkBar::HIDDEN;
-  }
-#endif  // !defined(OS_MACOSX)
-
   if (state == bookmark_bar_state_)
     return;
 
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index 62f6ba6..af74dbb 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -26,7 +26,6 @@
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h"
 #include "chrome/browser/ui/host_desktop.h"
-#include "chrome/browser/ui/search/search_model_observer.h"
 #include "chrome/browser/ui/search_engines/search_engine_tab_helper_delegate.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper_delegate.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
@@ -61,7 +60,6 @@
 class StatusBubble;
 class TabStripModel;
 class TabStripModelDelegate;
-struct SearchMode;
 struct WebApplicationInfo;
 
 namespace chrome {
@@ -105,8 +103,7 @@
                 public ZoomObserver,
                 public content::PageNavigator,
                 public content::NotificationObserver,
-                public ui::SelectFileDialog::Listener,
-                public SearchModelObserver {
+                public ui::SelectFileDialog::Listener {
  public:
   // SessionService::WindowType mirrors these values.  If you add to this
   // enum, look at SessionService::WindowType to see if it needs to be
@@ -568,7 +565,9 @@
       int route_id,
       WindowContainerType window_container_type,
       const string16& frame_name,
-      const GURL& target_url) OVERRIDE;
+      const GURL& target_url,
+      WindowOpenDisposition disposition,
+      bool user_action) OVERRIDE;
   virtual void WebContentsCreated(content::WebContents* source_contents,
                                   int64 source_frame_id,
                                   const string16& frame_name,
@@ -672,10 +671,6 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
-  // Overridden from SearchModelObserver:
-  virtual void ModelChanged(const SearchModel::State& old_state,
-                            const SearchModel::State& new_state) OVERRIDE;
-
   // Command and state updating ///////////////////////////////////////////////
 
   // Handle changes to kDevTools preference.
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index e8c2787..4603fbd 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -12,6 +12,7 @@
 #include "base/sys_info.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/chrome_content_browser_client.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/defaults.h"
@@ -44,7 +45,6 @@
 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
 #include "chrome/browser/ui/tabs/pinned_tab_codec.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index b38cf57..1e214b7 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -7,6 +7,7 @@
 #include "base/prefs/pref_service.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/ui/sync/sync_promo_ui.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_utils.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/profiling.h"
 #include "content/public/browser/native_web_keyboard_event.h"
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index d233e28..a68fd91 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_remover.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chrome_page_zoom.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -53,7 +54,6 @@
 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
 #include "chrome/browser/upgrade_detector.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/pref_names.h"
@@ -704,13 +704,10 @@
 void ShowWebsiteSettings(Browser* browser,
                          content::WebContents* web_contents,
                          const GURL& url,
-                         const SSLStatus& ssl,
-                         bool show_history) {
-  Profile* profile = Profile::FromBrowserContext(
-      web_contents->GetBrowserContext());
-
+                         const SSLStatus& ssl) {
   browser->window()->ShowWebsiteSettings(
-      profile, web_contents, url, ssl, show_history);
+      Profile::FromBrowserContext(web_contents->GetBrowserContext()),
+      web_contents, url, ssl);
 }
 
 void ShowChromeToMobileBubble(Browser* browser) {
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h
index b64b212..bea7ec3 100644
--- a/chrome/browser/ui/browser_commands.h
+++ b/chrome/browser/ui/browser_commands.h
@@ -104,8 +104,7 @@
 void ShowWebsiteSettings(Browser* browser,
                          content::WebContents* web_contents,
                          const GURL& url,
-                         const content::SSLStatus& ssl,
-                         bool show_history);
+                         const content::SSLStatus& ssl);
 void ShowChromeToMobileBubble(Browser* browser);
 void Print(Browser* browser);
 bool CanPrint(const Browser* browser);
diff --git a/chrome/browser/ui/browser_commands_mac.cc b/chrome/browser/ui/browser_commands_mac.cc
index e7304de..3a18758 100644
--- a/chrome/browser/ui/browser_commands_mac.cc
+++ b/chrome/browser/ui/browser_commands_mac.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/browser_commands_mac.h"
 
 #include "base/mac/mac_util.h"
+#include "chrome/browser/fullscreen.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
@@ -12,7 +13,7 @@
 namespace chrome {
 
 void ToggleFullscreenWithChromeOrFallback(Browser* browser) {
-  if (base::mac::IsOSLionOrLater())
+  if (chrome::mac::SupportsSystemFullscreen())
     browser->fullscreen_controller()->ToggleFullscreenWithChrome();
   else
     ToggleFullscreenMode(browser);
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc
index 303d4c2..e5c39c5 100644
--- a/chrome/browser/ui/browser_focus_uitest.cc
+++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "build/build_config.h"
-
 #include "base/bind.h"
 #include "base/file_util.h"
 #include "base/format_macros.h"
@@ -12,6 +10,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
@@ -23,7 +22,6 @@
 #include "chrome/browser/ui/omnibox/omnibox_view.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/view_ids.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -39,12 +37,6 @@
 #include "content/public/test/browser_test_utils.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 
-#if defined(TOOLKIT_VIEWS)
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "ui/views/focus/focus_manager.h"
-#include "ui/views/view.h"
-#endif
-
 #if defined(OS_WIN)
 #include <windows.h>
 #include <Psapi.h>
@@ -259,48 +251,6 @@
   ui_test_utils::HideNativeWindow(window);
   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(window));
   ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX));
-
-  // The rest of this test does not make sense on Linux because the behavior
-  // of Activate() is not well defined and can vary by window manager.
-#if defined(OS_WIN)
-  // Open a new browser window.
-  Browser* browser2 =
-      new Browser(Browser::CreateParams(browser()->profile(),
-                                        browser()->host_desktop_type()));
-  ASSERT_TRUE(browser2);
-  chrome::AddBlankTabAt(browser2, -1, true);
-  browser2->window()->Show();
-  ui_test_utils::NavigateToURL(browser2, url);
-
-  gfx::NativeWindow window2 = browser2->window()->GetNativeWindow();
-  BrowserView* browser_view2 =
-      BrowserView::GetBrowserViewForBrowser(browser2);
-  ASSERT_TRUE(browser_view2);
-  const views::Widget* widget2 =
-      views::Widget::GetWidgetForNativeWindow(window2);
-  ASSERT_TRUE(widget2);
-  const views::FocusManager* focus_manager2 = widget2->GetFocusManager();
-  ASSERT_TRUE(focus_manager2);
-  EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
-            focus_manager2->GetFocusedView());
-
-  // Switch to the 1st browser window, focus should still be on the location
-  // bar and the second browser should have nothing focused.
-  browser()->window()->Activate();
-  ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX));
-  EXPECT_EQ(NULL, focus_manager2->GetFocusedView());
-
-  // Switch back to the second browser, focus should still be on the page.
-  browser2->window()->Activate();
-  views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
-  ASSERT_TRUE(widget);
-  EXPECT_EQ(NULL, widget->GetFocusManager()->GetFocusedView());
-  EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
-            focus_manager2->GetFocusedView());
-
-  // Close the 2nd browser to avoid a DCHECK().
-  browser_view2->Close();
-#endif
 }
 
 // Tabs remember focus.
diff --git a/chrome/browser/ui/browser_instant_controller.cc b/chrome/browser/ui/browser_instant_controller.cc
index 6203f51..b1454e8 100644
--- a/chrome/browser/ui/browser_instant_controller.cc
+++ b/chrome/browser/ui/browser_instant_controller.cc
@@ -39,17 +39,8 @@
     : browser_(browser),
       instant_(this, chrome::IsInstantExtendedAPIEnabled()),
       instant_unload_handler_(browser) {
-
-  // TODO(sreeram): Perhaps this can be removed, if field trial info is
-  // available before we need to register the pref.
-  chrome::SetInstantExtendedPrefDefault(profile());
-
   profile_pref_registrar_.Init(profile()->GetPrefs());
   profile_pref_registrar_.Add(
-      prefs::kSearchInstantEnabled,
-      base::Bind(&BrowserInstantController::ResetInstant,
-                 base::Unretained(this)));
-  profile_pref_registrar_.Add(
       prefs::kSearchSuggestEnabled,
       base::Bind(&BrowserInstantController::ResetInstant,
                  base::Unretained(this)));
@@ -197,16 +188,13 @@
   instant_.SetOmniboxBounds(bounds);
 }
 
-void BrowserInstantController::UpdateLocationBar() {
-  browser_->window()->UpdateToolbar(GetActiveWebContents(), false);
-}
-
 void BrowserInstantController::ToggleVoiceSearch() {
   instant_.ToggleVoiceSearch();
 }
 
 void BrowserInstantController::ResetInstant(const std::string& pref_name) {
-  instant_.ReloadStaleNTP();
+  if (chrome::ShouldPreloadInstantNTP(profile()))
+    instant_.ReloadStaleNTP();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/browser_instant_controller.h b/chrome/browser/ui/browser_instant_controller.h
index 0f9414f..6f2a025 100644
--- a/chrome/browser/ui/browser_instant_controller.h
+++ b/chrome/browser/ui/browser_instant_controller.h
@@ -79,10 +79,6 @@
   // Sets the stored omnibox bounds.
   void SetOmniboxBounds(const gfx::Rect& bounds);
 
-  // Updates the location bar to reflect the active page contents Instant
-  // support state.
-  void UpdateLocationBar();
-
   // Notifies |instant_| to toggle voice search.
   void ToggleVoiceSearch();
 
diff --git a/chrome/browser/ui/browser_list.cc b/chrome/browser/ui/browser_list.cc
index b11c0ec..66968ae 100644
--- a/chrome/browser/ui/browser_list.cc
+++ b/chrome/browser/ui/browser_list.cc
@@ -9,6 +9,7 @@
 #include "base/logging.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/host_desktop.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/user_metrics.h"
 
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc
index 3942de5..f71625e 100644
--- a/chrome/browser/ui/browser_navigator.cc
+++ b/chrome/browser/ui/browser_navigator.cc
@@ -11,6 +11,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_about_handler.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/google/google_url_tracker.h"
@@ -30,7 +31,6 @@
 #include "chrome/browser/ui/status_bubble.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/browser_navigator.h b/chrome/browser/ui/browser_navigator.h
index f6e3cc0..5fbfb8b 100644
--- a/chrome/browser/ui/browser_navigator.h
+++ b/chrome/browser/ui/browser_navigator.h
@@ -13,9 +13,9 @@
 #include "content/public/browser/page_navigator.h"
 #include "content/public/common/page_transition_types.h"
 #include "content/public/common/referrer.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/window_open_disposition.h"
 #include "ui/gfx/rect.h"
+#include "url/gurl.h"
 
 class Browser;
 class Profile;
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index 1d3dfa1..d4381b8 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -272,8 +272,7 @@
   virtual void ShowWebsiteSettings(Profile* profile,
                                    content::WebContents* web_contents,
                                    const GURL& url,
-                                   const content::SSLStatus& ssl,
-                                   bool show_history) = 0;
+                                   const content::SSLStatus& ssl) = 0;
 
   // Shows the app menu (for accessibility).
   virtual void ShowAppMenu() = 0;
diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc
index c2a4e3c..2a09364 100644
--- a/chrome/browser/ui/chrome_pages.cc
+++ b/chrome/browser/ui/chrome_pages.cc
@@ -21,8 +21,8 @@
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/user_metrics.h"
 #include "google_apis/gaia/gaia_urls.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/url_util.h"
+#include "url/gurl.h"
 
 #if defined(OS_WIN)
 #include "chrome/browser/enumerate_modules_model_win.h"
diff --git a/chrome/browser/ui/cocoa/OWNERS b/chrome/browser/ui/cocoa/OWNERS
index 475b396..188cb91 100644
--- a/chrome/browser/ui/cocoa/OWNERS
+++ b/chrome/browser/ui/cocoa/OWNERS
@@ -13,4 +13,3 @@
 stuartmorgan@chromium.org
 thakis@chromium.org
 thomasvl@chromium.org
-viettrungluu@chromium.org
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm
index a9ca820..cc9ff82 100644
--- a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm
+++ b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm
@@ -11,7 +11,7 @@
 #import "chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h"
 #import "chrome/browser/ui/cocoa/applescript/constants_applescript.h"
 #include "chrome/browser/ui/cocoa/applescript/error_applescript.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 @implementation BookmarkFolderAppleScript
 
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_unittest.mm b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_unittest.mm
index 04bac0e..e2a0979 100644
--- a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_unittest.mm
+++ b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_unittest.mm
@@ -11,10 +11,10 @@
 #import "chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h"
 #import "chrome/browser/ui/cocoa/applescript/constants_applescript.h"
 #import "chrome/browser/ui/cocoa/applescript/error_applescript.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
+#include "url/gurl.h"
 
 typedef BookmarkAppleScriptTest BookmarkFolderAppleScriptTest;
 
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript_unittest.mm b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript_unittest.mm
index 8e581f2..07c5a1f 100644
--- a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript_unittest.mm
+++ b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript_unittest.mm
@@ -9,10 +9,10 @@
 #import "chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.h"
 #import "chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h"
 #import "chrome/browser/ui/cocoa/applescript/error_applescript.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
+#include "url/gurl.h"
 
 typedef BookmarkAppleScriptTest BookmarkItemAppleScriptTest;
 
diff --git a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm
index e2a3539..4bc6df9 100644
--- a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm
+++ b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm
@@ -21,7 +21,7 @@
 #include "content/public/browser/save_page_type.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::NavigationController;
 using content::NavigationEntry;
diff --git a/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm b/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm
index f627622..9ebba04 100644
--- a/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm
+++ b/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm
@@ -14,9 +14,9 @@
 #import "chrome/browser/ui/cocoa/applescript/tab_applescript.h"
 #import "chrome/browser/ui/cocoa/applescript/window_applescript.h"
 #include "chrome/test/base/in_process_browser_test.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
+#include "url/gurl.h"
 
 typedef InProcessBrowserTest WindowAppleScriptTest;
 
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_account_chooser.mm b/chrome/browser/ui/cocoa/autofill/autofill_account_chooser.mm
index 35111d2..ff07b74 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_account_chooser.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_account_chooser.mm
@@ -9,10 +9,10 @@
 #include "chrome/browser/ui/chrome_style.h"
 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h"
 #import "chrome/browser/ui/cocoa/autofill/down_arrow_popup_menu_cell.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
 #import "chrome/browser/ui/cocoa/menu_button.h"
 #include "grit/ui_resources.h"
 #include "skia/ext/skia_utils_mac.h"
+#import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #include "ui/base/models/menu_model.h"
 #include "ui/base/resource/resource_bundle.h"
 
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_account_chooser_unittest.mm b/chrome/browser/ui/cocoa/autofill/autofill_account_chooser_unittest.mm
index d4717cb..5843db4 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_account_chooser_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_account_chooser_unittest.mm
@@ -8,10 +8,10 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/autofill/mock_autofill_dialog_controller.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
 #import "chrome/browser/ui/cocoa/menu_button.h"
 #include "testing/gtest_mac.h"
 #include "testing/platform_test.h"
+#import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #include "ui/base/models/simple_menu_model.h"
 #import "ui/base/test/ui_cocoa_test_helper.h"
 
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_details_container.h b/chrome/browser/ui/cocoa/autofill/autofill_details_container.h
index aa99561..5748080 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_details_container.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_details_container.h
@@ -10,18 +10,26 @@
 #include "base/mac/scoped_nsobject.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_types.h"
 #import "chrome/browser/ui/cocoa/autofill/autofill_layout.h"
+#import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h"
+
 
 namespace autofill {
 class AutofillDialogController;
 }
 
-@class AutofillSectionContainer;
+@class InfoBubbleView;
 
 // UI controller for details for current payment instrument.
-@interface AutofillDetailsContainer : NSViewController<AutofillLayout> {
+@interface AutofillDetailsContainer
+    : NSViewController<AutofillLayout,
+                       AutofillValidationDisplay> {
  @private
-  base::scoped_nsobject<NSMutableArray> details_;   // The individual detail
-                                                    // sections.
+  // The individual detail sections.
+  base::scoped_nsobject<NSMutableArray> details_;
+
+  // An info bubble to display validation errors.
+  base::scoped_nsobject<InfoBubbleView> infoBubble_;
+
   autofill::AutofillDialogController* controller_;  // Not owned.
 }
 
@@ -34,6 +42,9 @@
 // Called when the controller-maintained suggestions model has changed.
 - (void)modelChanged;
 
+// Validate every visible details section.
+- (BOOL)validate;
+
 @end
 
 #endif  // CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_DETAILS_CONTAINER_H_
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
index 0defb1f..f2ce365 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
@@ -6,8 +6,23 @@
 
 #include <algorithm>
 
+#include "base/mac/foundation_util.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_controller.h"
 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h"
+#import "chrome/browser/ui/cocoa/info_bubble_view.h"
+#include "skia/ext/skia_utils_mac.h"
+
+namespace {
+
+// Imported constant from Views version. TODO(groby): Share.
+SkColor const kWarningColor = 0xffde4932;  // SkColorSetRGB(0xde, 0x49, 0x32);
+
+}  // namespace
+
+@interface AutofillDetailsContainer ()
+// Compute infobubble origin based on anchor/view.
+- (NSPoint)originFromAnchorView:(NSView*)view;
+@end
 
 @implementation AutofillDetailsContainer
 
@@ -22,6 +37,7 @@
   base::scoped_nsobject<AutofillSectionContainer> sectionContainer(
       [[AutofillSectionContainer alloc] initWithController:controller_
                                                 forSection:section]);
+  [sectionContainer setValidationDelegate:self];
   [details_ addObject:sectionContainer];
 }
 
@@ -38,11 +54,26 @@
   for (AutofillSectionContainer* container in details_.get())
     [[self view] addSubview:[container view]];
 
+  infoBubble_.reset([[InfoBubbleView alloc] initWithFrame:NSZeroRect]);
+  [infoBubble_ setBackgroundColor:
+      gfx::SkColorToCalibratedNSColor(kWarningColor)];
+  [infoBubble_ setArrowLocation:info_bubble::kTopRight];
+  [infoBubble_ setAlignment:info_bubble::kAlignArrowToAnchor];
+  [infoBubble_ setHidden:YES];
+
+  base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]);
+  [label setEditable:NO];
+  [label setBordered:NO];
+  [label setDrawsBackground:NO];
+  [infoBubble_ addSubview:label];
+
+  [[self view] addSubview:infoBubble_];
+
   [self performLayout];
 }
 
 - (NSSize)preferredSize {
-  NSSize size = NSMakeSize(0, 0);
+  NSSize size = NSZeroSize;
   for (AutofillSectionContainer* container in details_.get()) {
     NSSize containerSize = [container preferredSize];
     size.height += containerSize.height;
@@ -78,4 +109,58 @@
     [details modelChanged];
 }
 
+- (BOOL)validate {
+  bool allValid = true;
+  for (AutofillSectionContainer* details in details_.get()) {
+    if (![[details view] isHidden])
+      allValid = [details validateFor:autofill::VALIDATE_FINAL] && allValid;
+  }
+  return allValid;
+}
+
+// TODO(groby): Unify with BaseBubbleController's originFromAnchor:view:.
+- (NSPoint)originFromAnchorView:(NSView*)view {
+  NSView* bubbleParent = [infoBubble_ superview];
+  NSPoint origin = [[view superview] convertPoint:[view frame].origin
+                                           toView:nil];
+  NSRect bubbleFrame =
+      [bubbleParent convertRect:[infoBubble_ frame] toView:nil];
+
+  NSSize offsets = NSMakeSize(info_bubble::kBubbleArrowXOffset +
+                              info_bubble::kBubbleArrowWidth / 2.0, 0);
+  offsets = [view convertSize:offsets toView:nil];
+  origin.x -= NSWidth(bubbleFrame) - offsets.width;
+
+  origin.y -= NSHeight(bubbleFrame);
+  return [bubbleParent convertPoint:origin fromView:nil];
+}
+
+- (void)updateMessageForField:(NSControl<AutofillInputField>*)field {
+  // Ignore fields that are not first responder. Testing this is a bit
+  // convoluted, since for NSTextFields with firstResponder status, the
+  // firstResponder is a subview of the NSTextField, not the field itself.
+  NSView* firstResponderView =
+      base::mac::ObjCCast<NSView>([[field window] firstResponder]);
+  if (![firstResponderView isDescendantOf:field]) {
+    return;
+  }
+
+  if ([field invalid]) {
+    const CGFloat labelInset = 3.0;
+
+    NSTextField* label = [[infoBubble_ subviews] objectAtIndex:0];
+    [label setStringValue:[field validityMessage]];
+    [label sizeToFit];
+    NSSize bubbleSize = [label frame].size;
+    bubbleSize.width += 2 * labelInset;
+    bubbleSize.height += 2 * labelInset + info_bubble::kBubbleArrowHeight;
+    [infoBubble_ setFrameSize:bubbleSize];
+    [label setFrameOrigin:NSMakePoint(labelInset, labelInset)];
+    [infoBubble_ setFrameOrigin:[self originFromAnchorView:field]];
+    [infoBubble_ setHidden:NO];
+  } else {
+    [infoBubble_ setHidden:YES];
+  }
+}
+
 @end
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_details_container_unittest.mm b/chrome/browser/ui/cocoa/autofill/autofill_details_container_unittest.mm
index 7cbc178..e003752 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_details_container_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_details_container_unittest.mm
@@ -5,6 +5,8 @@
 #import "chrome/browser/ui/cocoa/autofill/autofill_details_container.h"
 
 #include "base/mac/scoped_nsobject.h"
+#include "base/strings/utf_string_conversions.h"
+#import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h"
 #include "chrome/browser/ui/autofill/mock_autofill_dialog_controller.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
@@ -34,3 +36,32 @@
   EXPECT_GT(NSHeight([[container_ view] frame]), 0);
   EXPECT_GT(NSWidth([[container_ view] frame]), 0);
 }
+
+TEST_F(AutofillDetailsContainerTest, ValidateAllSections) {
+  using namespace autofill;
+  using namespace testing;
+
+  DetailOutputMap output;
+  ValidityData validity;
+
+  EXPECT_CALL(controller_, InputsAreValid(_, _, VALIDATE_FINAL))
+      .Times(4)
+      .WillOnce(Return(validity))
+      .WillOnce(Return(validity))
+      .WillOnce(Return(validity))
+      .WillOnce(Return(validity));
+
+  EXPECT_TRUE([container_ validate]);
+
+  ValidityData invalid;
+  invalid[ADDRESS_HOME_ZIP] = ASCIIToUTF16("Some error message");
+
+  EXPECT_CALL(controller_, InputsAreValid(_, _, VALIDATE_FINAL))
+      .Times(4)
+      .WillOnce(Return(validity))
+      .WillOnce(Return(validity))
+      .WillOnce(Return(invalid))
+      .WillOnce(Return(validity));
+
+  EXPECT_FALSE([container_ validate]);
+}
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h
index 73fc8bf..688535c 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h
@@ -9,8 +9,10 @@
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_types.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_view.h"
+#include "chrome/browser/ui/autofill/testable_autofill_dialog_view.h"
 #import "chrome/browser/ui/cocoa/autofill/autofill_layout.h"
 #include "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
+#include "ui/gfx/size.h"
 
 namespace content {
   class NavigationController;
@@ -28,6 +30,7 @@
 namespace autofill {
 
 class AutofillDialogCocoa : public AutofillDialogView,
+                            public TestableAutofillDialogView,
                             public ConstrainedWindowMacDelegate {
  public:
   explicit AutofillDialogCocoa(AutofillDialogController* controller);
@@ -54,8 +57,23 @@
   virtual void UpdateProgressBar(double value) OVERRIDE;
   virtual void ModelChanged() OVERRIDE;
   virtual void OnSignInResize(const gfx::Size& pref_size) OVERRIDE;
+  virtual TestableAutofillDialogView* GetTestableView() OVERRIDE;
 
-  // ConstrainedWindowMacDelegate implementation.
+  // TestableAutofillDialogView implementation:
+  // TODO(groby): Create a separate class to implement the testable interface:
+  // http://crbug.com/256864
+  virtual void SubmitForTesting() OVERRIDE;
+  virtual void CancelForTesting() OVERRIDE;
+  virtual string16 GetTextContentsOfInput(const DetailInput& input) OVERRIDE;
+  virtual void SetTextContentsOfInput(const DetailInput& input,
+                                      const string16& contents) OVERRIDE;
+  virtual void SetTextContentsOfSuggestionInput(
+      DialogSection section,
+      const base::string16& text) OVERRIDE;
+  virtual void ActivateInput(const DetailInput& input) OVERRIDE;
+  virtual gfx::Size GetSize() const OVERRIDE;
+
+  // ConstrainedWindowMacDelegate implementation:
   virtual void OnConstrainedWindowClosed(
       ConstrainedWindowMac* window) OVERRIDE;
 
@@ -64,7 +82,6 @@
   void PerformClose();
 
  private:
-
   scoped_ptr<ConstrainedWindowMac> constrained_window_;
   base::scoped_nsobject<AutofillDialogWindowController> sheet_controller_;
 
@@ -100,11 +117,13 @@
 - (IBAction)cancel:(id)sender;
 
 // Forwarding AutofillDialogView calls.
-- (void)updateAccountChooser;
+- (void)hide;
 - (void)updateNotificationArea;
+- (void)updateAccountChooser;
 - (void)updateSection:(autofill::DialogSection)section;
 - (void)getInputs:(autofill::DetailOutputMap*)outputs
        forSection:(autofill::DialogSection)section;
+- (BOOL)saveDetailsLocally;
 - (content::NavigationController*)showSignIn;
 - (void)hideSignIn;
 - (void)modelChanged;
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
index 7d8e3e2..6ac323b 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
@@ -56,8 +56,12 @@
       new ConstrainedWindowMac(this, controller_->web_contents(), sheet));
 }
 
-// Closes the sheet and ends the modal loop. Triggers cleanup sequence.
 void AutofillDialogCocoa::Hide() {
+  [sheet_controller_ hide];
+}
+
+// Closes the sheet and ends the modal loop. Triggers cleanup sequence.
+void AutofillDialogCocoa::PerformClose() {
   constrained_window_->CloseWebContentsModalDialog();
 }
 
@@ -99,7 +103,7 @@
 }
 
 bool AutofillDialogCocoa::SaveDetailsLocally() {
-  return false;
+  return [sheet_controller_ saveDetailsLocally];
 }
 
 const content::NavigationController* AutofillDialogCocoa::ShowSignIn() {
@@ -120,6 +124,51 @@
   // TODO(groby): Implement Mac support for this.
 }
 
+TestableAutofillDialogView* AutofillDialogCocoa::GetTestableView() {
+  return this;
+}
+
+void AutofillDialogCocoa::SubmitForTesting() {
+  [sheet_controller_ accept:nil];
+}
+
+void AutofillDialogCocoa::CancelForTesting() {
+  [sheet_controller_ cancel:nil];
+}
+
+string16 AutofillDialogCocoa::GetTextContentsOfInput(const DetailInput& input) {
+  for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) {
+    DialogSection section = static_cast<DialogSection>(i);
+    DetailOutputMap contents;
+    [sheet_controller_ getInputs:&contents forSection:section];
+    DetailOutputMap::const_iterator it = contents.find(&input);
+    if (it != contents.end())
+      return it->second;
+  }
+
+  NOTREACHED();
+  return string16();
+}
+
+void AutofillDialogCocoa::SetTextContentsOfInput(const DetailInput& input,
+                                                 const string16& contents) {
+  // TODO(groby): Implement Mac support for this: http://crbug.com/256864
+}
+
+void AutofillDialogCocoa::SetTextContentsOfSuggestionInput(
+    DialogSection section,
+    const base::string16& text) {
+  // TODO(groby): Implement Mac support for this: http://crbug.com/256864
+}
+
+void AutofillDialogCocoa::ActivateInput(const DetailInput& input) {
+  // TODO(groby): Implement Mac support for this: http://crbug.com/256864
+}
+
+gfx::Size AutofillDialogCocoa::GetSize() const {
+  return gfx::Size(NSSizeToCGSize([[sheet_controller_ window] frame].size));
+}
+
 void AutofillDialogCocoa::OnConstrainedWindowClosed(
     ConstrainedWindowMac* window) {
   constrained_window_.reset();
@@ -180,7 +229,7 @@
     [mainContainer_ setAnchorView:[[accountChooser_ subviews] objectAtIndex:1]];
 
     NSRect contentRect = clientRect;
-    contentRect.origin = NSMakePoint(0, 0);
+    contentRect.origin = NSZeroPoint;
     contentRect.size.width += 2 * chrome_style::kHorizontalPadding;
     contentRect.size.height += NSHeight(headerRect) +
                                chrome_style::kClientBottomPadding +
@@ -236,14 +285,22 @@
 }
 
 - (IBAction)accept:(id)sender {
-  // TODO(groby): Validation goes here.
-  autofillDialog_->controller()->OnAccept();
+  if ([mainContainer_ validate])
+    autofillDialog_->controller()->OnAccept();
 }
 
 - (IBAction)cancel:(id)sender {
-  // TODO(groby): Validation goes here.
   autofillDialog_->controller()->OnCancel();
-  autofillDialog_->Hide();
+  autofillDialog_->PerformClose();
+}
+
+- (void)hide {
+  autofillDialog_->controller()->OnCancel();
+  autofillDialog_->PerformClose();
+}
+
+- (void)updateNotificationArea {
+  [mainContainer_ updateNotificationArea];
 }
 
 - (void)updateAccountChooser {
@@ -251,10 +308,6 @@
   [mainContainer_ updateLegalDocuments];
 }
 
-- (void)updateNotificationArea {
-  [mainContainer_ updateNotificationArea];
-}
-
 - (void)updateSection:(autofill::DialogSection)section {
   [[mainContainer_ sectionForId:section] update];
 }
@@ -273,6 +326,10 @@
   [[mainContainer_ sectionForId:section] getInputs:output];
 }
 
+- (BOOL)saveDetailsLocally {
+  return [mainContainer_ saveDetailsLocally];
+}
+
 - (void)hideSignIn {
   [[signInContainer_ view] setHidden:YES];
   [[mainContainer_ view] setHidden:NO];
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_input_field.h b/chrome/browser/ui/cocoa/autofill/autofill_input_field.h
index ea1e43d..4f8484f 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_input_field.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_input_field.h
@@ -5,13 +5,51 @@
 #ifndef CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_INPUT_FIELD_H_
 #define CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_INPUT_FIELD_H_
 
-// Protocol to allow access to any given input field in an Autofill dialog, no
-// matter what the underlying control is.
-@protocol AutofillInputField
+#import <Cocoa/Cocoa.h>
+
+@protocol AutofillInputField;
+
+// Access to cell state for autofill input controls.
+@protocol AutofillInputCell<NSObject>
 
 @property(nonatomic, assign) BOOL invalid;
 @property(nonatomic, copy) NSString* fieldValue;
 
 @end
 
+// Delegate to handle editing events on the AutofillInputFields.
+@protocol AutofillInputDelegate<NSObject>
+
+// An input field just became first responder.
+- (void)fieldBecameFirstResponder:(NSControl<AutofillInputField>*)field;
+
+// The user made changes to the value in the field. This is only invoked by
+// AutofillTextFields.
+- (void)didChange:(id)sender;
+
+// The user is done with this field. This indicates a loss of firstResponder
+// status.
+- (void)didEndEditing:(id)sender;
+
+@end
+
+// Protocol to allow access to any given input field in an Autofill dialog, no
+// matter what the underlying control is. All controls act as proxies for their
+// cells, so inherits from AutofillInputCell.
+@protocol AutofillInputField
+
+@property(nonatomic, assign) id<AutofillInputDelegate> delegate;
+
+@property(nonatomic, copy) NSString* fieldValue;
+
+// Indicates if the field is valid. Empty string or nil indicates a valid
+// field, everything else is a message to be displayed to the user when the
+// field has firstResponder status.
+@property(nonatomic, copy) NSString* validityMessage;
+
+// A reflection of the state of the validityMessage described above.
+@property(nonatomic, readonly) BOOL invalid;
+
+@end
+
 #endif  // CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_INPUT_FIELD_H_
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_main_container.h b/chrome/browser/ui/cocoa/autofill/autofill_main_container.h
index 7f6a92e..9b5e123 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_main_container.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_main_container.h
@@ -29,6 +29,7 @@
                                                     NSTextViewDelegate> {
  @private
   base::scoped_nsobject<GTMWidthBasedTweaker> buttonContainer_;
+  base::scoped_nsobject<NSButton> saveInChromeCheckbox_;
   base::scoped_nsobject<AutofillDetailsContainer> detailsContainer_;
   base::scoped_nsobject<HyperlinkTextView> legalDocumentsView_;
   base::scoped_nsobject<AutofillNotificationContainer> notificationContainer_;
@@ -58,12 +59,26 @@
 // Called when the controller-maintained suggestions model has changed.
 - (void)modelChanged;
 
+// Get status of "Save in Chrome" checkbox.
+- (BOOL)saveDetailsLocally;
+
 // Called when the legal documents text might need to be refreshed.
 - (void)updateLegalDocuments;
 
 // Called when there are changes to the notification area.
 - (void)updateNotificationArea;
 
+// Validates form input data.
+- (BOOL)validate;
+
+@end
+
+
+// AutofillMainContainer helper functions, for testing purposes only.
+@interface AutofillMainContainer (Testing)
+
+@property(readonly, nonatomic) NSButton* saveInChromeCheckboxForTesting;
+
 @end
 
 #endif  // CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_MAIN_CONTAINER_H_
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm
index 9d9449c..4a9492a 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm
@@ -50,6 +50,15 @@
 
   [self layoutButtons];
 
+  // Set up "Save in Chrome" checkbox.
+  saveInChromeCheckbox_.reset([[NSButton alloc] initWithFrame:NSZeroRect]);
+  [saveInChromeCheckbox_ setButtonType:NSSwitchButton];
+  [saveInChromeCheckbox_ setTitle:
+      base::SysUTF16ToNSString(controller_->SaveLocallyText())];
+  [saveInChromeCheckbox_ setState:NSOnState];
+  [saveInChromeCheckbox_ sizeToFit];
+  [[self view] addSubview:saveInChromeCheckbox_];
+
   detailsContainer_.reset(
       [[AutofillDetailsContainer alloc] initWithController:controller_]);
   NSSize frameSize = [[detailsContainer_ view] frame].size;
@@ -122,6 +131,10 @@
   buttonFrame.origin.y = currentY;
   [buttonContainer_ setFrameOrigin:buttonFrame.origin];
 
+  NSRect checkboxFrame = [saveInChromeCheckbox_ frame];
+  checkboxFrame.origin.y = NSMidY(buttonFrame) - NSHeight(checkboxFrame) / 2.0;
+  [saveInChromeCheckbox_ setFrameOrigin:checkboxFrame.origin];
+
   [detailsContainer_ performLayout];
   NSRect containerFrame = [[detailsContainer_ view] frame];
   containerFrame.origin.y = NSMaxY(buttonFrame);
@@ -208,9 +221,14 @@
 }
 
 - (void)modelChanged {
+  [saveInChromeCheckbox_ setHidden:!controller_->ShouldOfferToSaveInChrome()];
   [detailsContainer_ modelChanged];
 }
 
+- (BOOL)saveDetailsLocally {
+  return [saveInChromeCheckbox_ state] == NSOnState;
+}
+
 - (void)updateLegalDocuments {
   NSString* text = base::SysUTF16ToNSString(controller_->LegalDocumentsText());
 
@@ -249,4 +267,17 @@
   [notificationContainer_ setAnchorView:anchorView];
 }
 
+- (BOOL)validate {
+  return [detailsContainer_ validate];
+}
+
+@end
+
+
+@implementation AutofillMainContainer (Testing)
+
+- (NSButton*)saveInChromeCheckboxForTesting {
+  return saveInChromeCheckbox_.get();
+}
+
 @end
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_main_container_unittest.mm b/chrome/browser/ui/cocoa/autofill/autofill_main_container_unittest.mm
index 5eeaf1d..66ca163 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_main_container_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_main_container_unittest.mm
@@ -35,10 +35,11 @@
   bool hasButtons = false;
   bool hasTextView = false;
   bool hasDetailsContainer = false;
+  bool hasCheckbox = false;
   int hasNotificationContainer = false;
 
   // Should have account chooser, button strip, and details section.
-  EXPECT_EQ(4U, [[[container_ view] subviews] count]);
+  EXPECT_EQ(5U, [[[container_ view] subviews] count]);
   for (NSView* view in [[container_ view] subviews]) {
     NSArray* subviews = [view subviews];
     if ([subviews count] == 2) {
@@ -50,9 +51,12 @@
     } else if ([view isKindOfClass:[NSTextView class]]) {
       hasTextView = true;
     } else if ([subviews count] > 0 &&
-        [[subviews objectAtIndex:0] isKindOfClass:
-            [AutofillSectionView class]]) {
+               [[subviews objectAtIndex:0] isKindOfClass:
+                   [AutofillSectionView class]]) {
       hasDetailsContainer = true;
+    } else if ([view isKindOfClass:[NSButton class]] &&
+               view == [container_ saveInChromeCheckboxForTesting]) {
+      hasCheckbox = true;
     } else {
       // Assume by default this is the notification area view.
       // There is no way to easily verify that with more detail.
@@ -64,4 +68,27 @@
   EXPECT_TRUE(hasTextView);
   EXPECT_TRUE(hasDetailsContainer);
   EXPECT_TRUE(hasNotificationContainer);
+  EXPECT_TRUE(hasCheckbox);
+}
+
+TEST_F(AutofillMainContainerTest, SaveDetailsLocallyDefaultsToTrue) {
+  EXPECT_TRUE([container_ saveDetailsLocally]);
+}
+
+TEST_F(AutofillMainContainerTest, SaveInChromeCheckboxVisibility) {
+  using namespace testing;
+
+  // Tests that the checkbox is only visible if the controller allows it.
+  EXPECT_CALL(controller_, ShouldOfferToSaveInChrome()).Times(2)
+      .WillOnce(Return(false))
+      .WillOnce(Return(true));
+
+  NSButton* checkbox = [container_ saveInChromeCheckboxForTesting];
+  ASSERT_TRUE(checkbox);
+
+  EXPECT_FALSE([checkbox isHidden]);
+  [container_ modelChanged];
+  EXPECT_TRUE([checkbox isHidden]);
+  [container_ modelChanged];
+  EXPECT_FALSE([checkbox isHidden]);
 }
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button.h b/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button.h
index 8068169..6e42267 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button.h
@@ -7,12 +7,18 @@
 
 #import <Cocoa/Cocoa.h>
 
+#include "base/mac/scoped_nsobject.h"
 #include "chrome/browser/ui/cocoa/autofill/autofill_input_field.h"
 
-@interface AutofillPopUpButton : NSPopUpButton<AutofillInputField>
+@interface AutofillPopUpButton : NSPopUpButton<AutofillInputField> {
+ @private
+  id<AutofillInputDelegate> delegate_;
+  base::scoped_nsobject<NSString> validityMessage_;
+}
+
 @end
 
-@interface AutofillPopUpCell : NSPopUpButtonCell<AutofillInputField> {
+@interface AutofillPopUpCell : NSPopUpButtonCell<AutofillInputCell> {
  @private
   BOOL invalid_;
 }
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button.mm b/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button.mm
index b7d81a5..43f0398 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button.mm
@@ -9,18 +9,24 @@
 #include "base/mac/scoped_nsobject.h"
 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
 
+@interface AutofillPopUpButton ()
+- (void)didSelectItem:(id)sender;
+@end
+
 @implementation AutofillPopUpButton
 
+@synthesize delegate = delegate_;
+
 + (Class)cellClass {
   return [AutofillPopUpCell class];
 }
 
-- (BOOL)invalid {
-  return [[self cell] invalid];
-}
-
-- (void)setInvalid:(BOOL)invalid {
-  [[self cell] setInvalid:invalid];
+- (id)initWithFrame:(NSRect)frame pullsDown:(BOOL)pullsDown{
+  if (self = [super initWithFrame:frame pullsDown:pullsDown]) {
+    [self setTarget:self];
+    [self setAction:@selector(didSelectItem:)];
+  }
+  return self;
 }
 
 - (NSString*)fieldValue {
@@ -31,6 +37,25 @@
   [[self cell] setFieldValue:fieldValue];
 }
 
+- (NSString*)validityMessage {
+  return validityMessage_;
+}
+
+- (void)setValidityMessage:(NSString*)validityMessage {
+  validityMessage_.reset([validityMessage copy]);
+  [[self cell] setInvalid:[self invalid]];
+  [self setNeedsDisplay:YES];
+}
+
+- (BOOL)invalid {
+  return [validityMessage_ length] != 0;
+}
+
+- (void)didSelectItem:(id)sender {
+  if (delegate_)
+    [delegate_ didEndEditing:self];
+}
+
 @end
 
 
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button_unittest.mm b/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button_unittest.mm
index 9310992..04fd67e 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_pop_up_button_unittest.mm
@@ -28,8 +28,8 @@
 
 // Test invalid, mostly to ensure nothing leaks or crashes.
 TEST_F(AutofillPopUpButtonTest, DisplayWithInvalid) {
-  [button_ setInvalid:YES];
+  [button_ setValidityMessage:nil];
   [button_ display];
-  [button_ setInvalid:NO];
+  [button_ setValidityMessage:@"Something is rotten in the state of Denmark"];
   [button_ display];
 }
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_section_container.h b/chrome/browser/ui/cocoa/autofill/autofill_section_container.h
index 62ff41b..9330e68 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_section_container.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_section_container.h
@@ -8,7 +8,9 @@
 #import <Cocoa/Cocoa.h>
 
 #include "base/mac/scoped_nsobject.h"
+#include "base/memory/scoped_ptr.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_types.h"
+#import "chrome/browser/ui/cocoa/autofill/autofill_input_field.h"
 #import "chrome/browser/ui/cocoa/autofill/autofill_layout.h"
 
 namespace autofill {
@@ -21,18 +23,34 @@
 @class MenuButton;
 @class MenuController;
 
+// Delegate to handle display of validation messages.
+@protocol AutofillValidationDisplay
+
+// Updates the validation message for a given field.
+- (void)updateMessageForField:(NSControl<AutofillInputField>*)field;
+
+@end
+
+
 // View controller for a section of the payment details. Contains a label
 // describing the section as well as associated inputs and controls. Built
 // dynamically based on data retrieved from AutofillDialogController.
 @interface AutofillSectionContainer :
-    NSViewController<AutofillLayout> {
+    NSViewController<AutofillLayout, AutofillInputDelegate> {
  @private
   base::scoped_nsobject<LayoutView> inputs_;
   base::scoped_nsobject<MenuButton> suggestButton_;
   base::scoped_nsobject<AutofillSuggestionContainer> suggestContainer_;
   base::scoped_nsobject<NSTextField> label_;
-  base::scoped_nsobject<AutofillSectionView> view_;  // The view for the
-                                                     // container.
+
+  // The view for the container.
+  base::scoped_nsobject<AutofillSectionView> view_;
+
+  // List of weak pointers, which constitute unique field IDs.
+  std::vector<const autofill::DetailInput*> detailInputs_;
+
+  // A delegate to handle display of validation messages. Not owned.
+  id<AutofillValidationDisplay> validationDelegate_;
 
   base::scoped_nsobject<MenuController> menuController_;
   autofill::DialogSection section_;
@@ -40,6 +58,7 @@
 }
 
 @property(readonly, nonatomic) autofill::DialogSection section;
+@property(assign, nonatomic) id<AutofillValidationDisplay> validationDelegate;
 
 // Designated initializer. Queries |controller| for the list of desired input
 // fields for |section|.
@@ -55,10 +74,13 @@
 // Called when the contents of a section have changed.
 - (void)update;
 
+// Validate this section. Validation rules depend on |validationType|.
+- (BOOL)validateFor:(autofill::ValidationType)validationType;
+
 @end
 
 @interface AutofillSectionContainer (ForTesting)
-- (NSControl*)getField:(autofill::AutofillFieldType)type;
+- (NSControl<AutofillInputField>*)getField:(autofill::AutofillFieldType)type;
 @end
 
 #endif  // CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_SECTION_CONTAINER_H_
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm
index 7c48db9..077a916 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm
@@ -4,6 +4,7 @@
 
 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h"
 
+#include "base/mac/foundation_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_controller.h"
@@ -65,7 +66,20 @@
 
 }
 
-@interface AutofillSectionContainer (Internal)
+@interface AutofillSectionContainer ()
+
+// Convenience method to retrieve a field type via the control's tag.
+- (autofill::AutofillFieldType)fieldTypeForControl:(NSControl*)control;
+
+// Find the DetailInput* associated with a field type.
+- (const autofill::DetailInput*)detailInputForType:
+    (autofill::AutofillFieldType)type;
+
+// Takes an NSArray of controls and builds a DetailOutputMap from them.
+// Translates between Cocoa code and controller, essentially.
+// All controls must inherit from NSControl and conform to AutofillInputView.
+- (void)fillDetailOutputs:(autofill::DetailOutputMap*)outputs
+             fromControls:(NSArray*)controls;
 
 // Create properly styled label for section. Autoreleased.
 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText;
@@ -81,6 +95,7 @@
 @implementation AutofillSectionContainer
 
 @synthesize section = section_;
+@synthesize validationDelegate = validationDelegate_;
 
 - (id)initWithController:(autofill::AutofillDialogController*)controller
               forSection:(autofill::DialogSection)section {
@@ -92,14 +107,7 @@
 }
 
 - (void)getInputs:(autofill::DetailOutputMap*)output {
-  for (NSControl<AutofillInputField>* input in [inputs_ subviews]) {
-    const autofill::DetailInput* detailInput =
-        reinterpret_cast<autofill::DetailInput*>([input tag]);
-    DCHECK(detailInput);
-    NSString* value = [input fieldValue];
-    output->insert(
-        std::make_pair(detailInput,base::SysNSStringToUTF16(value)));
-  }
+  [self fillDetailOutputs:output fromControls:[inputs_ subviews]];
 }
 
 - (void)modelChanged {
@@ -117,6 +125,9 @@
 
   // TODO(groby): "Save in Chrome" handling.
 
+  if (![[self view] isHidden])
+    [self validateFor:autofill::VALIDATE_EDIT];
+
   // Always request re-layout on state change.
   id controller = [[view_ window] windowController];
   if ([controller respondsToSelector:@selector(requestRelayout)])
@@ -124,6 +135,13 @@
 }
 
 - (void)loadView {
+  // Keep a list of weak pointers to DetailInputs.
+  const autofill::DetailInputs& inputs =
+      controller_->RequestedFieldsForSection(section_);
+  for (size_t i = 0; i < inputs.size(); ++i) {
+    detailInputs_.push_back(&(inputs[i]));
+  }
+
   inputs_.reset([[self makeInputControls] retain]);
   string16 labelText = controller_->LabelForSection(section_);
   label_.reset([[self makeDetailSectionLabel:
@@ -132,16 +150,25 @@
   suggestButton_.reset([[self makeSuggestionButton] retain]);
   suggestContainer_.reset([[AutofillSuggestionContainer alloc] init]);
 
-  [self modelChanged];
   view_.reset([[AutofillSectionView alloc] initWithFrame:NSZeroRect]);
   [self setView:view_];
   [[self view] setSubviews:
       @[label_, inputs_, [suggestContainer_ view], suggestButton_]];
+
+  if (section_ == autofill::SECTION_CC) {
+    // SECTION_CC *MUST* have a CREDIT_CARD_VERIFICATION_CODE input.
+    DCHECK([self detailInputForType:autofill::CREDIT_CARD_VERIFICATION_CODE]);
+    [[suggestContainer_ inputField] setTag:
+        autofill::CREDIT_CARD_VERIFICATION_CODE];
+    [[suggestContainer_ inputField] setDelegate:self];
+  }
+
+  [self modelChanged];
 }
 
 - (NSSize)preferredSize {
   if ([view_ isHidden])
-    return NSMakeSize(0, 0);
+    return NSZeroSize;
 
   NSSize labelSize = [label_ frame].size;  // Assumes sizeToFit was called.
   CGFloat controlHeight = [inputs_ preferredHeightForWidth:kDetailsWidth];
@@ -202,6 +229,147 @@
   [view_ setFrameSize:viewFrame.size];
 }
 
+
+- (void)fieldBecameFirstResponder:(NSControl<AutofillInputField>*)field {
+  [validationDelegate_ updateMessageForField:field];
+}
+
+- (void)didChange:(id)sender {
+  // TODO(groby): This is part of TextfieldEditedOrActivated. Combine once that
+  // is implemented.
+  AutofillTextField* textfield =
+      base::mac::ObjCCastStrict<AutofillTextField>(sender);
+  autofill::AutofillFieldType type = [self fieldTypeForControl:textfield];
+  string16 fieldValue = base::SysNSStringToUTF16([textfield fieldValue]);
+
+  // If the field is marked as invalid, check if the text is now valid.
+  // Many fields (i.e. CC#) are invalid for most of the duration of editing,
+  // so flagging them as invalid prematurely is not helpful. However,
+  // correcting a minor mistake (i.e. a wrong CC digit) should immediately
+  // result in validation - positive user feedback.
+  if ([textfield invalid]) {
+    string16 message = controller_->InputValidityMessage(section_,
+                                                         type,
+                                                         fieldValue);
+    [textfield setValidityMessage:base::SysUTF16ToNSString(message)];
+    [validationDelegate_ updateMessageForField:textfield];
+
+    // If the field transitioned from invalid to valid, re-validate the group,
+    // since inter-field checks become meaningful with valid fields.
+    if (![textfield invalid])
+      [self validateFor:autofill::VALIDATE_EDIT];
+  }
+
+  // Update the icon for the textfield.
+  gfx::Image icon = controller_->IconForField(type, fieldValue);
+  if (!icon.IsEmpty()) {
+    [[textfield cell] setIcon:icon.ToNSImage()];
+  }
+}
+
+- (void)didEndEditing:(id)sender {
+  [self validateFor:autofill::VALIDATE_EDIT];
+}
+
+- (void)updateSuggestionState {
+  const autofill::SuggestionState& suggestionState =
+      controller_->SuggestionStateForSection(section_);
+  bool showSuggestions = !suggestionState.text.empty();
+
+  [[suggestContainer_ view] setHidden:!showSuggestions];
+  [inputs_ setHidden:showSuggestions];
+
+  string16 line1;
+  string16 line2;
+  BreakSuggestionText(suggestionState.text, &line1, &line2);
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  gfx::Font font = rb.GetFont(ui::ResourceBundle::BaseFont).DeriveFont(
+      0, suggestionState.text_style);
+  [suggestContainer_ setSuggestionText:base::SysUTF16ToNSString(line1)
+                                 line2:base::SysUTF16ToNSString(line2)
+                              withFont:font.GetNativeFont()];
+  [suggestContainer_ setIcon:suggestionState.icon.AsNSImage()];
+  if (!suggestionState.extra_text.empty()) {
+    NSString* extraText =
+        base::SysUTF16ToNSString(suggestionState.extra_text);
+    NSImage* extraIcon = suggestionState.extra_icon.AsNSImage();
+    [suggestContainer_ showInputField:extraText withIcon:extraIcon];
+  }
+  [view_ setShouldHighlightOnHover:showSuggestions];
+  [view_ setHidden:!controller_->SectionIsActive(section_)];
+}
+
+- (void)update {
+  // TODO(groby): Will need to update input fields/support clobbering.
+  // cf. AutofillDialogViews::UpdateSectionImpl.
+  [self modelChanged];
+}
+
+- (void)editLinkClicked {
+  controller_->EditClickedForSection(section_);
+}
+
+- (NSString*)editLinkTitle {
+  return base::SysUTF16ToNSString(controller_->EditSuggestionText());
+}
+
+- (BOOL)validateFor:(autofill::ValidationType)validationType {
+  DCHECK(![[self view] isHidden]);
+
+  NSArray* fields = nil;
+  if (![inputs_ isHidden]) {
+    fields = [inputs_ subviews];
+  } else if (section_ == autofill::SECTION_CC) {
+    fields = @[[suggestContainer_ inputField]];
+  }
+
+  autofill::DetailOutputMap detailOutputs;
+  [self fillDetailOutputs:&detailOutputs fromControls:fields];
+  autofill::ValidityData invalidInputs = controller_->InputsAreValid(
+      section_, detailOutputs, validationType);
+
+  for (NSControl<AutofillInputField>* input in fields) {
+    const autofill::AutofillFieldType type = [self fieldTypeForControl:input];
+    if (invalidInputs.count(type))
+      [input setValidityMessage:base::SysUTF16ToNSString(invalidInputs[type])];
+    else
+      [input setValidityMessage:@""];
+    [validationDelegate_ updateMessageForField:input];
+  }
+
+  return invalidInputs.empty();
+}
+
+#pragma mark Internal API for AutofillSectionContainer.
+
+- (autofill::AutofillFieldType)fieldTypeForControl:(NSControl*)control {
+  DCHECK([control tag]);
+  return static_cast<autofill::AutofillFieldType>([control tag]);
+}
+
+- (const autofill::DetailInput*)detailInputForType:
+    (autofill::AutofillFieldType)type {
+  for (size_t i = 0; i < detailInputs_.size(); ++i) {
+    if (detailInputs_[i]->type == type)
+      return detailInputs_[i];
+  }
+  NOTREACHED();
+  return NULL;
+}
+
+- (void)fillDetailOutputs:(autofill::DetailOutputMap*)outputs
+             fromControls:(NSArray*)controls {
+  for (NSControl<AutofillInputField>* input in controls) {
+    DCHECK([input isKindOfClass:[NSControl class]]);
+    DCHECK([input conformsToProtocol:@protocol(AutofillInputField)]);
+    autofill::AutofillFieldType fieldType = [self fieldTypeForControl:input];
+    DCHECK([self detailInputForType:fieldType]);
+    NSString* value = [input fieldValue];
+    outputs->insert(std::make_pair([self detailInputForType:fieldType],
+                                   base::SysNSStringToUTF16(value)));
+  }
+}
+
 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText {
   base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]);
   [label setFont:
@@ -246,23 +414,19 @@
 // TODO(estade): we should be using Chrome-style constrained window padding
 // values.
 - (LayoutView*)makeInputControls {
-  const autofill::DetailInputs& inputs =
-      controller_->RequestedFieldsForSection(section_);
-
   base::scoped_nsobject<LayoutView> view([[LayoutView alloc] init]);
   [view setLayoutManager:
       scoped_ptr<SimpleGridLayout>(new SimpleGridLayout(view))];
   SimpleGridLayout* layout = [view layoutManager];
 
-  for (autofill::DetailInputs::const_iterator it = inputs.begin();
-       it != inputs.end(); ++it) {
-    const autofill::DetailInput& input = *it;
+  for (size_t i = 0; i < detailInputs_.size(); ++i) {
+    const autofill::DetailInput& input = *detailInputs_[i];
     int kColumnSetId = input.row_id;
     ColumnSet* column_set = layout->GetColumnSet(kColumnSetId);
     if (!column_set) {
       // Create a new column set and row.
       column_set = layout->AddColumnSet(kColumnSetId);
-      if (it != inputs.begin())
+      if (i != 0)
         layout->AddPaddingRow(kRelatedControlVerticalSpacing);
       layout->StartRow(0, kColumnSetId);
     } else {
@@ -297,69 +461,22 @@
       control.reset(field.release());
     }
     [control setFieldValue:base::SysUTF16ToNSString(input.initial_value)];
-    [control setInvalid:YES];
     [control sizeToFit];
-    [control setTag:reinterpret_cast<NSInteger>(&input)];
+    [control setTag:input.type];
+    [control setDelegate:self];
     layout->AddView(control);
   }
 
   return view.autorelease();
 }
 
-- (void)updateSuggestionState {
-  const autofill::SuggestionState& suggestionState =
-      controller_->SuggestionStateForSection(section_);
-  bool showSuggestions = !suggestionState.text.empty();
-
-  [[suggestContainer_ view] setHidden:!showSuggestions];
-  [inputs_ setHidden:showSuggestions];
-
-  string16 line1, line2;
-  BreakSuggestionText(suggestionState.text, &line1, &line2);
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  gfx::Font font = rb.GetFont(ui::ResourceBundle::BaseFont).DeriveFont(
-      0, suggestionState.text_style);
-  [suggestContainer_ setSuggestionText:base::SysUTF16ToNSString(line1)
-                                 line2:base::SysUTF16ToNSString(line2)
-                              withFont:font.GetNativeFont()];
-  [suggestContainer_ setIcon:suggestionState.icon.AsNSImage()];
-  if (!suggestionState.extra_text.empty()) {
-    NSString* extraText =
-        base::SysUTF16ToNSString(suggestionState.extra_text);
-    NSImage* extraIcon = suggestionState.extra_icon.AsNSImage();
-    [suggestContainer_ showTextfield:extraText withIcon:extraIcon];
-  }
-  [view_ setShouldHighlightOnHover:showSuggestions];
-  [view_ setHidden:!controller_->SectionIsActive(section_)];
-}
-
-- (void)update {
-  // TODO(groby): Will need to update input fields/support clobbering.
-  // cf. AutofillDialogViews::UpdateSectionImpl.
-  [self modelChanged];
-}
-
-- (void)editLinkClicked {
-  controller_->EditClickedForSection(section_);
-}
-
-- (NSString*)editLinkTitle {
-  return base::SysUTF16ToNSString(controller_->EditSuggestionText());
-}
-
 @end
 
+
 @implementation AutofillSectionContainer (ForTesting)
 
 - (NSControl*)getField:(autofill::AutofillFieldType)type {
-  for (NSControl* control in [inputs_ subviews]) {
-    const autofill::DetailInput* detailInput =
-        reinterpret_cast<autofill::DetailInput*>([control tag]);
-    DCHECK(detailInput);
-    if (detailInput->type == type)
-      return control;
-  }
-  return nil;
+  return [inputs_ viewWithTag:type];
 }
 
 @end
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_section_container_unittest.mm b/chrome/browser/ui/cocoa/autofill/autofill_section_container_unittest.mm
index 12c8199..b586bc3 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_section_container_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_section_container_unittest.mm
@@ -9,6 +9,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_models.h"
 #include "chrome/browser/ui/autofill/mock_autofill_dialog_controller.h"
+#import "chrome/browser/ui/cocoa/autofill/autofill_input_field.h"
 #import "chrome/browser/ui/cocoa/autofill/layout_view.h"
 #import "chrome/browser/ui/cocoa/menu_button.h"
 #include "grit/generated_resources.h"
@@ -23,26 +24,24 @@
 
 class AutofillSectionContainerTest : public ui::CocoaTest {
  public:
+  AutofillSectionContainerTest() : section_(autofill::SECTION_BILLING) {}
   virtual void SetUp() {
     CocoaTest::SetUp();
-    container_.reset(
-        [[AutofillSectionContainer alloc]
-            initWithController:&controller_
-                    forSection:autofill::SECTION_CC]);
-    [[test_window() contentView] addSubview:[container_ view]];
+    ResetContainer();
   }
 
   void ResetContainer() {
     container_.reset(
         [[AutofillSectionContainer alloc]
             initWithController:&controller_
-                    forSection:autofill::SECTION_CC]);
+                    forSection:section_]);
     [[test_window() contentView] setSubviews:@[ [container_ view] ]];
   }
 
  protected:
   base::scoped_nsobject<AutofillSectionContainer> container_;
   testing::NiceMock<autofill::MockAutofillDialogController> controller_;
+  autofill::DialogSection section_;
 };
 
 }  // namespace
@@ -86,7 +85,7 @@
   inputs.push_back(kTestInputs[0]);
 
   autofill::MonthComboboxModel comboModel;
-  EXPECT_CALL(controller_, RequestedFieldsForSection(autofill::SECTION_CC))
+  EXPECT_CALL(controller_, RequestedFieldsForSection(section_))
       .WillOnce(ReturnRef(inputs));
   EXPECT_CALL(controller_, ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH))
       .WillRepeatedly(Return(&comboModel));
@@ -115,7 +114,7 @@
   inputs.push_back(kTestInputs[0]);
   inputs.push_back(kTestInputs[1]);
 
-  EXPECT_CALL(controller_, RequestedFieldsForSection(autofill::SECTION_CC))
+  EXPECT_CALL(controller_, RequestedFieldsForSection(section_))
       .WillOnce(ReturnRef(inputs));
   EXPECT_CALL(controller_, ComboboxModelForAutofillType(EMAIL_ADDRESS))
       .WillRepeatedly(ReturnNull());
@@ -145,7 +144,7 @@
   using namespace autofill;
   using namespace testing;
 
-  EXPECT_CALL(controller_, MenuModelForSection(autofill::SECTION_CC))
+  EXPECT_CALL(controller_, MenuModelForSection(section_))
       .WillOnce(Return(&model));
 
   ResetContainer();
@@ -164,3 +163,77 @@
   EXPECT_NSEQ(@"a", [[menu itemAtIndex:1] title]);
   EXPECT_NSEQ(@"b", [[menu itemAtIndex:2] title]);
 }
+
+TEST_F(AutofillSectionContainerTest, FieldsAreInitiallyValid) {
+  using namespace autofill;
+  using namespace testing;
+
+  const DetailInput kTestInputs[] = {
+    { 1, EMAIL_ADDRESS, IDS_AUTOFILL_DIALOG_PLACEHOLDER_EMAIL },
+    { 2, CREDIT_CARD_EXP_MONTH }
+  };
+
+  MonthComboboxModel comboModel;
+  DetailInputs inputs;
+  inputs.push_back(kTestInputs[0]);
+  inputs.push_back(kTestInputs[1]);
+
+  EXPECT_CALL(controller_, RequestedFieldsForSection(section_))
+      .WillOnce(ReturnRef(inputs));
+  EXPECT_CALL(controller_, ComboboxModelForAutofillType(EMAIL_ADDRESS))
+      .WillRepeatedly(ReturnNull());
+  EXPECT_CALL(controller_, ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH))
+      .WillRepeatedly(Return(&comboModel));
+
+  ResetContainer();
+  NSControl<AutofillInputField>* field = [container_ getField:EMAIL_ADDRESS];
+  EXPECT_FALSE([field invalid]);
+  field = [container_ getField:CREDIT_CARD_EXP_MONTH];
+  EXPECT_FALSE([field invalid]);
+}
+
+TEST_F(AutofillSectionContainerTest, ControllerInformsValidity) {
+  using namespace autofill;
+  using namespace testing;
+
+  const DetailInput kTestInputs[] = {
+    { 1, EMAIL_ADDRESS, IDS_AUTOFILL_DIALOG_PLACEHOLDER_EMAIL },
+    { 2, CREDIT_CARD_EXP_MONTH }
+  };
+
+  MonthComboboxModel comboModel;
+  DetailInputs inputs;
+  inputs.push_back(kTestInputs[0]);
+  inputs.push_back(kTestInputs[1]);
+
+  DetailOutputMap output;
+  ValidityData validity, validity2;
+
+  validity[EMAIL_ADDRESS] = ASCIIToUTF16("Some error message");
+  validity2[CREDIT_CARD_EXP_MONTH ] = ASCIIToUTF16("Some other error message");
+  EXPECT_CALL(controller_, RequestedFieldsForSection(section_))
+      .WillOnce(ReturnRef(inputs));
+  EXPECT_CALL(controller_, ComboboxModelForAutofillType(EMAIL_ADDRESS))
+      .WillRepeatedly(ReturnNull());
+  EXPECT_CALL(controller_, ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH))
+      .WillRepeatedly(Return(&comboModel));
+
+  ResetContainer();
+  [container_ getInputs:&output];
+  EXPECT_CALL(controller_, InputsAreValid(section_, output, VALIDATE_FINAL))
+      .WillOnce(Return(validity))
+      .WillOnce(Return(validity2));
+
+  [container_ validateFor:VALIDATE_FINAL];
+  NSControl<AutofillInputField>* field = [container_ getField:EMAIL_ADDRESS];
+  EXPECT_TRUE([field invalid]);
+  field = [container_ getField:CREDIT_CARD_EXP_MONTH];
+  EXPECT_FALSE([field invalid]);
+
+
+  [container_ validateFor:VALIDATE_FINAL];
+  field = [container_ getField:EMAIL_ADDRESS];
+  EXPECT_FALSE([field invalid]);
+  field = [container_ getField:CREDIT_CARD_EXP_MONTH];
+  EXPECT_TRUE([field invalid]);
+}
\ No newline at end of file
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_section_view_unittest.mm b/chrome/browser/ui/cocoa/autofill/autofill_section_view_unittest.mm
index 8cad9d7..9f9d6fe 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_section_view_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_section_view_unittest.mm
@@ -25,7 +25,7 @@
 
   NSEvent* fakeEvent(NSEventType type) {
     return [NSEvent enterExitEventWithType:type
-                              location:NSMakePoint(0, 0)
+                              location:NSZeroPoint
                          modifierFlags:0
                              timestamp:0
                           windowNumber:[[view_ window] windowNumber]
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.h b/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.h
index 6fe11d7..894c2df 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.h
@@ -34,6 +34,9 @@
   autofill::AutofillDialogController* controller_;  // Not owned.
 }
 
+// Auxiliary textfield. See showTextfield: for details.
+@property (readonly, nonatomic) AutofillTextField* inputField;
+
 // Set the icon for the suggestion.
 - (void)setIcon:(NSImage*)iconImage;
 
@@ -42,8 +45,9 @@
                     line2:(NSString*)line2
                  withFont:(NSFont*)font;
 
-// Turns editable textfield on, setting the field's placeholder text and icon.
-- (void)showTextfield:(NSString*)text withIcon:(NSImage*)icon;
+// Shows an auxiliary textfield to the right of the suggestion icon and
+// text. This is currently only used to show a CVC field for the CC section.
+- (void)showInputField:(NSString*)text withIcon:(NSImage*)icon;
 
 @end
 
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.mm
index 9989f83..a2ab4e7 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.mm
@@ -13,7 +13,6 @@
 #include "chrome/browser/ui/autofill/autofill_dialog_controller.h"
 #include "chrome/browser/ui/chrome_style.h"
 #import "chrome/browser/ui/cocoa/autofill/autofill_textfield.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
 #include "skia/ext/skia_utils_mac.h"
 
 namespace {
@@ -37,6 +36,10 @@
 
 @implementation AutofillSuggestionContainer
 
+- (AutofillTextField*)inputField {
+  return inputField_.get();
+}
+
 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText {
   base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]);
   [label setFont:
@@ -94,7 +97,7 @@
   [label2_ sizeToFit];
 }
 
-- (void)showTextfield:(NSString*)text withIcon:(NSImage*)icon {
+- (void)showInputField:(NSString*)text withIcon:(NSImage*)icon {
   [[inputField_ cell] setPlaceholderString:text];
   [[inputField_ cell] setIcon:icon];
   [inputField_ setHidden:NO];
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container_unittest.mm b/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container_unittest.mm
index e535d41..d573fbb 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_suggestion_container_unittest.mm
@@ -5,7 +5,6 @@
 #import "chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.h"
 
 #import "chrome/browser/ui/cocoa/autofill/autofill_textfield.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "ui/base/test/ui_cocoa_test_helper.h"
 
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_textfield.h b/chrome/browser/ui/cocoa/autofill/autofill_textfield.h
index 4a2d4d9..31d6598 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_textfield.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_textfield.h
@@ -12,10 +12,16 @@
 
 // Text field used for text inputs inside Autofill.
 // Provide both dog ear and red outline when the contents are marked invalid.
-@interface AutofillTextField : NSTextField<AutofillInputField>
+@interface AutofillTextField : NSTextField<AutofillInputField,
+                                           NSTextFieldDelegate> {
+ @private
+   id<AutofillInputDelegate> delegate_;
+   base::scoped_nsobject<NSString> validityMessage_;
+}
+
 @end
 
-@interface AutofillTextFieldCell : NSTextFieldCell<AutofillInputField> {
+@interface AutofillTextFieldCell : NSTextFieldCell<AutofillInputCell> {
  @private
   BOOL invalid_;
   base::scoped_nsobject<NSImage> icon_;
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_textfield.mm b/chrome/browser/ui/cocoa/autofill/autofill_textfield.mm
index 3daad77..97e005f 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_textfield.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_textfield.mm
@@ -23,16 +23,33 @@
 
 @implementation AutofillTextField
 
+@synthesize delegate = delegate_;
+
 + (Class)cellClass {
   return [AutofillTextFieldCell class];
 }
 
-- (BOOL)invalid {
-  return [[self cell] invalid];
+- (id)initWithFrame:(NSRect)frame {
+  if (self = [super initWithFrame:frame])
+    [super setDelegate:self];
+  return self;
 }
 
-- (void)setInvalid:(BOOL)invalid {
-  [[self cell] setInvalid:invalid];
+- (BOOL)becomeFirstResponder {
+  BOOL result = [super becomeFirstResponder];
+  if (result && delegate_)
+    [delegate_ fieldBecameFirstResponder:self];
+  return result;
+}
+
+- (void)controlTextDidEndEditing:(NSNotification*)notification {
+  if (delegate_)
+    [delegate_ didEndEditing:self];
+}
+
+- (void)controlTextDidChange:(NSNotification*)aNotification {
+  if (delegate_)
+    [delegate_ didChange:self];
 }
 
 - (NSString*)fieldValue {
@@ -43,6 +60,20 @@
   [[self cell] setFieldValue:fieldValue];
 }
 
+- (NSString*)validityMessage {
+  return validityMessage_;
+}
+
+- (void)setValidityMessage:(NSString*)validityMessage {
+  validityMessage_.reset([validityMessage copy]);
+  [[self cell] setInvalid:[self invalid]];
+  [self setNeedsDisplay:YES];
+}
+
+- (BOOL)invalid {
+  return [validityMessage_ length] != 0;
+}
+
 @end
 
 @implementation AutofillTextFieldCell
diff --git a/chrome/browser/ui/cocoa/base_bubble_controller.mm b/chrome/browser/ui/cocoa/base_bubble_controller.mm
index c7ef5b6..fad938f 100644
--- a/chrome/browser/ui/cocoa/base_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/base_bubble_controller.mm
@@ -77,7 +77,7 @@
     [theWindow setDelegate:self];
 
     base::scoped_nsobject<InfoBubbleView> contentView(
-        [[InfoBubbleView alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]);
+        [[InfoBubbleView alloc] initWithFrame:NSZeroRect]);
     [theWindow setContentView:contentView.get()];
     bubble_ = contentView.get();
 
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
index b654f44..9ae2499 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
@@ -1046,7 +1046,7 @@
   EXPECT_NSEQ(@"a", [[[bar_ buttons] objectAtIndex:0] title]);
 
   [bar_ dragButton:[[bar_ buttons] objectAtIndex:2]
-                to:NSMakePoint(0, 0)
+                to:NSZeroPoint
               copy:NO];
   EXPECT_NSEQ(@"c", [[[bar_ buttons] objectAtIndex:0] title]);
   // Make sure a 'copy' did not happen.
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
index 60835d6..137451a 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
@@ -845,7 +845,7 @@
   // more items) using the keyboard, the scroll view seems to want to be
   // offset by default: [ http://crbug.com/101099 ].  Explicitly reseting the
   // scroll position here is a bit hacky, but it does seem to work.
-  [[scrollView_ contentView] scrollToPoint:NSMakePoint(0, 0)];
+  [[scrollView_ contentView] scrollToPoint:NSZeroPoint];
 
   NSSize newSize = NSMakeSize(windowWidth, 0.0);
   [self adjustWindowLeft:newWindowTopLeft.x size:newSize scrollingBy:0.0];
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm
index c69a17d..49eecdf 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm
@@ -116,7 +116,7 @@
   NSImage* drag_image =
       [[[NSImage alloc] initWithSize:drag_image_size] autorelease];
   [drag_image lockFocus];
-  [favicon drawAtPoint:NSMakePoint(0, 0)
+  [favicon drawAtPoint:NSZeroPoint
               fromRect:NSZeroRect
              operation:NSCompositeSourceOver
               fraction:0.7];
diff --git a/chrome/browser/ui/cocoa/browser/avatar_button_controller.mm b/chrome/browser/ui/cocoa/browser/avatar_button_controller.mm
index ab62229..2428978 100644
--- a/chrome/browser/ui/cocoa/browser/avatar_button_controller.mm
+++ b/chrome/browser/ui/cocoa/browser/avatar_button_controller.mm
@@ -7,6 +7,7 @@
 #include "base/strings/sys_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/managed_mode/managed_user_service.h"
 #include "chrome/browser/profiles/profile.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #import "chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
@@ -270,7 +270,7 @@
   base::scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
   [shadow.get() setShadowColor:[NSColor colorWithCalibratedWhite:0.0
                                                            alpha:0.75]];
-  [shadow.get() setShadowOffset:NSMakeSize(0, 0)];
+  [shadow.get() setShadowOffset:NSZeroSize];
   [shadow.get() setShadowBlurRadius:3.0];
   [shadow.get() set];
 
diff --git a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.mm b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.mm
index 26e5ec9..e9baf59 100644
--- a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.mm
@@ -13,13 +13,13 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
 #import "ui/base/cocoa/cocoa_event_utils.h"
+#import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/image/image.h"
diff --git a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm
index 153efc4..05304e8 100644
--- a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm
@@ -12,10 +12,10 @@
 #include "chrome/browser/profiles/avatar_menu_model_observer.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "testing/gtest_mac.h"
+#import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #include "ui/base/test/cocoa_test_event_utils.h"
 
 class AvatarMenuBubbleControllerTest : public CocoaTest {
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h
index ea17ec7..57350fa 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h
@@ -114,8 +114,7 @@
   virtual void ShowWebsiteSettings(Profile* profile,
                                    content::WebContents* web_contents,
                                    const GURL& url,
-                                   const content::SSLStatus& ssl,
-                                   bool show_history) OVERRIDE;
+                                   const content::SSLStatus& ssl) OVERRIDE;
   virtual void ShowAppMenu() OVERRIDE;
   virtual bool PreHandleKeyboardEvent(
       const content::NativeWebKeyboardEvent& event,
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index 5c7d583..82e406c 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -14,8 +14,10 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_shelf.h"
 #include "chrome/browser/extensions/tab_helper.h"
+#include "chrome/browser/fullscreen.h"
 #include "chrome/browser/password_manager/password_manager.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/shell_integration.h"
@@ -47,7 +49,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/web_app_ui.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/crash_keys.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/native_web_keyboard_event.h"
@@ -520,7 +521,8 @@
     [bubble_controller showWindow:nil];
   } else {
     // Deletes itself when the dialog closes.
-    new OneClickSigninDialogController(web_contents, start_sync_callback);
+    new OneClickSigninDialogController(
+        web_contents, start_sync_callback, email);
   }
 }
 #endif
@@ -561,10 +563,8 @@
     Profile* profile,
     content::WebContents* web_contents,
     const GURL& url,
-    const content::SSLStatus& ssl,
-    bool show_history) {
-  WebsiteSettingsUIBridge::Show(
-      window(), profile, web_contents, url, ssl);
+    const content::SSLStatus& ssl) {
+  WebsiteSettingsUIBridge::Show(window(), profile, web_contents, url, ssl);
 }
 
 void BrowserWindowCocoa::ShowAppMenu() {
@@ -625,7 +625,7 @@
 }
 
 void BrowserWindowCocoa::EnterFullscreenWithChrome() {
-  CHECK(base::mac::IsOSLionOrLater());
+  CHECK(chrome::mac::SupportsSystemFullscreen());
   if ([controller_ inPresentationMode])
     [controller_ exitPresentationMode];
   else
@@ -653,7 +653,7 @@
 WindowOpenDisposition BrowserWindowCocoa::GetDispositionForPopupBounds(
     const gfx::Rect& bounds) {
   // In Lion fullscreen mode, convert popups into tabs.
-  if (base::mac::IsOSLionOrLater() && IsFullscreen())
+  if (chrome::mac::SupportsSystemFullscreen() && IsFullscreen())
     return NEW_FOREGROUND_TAB;
   return NEW_POPUP;
 }
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm b/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm
index 8bb2f9e..a2e6acc 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm
@@ -6,11 +6,12 @@
 #include "base/mac/scoped_nsobject.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string_util.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/fullscreen.h"
 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
 #import "chrome/browser/ui/cocoa/browser_window_cocoa.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -94,7 +95,7 @@
 }
 
 TEST_F(BrowserWindowCocoaTest, TestFullscreenWithChrome) {
-  if (!base::mac::IsOSLionOrLater())
+  if (!chrome::mac::SupportsSystemFullscreen())
     return;
   // Wrap the FakeController in a scoped_nsobject instead of autoreleasing in
   // windowWillClose: because we never actually open a window in this test (so
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h
index f50723c..ebecf99 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.h
+++ b/chrome/browser/ui/cocoa/browser_window_controller.h
@@ -160,8 +160,8 @@
   // handle.
   scoped_ptr<ExtensionKeybindingRegistryCocoa> extension_keybinding_registry_;
 
-  // The number of history overlay views being shown.
-  NSUInteger historyOverlayCount_;
+  // The number of overlapped views being shown.
+  NSUInteger overlappedViewCount_;
 }
 
 // A convenience class method which gets the |BrowserWindowController| for a
@@ -342,13 +342,15 @@
 // allowOverlappingViews state.
 - (void)onFindBarVisibilityChanged;
 
-// Called when a history overlay is shown. This is used to update the
-// allowOverlappingViews state.
-- (void)onHistoryOverlayShown;
+// Called when an overlapped view is shown. This is used to update the
+// allowOverlappingViews state. Currently used for history overlay and
+// confirm bubble.
+- (void)onOverlappedViewShown;
 
 // Called when a history overlay is hidden. This is used to update the
-// allowOverlappingViews state.
-- (void)onHistoryOverlayHidden;
+// allowOverlappingViews state. Currently used for history overlay and
+// confirm bubble.
+- (void)onOverlappedViewHidden;
 
 @end  // @interface BrowserWindowController
 
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm
index f9fb551..17c90a4 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -16,6 +16,7 @@
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/devtools/devtools_window.h"
+#include "chrome/browser/fullscreen.h"
 #include "chrome/browser/profiles/avatar_menu_model.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
@@ -1118,7 +1119,7 @@
                     IDS_ENTER_FULLSCREEN_MAC);
             [static_cast<NSMenuItem*>(item) setTitle:menuTitle];
 
-            if (base::mac::IsOSSnowLeopard())
+            if (!chrome::mac::SupportsSystemFullscreen())
               [static_cast<NSMenuItem*>(item) setHidden:YES];
           }
           break;
@@ -1997,13 +1998,13 @@
   [self updateAllowOverlappingViews:[self inPresentationMode]];
 }
 
-- (void)onHistoryOverlayShown {
-  ++historyOverlayCount_;
+- (void)onOverlappedViewShown {
+  ++overlappedViewCount_;
   [self updateAllowOverlappingViews:[self inPresentationMode]];
 }
 
-- (void)onHistoryOverlayHidden {
-  --historyOverlayCount_;
+- (void)onOverlappedViewHidden {
+  --overlappedViewCount_;
   [self updateAllowOverlappingViews:[self inPresentationMode]];
 }
 
@@ -2028,7 +2029,7 @@
   if (!chrome::IsCommandEnabled(browser_.get(), IDC_FULLSCREEN))
     return;
 
-  if (base::mac::IsOSLionOrLater()) {
+  if (chrome::mac::SupportsSystemFullscreen()) {
     enteredPresentationModeFromFullscreen_ = YES;
     if ([[self window] isKindOfClass:[FramedBrowserWindow class]])
       [static_cast<FramedBrowserWindow*>([self window]) toggleSystemFullScreen];
@@ -2073,8 +2074,9 @@
   fullscreenUrl_ = url;
   fullscreenBubbleType_ = bubbleType;
 
-  // Presentation mode on Snow Leopard maps directly to fullscreen mode.
-  if (base::mac::IsOSSnowLeopard()) {
+  // Presentation mode on systems without fullscreen support maps directly to
+  // fullscreen mode.
+  if (!chrome::mac::SupportsSystemFullscreen()) {
     [self setFullscreen:presentationMode];
     return;
   }
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
index 43de7e5..9ff7da1 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -10,6 +10,7 @@
 #import "base/mac/scoped_nsobject.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/fullscreen.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_info_util.h"
@@ -318,10 +319,10 @@
   // toggle button on Lion.  On non-Lion systems, the right indent needs to be
   // adjusted to make room for the new tab button when an avatar is present.
   CGFloat rightIndent = 0;
-  if (base::mac::IsOSLionOrLater()) {
+  if (base::mac::IsOSLionOrLater() &&
+      [[self window] isKindOfClass:[FramedBrowserWindow class]]) {
     FramedBrowserWindow* window =
         static_cast<FramedBrowserWindow*>([self window]);
-    DCHECK([window isKindOfClass:[FramedBrowserWindow class]]);
     rightIndent += -[window fullScreenButtonOriginAdjustment].x;
   } else if ([self shouldShowAvatar]) {
     rightIndent += kAvatarTabStripShrink;
@@ -492,14 +493,14 @@
 // Fullscreen and presentation mode methods
 
 - (BOOL)shouldShowPresentationModeToggle {
-  return base::mac::IsOSLionOrLater() && [self isFullscreen];
+  return chrome::mac::SupportsSystemFullscreen() && [self isFullscreen];
 }
 
 - (void)moveViewsForFullscreenForSnowLeopard:(BOOL)fullscreen
     regularWindow:(NSWindow*)regularWindow
     fullscreenWindow:(NSWindow*)fullscreenWindow {
-  // This method is only for Snow Leopard.
-  DCHECK(base::mac::IsOSSnowLeopard());
+  // This method is only for systems without fullscreen support.
+  DCHECK(!chrome::mac::SupportsSystemFullscreen());
 
   NSWindow* sourceWindow = fullscreen ? regularWindow : fullscreenWindow;
   NSWindow* destWindow = fullscreen ? fullscreenWindow : regularWindow;
@@ -613,7 +614,9 @@
 }
 
 - (void)enterFullscreenForSnowLeopard {
-  DCHECK(base::mac::IsOSSnowLeopard());
+  // TODO(rohitrao): This method is misnamed now, since there is a flag that
+  // enables 10.6-style fullscreen on newer OSes.
+  DCHECK(!chrome::mac::SupportsSystemFullscreen());
 
   // Fade to black.
   const CGDisplayReservationInterval kFadeDurationSeconds = 0.6;
@@ -650,7 +653,9 @@
 }
 
 - (void)exitFullscreenForSnowLeopard {
-  DCHECK(base::mac::IsOSSnowLeopard());
+  // TODO(rohitrao): This method is misnamed now, since there is a flag that
+  // enables 10.6-style fullscreen on newer OSes.
+  DCHECK(!chrome::mac::SupportsSystemFullscreen());
 
   // Fade to black.
   const CGDisplayReservationInterval kFadeDurationSeconds = 0.6;
@@ -779,7 +784,7 @@
 }
 
 - (void)windowDidEnterFullScreen:(NSNotification*)notification {
-  if (base::mac::IsOSLionOrLater())
+  if (chrome::mac::SupportsSystemFullscreen())
     [self deregisterForContentViewResizeNotifications];
   enteringFullscreen_ = NO;
   enteringPresentationMode_ = NO;
@@ -788,14 +793,14 @@
 }
 
 - (void)windowWillExitFullScreen:(NSNotification*)notification {
-  if (base::mac::IsOSLionOrLater())
+  if (chrome::mac::SupportsSystemFullscreen())
     [self registerForContentViewResizeNotifications];
   [self destroyFullscreenExitBubbleIfNecessary];
   [self setPresentationModeInternal:NO forceDropdown:NO];
 }
 
 - (void)windowDidExitFullScreen:(NSNotification*)notification {
-  if (base::mac::IsOSLionOrLater())
+  if (chrome::mac::SupportsSystemFullscreen())
     [self deregisterForContentViewResizeNotifications];
   browser_->WindowFullscreenStateChanged();
 }
@@ -914,7 +919,7 @@
     return YES;
   }
 
-  if (historyOverlayCount_)
+  if (overlappedViewCount_)
     return YES;
 
   return NO;
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm b/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm
index 82032a1..0786537 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm
@@ -10,6 +10,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/signin/fake_auth_status_provider.h"
 #include "chrome/browser/signin/fake_signin_manager.h"
 #include "chrome/browser/signin/signin_global_error.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/ui/cocoa/tabs/tab_strip_view.h"
 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
 #include "chrome/browser/ui/host_desktop.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_service.h"
@@ -707,10 +707,10 @@
   SigninManager* signin = SigninManagerFactory::GetForProfile(profile());
   signin->SetAuthenticatedUsername(username);
   ProfileSyncService* sync =
-    ProfileSyncServiceFactory::GetForProfile(profile());
+      ProfileSyncServiceFactory::GetForProfile(profile());
   sync->SetSyncSetupCompleted();
   // Force an auth error.
-  FakeAuthStatusProvider provider(signin->signin_global_error());
+  FakeAuthStatusProvider provider(SigninGlobalError::GetForProfile(profile()));
   GoogleServiceAuthError error(
       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
   provider.SetAuthError(error);
diff --git a/chrome/browser/ui/cocoa/chrome_browser_window.mm b/chrome/browser/ui/cocoa/chrome_browser_window.mm
index b0f03d6..24e2623 100644
--- a/chrome/browser/ui/cocoa/chrome_browser_window.mm
+++ b/chrome/browser/ui/cocoa/chrome_browser_window.mm
@@ -27,7 +27,7 @@
 - (NSPoint)themePatternPhase {
   id delegate = [self delegate];
   if (![delegate respondsToSelector:@selector(themePatternPhase)])
-    return NSMakePoint(0, 0);
+    return NSZeroPoint;
   return [delegate themePatternPhase];
 }
 
diff --git a/chrome/browser/ui/cocoa/confirm_bubble_controller.mm b/chrome/browser/ui/cocoa/confirm_bubble_controller.mm
index 9eb0c68..128996f 100644
--- a/chrome/browser/ui/cocoa/confirm_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/confirm_bubble_controller.mm
@@ -6,6 +6,7 @@
 
 #include "base/mac/mac_util.h"
 #include "base/strings/sys_string_conversions.h"
+#import "chrome/browser/ui/cocoa/browser_window_controller.h"
 #import "chrome/browser/ui/cocoa/confirm_bubble_cocoa.h"
 #import "chrome/browser/ui/confirm_bubble_model.h"
 #include "ui/gfx/image/image.h"
@@ -25,11 +26,15 @@
 }
 
 - (void)loadView {
+  [[BrowserWindowController
+      browserWindowControllerForView:parent_] onOverlappedViewShown];
   [self setView:[[[ConfirmBubbleCocoa alloc] initWithParent:parent_
                                                  controller:self] autorelease]];
 }
 
 - (void)windowWillClose:(NSNotification*)notification {
+  [[BrowserWindowController
+      browserWindowControllerForView:parent_] onOverlappedViewHidden];
   [self autorelease];
 }
 
diff --git a/chrome/browser/ui/cocoa/confirm_quit_panel_controller.mm b/chrome/browser/ui/cocoa/confirm_quit_panel_controller.mm
index 27813eb..499dc93 100644
--- a/chrome/browser/ui/cocoa/confirm_quit_panel_controller.mm
+++ b/chrome/browser/ui/cocoa/confirm_quit_panel_controller.mm
@@ -67,7 +67,7 @@
   if ((self = [super initWithFrame:frameRect])) {
     base::scoped_nsobject<NSTextField> message(
         // The frame will be fixed up when |-setMessageText:| is called.
-        [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]);
+        [[NSTextField alloc] initWithFrame:NSZeroRect]);
     message_ = message.get();
     [message_ setEditable:NO];
     [message_ setSelectable:NO];
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.h b/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.h
index 389f6a8..4365413 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.h
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.h
@@ -17,6 +17,7 @@
  @private
   base::scoped_nsobject<NSTextField> informativeTextField_;
   base::scoped_nsobject<NSTextField> messageTextField_;
+  base::scoped_nsobject<NSButton> linkView_;
   base::scoped_nsobject<NSView> accessoryView_;
   base::scoped_nsobject<NSMutableArray> buttons_;
   base::scoped_nsobject<NSButton> closeButton_;
@@ -40,10 +41,20 @@
                     target:(id)target
                     action:(SEL)action;
 
+// Sets the |text|, the |target| and the |action| of a left-aligned link
+// positioned above the buttons. If |text| is empty, no link is displayed.
+- (void)setLinkText:(NSString*)text
+             target:(id)target
+             action:(SEL)action;
+
 // Lays out the controls in the alert. This should be called before the window
 // is displayed.
 - (void)layout;
 
 @end
 
+@interface ConstrainedWindowAlert (ExposedForTesting)
+@property(nonatomic, readonly) NSButton* linkView;
+@end
+
 #endif  // CHROME_BROWSER_UI_COCOA_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_ALERT_H_
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.mm
index 036c42a..61fa6ac 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.mm
@@ -12,6 +12,7 @@
 #import "chrome/browser/ui/cocoa/hover_close_button.h"
 #include "skia/ext/skia_utils_mac.h"
 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+#include "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #include "ui/base/cocoa/window_size_constants.h"
 
 namespace {
@@ -29,6 +30,10 @@
 - (CGFloat)layoutTextField:(NSTextField*)textField
                       yPos:(CGFloat)yPos
                windowWidth:(CGFloat)windowWidth;
+// If a link has been set, resizes the link to fit within the window and
+// position it starting at |yPos|. Returns the new value of yPos.
+- (CGFloat)layoutLinkAtYPos:(CGFloat)yPos
+                windowWidth:(CGFloat)windowWidth;
 // Positions the accessory view starting at yPos. Returns the new value of yPos.
 - (CGFloat)layoutAccessoryViewAtYPos:(CGFloat)yPos;
 // Update the position of the close button.
@@ -82,6 +87,24 @@
           NSLineBreakByWordWrapping)];
 }
 
+- (void)setLinkText:(NSString*)text target:(id)target action:(SEL)action {
+  if (![text length]) {
+    [linkView_ removeFromSuperview];
+    linkView_.reset(nil);
+    return;
+  }
+
+  if (!linkView_.get()) {
+    linkView_.reset(
+        [[HyperlinkButtonCell buttonWithString:[NSString string]] retain]);
+    [[window_ contentView] addSubview:linkView_];
+  }
+
+  [linkView_ setTitle:text];
+  [linkView_ setTarget:target];
+  [linkView_ setAction:action];
+}
+
 - (NSView*)accessoryView {
   return accessoryView_;
 }
@@ -142,12 +165,14 @@
   [self layoutButtonsWithWindowWidth:windowWidth];
   CGFloat curY = [buttons_ count] ? NSMaxY([[buttons_ lastObject] frame])
       : chrome_style::kClientBottomPadding;
+  CGFloat availableMessageWidth =
+      windowWidth - chrome_style::GetCloseButtonSize() - kButtonGap;
+  curY = [self layoutLinkAtYPos:curY
+                    windowWidth:availableMessageWidth];
   curY = [self layoutAccessoryViewAtYPos:curY];
   curY = [self layoutTextField:informativeTextField_
                           yPos:curY
                    windowWidth:windowWidth];
-  CGFloat availableMessageWidth =
-      windowWidth - chrome_style::GetCloseButtonSize() - kButtonGap;
   curY = [self layoutTextField:messageTextField_
                           yPos:curY
                    windowWidth:availableMessageWidth];
@@ -205,6 +230,26 @@
   return NSMaxY([textField frame]);
 }
 
+- (CGFloat)layoutLinkAtYPos:(CGFloat)yPos
+                windowWidth:(CGFloat)windowWidth {
+  if (!linkView_.get())
+    return yPos;
+
+  NSRect availableBounds = NSMakeRect(
+      0,
+      0,
+      windowWidth - chrome_style::kHorizontalPadding * 2,
+      CGFLOAT_MAX);
+  NSSize size = [[linkView_ cell] cellSizeForBounds:availableBounds];
+
+  NSRect rect;
+  rect.origin.y = yPos + chrome_style::kRowPadding;
+  rect.origin.x = chrome_style::kHorizontalPadding;
+  rect.size = size;
+  [linkView_ setFrame:rect];
+  return NSMaxY([linkView_ frame]);
+}
+
 - (CGFloat)layoutAccessoryViewAtYPos:(CGFloat)yPos {
   if (!accessoryView_.get())
     return yPos;
@@ -227,4 +272,8 @@
   [closeButton_ setFrame:frame];
 }
 
+- (NSButton*)linkView {
+  return linkView_;
+}
+
 @end
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert_unittest.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert_unittest.mm
index 868f81d..b5fe7a7 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert_unittest.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_alert_unittest.mm
@@ -9,6 +9,25 @@
 class ConstrainedWindowAlertTest : public CocoaTest {
 };
 
+@interface ConstrainedWindowAlertTestTarget : NSObject {
+ @private
+  int linkClickedCount_;
+}
+@property(nonatomic, readonly) int linkClickedCount;
+
+- (void)onLinkClicked:(id)sender;
+@end
+
+@implementation ConstrainedWindowAlertTestTarget
+
+@synthesize linkClickedCount = linkClickedCount_;
+
+- (void)onLinkClicked:(id)sender {
+  ++linkClickedCount_;
+}
+
+@end
+
 // Test showing the alert.
 TEST_F(ConstrainedWindowAlertTest, Show) {
   base::scoped_nsobject<ConstrainedWindowAlert> alert(
@@ -53,3 +72,31 @@
 
   [[alert window] makeKeyAndOrderFront:nil];
 }
+
+// Test adding a link to an alert.
+TEST_F(ConstrainedWindowAlertTest, LinkView) {
+  base::scoped_nsobject<ConstrainedWindowAlert> alert(
+      [[ConstrainedWindowAlert alloc] init]);
+  base::scoped_nsobject<ConstrainedWindowAlertTestTarget> target(
+      [[ConstrainedWindowAlertTestTarget alloc] init]);
+
+  [alert layout];
+  NSRect initial_window_rect = [[alert window] frame];
+
+  EXPECT_EQ(nil, [alert linkView]);
+  NSString* linkText = @"Text of the link";
+  [alert setLinkText:linkText
+              target:target.get()
+              action:@selector(onLinkClicked:)];
+  EXPECT_EQ([linkText length], [[[alert linkView] title] length]);
+
+  [alert layout];
+  NSRect window_rect = [[alert window] frame];
+
+  EXPECT_GT(NSHeight(window_rect), NSHeight(initial_window_rect));
+
+  [[alert window] makeKeyAndOrderFront:nil];
+
+  [[alert linkView] performClick:nil];
+  EXPECT_EQ(1, [target linkClickedCount]);
+}
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm
index 04bc13a..b36e596 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm
@@ -16,8 +16,8 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_view.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "url/gurl.h"
 
 using ::testing::NiceMock;
 
diff --git a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm
index 424c512..469ad86 100644
--- a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm
+++ b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm
@@ -18,6 +18,7 @@
 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_server_bound_cert_helper.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/cookie_settings.h"
 #include "chrome/browser/content_settings/local_shared_objects_container.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
@@ -28,7 +29,6 @@
 #import "chrome/browser/ui/cocoa/content_settings/cookie_details_view_controller.h"
 #import "chrome/browser/ui/cocoa/vertical_gradient_view.h"
 #include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm
index 5040e5b..580a79a 100644
--- a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm
+++ b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm
@@ -12,7 +12,6 @@
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/plugins/plugin_finder.h"
 #include "chrome/browser/plugins/plugin_metadata.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
 #import "chrome/browser/ui/cocoa/l10n_util.h"
 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
@@ -21,6 +20,7 @@
 #include "grit/generated_resources.h"
 #include "skia/ext/skia_utils_mac.h"
 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+#import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #include "ui/base/l10n/l10n_util.h"
 
 using content::PluginService;
@@ -219,6 +219,8 @@
       nibPath = @"ContentProtocolHandlers"; break;
     case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
       nibPath = @"ContentBlockedMedia"; break;
+    case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
+      nibPath = @"ContentBlockedDownloads"; break;
     // These content types have no bubble:
     case CONTENT_SETTINGS_TYPE_DEFAULT:
     case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
diff --git a/chrome/browser/ui/cocoa/content_settings/cookie_details_unittest.mm b/chrome/browser/ui/cocoa/content_settings/cookie_details_unittest.mm
index fed777c..ce723c9 100644
--- a/chrome/browser/ui/cocoa/content_settings/cookie_details_unittest.mm
+++ b/chrome/browser/ui/cocoa/content_settings/cookie_details_unittest.mm
@@ -5,10 +5,10 @@
 #include "base/strings/sys_string_conversions.h"
 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
 #include "chrome/browser/ui/cocoa/content_settings/cookie_details.h"
-#include "googleurl/src/gurl.h"
 #include "net/cookies/canonical_cookie.h"
 #include "net/cookies/parsed_cookie.h"
 #import "testing/gtest_mac.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/cocoa/drag_util.mm b/chrome/browser/ui/cocoa/drag_util.mm
index 98a9d5f..b991fec 100644
--- a/chrome/browser/ui/cocoa/drag_util.mm
+++ b/chrome/browser/ui/cocoa/drag_util.mm
@@ -8,12 +8,12 @@
 #include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/common/url_constants.h"
-#include "googleurl/src/gurl.h"
 #include "ipc/ipc_message.h"
 #include "net/base/mime_util.h"
 #include "net/base/net_util.h"
 #import "third_party/mozilla/NSPasteboard+Utils.h"
 #import "ui/base/dragdrop/cocoa_dnd_util.h"
+#include "url/gurl.h"
 #include "webkit/plugins/webplugininfo.h"
 
 using content::PluginService;
diff --git a/chrome/browser/ui/cocoa/extensions/browser_action_button.mm b/chrome/browser/ui/cocoa/extensions/browser_action_button.mm
index 484cecd..aefec8f 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_action_button.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_action_button.mm
@@ -9,12 +9,12 @@
 
 #include "base/logging.h"
 #include "base/strings/sys_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_icon_factory.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/cocoa/extensions/extension_action_context_menu.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h
index 37cd3f0..65f2951 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h
@@ -23,10 +23,6 @@
 class Extension;
 }
 
-namespace user_prefs {
-class PrefRegistrySyncable;
-}
-
 // Sent when the visibility of the Browser Actions changes.
 extern NSString* const kBrowserActionVisibilityChangedNotification;
 
@@ -108,9 +104,6 @@
 // process of fading in.
 - (BOOL)chevronIsHidden;
 
-// Registers the user preferences used by this class.
-+ (void)registerUserPrefs:(user_prefs::PrefRegistrySyncable*)prefs;
-
 @end  // @interface BrowserActionsController
 
 @interface BrowserActionsController(TestingAPI)
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
index e551c4b..a17f3d8 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
@@ -9,6 +9,7 @@
 
 #include "base/prefs/pref_service.h"
 #include "base/strings/sys_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -24,10 +25,8 @@
 #import "chrome/browser/ui/cocoa/image_button_cell.h"
 #import "chrome/browser/ui/cocoa/menu_button.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
 #include "chrome/common/pref_names.h"
-#include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -267,13 +266,6 @@
     browser_ = browser;
     profile_ = browser->profile();
 
-    // TODO(joi): Do all registrations up front.
-    if (!profile_->GetPrefs()->FindPreference(
-        prefs::kBrowserActionContainerWidth))
-      [BrowserActionsController registerUserPrefs:(
-          (user_prefs::PrefRegistrySyncable*)
-          profile_->GetPrefs()->DeprecatedGetPrefRegistry())];
-
     observer_.reset(new ExtensionServiceObserverBridge(self, browser_));
     ExtensionService* extensionService =
         extensions::ExtensionSystem::Get(profile_)->extension_service();
@@ -447,13 +439,6 @@
   return YES;
 }
 
-+ (void)registerUserPrefs:(user_prefs::PrefRegistrySyncable*)registry {
-  registry->RegisterDoublePref(
-      prefs::kBrowserActionContainerWidth,
-      0,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-}
-
 #pragma mark -
 #pragma mark NSMenuDelegate
 
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller_prefs.cc b/chrome/browser/ui/cocoa/extensions/browser_actions_controller_prefs.cc
new file mode 100644
index 0000000..dc73c96
--- /dev/null
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller_prefs.cc
@@ -0,0 +1,16 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/cocoa/extensions/browser_actions_controller_prefs.h"
+
+#include "chrome/common/pref_names.h"
+#include "components/user_prefs/pref_registry_syncable.h"
+
+void RegisterBrowserActionsControllerProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  registry->RegisterDoublePref(
+      prefs::kBrowserActionContainerWidth,
+      0,
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+}
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller_prefs.h b/chrome/browser/ui/cocoa/extensions/browser_actions_controller_prefs.h
new file mode 100644
index 0000000..698a95c
--- /dev/null
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller_prefs.h
@@ -0,0 +1,16 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_COCOA_EXTENSIONS_BROWSER_ACTIONS_CONTROLLER_PREFS_H_
+#define CHROME_BROWSER_UI_COCOA_EXTENSIONS_BROWSER_ACTIONS_CONTROLLER_PREFS_H_
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+// Registers the user preferences used by BrowserActionsController.
+void RegisterBrowserActionsControllerProfilePrefs(
+    user_prefs::PrefRegistrySyncable* prefs);
+
+#endif  // CHROME_BROWSER_UI_COCOA_EXTENSIONS_BROWSER_ACTIONS_CONTROLLER_PREFS_H_
diff --git a/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm b/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm
index 77b5159..3f2f585 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm
@@ -7,6 +7,7 @@
 #include "base/prefs/pref_change_registrar.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/sys_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
@@ -27,7 +28,6 @@
 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
 #include "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/manifest_url_handler.h"
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm
index 5e5af3c..4e69bdd 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm
@@ -13,12 +13,12 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/extensions/bundle_installer.h"
 #import "chrome/browser/ui/chrome_style.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/page_navigator.h"
 #include "grit/generated_resources.h"
 #include "skia/ext/skia_utils_mac.h"
 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+#import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 #include "ui/gfx/image/image_skia_util_mac.h"
diff --git a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm
index 4536b8d..55b9db3 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm
@@ -9,6 +9,7 @@
 #include "base/mac/mac_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/commands/command_service.h"
 #include "chrome/browser/extensions/bundle_installer.h"
 #include "chrome/browser/extensions/extension_action.h"
@@ -30,7 +31,6 @@
 #include "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "chrome/browser/ui/sync/sync_promo_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/commands/commands_handler.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
 #include "chrome/common/extensions/api/omnibox/omnibox_handler.h"
diff --git a/chrome/browser/ui/cocoa/extensions/extension_keybinding_registry_cocoa.mm b/chrome/browser/ui/cocoa/extensions/extension_keybinding_registry_cocoa.mm
index 1ee3c0f..48ffc5c 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_keybinding_registry_cocoa.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_keybinding_registry_cocoa.mm
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/ui/cocoa/extensions/extension_keybinding_registry_cocoa.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/commands/command_service.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/extensions/extension.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.h b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.h
index 7bd1f23..121ca64 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.h
+++ b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.h
@@ -10,7 +10,7 @@
 #include "base/memory/scoped_ptr.h"
 #import "chrome/browser/ui/cocoa/base_bubble_controller.h"
 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 
 class Browser;
diff --git a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
index d5dc47a..8cdb921 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
@@ -7,6 +7,7 @@
 #include <algorithm>
 
 #include "base/callback.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
@@ -16,7 +17,6 @@
 #import "chrome/browser/ui/cocoa/browser_window_cocoa.h"
 #import "chrome/browser/ui/cocoa/extensions/extension_view_mac.h"
 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/devtools_manager.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.mm b/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.mm
index d6ee237..7587df5 100644
--- a/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.mm
@@ -86,6 +86,13 @@
   return YES;
 }
 
+// Allow non resizable windows (without NSResizableWindowMask) to enter
+// fullscreen by passing through the full size in willUseFullScreenContentSize.
+- (NSSize)window:(NSWindow *)window
+    willUseFullScreenContentSize:(NSSize)proposedSize {
+  return proposedSize;
+}
+
 - (void)executeCommand:(int)command {
   // No-op, swallow the event.
 }
diff --git a/chrome/browser/ui/cocoa/external_protocol_dialog.h b/chrome/browser/ui/cocoa/external_protocol_dialog.h
index e677c3e..5e229f6 100644
--- a/chrome/browser/ui/cocoa/external_protocol_dialog.h
+++ b/chrome/browser/ui/cocoa/external_protocol_dialog.h
@@ -5,7 +5,7 @@
 #import <Cocoa/Cocoa.h>
 
 #include "base/time/time.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 @interface ExternalProtocolDialogController : NSObject {
  @private
diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm
index 6fcb98f..3b11b08 100644
--- a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm
+++ b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm
@@ -295,7 +295,7 @@
 
   // Animate the view into place.
   NSRect frame = [findBarView_ frame];
-  frame.origin = NSMakePoint(0, 0);
+  frame.origin = NSZeroPoint;
   [self setFindBarFrame:frame animate:animate duration:kFindBarOpenDuration];
 }
 
diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller_unittest.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller_unittest.mm
index 9cd4db5..1b74a98 100644
--- a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller_unittest.mm
@@ -15,15 +15,10 @@
 
 // Expose private variables to make testing easier.
 @interface FindBarCocoaController(Testing)
-- (NSView*)findBarView;
 - (FindBarTextField*)findTextField;
 @end
 
 @implementation FindBarCocoaController(Testing)
-- (NSView*)findBarView {
-  return findBarView_;
-}
-
 - (FindBarTextField*)findTextField {
   return findText_;
 }
diff --git a/chrome/browser/ui/cocoa/first_run_dialog.mm b/chrome/browser/ui/cocoa/first_run_dialog.mm
index 29486ff..f1dfd05 100644
--- a/chrome/browser/ui/cocoa/first_run_dialog.mm
+++ b/chrome/browser/ui/cocoa/first_run_dialog.mm
@@ -19,10 +19,10 @@
 #include "chrome/browser/shell_integration.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/url_constants.h"
-#include "googleurl/src/gurl.h"
 #include "grit/locale_settings.h"
 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
 #include "ui/base/l10n/l10n_util_mac.h"
+#include "url/gurl.h"
 
 #if defined(GOOGLE_CHROME_BUILD)
 #include "base/prefs/pref_service.h"
diff --git a/chrome/browser/ui/cocoa/framed_browser_window.mm b/chrome/browser/ui/cocoa/framed_browser_window.mm
index a868fa0..5e39839 100644
--- a/chrome/browser/ui/cocoa/framed_browser_window.mm
+++ b/chrome/browser/ui/cocoa/framed_browser_window.mm
@@ -339,7 +339,7 @@
 
   // Only paint the top of the window.
   NSRect windowRect = [view convertRect:[self frame] fromView:nil];
-  windowRect.origin = NSMakePoint(0, 0);
+  windowRect.origin = NSZeroPoint;
 
   NSRect paintRect = windowRect;
   paintRect.origin.y = NSMaxY(paintRect) - kBrowserFrameViewPaintHeight;
@@ -378,7 +378,7 @@
     CGFloat lineWidth = [view cr_lineWidth];
 
     windowRect = [view convertRect:[self frame] fromView:nil];
-    windowRect.origin = NSMakePoint(0, 0);
+    windowRect.origin = NSZeroPoint;
     windowRect.origin.y -= 0.5 * lineWidth;
     windowRect.origin.x -= 0.5 * lineWidth;
     windowRect.size.width += lineWidth;
diff --git a/chrome/browser/ui/cocoa/fullscreen_exit_bubble_controller.h b/chrome/browser/ui/cocoa/fullscreen_exit_bubble_controller.h
index 60b986d..f2ce354 100644
--- a/chrome/browser/ui/cocoa/fullscreen_exit_bubble_controller.h
+++ b/chrome/browser/ui/cocoa/fullscreen_exit_bubble_controller.h
@@ -6,7 +6,7 @@
 
 #include "base/mac/scoped_nsobject.h"
 #include "chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 @class BrowserWindowController;
 class Browser;
diff --git a/chrome/browser/ui/cocoa/fullscreen_exit_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/fullscreen_exit_bubble_controller_unittest.mm
index fc169c1..6bd761e 100644
--- a/chrome/browser/ui/cocoa/fullscreen_exit_bubble_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/fullscreen_exit_bubble_controller_unittest.mm
@@ -5,12 +5,12 @@
 #import "chrome/browser/ui/cocoa/fullscreen_exit_bubble_controller.h"
 
 #include "base/mac/mac_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/cocoa/browser_window_controller.h"
 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/cocoa/history_menu_bridge.mm b/chrome/browser/ui/cocoa/history_menu_bridge.mm
index 0fc7438..beaa5f0 100644
--- a/chrome/browser/ui/cocoa/history_menu_bridge.mm
+++ b/chrome/browser/ui/cocoa/history_menu_bridge.mm
@@ -12,6 +12,7 @@
 #include "base/strings/sys_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"  // IDC_HISTORY_MENU
 #import "chrome/browser/app_controller_mac.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/favicon/favicon_types.h"
 #include "chrome/browser/history/history_service_factory.h"
@@ -20,7 +21,6 @@
 #include "chrome/browser/sessions/session_types.h"
 #include "chrome/browser/sessions/tab_restore_service_factory.h"
 #import "chrome/browser/ui/cocoa/history_menu_cocoa_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/ui/cocoa/history_overlay_controller.mm b/chrome/browser/ui/cocoa/history_overlay_controller.mm
index 593a942..7d4fbac 100644
--- a/chrome/browser/ui/cocoa/history_overlay_controller.mm
+++ b/chrome/browser/ui/cocoa/history_overlay_controller.mm
@@ -95,7 +95,7 @@
 
 - (void)dealloc {
   [[BrowserWindowController
-      browserWindowControllerForView:[self view]] onHistoryOverlayHidden];
+      browserWindowControllerForView:[self view]] onOverlappedViewHidden];
   [self.view removeFromSuperview];
   [super dealloc];
 }
@@ -154,7 +154,7 @@
                        positioned:NSWindowAbove
                        relativeTo:parent_];
   [[BrowserWindowController
-      browserWindowControllerForView:[self view]] onHistoryOverlayShown];
+      browserWindowControllerForView:[self view]] onOverlappedViewShown];
 }
 
 - (void)dismiss {
diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.h b/chrome/browser/ui/cocoa/hung_renderer_controller.h
index 1725726..282f218 100644
--- a/chrome/browser/ui/cocoa/hung_renderer_controller.h
+++ b/chrome/browser/ui/cocoa/hung_renderer_controller.h
@@ -73,7 +73,7 @@
 
 // Called by |hungContentsObserver_| to indicate that |hungContents_|
 // has gone away.
-- (void)renderViewGone;
+- (void)renderProcessGone;
 
 @end  // HungRendererController
 
diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.mm b/chrome/browser/ui/cocoa/hung_renderer_controller.mm
index b75da41..dc21d44 100644
--- a/chrome/browser/ui/cocoa/hung_renderer_controller.mm
+++ b/chrome/browser/ui/cocoa/hung_renderer_controller.mm
@@ -49,11 +49,11 @@
 
  protected:
   // WebContentsObserver overrides:
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE {
-    [controller_ renderViewGone];
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE {
+    [controller_ renderProcessGone];
   }
   virtual void WebContentsDestroyed(WebContents* tab) OVERRIDE {
-    [controller_ renderViewGone];
+    [controller_ renderProcessGone];
   }
 
  private:
@@ -205,7 +205,7 @@
   }
 }
 
-- (void)renderViewGone {
+- (void)renderProcessGone {
   // Cannot call performClose:, because the close button is disabled.
   [self close];
 }
diff --git a/chrome/browser/ui/cocoa/hyperlink_button_cell.h b/chrome/browser/ui/cocoa/hyperlink_button_cell.h
deleted file mode 100644
index 1cdc263..0000000
--- a/chrome/browser/ui/cocoa/hyperlink_button_cell.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import <Cocoa/Cocoa.h>
-#include "base/mac/scoped_nsobject.h"
-
-// A HyperlinkButtonCell is used to create an NSButton that looks and acts
-// like a hyperlink. The default styling is to look like blue, underlined text
-// and to have the pointingHand cursor on mouse over.
-//
-// To use in Interface Builder:
-//  1. Drag out an NSButton.
-//  2. Double click on the button so you have the cell component selected.
-//  3. In the Identity panel of the inspector, set the custom class to this.
-//  4. In the Attributes panel, change the Bezel to Square.
-//  5. In the Size panel, set the Height to 16.
-@interface HyperlinkButtonCell : NSButtonCell {
-  base::scoped_nsobject<NSColor> textColor_;
-  BOOL shouldUnderline_;
-  BOOL underlineOnHover_;
-  BOOL mouseIsInside_;
-}
-@property(nonatomic, retain) NSColor* textColor;
-@property(nonatomic, assign) BOOL underlineOnHover;
-@property(nonatomic, assign) BOOL shouldUnderline;
-
-+ (NSColor*)defaultTextColor;
-
-// Helper function to create a button with HyperLinkButtonCell as its cell.
-+ (NSButton*)buttonWithString:(NSString*)string;
-
-@end
-
-@interface HyperlinkButtonCell (ExposedForTesting)
-- (NSDictionary*)linkAttributes;
-@end
diff --git a/chrome/browser/ui/cocoa/hyperlink_button_cell.mm b/chrome/browser/ui/cocoa/hyperlink_button_cell.mm
deleted file mode 100644
index 49f316c..0000000
--- a/chrome/browser/ui/cocoa/hyperlink_button_cell.mm
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
-
-@interface HyperlinkButtonCell ()
-- (void)customizeButtonCell;
-@end
-
-@implementation HyperlinkButtonCell
-
-@dynamic textColor;
-@synthesize underlineOnHover = underlineOnHover_;
-@synthesize shouldUnderline = shouldUnderline_;
-
-+ (NSColor*)defaultTextColor {
-  return [NSColor blueColor];
-}
-
-+ (NSButton*)buttonWithString:(NSString*)string {
-  NSButton* button = [[[NSButton alloc] initWithFrame:NSZeroRect] autorelease];
-  base::scoped_nsobject<HyperlinkButtonCell> cell(
-      [[HyperlinkButtonCell alloc] initTextCell:string]);
-  [cell setAlignment:NSLeftTextAlignment];
-  [button setCell:cell.get()];
-  [button setBezelStyle:NSRegularSquareBezelStyle];
-  return button;
-}
-
-// Designated initializer.
-- (id)init {
-  if ((self = [super init])) {
-    [self customizeButtonCell];
-  }
-  return self;
-}
-
-// Initializer called when the cell is loaded from the NIB.
-- (id)initWithCoder:(NSCoder*)aDecoder {
-  if ((self = [super initWithCoder:aDecoder])) {
-    [self customizeButtonCell];
-  }
-  return self;
-}
-
-// Initializer for code-based creation.
-- (id)initTextCell:(NSString*)title {
-  if ((self = [super initTextCell:title])) {
-    [self customizeButtonCell];
-  }
-  return self;
-}
-
-// Because an NSButtonCell has multiple initializers, this method performs the
-// common cell customization code.
-- (void)customizeButtonCell {
-  [self setBordered:NO];
-  [self setTextColor:[HyperlinkButtonCell defaultTextColor]];
-  [self setShouldUnderline:YES];
-
-  CGFloat fontSize = [NSFont systemFontSizeForControlSize:[self controlSize]];
-  NSFont* font = [NSFont controlContentFontOfSize:fontSize];
-  [self setFont:font];
-
-  // Do not change button appearance when we are pushed.
-  [self setHighlightsBy:NSNoCellMask];
-
-  // We need to set this so that we can override |-mouseEntered:| and
-  // |-mouseExited:| to change the cursor style on hover states.
-  [self setShowsBorderOnlyWhileMouseInside:YES];
-}
-
-- (void)setControlSize:(NSControlSize)size {
-  [super setControlSize:size];
-  [self customizeButtonCell];  // recompute |font|.
-}
-
-// Creates the NSDictionary of attributes for the attributed string.
-- (NSDictionary*)linkAttributes {
-  NSUInteger underlineMask = NSNoUnderlineStyle;
-  if (shouldUnderline_ &&
-      (!underlineOnHover_ || (mouseIsInside_ && [self isEnabled])))
-    underlineMask = NSUnderlinePatternSolid | NSUnderlineStyleSingle;
-
-  base::scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
-      [[NSParagraphStyle defaultParagraphStyle] mutableCopy]);
-  [paragraphStyle setAlignment:[self alignment]];
-  [paragraphStyle setLineBreakMode:[self lineBreakMode]];
-
-  return [NSDictionary dictionaryWithObjectsAndKeys:
-      [self textColor], NSForegroundColorAttributeName,
-      [NSNumber numberWithInt:underlineMask], NSUnderlineStyleAttributeName,
-      [self font], NSFontAttributeName,
-      [NSCursor pointingHandCursor], NSCursorAttributeName,
-      paragraphStyle.get(), NSParagraphStyleAttributeName,
-      nil
-  ];
-}
-
-// Override the drawing for the cell so that the custom style attributes
-// can always be applied and so that ellipses will appear when appropriate.
-- (NSRect)drawTitle:(NSAttributedString*)title
-          withFrame:(NSRect)frame
-             inView:(NSView*)controlView {
-  NSDictionary* linkAttributes = [self linkAttributes];
-  NSString* plainTitle = [title string];
-  [plainTitle drawWithRect:frame
-                   options:(NSStringDrawingUsesLineFragmentOrigin |
-                            NSStringDrawingTruncatesLastVisibleLine)
-                attributes:linkAttributes];
-  return frame;
-}
-
-// Override the default behavior to draw the border. Instead, change the cursor.
-- (void)mouseEntered:(NSEvent*)event {
-  mouseIsInside_ = YES;
-  if ([self isEnabled])
-    [[NSCursor pointingHandCursor] push];
-  else
-    [[NSCursor currentCursor] push];
-  if (underlineOnHover_)
-    [[self controlView] setNeedsDisplay:YES];
-}
-
-- (void)mouseExited:(NSEvent*)event {
-  mouseIsInside_ = NO;
-  [NSCursor pop];
-  if (underlineOnHover_)
-    [[self controlView] setNeedsDisplay:YES];
-}
-
-// Setters and getters.
-- (NSColor*)textColor {
-  if ([self isEnabled])
-    return textColor_.get();
-  else
-    return [NSColor disabledControlTextColor];
-}
-
-- (void)setTextColor:(NSColor*)color {
-  textColor_.reset([color retain]);
-}
-
-// Override so that |-sizeToFit| works better with this type of cell.
-- (NSSize)cellSize {
-  NSSize size = [super cellSize];
-  size.width += 2;
-  return size;
-}
-
-@end
diff --git a/chrome/browser/ui/cocoa/hyperlink_button_cell_unittest.mm b/chrome/browser/ui/cocoa/hyperlink_button_cell_unittest.mm
deleted file mode 100644
index 18abc03..0000000
--- a/chrome/browser/ui/cocoa/hyperlink_button_cell_unittest.mm
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/mac/foundation_util.h"
-#include "base/mac/scoped_nsobject.h"
-#import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-
-class HyperlinkButtonCellTest : public CocoaTest {
- public:
-  HyperlinkButtonCellTest() {
-    NSRect frame = NSMakeRect(0, 0, 50, 30);
-    base::scoped_nsobject<NSButton> view(
-        [[NSButton alloc] initWithFrame:frame]);
-    view_ = view.get();
-    base::scoped_nsobject<HyperlinkButtonCell> cell(
-        [[HyperlinkButtonCell alloc] initTextCell:@"Testing"]);
-    cell_ = cell.get();
-    [view_ setCell:cell_];
-    [[test_window() contentView] addSubview:view_];
-  }
-
-  void TestCellCustomization(HyperlinkButtonCell* cell) {
-    EXPECT_FALSE([cell isBordered]);
-    EXPECT_EQ(NSNoCellMask, [cell_ highlightsBy]);
-    EXPECT_TRUE([cell showsBorderOnlyWhileMouseInside]);
-    EXPECT_TRUE([cell textColor]);
-  }
-
- protected:
-  bool HasUnderlineAttribute(NSDictionary* attributes) {
-    NSNumber* number = base::mac::ObjCCastStrict<NSNumber>(
-        [attributes objectForKey:NSUnderlineStyleAttributeName]);
-    return [number unsignedIntegerValue] != 0;
-  }
-
-  NSButton* view_;
-  HyperlinkButtonCell* cell_;
-};
-
-TEST_VIEW(HyperlinkButtonCellTest, view_)
-
-// Tests the three designated intializers.
-TEST_F(HyperlinkButtonCellTest, Initializers) {
-  TestCellCustomization(cell_);  // |-initTextFrame:|
-  base::scoped_nsobject<HyperlinkButtonCell> cell(
-      [[HyperlinkButtonCell alloc] init]);
-  TestCellCustomization(cell.get());
-
-  // Need to create a dummy archiver to test |-initWithCoder:|.
-  NSData* emptyData = [NSKeyedArchiver archivedDataWithRootObject:@""];
-  NSCoder* coder =
-    [[[NSKeyedUnarchiver alloc] initForReadingWithData:emptyData] autorelease];
-  cell.reset([[HyperlinkButtonCell alloc] initWithCoder:coder]);
-  TestCellCustomization(cell);
-}
-
-// Test set color.
-TEST_F(HyperlinkButtonCellTest, SetTextColor) {
-  NSColor* textColor = [NSColor redColor];
-  EXPECT_NE(textColor, [cell_ textColor]);
-  [cell_ setTextColor:textColor];
-  EXPECT_EQ(textColor, [cell_ textColor]);
-}
-
-// Test mouse events.
-// TODO(rsesek): See if we can synthesize mouse events to more accurately
-// test this.
-TEST_F(HyperlinkButtonCellTest, MouseHover) {
-  [[NSCursor disappearingItemCursor] push];  // Set a known state.
-  [cell_ mouseEntered:nil];
-  EXPECT_EQ([NSCursor pointingHandCursor], [NSCursor currentCursor]);
-  [cell_ mouseExited:nil];
-  EXPECT_EQ([NSCursor disappearingItemCursor], [NSCursor currentCursor]);
-  [NSCursor pop];
-}
-
-// Test mouse events when button is disabled. {
-TEST_F(HyperlinkButtonCellTest, MouseHoverWhenDisabled) {
-  [cell_ setEnabled:NO];
-
-  [[NSCursor disappearingItemCursor] push];  // Set a known state.
-  [cell_ mouseEntered:nil];
-  EXPECT_EQ([NSCursor disappearingItemCursor], [NSCursor currentCursor]);
-
-  [cell_ mouseExited:nil];
-  EXPECT_EQ([NSCursor disappearingItemCursor], [NSCursor currentCursor]);
-  [NSCursor pop];
-  [NSCursor pop];
-}
-
-// Test underline on hover.
-TEST_F(HyperlinkButtonCellTest, UnderlineOnHover) {
-  EXPECT_TRUE(HasUnderlineAttribute([cell_ linkAttributes]));
-  [cell_ mouseEntered:nil];
-  EXPECT_TRUE(HasUnderlineAttribute([cell_ linkAttributes]));
-  [cell_ mouseExited:nil];
-  EXPECT_TRUE(HasUnderlineAttribute([cell_ linkAttributes]));
-
-  [cell_ setUnderlineOnHover:YES];
-  EXPECT_FALSE(HasUnderlineAttribute([cell_ linkAttributes]));
-  [cell_ mouseEntered:nil];
-  EXPECT_TRUE(HasUnderlineAttribute([cell_ linkAttributes]));
-  [cell_ mouseExited:nil];
-  EXPECT_FALSE(HasUnderlineAttribute([cell_ linkAttributes]));
-}
diff --git a/chrome/browser/ui/cocoa/info_bubble_window.mm b/chrome/browser/ui/cocoa/info_bubble_window.mm
index 1cc17b8..7c72934 100644
--- a/chrome/browser/ui/cocoa/info_bubble_window.mm
+++ b/chrome/browser/ui/cocoa/info_bubble_window.mm
@@ -7,7 +7,7 @@
 #include "base/basictypes.h"
 #include "base/logging.h"
 #include "base/mac/scoped_nsobject.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_container_controller.mm b/chrome/browser/ui/cocoa/infobars/infobar_container_controller.mm
index 2d33f80..f68a15e 100644
--- a/chrome/browser/ui/cocoa/infobars/infobar_container_controller.mm
+++ b/chrome/browser/ui/cocoa/infobars/infobar_container_controller.mm
@@ -5,6 +5,7 @@
 #include "base/logging.h"
 #include "base/mac/bundle_locations.h"
 #include "base/mac/mac_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar.h"
 #include "chrome/browser/infobars/infobar_service.h"
@@ -13,7 +14,6 @@
 #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h"
 #import "chrome/browser/ui/cocoa/infobars/infobar_controller.h"
 #import "chrome/browser/ui/cocoa/view_id_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "skia/ext/skia_utils_mac.h"
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_container_controller_unittest.mm b/chrome/browser/ui/cocoa/infobars/infobar_container_controller_unittest.mm
index 88d3152..617cf3f 100644
--- a/chrome/browser/ui/cocoa/infobars/infobar_container_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/infobars/infobar_container_controller_unittest.mm
@@ -2,11 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h"
+
 #import <Cocoa/Cocoa.h>
 
 #include "base/mac/scoped_nsobject.h"
 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
-#import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h"
 #include "chrome/browser/ui/cocoa/infobars/mock_confirm_infobar_delegate.h"
 #import "chrome/browser/ui/cocoa/view_resizer_pong.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h
index eadb217..cf21ce0 100644
--- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h
+++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h
@@ -155,8 +155,8 @@
 // Sets the suggest text that shows at the end of the field's normal text.
 // This can't be simply appended to the field's text storage because that
 // will end any pending IME session.
-- (void)setInstantSuggestion:(NSString*)suggestText
-                   textColor:(NSColor*)suggestColor;
+- (void)setGrayTextAutocompletion:(NSString*)suggestText
+                        textColor:(NSColor*)suggestColor;
 
 - (NSString*)suggestText;
 - (NSColor*)suggestColor;
@@ -165,12 +165,12 @@
 
 namespace autocomplete_text_field {
 
-// Draw instant suggestion text in |controlView|.
-void DrawInstantSuggestion(NSAttributedString* mainText,
-                           NSString* suggestText,
-                           NSColor* suggestColor,
-                           NSView* controlView,
-                           NSRect frame);
+// Draw gray text suggestion in |controlView|.
+void DrawGrayTextAutocompletion(NSAttributedString* mainText,
+                                NSString* suggestText,
+                                NSColor* suggestColor,
+                                NSView* controlView,
+                                NSRect frame);
 
 }  // namespace autocomplete_text_field
 
diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.mm
index addda9c..ee2dc0f 100644
--- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.mm
+++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.mm
@@ -234,8 +234,8 @@
   [self addToolTipRect:aRect owner:tooltip userData:nil];
 }
 
-- (void)setInstantSuggestion:(NSString*)suggestText
-                   textColor:(NSColor*)suggestColor {
+- (void)setGrayTextAutocompletion:(NSString*)suggestText
+                        textColor:(NSColor*)suggestColor {
   [self setNeedsDisplay:YES];
   suggestText_.reset([suggestText retain]);
   suggestColor_.reset([suggestColor retain]);
@@ -388,7 +388,7 @@
 
 - (void)drawRect:(NSRect)rect {
   [super drawRect:rect];
-  autocomplete_text_field::DrawInstantSuggestion(
+  autocomplete_text_field::DrawGrayTextAutocompletion(
       [self attributedStringValue],
       suggestText_,
       suggestColor_,
@@ -441,11 +441,11 @@
 
 namespace autocomplete_text_field {
 
-void DrawInstantSuggestion(NSAttributedString* mainText,
-                           NSString* suggestText,
-                           NSColor* suggestColor,
-                           NSView* controlView,
-                           NSRect frame) {
+void DrawGrayTextAutocompletion(NSAttributedString* mainText,
+                                NSString* suggestText,
+                                NSColor* suggestColor,
+                                NSView* controlView,
+                                NSRect frame) {
   if (![suggestText length])
     return;
 
diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm
index 1c7b087..9e67806 100644
--- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm
+++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm
@@ -539,7 +539,7 @@
 
 - (void)drawRect:(NSRect)rect {
   [super drawRect:rect];
-  autocomplete_text_field::DrawInstantSuggestion(
+  autocomplete_text_field::DrawGrayTextAutocompletion(
       [self textStorage],
       [[self delegate] suggestText],
       [[self delegate] suggestColor],
diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm
index dac079a..b2382f3 100644
--- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm
+++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm
@@ -188,11 +188,11 @@
   [editor_ display];
 }
 
-// Test setting instant suggestion, mostly to ensure nothing leaks or crashes.
-TEST_F(AutocompleteTextFieldEditorTest, InstantSuggestion) {
+// Test setting gray text, mostly to ensure nothing leaks or crashes.
+TEST_F(AutocompleteTextFieldEditorTest, GrayText) {
   [editor_ display];
   EXPECT_FALSE([editor_ needsDisplay]);
-  [field_ setInstantSuggestion:@"foo" textColor:[NSColor redColor]];
+  [field_ setGrayTextAutocompletion:@"foo" textColor:[NSColor redColor]];
   EXPECT_TRUE([editor_ needsDisplay]);
   [editor_ display];
 }
diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm
index 72ffc7a..f667397 100644
--- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm
+++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm
@@ -217,11 +217,11 @@
   [field_ display];
 }
 
-// Test setting instant suggestion, mostly to ensure nothing leaks or crashes.
-TEST_F(AutocompleteTextFieldTest, InstantSuggestion) {
+// Test setting gray text, mostly to ensure nothing leaks or crashes.
+TEST_F(AutocompleteTextFieldTest, GrayText) {
   [field_ display];
   EXPECT_FALSE([field_ needsDisplay]);
-  [field_ setInstantSuggestion:@"foo" textColor:[NSColor redColor]];
+  [field_ setGrayTextAutocompletion:@"foo" textColor:[NSColor redColor]];
   EXPECT_TRUE([field_ needsDisplay]);
   [field_ display];
 }
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
index 3948654..69af462 100644
--- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
+++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
@@ -54,8 +54,6 @@
 
   // Overridden from LocationBar:
   virtual void ShowFirstRunBubble() OVERRIDE;
-  virtual void SetInstantSuggestion(
-      const InstantSuggestion& suggestion) OVERRIDE;
   virtual string16 GetInputString() const OVERRIDE;
   virtual WindowOpenDisposition GetWindowOpenDisposition() const OVERRIDE;
   virtual content::PageTransition GetPageTransition() const OVERRIDE;
@@ -66,6 +64,7 @@
   virtual void UpdatePageActions() OVERRIDE;
   virtual void InvalidatePageActions() OVERRIDE;
   virtual void UpdateOpenPDFInReaderPrompt() OVERRIDE;
+  virtual void UpdateAutofillCreditCardView() OVERRIDE;
   virtual void SaveStateToContents(content::WebContents* contents) OVERRIDE;
   virtual void Revert() OVERRIDE;
   virtual const OmniboxView* GetLocationEntry() const OVERRIDE;
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
index 8e871d2..f5bfced 100644
--- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
+++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
@@ -14,6 +14,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #import "chrome/browser/app_controller_mac.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/extensions/api/omnibox/omnibox_api.h"
@@ -50,7 +51,6 @@
 #import "chrome/browser/ui/omnibox/omnibox_popup_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/zoom/zoom_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/feature_switch.h"
@@ -165,11 +165,6 @@
   return location_input_;
 }
 
-void LocationBarViewMac::SetInstantSuggestion(
-    const InstantSuggestion& suggestion) {
-  omnibox_view_->model()->SetInstantSuggestion(suggestion);
-}
-
 WindowOpenDisposition LocationBarViewMac::GetWindowOpenDisposition() const {
   return disposition_;
 }
@@ -227,6 +222,11 @@
   // Not implemented on Mac.
 }
 
+void LocationBarViewMac::UpdateAutofillCreditCardView() {
+  // TODO(dbeam): encourage groby@ to implement via prodding or chocolate.
+  NOTIMPLEMENTED();
+}
+
 void LocationBarViewMac::SaveStateToContents(WebContents* contents) {
   // TODO(shess): Why SaveStateToContents vs SaveStateToTab?
   omnibox_view_->SaveStateToTab(contents);
diff --git a/chrome/browser/ui/cocoa/location_bar/location_icon_decoration.mm b/chrome/browser/ui/cocoa/location_bar/location_icon_decoration.mm
index eeaf783..1e96e67 100644
--- a/chrome/browser/ui/cocoa/location_bar/location_icon_decoration.mm
+++ b/chrome/browser/ui/cocoa/location_bar/location_icon_decoration.mm
@@ -105,7 +105,7 @@
   }
   Browser* browser = chrome::FindBrowserWithWebContents(tab);
   chrome::ShowWebsiteSettings(browser, tab, nav_entry->GetURL(),
-                              nav_entry->GetSSL(), true);
+                              nav_entry->GetSSL());
   return true;
 }
 
diff --git a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h
index 74f56cc..55a4cd4 100644
--- a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h
+++ b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h
@@ -10,7 +10,7 @@
 #import "chrome/browser/ui/cocoa/location_bar/image_decoration.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 @class ExtensionActionContextMenu;
 class Browser;
diff --git a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm
index c0c1160..b885b80 100644
--- a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm
+++ b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm
@@ -7,6 +7,7 @@
 #import "chrome/browser/ui/cocoa/location_bar/page_action_decoration.h"
 
 #include "base/strings/sys_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
@@ -22,7 +23,6 @@
 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
 #include "chrome/browser/ui/omnibox/location_bar_util.h"
 #include "chrome/browser/ui/webui/extensions/extension_info_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.h b/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.h
index d78a910..2b4daf1 100644
--- a/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.h
+++ b/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.h
@@ -36,7 +36,6 @@
   virtual void OnMessageCenterTrayChanged() OVERRIDE;
   virtual bool ShowPopups() OVERRIDE;
   virtual void HidePopups() OVERRIDE;
-  virtual void UpdatePopups() OVERRIDE;
   virtual bool ShowMessageCenter() OVERRIDE;
   virtual void HideMessageCenter() OVERRIDE;
   virtual bool ShowNotifierSettings() OVERRIDE;
diff --git a/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm b/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm
index adca08e..25595e7 100644
--- a/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm
+++ b/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm
@@ -57,11 +57,6 @@
   popup_collection_.reset();
 }
 
-void MessageCenterTrayBridge::UpdatePopups() {
-  // Nothing to do since the popup collection observes the MessageCenter
-  // directly.
-}
-
 bool MessageCenterTrayBridge::ShowMessageCenter() {
   if (tray_controller_)
     return false;
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h
index 0012560..b52da56 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h
@@ -60,8 +60,8 @@
   virtual bool OnAfterPossibleChange() OVERRIDE;
   virtual gfx::NativeView GetNativeView() const OVERRIDE;
   virtual gfx::NativeView GetRelativeWindowForPopup() const OVERRIDE;
-  virtual void SetInstantSuggestion(const string16& input) OVERRIDE;
-  virtual string16 GetInstantSuggestion() const OVERRIDE;
+  virtual void SetGrayTextAutocompletion(const string16& input) OVERRIDE;
+  virtual string16 GetGrayTextAutocompletion() const OVERRIDE;
   virtual int TextWidth() const OVERRIDE;
   virtual bool IsImeComposing() const OVERRIDE;
 
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
index 7a2ce85..e0bc46d 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
@@ -525,16 +525,9 @@
 void OmniboxViewMac::OnRevertTemporaryText() {
   SetSelectedRange(saved_temporary_selection_);
   // We got here because the user hit the Escape key. We explicitly don't call
-  // TextChanged(), since calling it breaks Instant-Extended, and isn't needed
-  // otherwise (in regular non-Instant or Instant-but-not-Extended modes).
-  //
-  // Why it breaks Instant-Extended: Instant handles the Escape key separately
-  // (cf: OmniboxEditModel::RevertTemporaryText). Calling TextChanged() makes
-  // the page think the user additionally typed some text, causing it to update
-  // its suggestions dropdown with new suggestions, which is wrong.
-  //
-  // Why it isn't needed: OmniboxPopupModel::ResetToDefaultMatch() has already
-  // been called by now; it would've called TextChanged() if it was warranted.
+  // TextChanged(), since OmniboxPopupModel::ResetToDefaultMatch() has already
+  // been called by now, and it would've called TextChanged() if it was
+  // warranted.
 }
 
 bool OmniboxViewMac::IsFirstResponder() const {
@@ -611,15 +604,15 @@
   return NULL;
 }
 
-void OmniboxViewMac::SetInstantSuggestion(const string16& suggest_text) {
+void OmniboxViewMac::SetGrayTextAutocompletion(const string16& suggest_text) {
   if (suggest_text == suggest_text_)
     return;
   suggest_text_ = suggest_text;
-  [field_ setInstantSuggestion:base::SysUTF16ToNSString(suggest_text)
-                     textColor:SuggestTextColor()];
+  [field_ setGrayTextAutocompletion:base::SysUTF16ToNSString(suggest_text)
+                          textColor:SuggestTextColor()];
 }
 
-string16 OmniboxViewMac::GetInstantSuggestion() const {
+string16 OmniboxViewMac::GetGrayTextAutocompletion() const {
   return suggest_text_;
 }
 
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm
index e9d77a3..de9f42a 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm
@@ -144,7 +144,7 @@
   EXPECT_EQ(-1, model->up_or_down_count());
 }
 
-TEST_F(OmniboxViewMacTest, SetInstantSuggestion) {
+TEST_F(OmniboxViewMacTest, SetGrayTextAutocompletion) {
   const NSRect frame = NSMakeRect(0, 0, 50, 30);
   base::scoped_nsobject<AutocompleteTextField> field(
       [[AutocompleteTextField alloc] initWithFrame:frame]);
@@ -164,13 +164,13 @@
 
   view.SetUserText(ASCIIToUTF16("Alfred"));
   EXPECT_EQ("Alfred", UTF16ToUTF8(view.GetText()));
-  view.SetInstantSuggestion(ASCIIToUTF16(" Hitchcock"));
+  view.SetGrayTextAutocompletion(ASCIIToUTF16(" Hitchcock"));
   EXPECT_EQ("Alfred", UTF16ToUTF8(view.GetText()));
-  EXPECT_EQ(" Hitchcock", UTF16ToUTF8(view.GetInstantSuggestion()));
+  EXPECT_EQ(" Hitchcock", UTF16ToUTF8(view.GetGrayTextAutocompletion()));
 
   view.SetUserText(string16());
   EXPECT_EQ(string16(), view.GetText());
-  EXPECT_EQ(string16(), view.GetInstantSuggestion());
+  EXPECT_EQ(string16(), view.GetGrayTextAutocompletion());
 }
 
 TEST_F(OmniboxViewMacTest, UpDownArrow) {
diff --git a/chrome/browser/ui/cocoa/one_click_signin_bubble_controller.mm b/chrome/browser/ui/cocoa/one_click_signin_bubble_controller.mm
index a3d97fa..4528076 100644
--- a/chrome/browser/ui/cocoa/one_click_signin_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/one_click_signin_bubble_controller.mm
@@ -31,6 +31,7 @@
          syncCallback:syncCallback
         closeCallback:base::Bind(PerformClose, self)
          isSyncDialog:NO
+                email:string16()
          errorMessage:errorMessage]);
 
   NSWindow* parentWindow = [controller window];
diff --git a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h
index 4a7f082..6a2f56d 100644
--- a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h
+++ b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h
@@ -21,9 +21,13 @@
 // signin confirmation dialog.
 class OneClickSigninDialogController : public ConstrainedWindowMacDelegate {
  public:
+  // Creates an OneClickSigninDialogController. |web_contents| is used to
+  // open links, |email| is the user's email address that is used for sync,
+  // and |sync_callback| is called to start sync.
   OneClickSigninDialogController(
       content::WebContents* web_contents,
-      const BrowserWindow::StartSyncCallback& sync_callback);
+      const BrowserWindow::StartSyncCallback& sync_callback,
+      const string16& email);
   virtual ~OneClickSigninDialogController();
 
   // ConstrainedWindowMacDelegate implementation.
diff --git a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm
index 6078a50..eadf20a 100644
--- a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm
+++ b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm
@@ -12,7 +12,8 @@
 
 OneClickSigninDialogController::OneClickSigninDialogController(
     content::WebContents* web_contents,
-    const BrowserWindow::StartSyncCallback& sync_callback) {
+    const BrowserWindow::StartSyncCallback& sync_callback,
+    const string16& email) {
   base::Closure close_callback = base::Bind(
       &OneClickSigninDialogController::PerformClose, base::Unretained(this));
   view_controller_.reset([[OneClickSigninViewController alloc]
@@ -21,6 +22,7 @@
          syncCallback:sync_callback
         closeCallback:close_callback
          isSyncDialog:YES
+                email:email
          errorMessage:nil]);
   base::scoped_nsobject<NSWindow> window([[ConstrainedWindowCustomWindow alloc]
       initWithContentRect:[[view_controller_ view] bounds]]);
diff --git a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller_browsertest.mm b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller_browsertest.mm
index f3a32a7..ec8ce3e 100644
--- a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller_browsertest.mm
+++ b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller_browsertest.mm
@@ -26,7 +26,8 @@
     BrowserWindow::StartSyncCallback callback = base::Bind(
         &OneClickSigninDialogControllerTest::OnStartSyncCallback,
         base::Unretained(this));
-    controller_ = new OneClickSigninDialogController(web_contents, callback);
+    controller_ = new OneClickSigninDialogController(
+        web_contents, callback, string16());
     EXPECT_NSEQ(@"OneClickSigninDialog",
                 [controller_->view_controller() nibName]);
   }
diff --git a/chrome/browser/ui/cocoa/one_click_signin_view_controller.h b/chrome/browser/ui/cocoa/one_click_signin_view_controller.h
index 02d71ae..751970a 100644
--- a/chrome/browser/ui/cocoa/one_click_signin_view_controller.h
+++ b/chrome/browser/ui/cocoa/one_click_signin_view_controller.h
@@ -31,6 +31,10 @@
   // This is YES if the user clicked the Learn More link before another action.
   BOOL clickedLearnMore_;
 
+  // The user's email address to be used for sync.
+  string16 email_;
+
+  // Alternate error message to be displayed.
   base::scoped_nsobject<NSString> errorMessage_;
 
   // Text fields don't work as well with embedded links as text views, but
@@ -44,15 +48,16 @@
 }
 
 // Initializes the controller from a nib file, with an alternate |errorMessage|
-// that can be displayed in the case of an authentication error,
-// |syncCallback| is called to start sync if |isSyncDialog| is YES,
-// |webContents| is used to open the Learn More and Advanced links and
-// |callback| is called when the view is closing.
+// that can be displayed in the case of an authentication error.
+// |syncCallback| is called to start sync for the given |email|, if
+// |isSyncDialog| is YES. |webContents| is used to open the Learn More and
+// Advanced links and |callback| is called when the view is closing.
 - (id)initWithNibName:(NSString*)nibName
           webContents:(content::WebContents*)webContents
          syncCallback:(const BrowserWindow::StartSyncCallback&)syncCallback
         closeCallback:(const base::Closure&)callback
          isSyncDialog:(BOOL)isSyncDialog
+                email:(const string16&)email
          errorMessage:(NSString*)errorMessage;
 
 // Called before the view is closed.
diff --git a/chrome/browser/ui/cocoa/one_click_signin_view_controller.mm b/chrome/browser/ui/cocoa/one_click_signin_view_controller.mm
index 728bcdc..b663214 100644
--- a/chrome/browser/ui/cocoa/one_click_signin_view_controller.mm
+++ b/chrome/browser/ui/cocoa/one_click_signin_view_controller.mm
@@ -13,6 +13,7 @@
 #include "chrome/browser/ui/sync/one_click_signin_histogram.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/web_contents.h"
+#include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "skia/ext/skia_utils_mac.h"
 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
@@ -43,6 +44,7 @@
          syncCallback:(const BrowserWindow::StartSyncCallback&)syncCallback
         closeCallback:(const base::Closure&)closeCallback
          isSyncDialog:(BOOL)isSyncDialog
+                email:(const string16&)email
          errorMessage:(NSString*)errorMessage {
   if ((self = [super initWithNibName:nibName
                               bundle:base::mac::FrameworkBundle()])) {
@@ -51,6 +53,7 @@
     closeCallback_ = closeCallback;
     isSyncDialog_ = isSyncDialog;
     clickedLearnMore_ = NO;
+    email_ = email;
     errorMessage_.reset([errorMessage retain]);
     if (isSyncDialog_)
       DCHECK(!startSyncCallback_.is_null());
@@ -90,7 +93,6 @@
 
     base::ResetAndReturn(&startSyncCallback_).Run(
       OneClickSigninSyncStarter::UNDO_SYNC);
-
   }
   [self close];
 }
@@ -164,8 +166,12 @@
 
   NSSize delta = NSMakeSize(0.0, totalYOffset);
 
-  if (!isSyncDialog_ && [errorMessage_ length] != 0)
+  if (isSyncDialog_) {
+    [messageTextField_ setStringValue:l10n_util::GetNSStringFWithFixup(
+        IDS_ONE_CLICK_SIGNIN_DIALOG_TITLE_NEW, email_)];
+  } else if ([errorMessage_ length] != 0) {
     [messageTextField_ setStringValue:errorMessage_];
+  }
 
   // Resize bubble and window to hold the controls.
   [GTMUILocalizerAndLayoutTweaker
@@ -203,8 +209,8 @@
   // The non-modal bubble already has a text content and only needs the
   // Learn More link (in a smaller font).
   if (isSyncDialog_) {
-    messageText = l10n_util::GetNSStringWithFixup(
-      IDS_ONE_CLICK_SIGNIN_DIALOG_MESSAGE);
+    messageText = l10n_util::GetNSStringFWithFixup(
+        IDS_ONE_CLICK_SIGNIN_DIALOG_MESSAGE_NEW, email_);
     messageText = [messageText stringByAppendingString:@" "];
   } else {
     messageText = @"";
diff --git a/chrome/browser/ui/cocoa/panels/display_settings_provider_cocoa.mm b/chrome/browser/ui/cocoa/panels/display_settings_provider_cocoa.mm
index 2d20e09..098580f 100644
--- a/chrome/browser/ui/cocoa/panels/display_settings_provider_cocoa.mm
+++ b/chrome/browser/ui/cocoa/panels/display_settings_provider_cocoa.mm
@@ -6,12 +6,13 @@
 #include "base/mac/mac_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/fullscreen.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h"
 #include "chrome/browser/ui/panels/display_settings_provider.h"
 #import "chrome/browser/app_controller_mac.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
@@ -93,13 +94,13 @@
   // So we don't need to do anything when any other application enters
   // fullscreen mode. We still need to handle the case when chrome enters
   // fullscreen mode and our topmost windows will not get hided by the system.
-  return !base::mac::IsOSLionOrLater();
+  return !chrome::mac::SupportsSystemFullscreen();
 }
 
 bool DisplaySettingsProviderCocoa::IsFullScreen() {
   // For Lion and later, we only need to check if chrome enters fullscreen mode
   // (see detailed reason above in NeedsPeriodicFullScreenCheck).
-  if (!base::mac::IsOSLionOrLater())
+  if (!chrome::mac::SupportsSystemFullscreen())
     return DisplaySettingsProvider::IsFullScreen();
 
   Browser* browser = chrome::GetLastActiveBrowser();
diff --git a/chrome/browser/ui/cocoa/panels/panel_cocoa.mm b/chrome/browser/ui/cocoa/panels/panel_cocoa.mm
index 01375ce..98bc89d 100644
--- a/chrome/browser/ui/cocoa/panels/panel_cocoa.mm
+++ b/chrome/browser/ui/cocoa/panels/panel_cocoa.mm
@@ -351,6 +351,7 @@
   virtual bool IsButtonVisible(
       panel::TitlebarButtonType button_type) const OVERRIDE;
   virtual panel::CornerStyle GetWindowCornerStyle() const OVERRIDE;
+  virtual bool EnsureApplicationRunOnForeground() OVERRIDE;
 
  private:
   PanelTitlebarViewCocoa* titlebar() const;
@@ -455,3 +456,10 @@
 panel::CornerStyle CocoaNativePanelTesting::GetWindowCornerStyle() const {
   return native_panel_window_->corner_style_;
 }
+
+bool CocoaNativePanelTesting::EnsureApplicationRunOnForeground() {
+  if ([NSApp isActive])
+    return true;
+  [NSApp activateIgnoringOtherApps:YES];
+  return [NSApp isActive];
+}
diff --git a/chrome/browser/ui/cocoa/panels/panel_cocoa_browsertest.mm b/chrome/browser/ui/cocoa/panels/panel_cocoa_browsertest.mm
index 7ca3f10..6f8cc1c 100644
--- a/chrome/browser/ui/cocoa/panels/panel_cocoa_browsertest.mm
+++ b/chrome/browser/ui/cocoa/panels/panel_cocoa_browsertest.mm
@@ -5,11 +5,11 @@
 #import <Cocoa/Cocoa.h>
 
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/panels/base_panel_browser_test.h"
 #include "chrome/browser/ui/panels/panel.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/test/test_utils.h"
 
 typedef BasePanelBrowserTest PanelCocoaBrowserTest;
diff --git a/chrome/browser/ui/cocoa/panels/panel_cocoa_unittest.mm b/chrome/browser/ui/cocoa/panels/panel_cocoa_unittest.mm
index a817812..81e5651 100644
--- a/chrome/browser/ui/cocoa/panels/panel_cocoa_unittest.mm
+++ b/chrome/browser/ui/cocoa/panels/panel_cocoa_unittest.mm
@@ -11,6 +11,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/sys_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"  // IDC_*
+#include "chrome/browser/chrome_notification_types.h"
 #import "chrome/browser/ui/cocoa/browser_window_utils.h"
 #import "chrome/browser/ui/cocoa/cocoa_profile_test.h"
 #import "chrome/browser/ui/cocoa/panels/panel_cocoa.h"
@@ -19,7 +20,6 @@
 #import "chrome/browser/ui/cocoa/run_loop_testing.h"
 #include "chrome/browser/ui/panels/panel.h"
 #include "chrome/browser/ui/panels/panel_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/ui/cocoa/presentation_mode_controller.mm b/chrome/browser/ui/cocoa/presentation_mode_controller.mm
index ccba724..0448db2 100644
--- a/chrome/browser/ui/cocoa/presentation_mode_controller.mm
+++ b/chrome/browser/ui/cocoa/presentation_mode_controller.mm
@@ -8,6 +8,7 @@
 
 #include "base/command_line.h"
 #import "base/mac/mac_util.h"
+#include "chrome/browser/fullscreen.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
 #include "chrome/common/chrome_switches.h"
 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h"
@@ -421,7 +422,7 @@
 }
 
 - (BOOL)shouldToggleMenuBar {
-  return base::mac::IsOSSnowLeopard() &&
+  return !chrome::mac::SupportsSystemFullscreen() &&
          [self isWindowOnPrimaryScreen] &&
          [[browserController_ window] isMainWindow];
 }
diff --git a/chrome/browser/ui/cocoa/profile_signin_confirmation_view_controller.mm b/chrome/browser/ui/cocoa/profile_signin_confirmation_view_controller.mm
index 367556b..51087ef 100644
--- a/chrome/browser/ui/cocoa/profile_signin_confirmation_view_controller.mm
+++ b/chrome/browser/ui/cocoa/profile_signin_confirmation_view_controller.mm
@@ -16,7 +16,6 @@
 #import "chrome/browser/ui/chrome_style.h"
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_control_utils.h"
 #import "chrome/browser/ui/cocoa/hover_close_button.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/sync/profile_signin_confirmation_helper.h"
@@ -26,6 +25,7 @@
 #include "grit/generated_resources.h"
 #include "skia/ext/skia_utils_mac.h"
 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+#import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #include "ui/base/l10n/l10n_util.h"
 
 namespace {
diff --git a/chrome/browser/ui/cocoa/status_bubble_mac.h b/chrome/browser/ui/cocoa/status_bubble_mac.h
index 1366220..d38c9e5 100644
--- a/chrome/browser/ui/cocoa/status_bubble_mac.h
+++ b/chrome/browser/ui/cocoa/status_bubble_mac.h
@@ -14,7 +14,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/ui/status_bubble.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class StatusBubbleMacTest;
 
diff --git a/chrome/browser/ui/cocoa/status_bubble_mac_unittest.mm b/chrome/browser/ui/cocoa/status_bubble_mac_unittest.mm
index ffd903b..e16feab 100644
--- a/chrome/browser/ui/cocoa/status_bubble_mac_unittest.mm
+++ b/chrome/browser/ui/cocoa/status_bubble_mac_unittest.mm
@@ -11,11 +11,11 @@
 #import "chrome/browser/ui/cocoa/bubble_view.h"
 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
 #import "chrome/browser/ui/cocoa/status_bubble_mac.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
 #include "ui/gfx/point.h"
+#include "url/gurl.h"
 
 // The test delegate records all of the status bubble object's state
 // transitions.
@@ -34,7 +34,7 @@
 - (id)initWithWindow:(NSWindow*)window {
   if ((self = [super init])) {
     window_ = window;
-    baseFrameOffset_ = NSMakePoint(0, 0);
+    baseFrameOffset_ = NSZeroPoint;
   }
   return self;
 }
diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.mm
index 0662eb8..411ffff 100644
--- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.mm
+++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.mm
@@ -6,7 +6,6 @@
 
 #include "base/logging.h"
 #include "base/strings/sys_string_conversions.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h"
 #include "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm
index e9b938e..bdca853 100644
--- a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm
+++ b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm
@@ -11,6 +11,7 @@
 #import "chrome/browser/ui/cocoa/key_equivalent_constants.h"
 #include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
 #include "chrome/common/chrome_switches.h"
+#include "ui/base/cocoa/cocoa_event_utils.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 #include "ui/gfx/image/image.h"
 
@@ -45,6 +46,12 @@
   delegate_->Cancel();
 }
 
+- (void)onLinkClicked:(id)sender {
+  WindowOpenDisposition disposition =
+      ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
+  delegate_->LinkClicked(disposition);
+}
+
 @end
 
 TabModalConfirmDialogMac::TabModalConfirmDialogMac(
@@ -57,6 +64,10 @@
   alert_.reset([[ConstrainedWindowAlert alloc] init]);
   [alert_ setMessageText:
       l10n_util::FixUpWindowsStyleLabel(delegate->GetTitle())];
+  [alert_ setLinkText:l10n_util::FixUpWindowsStyleLabel(
+                          delegate->GetLinkText())
+               target:bridge_
+               action:@selector(onLinkClicked:)];
   [alert_ setInformativeText:
       l10n_util::FixUpWindowsStyleLabel(delegate->GetMessage())];
   [alert_ addButtonWithTitle:
diff --git a/chrome/browser/ui/cocoa/tabs/OWNERS b/chrome/browser/ui/cocoa/tabs/OWNERS
index 30d99dc..c7f0be3 100644
--- a/chrome/browser/ui/cocoa/tabs/OWNERS
+++ b/chrome/browser/ui/cocoa/tabs/OWNERS
@@ -1,4 +1,3 @@
 avi@chromium.org
 pinkerton@chromium.org
 rohitrao@chromium.org
-viettrungluu@chromium.org
diff --git a/chrome/browser/ui/cocoa/tabs/tab_controller.h b/chrome/browser/ui/cocoa/tabs/tab_controller.h
index 93cdbe4..3b516f7 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_controller.h
+++ b/chrome/browser/ui/cocoa/tabs/tab_controller.h
@@ -10,7 +10,7 @@
 #import "chrome/browser/ui/cocoa/hover_close_button.h"
 #import "chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.h"
 #include "chrome/browser/ui/tabs/tab_menu_model.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 // The loading/waiting state of the tab.
 enum TabLoadingState {
diff --git a/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm b/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
index ad24ca7..0267e79 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
@@ -182,7 +182,7 @@
   [[window contentView] addSubview:[controller view]];
   NSRect frame = [[controller view] frame];
   frame.size.width = [TabController minTabWidth];
-  frame.origin = NSMakePoint(0, 0);
+  frame.origin = NSZeroPoint;
   [[controller view] setFrame:frame];
 
   // Set the target and action.
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
index b7f1c9d..7bbea78 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
@@ -539,7 +539,7 @@
                                                        controller:self]);
     [self addSubviewToPermanentList:dragBlockingView_];
 
-    newTabTargetFrame_ = NSMakeRect(0, 0, 0, 0);
+    newTabTargetFrame_ = NSZeroRect;
     availableResizeWidth_ = kUseFullAvailableWidth;
 
     closingControllers_.reset([[NSMutableSet alloc] init]);
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm
index cf230d1..84cb900 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm
@@ -188,7 +188,7 @@
   // Check that there's no tooltip yet.
   EXPECT_FALSE([controller_ view:nil
                 stringForToolTip:nil
-                           point:NSMakePoint(0,0)
+                           point:NSZeroPoint
                         userData:nil]);
 
   // Set up mouse event on overlap of tab1 + tab2.
@@ -202,7 +202,7 @@
   EXPECT_STREQ("Tab2",
       [[controller_ view:nil
         stringForToolTip:nil
-                   point:NSMakePoint(0,0)
+                   point:NSZeroPoint
                 userData:nil] cStringUsingEncoding:NSASCIIStringEncoding]);
 
 
@@ -213,7 +213,7 @@
   EXPECT_STREQ("Tab1",
       [[controller_ view:nil
         stringForToolTip:nil
-                   point:NSMakePoint(0,0)
+                   point:NSZeroPoint
                 userData:nil] cStringUsingEncoding:NSASCIIStringEncoding]);
 
   // Hover over tab 2.
@@ -223,7 +223,7 @@
   EXPECT_STREQ("Tab2",
       [[controller_ view:nil
         stringForToolTip:nil
-                   point:NSMakePoint(0,0)
+                   point:NSZeroPoint
                 userData:nil] cStringUsingEncoding:NSASCIIStringEncoding]);
 }
 
@@ -246,7 +246,7 @@
   [runner scheduleDelayedRun];
 
   NSEvent* event =
-      cocoa_test_event_utils::LeftMouseDownAtPoint(NSMakePoint(0, 0));
+      cocoa_test_event_utils::LeftMouseDownAtPoint(NSZeroPoint);
   [[controller_ dragController] maybeStartDrag:event forTab:tab];
 }
 
diff --git a/chrome/browser/ui/cocoa/toolbar/OWNERS b/chrome/browser/ui/cocoa/toolbar/OWNERS
index 5d0c2e4..18d19b1 100644
--- a/chrome/browser/ui/cocoa/toolbar/OWNERS
+++ b/chrome/browser/ui/cocoa/toolbar/OWNERS
@@ -2,4 +2,3 @@
 pinkerton@chromium.org
 rohitrao@chromium.org
 shess@chromium.org
-viettrungluu@chromium.org
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm
index 15cc8fb..f942a1d 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm
@@ -17,6 +17,7 @@
 #include "chrome/browser/autocomplete/autocomplete_classifier.h"
 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/net/url_fixer_upper.h"
 #include "chrome/browser/profiles/profile.h"
@@ -49,7 +50,6 @@
 #include "chrome/browser/ui/toolbar/toolbar_model.h"
 #include "chrome/browser/ui/toolbar/wrench_menu_model.h"
 #include "chrome/browser/upgrade_detector.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_observer.h"
diff --git a/chrome/browser/ui/cocoa/url_drop_target.mm b/chrome/browser/ui/cocoa/url_drop_target.mm
index 1243e72..b1d6fd2 100644
--- a/chrome/browser/ui/cocoa/url_drop_target.mm
+++ b/chrome/browser/ui/cocoa/url_drop_target.mm
@@ -6,8 +6,8 @@
 
 #include "base/basictypes.h"
 #include "chrome/browser/ui/cocoa/drag_util.h"
-#include "googleurl/src/gurl.h"
 #import "third_party/mozilla/NSPasteboard+Utils.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/cocoa/view_id_util_browsertest.mm b/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
index 3cf0dc9..6fcafbc 100644
--- a/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
+++ b/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
@@ -70,7 +70,8 @@
       if (i == VIEW_ID_STAR_BUTTON ||
           i == VIEW_ID_CONTENTS_SPLIT ||
           i == VIEW_ID_FEEDBACK_BUTTON ||
-          i == VIEW_ID_SCRIPT_BUBBLE) {
+          i == VIEW_ID_SCRIPT_BUBBLE ||
+          i == VIEW_ID_MIC_SEARCH_BUTTON) {
         continue;
       }
 
diff --git a/chrome/browser/ui/cocoa/web_dialog_window_controller_unittest.mm b/chrome/browser/ui/cocoa/web_dialog_window_controller_unittest.mm
index 0f8ebef..c3bb0d6 100644
--- a/chrome/browser/ui/cocoa/web_dialog_window_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/web_dialog_window_controller_unittest.mm
@@ -18,11 +18,11 @@
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_message_handler.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/size.h"
 #include "ui/web_dialogs/web_dialog_delegate.h"
+#include "url/gurl.h"
 
 using content::WebContents;
 using content::WebUIMessageHandler;
diff --git a/chrome/browser/ui/cocoa/website_settings_bubble_controller.mm b/chrome/browser/ui/cocoa/website_settings_bubble_controller.mm
index b66584f..d131376 100644
--- a/chrome/browser/ui/cocoa/website_settings_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/website_settings_bubble_controller.mm
@@ -14,7 +14,6 @@
 #include "chrome/browser/infobars/infobar_service.h"
 #import "chrome/browser/ui/browser_dialogs.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
-#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
@@ -29,6 +28,7 @@
 #include "grit/theme_resources.h"
 #include "grit/ui_resources.h"
 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+#import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #import "ui/base/cocoa/flipped_view.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -513,19 +513,14 @@
 // Handler for the link button to show certificate information.
 - (void)showCertificateInfo:(id)sender {
   DCHECK(certificateId_);
-  ShowCertificateViewerByID(webContents_,
-                            [self parentWindow],
-                            certificateId_);
+  ShowCertificateViewerByID(webContents_, [self parentWindow], certificateId_);
 }
 
 // Handler for the link to show help information about the connection tab.
 - (void)showHelpPage:(id)sender {
   webContents_->OpenURL(content::OpenURLParams(
-      GURL(chrome::kPageInfoHelpCenterURL),
-      content::Referrer(),
-      NEW_FOREGROUND_TAB,
-      content::PAGE_TRANSITION_LINK,
-      false));
+      GURL(chrome::kPageInfoHelpCenterURL), content::Referrer(),
+      NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK, false));
 }
 
 // Create the contents of the Connection tab and add it to the given tab view.
diff --git a/chrome/browser/ui/collected_cookies_infobar_delegate.cc b/chrome/browser/ui/collected_cookies_infobar_delegate.cc
index e106cc7..e335e4d 100644
--- a/chrome/browser/ui/collected_cookies_infobar_delegate.cc
+++ b/chrome/browser/ui/collected_cookies_infobar_delegate.cc
@@ -22,6 +22,9 @@
     : ConfirmInfoBarDelegate(infobar_service) {
 }
 
+CollectedCookiesInfoBarDelegate::~CollectedCookiesInfoBarDelegate() {
+}
+
 int CollectedCookiesInfoBarDelegate::GetIconID() const {
   return IDR_INFOBAR_COOKIE;
 }
diff --git a/chrome/browser/ui/collected_cookies_infobar_delegate.h b/chrome/browser/ui/collected_cookies_infobar_delegate.h
index 7dc87b5..2c0e1a7 100644
--- a/chrome/browser/ui/collected_cookies_infobar_delegate.h
+++ b/chrome/browser/ui/collected_cookies_infobar_delegate.h
@@ -21,6 +21,7 @@
 
  private:
   explicit CollectedCookiesInfoBarDelegate(InfoBarService* infobar_service);
+  virtual ~CollectedCookiesInfoBarDelegate();
 
   // ConfirmInfoBarDelegate:
   virtual int GetIconID() const OVERRIDE;
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
index dae1522a..d73ffb3 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -6,6 +6,7 @@
 
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_utils.h"
 #include "chrome/browser/content_settings/cookie_settings.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
 #include "chrome/browser/ui/content_settings/content_setting_bubble_model_delegate.h"
 #include "chrome/browser/ui/content_settings/content_setting_changed_infobar_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/render_messages.h"
@@ -84,11 +84,11 @@
     ContentSettingsType content_type)
     : ContentSettingBubbleModel(web_contents, profile, content_type),
         delegate_(delegate) {
-   // Notifications do not have a bubble.
-   DCHECK_NE(content_type, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
-   SetBlockedResources();
-   SetTitle();
-   SetManageLink();
+  // Notifications do not have a bubble.
+  DCHECK_NE(content_type, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
+  SetBlockedResources();
+  SetTitle();
+  SetManageLink();
 }
 
 void ContentSettingTitleAndLinkModel::SetBlockedResources() {
@@ -113,6 +113,7 @@
         IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT},
     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER,
         IDS_BLOCKED_PPAPI_BROKER_TITLE},
+    {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_BLOCKED_DOWNLOAD_TITLE},
   };
   // Fields as for kBlockedTitleIDs, above.
   static const ContentSettingsTypeIdEntry
@@ -122,6 +123,7 @@
   static const ContentSettingsTypeIdEntry kAccessedTitleIDs[] = {
     {CONTENT_SETTINGS_TYPE_COOKIES, IDS_ACCESSED_COOKIES_TITLE},
     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_TITLE},
+    {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_ALLOWED_DOWNLOAD_TITLE},
   };
   const ContentSettingsTypeIdEntry *title_ids = kBlockedTitleIDs;
   size_t num_title_ids = arraysize(kBlockedTitleIDs);
@@ -154,6 +156,7 @@
     {CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS, IDS_HANDLERS_BUBBLE_MANAGE_LINK},
     {CONTENT_SETTINGS_TYPE_MEDIASTREAM, IDS_MEDIASTREAM_BUBBLE_MANAGE_LINK},
     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_PPAPI_BROKER_BUBBLE_MANAGE_LINK},
+    {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_BLOCKED_DOWNLOADS_LINK},
   };
   set_manage_link(l10n_util::GetStringUTF8(
       GetIdForContentType(kLinkIDs, arraysize(kLinkIDs), content_type())));
@@ -288,6 +291,7 @@
     {CONTENT_SETTINGS_TYPE_PLUGINS, IDS_BLOCKED_PLUGINS_UNBLOCK_ALL},
     {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_UNBLOCK},
     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_UNBLOCK},
+    {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_BLOCKED_DOWNLOAD_UNBLOCK},
   };
   // Fields as for kBlockedAllowIDs, above.
   static const ContentSettingsTypeIdEntry kResourceSpecificBlockedAllowIDs[] = {
@@ -297,6 +301,7 @@
     // TODO(bauerb): The string shouldn't be "unblock" (they weren't blocked).
     {CONTENT_SETTINGS_TYPE_COOKIES, IDS_BLOCKED_COOKIES_UNBLOCK},
     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_NO_ACTION},
+    {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_ALLOWED_DOWNLOAD_NO_ACTION},
   };
 
   std::string radio_allow_label;
@@ -327,11 +332,13 @@
     {CONTENT_SETTINGS_TYPE_PLUGINS, IDS_BLOCKED_PLUGINS_NO_ACTION},
     {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_NO_ACTION},
     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_NO_ACTION},
+    {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_BLOCKED_DOWNLOAD_NO_ACTION},
   };
   static const ContentSettingsTypeIdEntry kAllowedBlockIDs[] = {
     // TODO(bauerb): The string should say "block".
     {CONTENT_SETTINGS_TYPE_COOKIES, IDS_BLOCKED_COOKIES_NO_ACTION},
     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_BLOCK},
+    {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_ALLOWED_DOWNLOAD_BLOCK},
   };
 
   std::string radio_block_label;
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.h b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
index 9ac5096..fbb19c1 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.h
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
@@ -16,8 +16,8 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/common/media_stream_request.h"
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/image/image.h"
+#include "url/gurl.h"
 
 class ContentSettingBubbleModelDelegate;
 class Profile;
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.cc b/chrome/browser/ui/content_settings/content_setting_image_model.cc
index 02e6241..97e881a 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model.cc
@@ -90,6 +90,7 @@
     {CONTENT_SETTINGS_TYPE_POPUPS, IDR_BLOCKED_POPUPS},
     {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, IDR_BLOCKED_MIXED_CONTENT},
     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDR_BLOCKED_PPAPI_BROKER},
+    {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDR_BLOCKED_DOWNLOADS},
   };
   static const ContentSettingsTypeIdEntry kBlockedTooltipIDs[] = {
     {CONTENT_SETTINGS_TYPE_COOKIES, IDS_BLOCKED_COOKIES_TITLE},
@@ -100,9 +101,12 @@
     {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT,
         IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT},
     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_TITLE},
+    {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_BLOCKED_DOWNLOAD_TITLE},
   };
   static const ContentSettingsTypeIdEntry kBlockedExplanatoryTextIDs[] = {
     {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_EXPLANATORY_TEXT},
+    {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
+        IDS_BLOCKED_DOWNLOADS_EXPLANATION},
   };
 
   ContentSettingsType type = get_content_settings_type();
@@ -136,10 +140,12 @@
     static const ContentSettingsTypeIdEntry kAccessedIconIDs[] = {
       {CONTENT_SETTINGS_TYPE_COOKIES, IDR_ACCESSED_COOKIES},
       {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDR_BLOCKED_PPAPI_BROKER},
+      {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDR_ALLOWED_DOWNLOADS},
     };
     static const ContentSettingsTypeIdEntry kAccessedTooltipIDs[] = {
       {CONTENT_SETTINGS_TYPE_COOKIES, IDS_ACCESSED_COOKIES_TITLE},
       {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_TITLE},
+      {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_ALLOWED_DOWNLOAD_TITLE},
     };
     icon_id = GetIdForContentType(
         kAccessedIconIDs, arraysize(kAccessedIconIDs), type);
@@ -231,7 +237,7 @@
       // icon is displayed in the omnibox.
       return;
     case TabSpecificContentSettings::MICROPHONE_ACCESSED:
-      set_icon(IDR_ALLOWED_MICROPHONE);
+      set_icon(IDR_ASK_MEDIA);
       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED));
       break;
     case TabSpecificContentSettings::CAMERA_ACCESSED:
@@ -243,7 +249,7 @@
       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED));
       break;
     case TabSpecificContentSettings::MICROPHONE_BLOCKED:
-      set_icon(IDR_BLOCKED_MICROPHONE);
+      set_icon(IDR_BLOCKED_MEDIA);
       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_BLOCKED));
       break;
     case TabSpecificContentSettings::CAMERA_BLOCKED:
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
index 6843f84..89bcbbd 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
@@ -3,12 +3,12 @@
 // found in the LICENSE file.
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/prerender/prerender_manager.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/content_settings/content_setting_image_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_observer.h"
diff --git a/chrome/browser/ui/crypto_module_password_dialog.cc b/chrome/browser/ui/crypto_module_password_dialog.cc
index c98d1d8..403e4c9 100644
--- a/chrome/browser/ui/crypto_module_password_dialog.cc
+++ b/chrome/browser/ui/crypto_module_password_dialog.cc
@@ -10,9 +10,9 @@
 #include "base/synchronization/waitable_event.h"
 #include "content/public/browser/browser_thread.h"
 #include "crypto/crypto_module_blocking_password_delegate.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc
index 06d250c..72b1c95 100644
--- a/chrome/browser/ui/extensions/application_launch.cc
+++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -86,7 +86,7 @@
     return ui::SHOW_STATE_DEFAULT;
   }
 
-  if (chrome::ShouldForceFullscreenApp())
+  if (chrome::IsRunningInForcedAppMode())
     return ui::SHOW_STATE_FULLSCREEN;
 
 #if defined(USE_ASH)
diff --git a/chrome/browser/ui/extensions/application_launch.h b/chrome/browser/ui/extensions/application_launch.h
index cecbd7d..334f1bc 100644
--- a/chrome/browser/ui/extensions/application_launch.h
+++ b/chrome/browser/ui/extensions/application_launch.h
@@ -7,9 +7,9 @@
 
 #include "base/files/file_path.h"
 #include "chrome/common/extensions/extension_constants.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/window_open_disposition.h"
 #include "ui/gfx/rect.h"
+#include "url/gurl.h"
 
 class Browser;
 class CommandLine;
diff --git a/chrome/browser/ui/extensions/extension_install_ui_default.cc b/chrome/browser/ui/extensions/extension_install_ui_default.cc
index 92389c3..54e6a8a 100644
--- a/chrome/browser/ui/extensions/extension_install_ui_default.cc
+++ b/chrome/browser/ui/extensions/extension_install_ui_default.cc
@@ -8,6 +8,7 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_install_prompt.h"
 #include "chrome/browser/extensions/theme_installed_infobar_delegate.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/ui/simple_message_box.h"
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/url_constants.h"
@@ -76,18 +76,20 @@
     chrome::ShowExtensionInstalledBubble(extension, browser, icon);
 }
 
-// ErrorInfobarDelegate -------------------------------------------------------
+
+// ErrorInfoBarDelegate -------------------------------------------------------
 
 // Helper class to put up an infobar when installation fails.
-class ErrorInfobarDelegate : public ConfirmInfoBarDelegate {
+class ErrorInfoBarDelegate : public ConfirmInfoBarDelegate {
  public:
   // Creates an error delegate and adds it to |infobar_service|.
   static void Create(InfoBarService* infobar_service,
                      const extensions::CrxInstallerError& error);
 
  private:
-  ErrorInfobarDelegate(InfoBarService* infobar_service,
+  ErrorInfoBarDelegate(InfoBarService* infobar_service,
                        const extensions::CrxInstallerError& error);
+  virtual ~ErrorInfoBarDelegate();
 
   // ConfirmInfoBarDelegate:
   virtual string16 GetMessageText() const OVERRIDE;
@@ -97,37 +99,40 @@
 
   extensions::CrxInstallerError error_;
 
-  DISALLOW_COPY_AND_ASSIGN(ErrorInfobarDelegate);
+  DISALLOW_COPY_AND_ASSIGN(ErrorInfoBarDelegate);
 };
 
 // static
-void ErrorInfobarDelegate::Create(InfoBarService* infobar_service,
+void ErrorInfoBarDelegate::Create(InfoBarService* infobar_service,
                                   const extensions::CrxInstallerError& error) {
   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
-      new ErrorInfobarDelegate(infobar_service, error)));
+      new ErrorInfoBarDelegate(infobar_service, error)));
 }
 
-ErrorInfobarDelegate::ErrorInfobarDelegate(
+ErrorInfoBarDelegate::ErrorInfoBarDelegate(
     InfoBarService* infobar_service,
     const extensions::CrxInstallerError& error)
     : ConfirmInfoBarDelegate(infobar_service),
       error_(error) {
 }
 
-string16 ErrorInfobarDelegate::GetMessageText() const {
+ErrorInfoBarDelegate::~ErrorInfoBarDelegate() {
+}
+
+string16 ErrorInfoBarDelegate::GetMessageText() const {
   return error_.message();
 }
 
-int ErrorInfobarDelegate::GetButtons() const {
+int ErrorInfoBarDelegate::GetButtons() const {
   return BUTTON_OK;
 }
 
-string16 ErrorInfobarDelegate::GetLinkText() const {
-  return error_.type() == extensions::CrxInstallerError::ERROR_OFF_STORE ?
-      l10n_util::GetStringUTF16(IDS_LEARN_MORE) : ASCIIToUTF16("");
+string16 ErrorInfoBarDelegate::GetLinkText() const {
+  return (error_.type() == extensions::CrxInstallerError::ERROR_OFF_STORE) ?
+      l10n_util::GetStringUTF16(IDS_LEARN_MORE) : string16();
 }
 
-bool ErrorInfobarDelegate::LinkClicked(WindowOpenDisposition disposition) {
+bool ErrorInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition) {
   web_contents()->OpenURL(content::OpenURLParams(
       GURL("http://support.google.com/chrome_webstore/?p=crx_warning"),
       content::Referrer(),
@@ -285,7 +290,7 @@
       browser->tab_strip_model()->GetActiveWebContents();
   if (!web_contents)
     return;
-  ErrorInfobarDelegate::Create(InfoBarService::FromWebContents(web_contents),
+  ErrorInfoBarDelegate::Create(InfoBarService::FromWebContents(web_contents),
                                error);
 }
 
diff --git a/chrome/browser/ui/external_protocol_dialog_delegate.h b/chrome/browser/ui/external_protocol_dialog_delegate.h
index 8862e7e..1fccfb9 100644
--- a/chrome/browser/ui/external_protocol_dialog_delegate.h
+++ b/chrome/browser/ui/external_protocol_dialog_delegate.h
@@ -9,7 +9,7 @@
 #include "base/compiler_specific.h"
 #include "base/time/time.h"
 #include "chrome/browser/ui/protocol_dialog_delegate.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 // Provides text for the external protocol handler dialog and handles whether
 // or not to launch the application for the given protocol.
diff --git a/chrome/browser/ui/fast_unload_controller.cc b/chrome/browser/ui/fast_unload_controller.cc
index 5a8373e..a2609d9 100644
--- a/chrome/browser/ui/fast_unload_controller.cc
+++ b/chrome/browser/ui/fast_unload_controller.cc
@@ -6,12 +6,12 @@
 
 #include "base/logging.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/notification_types.h"
diff --git a/chrome/browser/ui/find_bar/find_bar_controller.cc b/chrome/browser/ui/find_bar/find_bar_controller.cc
index d63d41b..1f450c8 100644
--- a/chrome/browser/ui/find_bar/find_bar_controller.cc
+++ b/chrome/browser/ui/find_bar/find_bar_controller.cc
@@ -9,12 +9,12 @@
 #include "base/i18n/rtl.h"
 #include "base/logging.h"
 #include "build/build_config.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/find_bar/find_bar.h"
 #include "chrome/browser/ui/find_bar/find_bar_state.h"
 #include "chrome/browser/ui/find_bar/find_bar_state_factory.h"
 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
index f576175..b65c5d8 100644
--- a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
+++ b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
@@ -70,10 +70,6 @@
 
 const int kMoveIterations = 30;
 
-void HistoryServiceQueried(int) {
-  base::MessageLoop::current()->Quit();
-}
-
 }  // namespace
 
 class FindInPageControllerTest : public InProcessBrowserTest {
@@ -181,8 +177,9 @@
 
   void FlushHistoryService() {
     HistoryServiceFactory::GetForProfile(
-        browser()->profile(), Profile::IMPLICIT_ACCESS)->
-        GetNextDownloadId(base::Bind(&HistoryServiceQueried));
+        browser()->profile(), Profile::IMPLICIT_ACCESS)->FlushForTest(
+        base::Bind(&base::MessageLoop::Quit,
+                   base::Unretained(base::MessageLoop::current()->current())));
     content::RunMessageLoop();
   }
 };
diff --git a/chrome/browser/ui/find_bar/find_tab_helper.cc b/chrome/browser/ui/find_bar/find_tab_helper.cc
index e83defa..4e66a99 100644
--- a/chrome/browser/ui/find_bar/find_tab_helper.cc
+++ b/chrome/browser/ui/find_bar/find_tab_helper.cc
@@ -6,10 +6,10 @@
 
 #include <vector>
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/find_bar/find_bar_state.h"
 #include "chrome/browser/ui/find_bar/find_bar_state_factory.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/fullscreen/fullscreen_controller.cc b/chrome/browser/ui/fullscreen/fullscreen_controller.cc
index 935703d..8b0f965 100644
--- a/chrome/browser/ui/fullscreen/fullscreen_controller.cc
+++ b/chrome/browser/ui/fullscreen/fullscreen_controller.cc
@@ -8,13 +8,14 @@
 #include "base/command_line.h"
 #include "base/message_loop.h"
 #include "chrome/browser/app_mode/app_mode_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/download/download_shelf.h"
+#include "chrome/browser/fullscreen.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/navigation_details.h"
@@ -571,7 +572,7 @@
 
 #if defined(OS_MACOSX)
   if (option == BROWSER_WITH_CHROME) {
-    CHECK(base::mac::IsOSLionOrLater());
+    CHECK(chrome::mac::SupportsSystemFullscreen());
     window_->EnterFullscreenWithChrome();
   } else {
 #else
diff --git a/chrome/browser/ui/fullscreen/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/fullscreen/fullscreen_controller_interactive_browsertest.cc
index cfe3778..1ab6665 100644
--- a/chrome/browser/ui/fullscreen/fullscreen_controller_interactive_browsertest.cc
+++ b/chrome/browser/ui/fullscreen/fullscreen_controller_interactive_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include "build/build_config.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/browser/fullscreen.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
@@ -387,7 +388,7 @@
     EXPECT_FALSE(browser()->window()->IsFullscreenWithoutChrome());
   }
 
-  if (base::mac::IsOSLionOrLater()) {
+  if (chrome::mac::SupportsSystemFullscreen()) {
     // Test that tab fullscreen mode doesn't make presentation mode the default
     // on Lion.
     FullscreenNotificationObserver fullscreen_observer;
diff --git a/chrome/browser/ui/fullscreen/fullscreen_controller_state_test.cc b/chrome/browser/ui/fullscreen/fullscreen_controller_state_test.cc
index c0e9ff0..bbc4c23 100644
--- a/chrome/browser/ui/fullscreen/fullscreen_controller_state_test.cc
+++ b/chrome/browser/ui/fullscreen/fullscreen_controller_state_test.cc
@@ -9,6 +9,7 @@
 #include <iomanip>
 #include <iostream>
 
+#include "chrome/browser/fullscreen.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
@@ -23,9 +24,9 @@
 
 namespace {
 
-bool IsMacOSLionOrLater() {
+bool SupportsMacSystemFullscreen() {
 #if defined(OS_MACOSX)
-  return base::mac::IsOSLionOrLater();
+  return chrome::mac::SupportsSystemFullscreen();
 #else
   return false;
 #endif
@@ -393,7 +394,7 @@
       break;
     case TOGGLE_FULLSCREEN_CHROME:
 #if defined(OS_MACOSX)
-      if (base::mac::IsOSLionOrLater()) {
+      if (chrome::mac::SupportsSystemFullscreen()) {
         GetFullscreenController()->ToggleFullscreenWithChrome();
         break;
       }
@@ -734,7 +735,7 @@
 #endif
 
   // Skip Mac Lion Fullscreen state and events when not on OSX 10.7+.
-  if (!IsMacOSLionOrLater()) {
+  if (!SupportsMacSystemFullscreen()) {
     if (state == STATE_BROWSER_FULLSCREEN_WITH_CHROME ||
         state == STATE_TAB_BROWSER_FULLSCREEN_CHROME ||
         state == STATE_TO_BROWSER_FULLSCREEN_WITH_CHROME ||
@@ -758,7 +759,7 @@
 #endif
 
   // Quietly skip Mac Lion Fullscreen tests when not on OSX 10.7+.
-  if (!IsMacOSLionOrLater()) {
+  if (!SupportsMacSystemFullscreen()) {
     if (state == STATE_BROWSER_FULLSCREEN_WITH_CHROME ||
         event == TOGGLE_FULLSCREEN_CHROME) {
       debugging_log_ << "\nSkipping Lion Fullscreen test on non-OSX 10.7+.\n";
diff --git a/chrome/browser/ui/fullscreen/fullscreen_controller_test.h b/chrome/browser/ui/fullscreen/fullscreen_controller_test.h
index cdc4730..94c3e2b 100644
--- a/chrome/browser/ui/fullscreen/fullscreen_controller_test.h
+++ b/chrome/browser/ui/fullscreen/fullscreen_controller_test.h
@@ -5,8 +5,8 @@
 #ifndef CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_TEST_H_
 #define CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_TEST_H_
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/ui/fullscreen/fullscreen_exit_bubble.h b/chrome/browser/ui/fullscreen/fullscreen_exit_bubble.h
index d8d464d..a1cb0e2 100644
--- a/chrome/browser/ui/fullscreen/fullscreen_exit_bubble.h
+++ b/chrome/browser/ui/fullscreen/fullscreen_exit_bubble.h
@@ -7,9 +7,9 @@
 
 #include "base/timer/timer.h"
 #include "chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/animation/animation_delegate.h"
 #include "ui/gfx/point.h"
+#include "url/gurl.h"
 
 class Browser;
 
diff --git a/chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.h b/chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.h
index d3d90fa..bd5bae5 100644
--- a/chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.h
+++ b/chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_EXIT_BUBBLE_TYPE_H_
 
 #include "base/strings/string16.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class ExtensionService;
 
diff --git a/chrome/browser/ui/gesture_prefs_observer_factory_aura.cc b/chrome/browser/ui/gesture_prefs_observer_factory_aura.cc
index c02c3e4..7c593fa 100644
--- a/chrome/browser/ui/gesture_prefs_observer_factory_aura.cc
+++ b/chrome/browser/ui/gesture_prefs_observer_factory_aura.cc
@@ -11,9 +11,9 @@
 #include "base/compiler_specific.h"
 #include "base/prefs/pref_change_registrar.h"
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -452,7 +452,7 @@
 #endif  // USE_ASH
 }
 
-void GesturePrefsObserverFactoryAura::RegisterUserPrefs(
+void GesturePrefsObserverFactoryAura::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterDoublePref(
       prefs::kFlingAccelerationCurveCoefficient0,
diff --git a/chrome/browser/ui/gesture_prefs_observer_factory_aura.h b/chrome/browser/ui/gesture_prefs_observer_factory_aura.h
index 62de59b..fcd68f7 100644
--- a/chrome/browser/ui/gesture_prefs_observer_factory_aura.h
+++ b/chrome/browser/ui/gesture_prefs_observer_factory_aura.h
@@ -32,7 +32,7 @@
   // BrowserContextKeyedServiceFactory:
   virtual BrowserContextKeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const OVERRIDE;
-  virtual void RegisterUserPrefs(
+  virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
   virtual bool ServiceIsCreatedWithBrowserContext() const OVERRIDE;
   virtual content::BrowserContext* GetBrowserContextToUse(
diff --git a/chrome/browser/ui/global_error/global_error_service.cc b/chrome/browser/ui/global_error/global_error_service.cc
index 8baff84..2acf270 100644
--- a/chrome/browser/ui/global_error/global_error_service.cc
+++ b/chrome/browser/ui/global_error/global_error_service.cc
@@ -7,10 +7,10 @@
 #include <algorithm>
 
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/global_error/global_error.h"
 #include "chrome/browser/ui/global_error/global_error_bubble_view_base.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 
 GlobalErrorService::GlobalErrorService(Profile* profile) : profile_(profile) {
diff --git a/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.cc b/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.cc
index 5488cf8..d68d933 100644
--- a/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.cc
@@ -7,6 +7,7 @@
 #include "base/i18n/rtl.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/avatar_menu_model.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -18,7 +19,6 @@
 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/generated_resources.h"
 #include "ui/base/gtk/gtk_hig_constants.h"
diff --git a/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc b/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc
index 1f0ec20..08a24ba 100644
--- a/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc
+++ b/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc
@@ -75,8 +75,13 @@
   GtkAllocation allocation;
   gtk_widget_get_allocation(widget(), &allocation);
   old_height_ = allocation.height;
-  gfx::Image icon = profiles::GetAvatarIconForTitleBar(*icon_, is_gaia_picture_,
-      profiles::kAvatarIconWidth, old_height_);
+
+  // GAIA images are square; use kWidth for both destination height and width
+  // since old_height_ is often not usable (typically a value of 1 which, after
+  // subtracting border, tries to resize the profile image to a size of -1).
+  gfx::Image icon = profiles::GetAvatarIconForTitleBar(
+      *icon_, is_gaia_picture_,
+      profiles::kAvatarIconWidth, profiles::kAvatarIconWidth);
   gtk_image_set_from_pixbuf(GTK_IMAGE(image_), icon.ToGdkPixbuf());
   gtk_misc_set_alignment(GTK_MISC(image_), 0.0, 1.0);
   gtk_widget_set_size_request(image_, -1, 0);
diff --git a/chrome/browser/ui/gtk/avatar_menu_item_gtk.cc b/chrome/browser/ui/gtk/avatar_menu_item_gtk.cc
index 6571988..5eeaf03 100644
--- a/chrome/browser/ui/gtk/avatar_menu_item_gtk.cc
+++ b/chrome/browser/ui/gtk/avatar_menu_item_gtk.cc
@@ -9,10 +9,10 @@
 #include "base/bind.h"
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc
index cc2443d..730a945 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/bookmarks/bookmark_node_data.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_properties.h"
@@ -42,9 +43,9 @@
 #include "chrome/browser/ui/ntp_background_util.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/user_metrics.h"
@@ -169,6 +170,14 @@
   registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
                  content::Source<ThemeService>(theme_service_));
 
+  apps_shortcut_visible_.Init(
+      prefs::kShowAppsShortcutInBookmarkBar,
+      browser_->profile()->GetPrefs(),
+      base::Bind(&BookmarkBarGtk::OnAppsPageShortcutVisibilityChanged,
+                 base::Unretained(this)));
+
+  OnAppsPageShortcutVisibilityChanged();
+
   edit_bookmarks_enabled_.Init(
       prefs::kEditBookmarksEnabled,
       browser_->profile()->GetPrefs(),
@@ -209,6 +218,17 @@
   bookmark_hbox_ = gtk_hbox_new(FALSE, 0);
   gtk_container_add(GTK_CONTAINER(paint_box_), bookmark_hbox_);
 
+  apps_shortcut_button_ = theme_service_->BuildChromeButton();
+  bookmark_utils::ConfigureAppsShortcutButton(apps_shortcut_button_,
+                                              theme_service_);
+  g_signal_connect(apps_shortcut_button_, "clicked",
+                   G_CALLBACK(OnAppsButtonClickedThunk), this);
+  // Accept middle mouse clicking.
+  gtk_util::SetButtonClickableByMouseButtons(
+      apps_shortcut_button_, true, true, false);
+  gtk_box_pack_start(GTK_BOX(bookmark_hbox_), apps_shortcut_button_,
+                     FALSE, FALSE, 0);
+
   instructions_ = gtk_alignment_new(0, 0, 1, 1);
   gtk_alignment_set_padding(GTK_ALIGNMENT(instructions_), 0, 0,
                             kInstructionsPadding, 0);
@@ -1239,6 +1259,17 @@
                                            browser_->profile());
 }
 
+void BookmarkBarGtk::OnAppsButtonClicked(GtkWidget* sender) {
+  content::OpenURLParams params(
+      GURL(chrome::kChromeUIAppsURL),
+      content::Referrer(),
+      event_utils::DispositionForCurrentButtonPressEvent(),
+      content::PAGE_TRANSITION_AUTO_BOOKMARK,
+      false);
+  browser_->OpenURL(params);
+  bookmark_utils::RecordAppsPageOpen(GetBookmarkLaunchLocation());
+}
+
 void BookmarkBarGtk::OnFolderClicked(GtkWidget* sender) {
   // Stop its throbbing, if any.
   HoverControllerGtk* hover_controller =
@@ -1471,6 +1502,13 @@
   chrome::ShowImportDialog(browser_);
 }
 
+void BookmarkBarGtk::OnAppsPageShortcutVisibilityChanged() {
+  const bool visible =
+      chrome::ShouldShowAppsShortcutInBookmarkBar(browser_->profile());
+  gtk_widget_set_visible(apps_shortcut_button_, visible);
+  gtk_widget_set_no_show_all(apps_shortcut_button_, !visible);
+}
+
 void BookmarkBarGtk::OnEditBookmarksEnabledChanged() {
   GtkDestDefaults dest_defaults =
       *edit_bookmarks_enabled_ ? GTK_DEST_DEFAULT_ALL :
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h
index 107407a..2d78d00 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h
@@ -265,6 +265,9 @@
   // GtkButton callbacks for folder buttons.
   CHROMEGTK_CALLBACK_0(BookmarkBarGtk, void, OnFolderClicked);
 
+  // GtkButton callback for apps button.
+  CHROMEGTK_CALLBACK_0(BookmarkBarGtk, void, OnAppsButtonClicked);
+
   // GtkToolbar callbacks.
   CHROMEGTK_CALLBACK_4(BookmarkBarGtk, gboolean, OnToolbarDragMotion,
                        GdkDragContext*, gint, gint, guint);
@@ -297,6 +300,10 @@
   // Overriden from chrome::BookmarkBarInstructionsDelegate:
   virtual void ShowImportDialog() OVERRIDE;
 
+  // Updates the visibility of the apps shortcut button |apps_shortcut_visible_|
+  // changes.
+  void OnAppsPageShortcutVisibilityChanged();
+
   // Updates the drag&drop state when |edit_bookmarks_enabled_| changes.
   void OnEditBookmarksEnabledChanged();
 
@@ -334,6 +341,9 @@
   // bookmarks when there are no bookmarks on the bookmark bar.
   scoped_ptr<BookmarkBarInstructionsGtk> instructions_gtk_;
 
+  // The apps page shortcut button.
+  GtkWidget* apps_shortcut_button_;
+
   // GtkToolbar which contains all the bookmark buttons.
   ui::OwnedWidgetGtk bookmark_toolbar_;
 
@@ -400,6 +410,9 @@
   // We track it because we only want to allow one widget to throb at a time.
   GtkWidget* throbbing_widget_;
 
+  // Tracks whether the apps shortcut button should be shown.
+  BooleanPrefMember apps_shortcut_visible_;
+
   // Tracks whether bookmarks can be modified.
   BooleanPrefMember edit_bookmarks_enabled_;
 
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_instructions_gtk.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_instructions_gtk.cc
index ac66a4b..366565b 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_instructions_gtk.cc
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_instructions_gtk.cc
@@ -5,13 +5,13 @@
 #include "chrome/browser/ui/gtk/bookmarks/bookmark_bar_instructions_gtk.h"
 
 #include "base/observer_list.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/bookmarks/bookmark_bar_instructions_delegate.h"
 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
 #include "chrome/browser/ui/gtk/gtk_chrome_shrinkable_hbox.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc
index 7125577..4df051c 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/bookmarks/bookmark_editor.h"
 #include "chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/user_metrics.h"
 #include "grit/generated_resources.h"
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.h b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.h
index 96bd5f7..22e7f4a 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.h
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.h
@@ -22,8 +22,8 @@
 #include "chrome/browser/ui/gtk/bubble/bubble_gtk.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/gtk/gtk_signal.h"
+#include "url/gurl.h"
 
 class BookmarkModel;
 class Profile;
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_editor_gtk.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_editor_gtk.cc
index aa6030b..cf5cd3d 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_editor_gtk.cc
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_editor_gtk.cc
@@ -27,7 +27,6 @@
 #include "chrome/browser/ui/gtk/gtk_util.h"
 #include "chrome/browser/ui/gtk/menu_gtk.h"
 #include "components/user_prefs/user_prefs.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/locale_settings.h"
@@ -37,6 +36,7 @@
 #include "ui/gfx/gtk_util.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/point.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.cc
index f0b2b4a..367092c 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.cc
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.cc
@@ -16,6 +16,8 @@
 #include "chrome/browser/ui/gtk/gtk_chrome_button.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
 #include "grit/ui_strings.h"
 #include "net/base/net_util.h"
 #include "ui/base/dragdrop/gtk_dnd_util.h"
@@ -253,6 +255,15 @@
                     AsVoid(node));
 }
 
+void ConfigureAppsShortcutButton(GtkWidget* button, GtkThemeService* provider) {
+  GdkPixbuf* pixbuf = ui::ResourceBundle::GetSharedInstance().
+      GetNativeImageNamed(IDR_BOOKMARK_BAR_APPS_SHORTCUT,
+                          ui::ResourceBundle::RTL_ENABLED).ToGdkPixbuf();
+  const string16& label = l10n_util::GetStringUTF16(
+      IDS_BOOKMARK_BAR_APPS_SHORTCUT_NAME);
+  PackButton(pixbuf, label, false, provider, button);
+}
+
 std::string BuildTooltipFor(const BookmarkNode* node) {
   if (node->is_folder())
     return std::string();
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h b/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h
index f4eb3a1..a3a8224 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h
@@ -45,6 +45,10 @@
 void ConfigureButtonForNode(const BookmarkNode* node, BookmarkModel* model,
                             GtkWidget* button, GtkThemeService* provider);
 
+// Helper function to set the visual properties for the apps page shortcut
+// |button|.
+void ConfigureAppsShortcutButton(GtkWidget* button, GtkThemeService* provider);
+
 // Returns the tooltip.
 std::string BuildTooltipFor(const BookmarkNode* node);
 
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk_unittest.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk_unittest.cc
index 81b30f1..1b88bbd 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk_unittest.cc
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk_unittest.cc
@@ -6,9 +6,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/dragdrop/gtk_dnd_util.h"
+#include "url/gurl.h"
 
 TEST(BookmarkUtilsGtkTest, GetNodesFromSelectionInvalid) {
   std::vector<const BookmarkNode*> nodes;
diff --git a/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc
index 5ebfaf7..d7fe075 100644
--- a/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc
+++ b/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc
@@ -13,6 +13,7 @@
 #include "base/i18n/rtl.h"
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/commands/command_service.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_icon_factory.h"
@@ -34,7 +35,6 @@
 #include "chrome/browser/ui/gtk/menu_gtk.h"
 #include "chrome/browser/ui/gtk/view_id_util.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/ui/gtk/browser_titlebar.cc b/chrome/browser/ui/gtk/browser_titlebar.cc
index 0780f19..f59fa66 100644
--- a/chrome/browser/ui/gtk/browser_titlebar.cc
+++ b/chrome/browser/ui/gtk/browser_titlebar.cc
@@ -19,6 +19,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/managed_mode/managed_user_service.h"
 #include "chrome/browser/profiles/avatar_menu_model.h"
 #include "chrome/browser/profiles/profile.h"
@@ -44,7 +45,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h"
 #include "chrome/browser/ui/toolbar/wrench_menu_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/gtk/browser_toolbar_gtk.cc b/chrome/browser/ui/gtk/browser_toolbar_gtk.cc
index 89a94df..4d4d6ac 100644
--- a/chrome/browser/ui/gtk/browser_toolbar_gtk.cc
+++ b/chrome/browser/ui/gtk/browser_toolbar_gtk.cc
@@ -17,6 +17,7 @@
 #include "base/path_service.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/net/url_fixer_upper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_properties.h"
@@ -43,7 +44,6 @@
 #include "chrome/browser/ui/gtk/view_id_util.h"
 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h"
 #include "chrome/browser/upgrade_detector.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/host_zoom_map.h"
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc
index d3ab2c8..0c5e27d 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.cc
+++ b/chrome/browser/ui/gtk/browser_window_gtk.cc
@@ -27,6 +27,7 @@
 #include "base/time/time.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_item_model.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/infobars/infobar_service.h"
@@ -79,7 +80,6 @@
 #include "chrome/browser/ui/omnibox/omnibox_view.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -1028,10 +1028,9 @@
     Profile* profile,
     content::WebContents* web_contents,
     const GURL& url,
-    const content::SSLStatus& ssl,
-    bool show_history) {
-  WebsiteSettingsPopupGtk::Show(GetNativeWindow(), profile,
-                                web_contents, url, ssl);
+    const content::SSLStatus& ssl) {
+  WebsiteSettingsPopupGtk::Show(GetNativeWindow(), profile, web_contents, url,
+                                ssl);
 }
 
 void BrowserWindowGtk::ShowAppMenu() {
@@ -1221,9 +1220,8 @@
   // Update various elements that are interested in knowing the current
   // WebContents.
   UpdateDevToolsForContents(new_contents);
-  InfoBarService* new_infobar_service =
-      InfoBarService::FromWebContents(new_contents);
-  infobar_container_->ChangeInfoBarService(new_infobar_service);
+  infobar_container_->ChangeInfoBarService(
+      InfoBarService::FromWebContents(new_contents));
   contents_container_->SetTab(new_contents);
 
   // TODO(estade): after we manage browser activation, add a check to make sure
@@ -1517,7 +1515,7 @@
 }
 
 // static
-void BrowserWindowGtk::RegisterUserPrefs(
+void BrowserWindowGtk::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   bool custom_frame_default = false;
   // Avoid checking the window manager if we're not connected to an X server (as
@@ -1664,9 +1662,7 @@
     gtk_widget_show(toolbar_border_);
 
   infobar_container_.reset(
-      new InfoBarContainerGtk(this,
-                              browser_->search_model(),
-                              browser_->profile()));
+      new InfoBarContainerGtk(this, browser_->profile()));
   gtk_box_pack_start(GTK_BOX(render_area_vbox_),
                      infobar_container_->widget(),
                      FALSE, FALSE, 0);
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.h b/chrome/browser/ui/gtk/browser_window_gtk.h
index 40f763f..c4af3e0 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.h
+++ b/chrome/browser/ui/gtk/browser_window_gtk.h
@@ -149,8 +149,7 @@
   virtual void ShowWebsiteSettings(Profile* profile,
                                    content::WebContents* web_contents,
                                    const GURL& url,
-                                   const content::SSLStatus& ssl,
-                                   bool show_history) OVERRIDE;
+                                   const content::SSLStatus& ssl) OVERRIDE;
   virtual void ShowAppMenu() OVERRIDE;
   virtual bool PreHandleKeyboardEvent(
       const content::NativeWebKeyboardEvent& event,
@@ -251,7 +250,7 @@
   // Returns the tab we're currently displaying in the tab contents container.
   content::WebContents* GetDisplayedTab();
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Tells GTK that the toolbar area is invalidated and needs redrawing. We
   // have this method as a hack because GTK doesn't queue the toolbar area for
diff --git a/chrome/browser/ui/gtk/bubble/bubble_gtk.cc b/chrome/browser/ui/gtk/bubble/bubble_gtk.cc
index 0b023b0..951f8a1 100644
--- a/chrome/browser/ui/gtk/bubble/bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/bubble/bubble_gtk.cc
@@ -7,10 +7,10 @@
 #include <gdk/gdkkeysyms.h>
 
 #include "base/i18n/rtl.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/gtk/bubble/bubble_accelerators_gtk.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "ui/base/gtk/gtk_compat.h"
 #include "ui/base/gtk/gtk_hig_constants.h"
diff --git a/chrome/browser/ui/gtk/chrome_browser_main_extra_parts_gtk.cc b/chrome/browser/ui/gtk/chrome_browser_main_extra_parts_gtk.cc
index 8d7c88f..a6f5d49 100644
--- a/chrome/browser/ui/gtk/chrome_browser_main_extra_parts_gtk.cc
+++ b/chrome/browser/ui/gtk/chrome_browser_main_extra_parts_gtk.cc
@@ -8,7 +8,6 @@
 
 #include "base/command_line.h"
 #include "chrome/browser/chrome_browser_main.h"
-#include "chrome/browser/toolkit_extra_parts.h"
 #include "chrome/common/chrome_switches.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
@@ -79,11 +78,3 @@
   gtk_dialog_run(GTK_DIALOG(dialog));
   gtk_widget_destroy(dialog);
 }
-
-namespace chrome {
-
-void AddGtkToolkitExtraParts(ChromeBrowserMainParts* main_parts) {
-  main_parts->AddParts(new ChromeBrowserMainExtraPartsGtk());
-}
-
-}  // namespace chrome
diff --git a/chrome/browser/ui/gtk/chrome_to_mobile_bubble_gtk.cc b/chrome/browser/ui/gtk/chrome_to_mobile_bubble_gtk.cc
index a33b3eb..ac16fb4 100644
--- a/chrome/browser/ui/gtk/chrome_to_mobile_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/chrome_to_mobile_bubble_gtk.cc
@@ -16,11 +16,11 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chrome_to_mobile_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
diff --git a/chrome/browser/ui/gtk/collected_cookies_gtk.cc b/chrome/browser/ui/gtk/collected_cookies_gtk.cc
index ee12e58..716afa5 100644
--- a/chrome/browser/ui/gtk/collected_cookies_gtk.cc
+++ b/chrome/browser/ui/gtk/collected_cookies_gtk.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/browsing_data/browsing_data_server_bound_cert_helper.h"
 #include "chrome/browser/browsing_data/cookies_tree_model.h"
 #include "chrome/browser/browsing_data/local_data_container.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/cookie_settings.h"
 #include "chrome/browser/content_settings/local_shared_objects_container.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/ui/gtk/constrained_window_gtk.h"
 #include "chrome/browser/ui/gtk/gtk_chrome_cookie_view.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h b/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h
index b90cd26..1491b09 100644
--- a/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h
+++ b/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h
@@ -11,8 +11,8 @@
 #include "base/sequenced_task_runner_helpers.h"
 #include "chrome/browser/shell_integration.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/gtk/gtk_signal.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
diff --git a/chrome/browser/ui/gtk/crypto_module_password_dialog_gtk.cc b/chrome/browser/ui/gtk/crypto_module_password_dialog_gtk.cc
index e6afbd1..42fc76d 100644
--- a/chrome/browser/ui/gtk/crypto_module_password_dialog_gtk.cc
+++ b/chrome/browser/ui/gtk/crypto_module_password_dialog_gtk.cc
@@ -10,11 +10,11 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
 #include "crypto/crypto_module_blocking_password_delegate.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "ui/base/gtk/gtk_hig_constants.h"
 #include "ui/base/gtk/gtk_signal.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/gtk/custom_button.cc b/chrome/browser/ui/gtk/custom_button.cc
index 7a20f6b..e4de176 100644
--- a/chrome/browser/ui/gtk/custom_button.cc
+++ b/chrome/browser/ui/gtk/custom_button.cc
@@ -7,10 +7,10 @@
 #include "base/basictypes.h"
 #include "base/debug/trace_event.h"
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/gtk/gtk_chrome_button.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/theme_resources.h"
 #include "grit/ui_resources.h"
diff --git a/chrome/browser/ui/gtk/custom_drag.cc b/chrome/browser/ui/gtk/custom_drag.cc
index 3fb4225..2a690f6 100644
--- a/chrome/browser/ui/gtk/custom_drag.cc
+++ b/chrome/browser/ui/gtk/custom_drag.cc
@@ -8,12 +8,12 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h"
 #include "content/public/browser/download_item.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/net_util.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/dragdrop/gtk_dnd_util.h"
 #include "ui/gfx/gtk_util.h"
 #include "ui/gfx/image/image.h"
+#include "url/gurl.h"
 
 using content::DownloadItem;
 
diff --git a/chrome/browser/ui/gtk/download/download_item_gtk.cc b/chrome/browser/ui/gtk/download/download_item_gtk.cc
index 860f011..8c838a1 100644
--- a/chrome/browser/ui/gtk/download/download_item_gtk.cc
+++ b/chrome/browser/ui/gtk/download/download_item_gtk.cc
@@ -12,6 +12,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/chrome_download_manager_delegate.h"
 #include "chrome/browser/download/download_item_model.h"
 #include "chrome/browser/download/download_util.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
 #include "chrome/browser/ui/gtk/nine_box.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/download_manager.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/generated_resources.h"
diff --git a/chrome/browser/ui/gtk/download/download_shelf_gtk.cc b/chrome/browser/ui/gtk/download/download_shelf_gtk.cc
index 7724de7..36b25dc 100644
--- a/chrome/browser/ui/gtk/download/download_shelf_gtk.cc
+++ b/chrome/browser/ui/gtk/download/download_shelf_gtk.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "base/bind.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_item_model.h"
 #include "chrome/browser/download/download_util.h"
 #include "chrome/browser/themes/theme_properties.h"
@@ -19,7 +20,6 @@
 #include "chrome/browser/ui/gtk/gtk_chrome_shrinkable_hbox.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/download_item.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/page_navigator.h"
diff --git a/chrome/browser/ui/gtk/edit_search_engine_dialog.cc b/chrome/browser/ui/gtk/edit_search_engine_dialog.cc
index fdbd29e..0044332 100644
--- a/chrome/browser/ui/gtk/edit_search_engine_dialog.cc
+++ b/chrome/browser/ui/gtk/edit_search_engine_dialog.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
 #include "chrome/browser/ui/search_engines/edit_search_engine_controller.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "grit/ui_resources.h"
@@ -24,6 +23,7 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/image/image.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc b/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc
index d93eba3..d23ad9a 100644
--- a/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc
@@ -11,6 +11,7 @@
 #include "base/i18n/rtl.h"
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/commands/command_service.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/ui/gtk/gtk_util.h"
 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h"
 #include "chrome/browser/ui/singleton_tabs.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
 #include "chrome/common/extensions/api/omnibox/omnibox_handler.h"
 #include "chrome/common/extensions/extension.h"
diff --git a/chrome/browser/ui/gtk/extensions/extension_popup_gtk.cc b/chrome/browser/ui/gtk/extensions/extension_popup_gtk.cc
index 2b82adf..0a13c6b 100644
--- a/chrome/browser/ui/gtk/extensions/extension_popup_gtk.cc
+++ b/chrome/browser/ui/gtk/extensions/extension_popup_gtk.cc
@@ -13,6 +13,7 @@
 #include "base/callback.h"
 #include "base/i18n/rtl.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
@@ -21,14 +22,13 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/devtools_manager.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::RenderViewHost;
 
diff --git a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc
index 76e5b04..e96e322 100644
--- a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc
+++ b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc
@@ -354,25 +354,32 @@
   // gtk_window_get_position() to get the right values. (Otherwise session
   // restore, if enabled, will restore windows to incorrect positions.) That's
   // a round trip to the X server though, so we set a debounce timer and only
-  // call it (in OnDebouncedBoundsChanged() below) after we haven't seen a
+  // call it (in OnConfigureDebounced() below) after we haven't seen a
   // reconfigure event in a short while.
   // We don't use Reset() because the timer may not yet be running.
   // (In that case Stop() is a no-op.)
   window_configure_debounce_timer_.Stop();
   window_configure_debounce_timer_.Start(FROM_HERE,
       base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), this,
-      &NativeAppWindowGtk::OnDebouncedBoundsChanged);
+      &NativeAppWindowGtk::OnConfigureDebounced);
 
   return FALSE;
 }
 
-void NativeAppWindowGtk::OnDebouncedBoundsChanged() {
+void NativeAppWindowGtk::OnConfigureDebounced() {
   gtk_window_util::UpdateWindowPosition(this, &bounds_, &restored_bounds_);
   shell_window_->OnNativeWindowChanged();
 
   FOR_EACH_OBSERVER(web_modal::WebContentsModalDialogHostObserver,
                     observer_list_,
                     OnPositionRequiresUpdate());
+
+  // Fullscreen of non-resizable windows requires them to be made resizable
+  // first. After that takes effect and OnConfigure is called we transition
+  // to fullscreen.
+  if (!IsFullscreen() && IsFullscreenOrPending()) {
+    gtk_window_fullscreen(window_);
+  }
 }
 
 gboolean NativeAppWindowGtk::OnWindowState(GtkWidget* sender,
@@ -490,10 +497,19 @@
 
 void NativeAppWindowGtk::SetFullscreen(bool fullscreen) {
   content_thinks_its_fullscreen_ = fullscreen;
-  if (fullscreen)
-    gtk_window_fullscreen(window_);
-  else
+  if (fullscreen){
+    if (resizable_) {
+      gtk_window_fullscreen(window_);
+    } else {
+      // We must first make the window resizable. That won't take effect
+      // immediately, so OnConfigureDebounced completes the fullscreen call.
+      gtk_window_set_resizable(window_, TRUE);
+    }
+  } else {
     gtk_window_unfullscreen(window_);
+    if (!resizable_)
+      gtk_window_set_resizable(window_, FALSE);
+  }
 }
 
 bool NativeAppWindowGtk::IsFullscreenOrPending() const {
diff --git a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h
index c1c018e..2b71243 100644
--- a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h
+++ b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h
@@ -103,7 +103,7 @@
   CHROMEGTK_CALLBACK_1(NativeAppWindowGtk, gboolean, OnButtonPress,
                        GdkEventButton*);
 
-  void OnDebouncedBoundsChanged();
+  void OnConfigureDebounced();
 
   apps::ShellWindow* shell_window_;  // weak - ShellWindow owns NativeAppWindow.
 
diff --git a/chrome/browser/ui/gtk/find_bar_gtk.cc b/chrome/browser/ui/gtk/find_bar_gtk.cc
index 9acbddf..ba9071c 100644
--- a/chrome/browser/ui/gtk/find_bar_gtk.cc
+++ b/chrome/browser/ui/gtk/find_bar_gtk.cc
@@ -15,6 +15,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/browser.h"
@@ -32,7 +33,6 @@
 #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h"
 #include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h"
 #include "chrome/browser/ui/gtk/view_id_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_view_host.h"
diff --git a/chrome/browser/ui/gtk/first_run_dialog.cc b/chrome/browser/ui/gtk/first_run_dialog.cc
index a5b7a02..cfb59de 100644
--- a/chrome/browser/ui/gtk/first_run_dialog.cc
+++ b/chrome/browser/ui/gtk/first_run_dialog.cc
@@ -10,6 +10,7 @@
 #include "base/i18n/rtl.h"
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/app/breakpad_linux.h"
 #include "chrome/browser/first_run/first_run_dialog.h"
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/process_singleton.h"
@@ -28,10 +29,6 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 
-#if defined(USE_LINUX_BREAKPAD)
-#include "chrome/app/breakpad_linux.h"
-#endif
-
 #if defined(GOOGLE_CHROME_BUILD)
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
@@ -169,10 +166,8 @@
   // Check if user has opted into reporting.
   if (report_crashes_ &&
       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(report_crashes_))) {
-#if defined(USE_LINUX_BREAKPAD)
     if (GoogleUpdateSettings::SetCollectStatsConsent(true))
       InitCrashReporter();
-#endif
   } else {
     GoogleUpdateSettings::SetCollectStatsConsent(false);
   }
diff --git a/chrome/browser/ui/gtk/fullscreen_exit_bubble_gtk.cc b/chrome/browser/ui/gtk/fullscreen_exit_bubble_gtk.cc
index a56a35d..8415dae 100644
--- a/chrome/browser/ui/gtk/fullscreen_exit_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/fullscreen_exit_bubble_gtk.cc
@@ -5,12 +5,12 @@
 #include "chrome/browser/ui/gtk/fullscreen_exit_bubble_gtk.h"
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
 #include "chrome/browser/ui/gtk/rounded_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "grit/generated_resources.h"
diff --git a/chrome/browser/ui/gtk/global_history_menu.cc b/chrome/browser/ui/gtk/global_history_menu.cc
index b944665..e8e283a 100644
--- a/chrome/browser/ui/gtk/global_history_menu.cc
+++ b/chrome/browser/ui/gtk/global_history_menu.cc
@@ -12,6 +12,7 @@
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/tab_restore_service.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/ui/gtk/global_menu_bar.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/generated_resources.h"
diff --git a/chrome/browser/ui/gtk/global_menu_bar.cc b/chrome/browser/ui/gtk/global_menu_bar.cc
index 3d6aafd..46c3047 100644
--- a/chrome/browser/ui/gtk/global_menu_bar.cc
+++ b/chrome/browser/ui/gtk/global_menu_bar.cc
@@ -9,13 +9,13 @@
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/gtk/accelerators_gtk.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/ui/gtk/gtk_theme_service.cc b/chrome/browser/ui/gtk/gtk_theme_service.cc
index 143ddcb..5337860 100644
--- a/chrome/browser/ui/gtk/gtk_theme_service.cc
+++ b/chrome/browser/ui/gtk/gtk_theme_service.cc
@@ -15,6 +15,7 @@
 #include "base/nix/xdg_util.h"
 #include "base/prefs/pref_service.h"
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/managed_mode/managed_user_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_properties.h"
@@ -27,7 +28,6 @@
 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
 #include "chrome/browser/ui/gtk/hover_controller_gtk.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/ui/gtk/gtk_util.cc b/chrome/browser/ui/gtk/gtk_util.cc
index df8a277..6c07e14 100644
--- a/chrome/browser/ui/gtk/gtk_util.cc
+++ b/chrome/browser/ui/gtk/gtk_util.cc
@@ -31,7 +31,6 @@
 #include "chrome/browser/ui/gtk/browser_window_gtk.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/host_desktop.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chrome_unscaled_resources.h"
 #include "grit/theme_resources.h"
 #include "ui/base/gtk/gtk_compat.h"
@@ -45,6 +44,7 @@
 #include "ui/gfx/image/cairo_cached_surface.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/pango_util.h"
+#include "url/gurl.h"
 
 // These conflict with base/tracked_objects.h, so need to come last.
 #include <gdk/gdkx.h>  // NOLINT
diff --git a/chrome/browser/ui/gtk/hung_renderer_dialog_gtk.cc b/chrome/browser/ui/gtk/hung_renderer_dialog_gtk.cc
index bf703d6..c0ea1ac 100644
--- a/chrome/browser/ui/gtk/hung_renderer_dialog_gtk.cc
+++ b/chrome/browser/ui/gtk/hung_renderer_dialog_gtk.cc
@@ -52,7 +52,7 @@
     }
 
     // content::WebContentsObserver overrides:
-    virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE {
+    virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE {
       dialog_->Hide();
     }
     virtual void WebContentsDestroyed(WebContents* tab) OVERRIDE {
diff --git a/chrome/browser/ui/gtk/infobars/after_translate_infobar_gtk.cc b/chrome/browser/ui/gtk/infobars/after_translate_infobar_gtk.cc
index 29753a5..833c2db 100644
--- a/chrome/browser/ui/gtk/infobars/after_translate_infobar_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/after_translate_infobar_gtk.cc
@@ -37,8 +37,8 @@
         &strings, &swapped_language_combos, autodetermined_source_language);
   DCHECK_EQ(autodetermined_source_language ? 2U : 3U, strings.size());
 
-  GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing);
-  gtk_util::CenterWidgetInHBox(hbox_, hbox, false, 0);
+  GtkWidget* new_hbox = gtk_hbox_new(FALSE, ui::kControlSpacing);
+  gtk_util::CenterWidgetInHBox(hbox(), new_hbox, false, 0);
 
   size_t original_language_index = GetDelegate()->original_language_index();
   size_t target_language_index = GetDelegate()->target_language_index();
@@ -48,41 +48,41 @@
   if (!autodetermined_source_language) {
     original_lang_combo = CreateLanguageCombobox(
         original_language_index,
-        exclude_the_other ? target_language_index :
-                            TranslateInfoBarDelegate::kNoIndex);
-    Signals()->Connect(original_lang_combo, "changed",
+        exclude_the_other ?
+            target_language_index : TranslateInfoBarDelegate::kNoIndex);
+    signals()->Connect(original_lang_combo, "changed",
                        G_CALLBACK(&OnOriginalLanguageModifiedThunk), this);
   }
   GtkWidget* target_lang_combo = CreateLanguageCombobox(
       target_language_index,
       exclude_the_other ? original_language_index :
                           TranslateInfoBarDelegate::kNoIndex);
-  Signals()->Connect(target_lang_combo, "changed",
+  signals()->Connect(target_lang_combo, "changed",
                      G_CALLBACK(&OnTargetLanguageModifiedThunk), this);
 
-  gtk_box_pack_start(GTK_BOX(hbox), CreateLabel(UTF16ToUTF8(strings[0])),
+  gtk_box_pack_start(GTK_BOX(new_hbox), CreateLabel(UTF16ToUTF8(strings[0])),
                      FALSE, FALSE, 0);
   gtk_box_pack_start(
-      GTK_BOX(hbox),
+      GTK_BOX(new_hbox),
       (swapped_language_combos || autodetermined_source_language) ?
           target_lang_combo : original_lang_combo,
       FALSE, FALSE, 0);
-  gtk_box_pack_start(GTK_BOX(hbox), CreateLabel(UTF16ToUTF8(strings[1])),
+  gtk_box_pack_start(GTK_BOX(new_hbox), CreateLabel(UTF16ToUTF8(strings[1])),
                      FALSE, FALSE, 0);
   if (!autodetermined_source_language) {
-    gtk_box_pack_start(GTK_BOX(hbox),
-                       swapped_language_combos ? original_lang_combo :
-                                                 target_lang_combo,
+    gtk_box_pack_start(GTK_BOX(new_hbox),
+                       swapped_language_combos ?
+                           original_lang_combo : target_lang_combo,
                        FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(hbox), CreateLabel(UTF16ToUTF8(strings[2])),
+    gtk_box_pack_start(GTK_BOX(new_hbox), CreateLabel(UTF16ToUTF8(strings[2])),
                        FALSE, FALSE, 0);
   }
 
   GtkWidget* button = gtk_button_new_with_label(
       l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_REVERT).c_str());
-  Signals()->Connect(button, "clicked",
+  signals()->Connect(button, "clicked",
                      G_CALLBACK(&OnRevertPressedThunk), this);
-  gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(new_hbox), button, FALSE, FALSE, 0);
 }
 
 bool AfterTranslateInfoBar::ShowOptionsMenuButton() const {
diff --git a/chrome/browser/ui/gtk/infobars/before_translate_infobar_gtk.cc b/chrome/browser/ui/gtk/infobars/before_translate_infobar_gtk.cc
index fadc923..7040dbd 100644
--- a/chrome/browser/ui/gtk/infobars/before_translate_infobar_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/before_translate_infobar_gtk.cc
@@ -24,14 +24,14 @@
 void BeforeTranslateInfoBar::InitWidgets() {
   TranslateInfoBarBase::InitWidgets();
 
-  GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing);
-  gtk_util::CenterWidgetInHBox(hbox_, hbox, false, 0);
+  GtkWidget* new_hbox = gtk_hbox_new(FALSE, ui::kControlSpacing);
+  gtk_util::CenterWidgetInHBox(hbox(), new_hbox, false, 0);
   size_t offset = 0;
   string16 text =
       l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE,
                                  string16(), &offset);
 
-  gtk_box_pack_start(GTK_BOX(hbox),
+  gtk_box_pack_start(GTK_BOX(new_hbox),
                      CreateLabel(UTF16ToUTF8(text.substr(0, offset))),
                      FALSE, FALSE, 0);
   size_t original_language_index = GetDelegate()->original_language_index();
@@ -41,24 +41,24 @@
       original_language_index,
       exclude_the_other ? target_language_index :
                           TranslateInfoBarDelegate::kNoIndex);
-  Signals()->Connect(combobox, "changed",
+  signals()->Connect(combobox, "changed",
                      G_CALLBACK(&OnLanguageModifiedThunk), this);
-  gtk_box_pack_start(GTK_BOX(hbox), combobox, FALSE, FALSE, 0);
-  gtk_box_pack_start(GTK_BOX(hbox),
+  gtk_box_pack_start(GTK_BOX(new_hbox), combobox, FALSE, FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(new_hbox),
                      CreateLabel(UTF16ToUTF8(text.substr(offset))),
                      FALSE, FALSE, 0);
 
   GtkWidget* button = gtk_button_new_with_label(
       l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_ACCEPT).c_str());
-  Signals()->Connect(button, "clicked",
+  signals()->Connect(button, "clicked",
                      G_CALLBACK(&OnAcceptPressedThunk), this);
-  gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(new_hbox), button, FALSE, FALSE, 0);
 
   button = gtk_button_new_with_label(
       l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_DENY).c_str());
-  Signals()->Connect(button, "clicked",
+  signals()->Connect(button, "clicked",
                      G_CALLBACK(&OnDenyPressedThunk), this);
-  gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(new_hbox), button, FALSE, FALSE, 0);
 
   TranslateInfoBarDelegate* delegate = GetDelegate();
   if (delegate->ShouldShowNeverTranslateShortcut()) {
@@ -66,9 +66,9 @@
         IDS_TRANSLATE_INFOBAR_NEVER_TRANSLATE,
         delegate->language_name_at(delegate->original_language_index()));
     button = gtk_button_new_with_label(label.c_str());
-    Signals()->Connect(button, "clicked",
+    signals()->Connect(button, "clicked",
                        G_CALLBACK(&OnNeverTranslatePressedThunk), this);
-    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(new_hbox), button, FALSE, FALSE, 0);
   }
 
   if (delegate->ShouldShowAlwaysTranslateShortcut()) {
@@ -76,9 +76,9 @@
         IDS_TRANSLATE_INFOBAR_ALWAYS_TRANSLATE,
         delegate->language_name_at(delegate->original_language_index()));
     button = gtk_button_new_with_label(label.c_str());
-    Signals()->Connect(button, "clicked",
+    signals()->Connect(button, "clicked",
                        G_CALLBACK(&OnAlwaysTranslatePressedThunk), this);
-    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(new_hbox), button, FALSE, FALSE, 0);
   }
 }
 
diff --git a/chrome/browser/ui/gtk/infobars/confirm_infobar_gtk.cc b/chrome/browser/ui/gtk/infobars/confirm_infobar_gtk.cc
index dfab270..e5ca3cb 100644
--- a/chrome/browser/ui/gtk/infobars/confirm_infobar_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/confirm_infobar_gtk.cc
@@ -44,7 +44,7 @@
   // requests, and less if there is not enough available.
   GtkWidget* align = gtk_alignment_new(0, 0, 0, 1);
   gtk_container_add(GTK_CONTAINER(align), confirm_hbox_);
-  gtk_box_pack_start(GTK_BOX(hbox_), align, TRUE, TRUE, 0);
+  gtk_box_pack_start(GTK_BOX(hbox()), align, TRUE, TRUE, 0);
 
   // We add the buttons in reverse order and pack end instead of start so
   // that the first widget to get shrunk is the label rather than the button(s).
@@ -56,7 +56,7 @@
   gtk_util::ForceFontSizePixels(label, 13.4);
   gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
   gtk_util::CenterWidgetInHBox(confirm_hbox_, label, true, 0);
-  Signals()->Connect(label, "map",
+  signals()->Connect(label, "map",
                      G_CALLBACK(gtk_util::InitLabelSizeRequestAndEllipsizeMode),
                      NULL);
 
@@ -66,12 +66,12 @@
 
   GtkWidget* link = CreateLinkButton(link_text);
   gtk_misc_set_alignment(GTK_MISC(GTK_CHROME_LINK_BUTTON(link)->label), 0, 0.5);
-  Signals()->Connect(link, "clicked", G_CALLBACK(OnLinkClickedThunk), this);
+  signals()->Connect(link, "clicked", G_CALLBACK(OnLinkClickedThunk), this);
   gtk_util::SetButtonTriggersNavigation(link);
   // Until we switch to vector graphics, force the font size.
   // 13.4px == 10pt @ 96dpi
   gtk_util::ForceFontSizePixels(GTK_CHROME_LINK_BUTTON(link)->label, 13.4);
-  gtk_util::CenterWidgetInHBox(hbox_, link, true, kEndOfLabelSpacing);
+  gtk_util::CenterWidgetInHBox(hbox(), link, true, kEndOfLabelSpacing);
 }
 
 ConfirmInfoBarDelegate* ConfirmInfoBarGtk::GetDelegate() {
@@ -89,7 +89,7 @@
     gtk_size_group_add_widget(size_group_, button);
 
     gtk_util::CenterWidgetInHBox(confirm_hbox_, button, true, 0);
-    Signals()->Connect(button, "clicked",
+    signals()->Connect(button, "clicked",
                        G_CALLBACK(type == ConfirmInfoBarDelegate::BUTTON_OK ?
                                   OnOkButtonThunk : OnCancelButtonThunk),
                        this);
diff --git a/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc b/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc
index 1edced9..bb87abb 100644
--- a/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc
@@ -59,6 +59,7 @@
 }
 
 void ExtensionInfoBarGtk::PlatformSpecificHide(bool animate) {
+  DCHECK(view_);
   DCHECK(alignment_);
   gtk_util::RemoveAllChildren(alignment_);
 }
@@ -75,8 +76,6 @@
 }
 
 void ExtensionInfoBarGtk::OnImageLoaded(const gfx::Image& image) {
-  if (!delegate_)
-    return;  // The delegate can go away while we asynchronously load images.
 
   DCHECK(icon_);
   // TODO(erg): IDR_EXTENSIONS_SECTION should have an IDR_INFOBAR_EXTENSIONS
@@ -120,13 +119,13 @@
   // extension authors are going to expect to match the declared gradient in
   // extensions_infobar.css, and the close button provided by some GTK+ themes
   // won't look good on this background.
-  close_button_->ForceChromeTheme();
+  ForceCloseButtonToUseChromeTheme();
 
   icon_ = gtk_image_new();
   gtk_misc_set_alignment(GTK_MISC(icon_), 0.5, 0.5);
 
-  const extensions::Extension* extension =
-      delegate_->extension_host()->extension();
+  extensions::ExtensionHost* extension_host = delegate_->extension_host();
+  const extensions::Extension* extension = extension_host->extension();
 
   if (extension->ShowConfigureContextMenus()) {
     button_ = gtk_chrome_button_new();
@@ -135,9 +134,9 @@
                       reinterpret_cast<void*>(true));
 
     gtk_button_set_image(GTK_BUTTON(button_), icon_);
-    gtk_util::CenterWidgetInHBox(hbox_, button_, false, 0);
+    gtk_util::CenterWidgetInHBox(hbox(), button_, false, 0);
   } else {
-    gtk_util::CenterWidgetInHBox(hbox_, icon_, false, 0);
+    gtk_util::CenterWidgetInHBox(hbox(), icon_, false, 0);
   }
 
   // Start loading the image for the menu button.
@@ -158,9 +157,8 @@
   // Pad the bottom of the infobar by one pixel for the border.
   alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
   gtk_alignment_set_padding(GTK_ALIGNMENT(alignment_), 0, 1, 0, 0);
-  gtk_box_pack_start(GTK_BOX(hbox_), alignment_, TRUE, TRUE, 0);
+  gtk_box_pack_start(GTK_BOX(hbox()), alignment_, TRUE, TRUE, 0);
 
-  extensions::ExtensionHost* extension_host = delegate_->extension_host();
   view_ = extension_host->view();
 
   if (gtk_widget_get_parent(view_->native_view())) {
@@ -170,12 +168,12 @@
   }
 
   if (button_) {
-    Signals()->Connect(button_, "button-press-event",
+    signals()->Connect(button_, "button-press-event",
                        G_CALLBACK(&OnButtonPressThunk), this);
   }
-  Signals()->Connect(view_->native_view(), "expose-event",
+  signals()->Connect(view_->native_view(), "expose-event",
                      G_CALLBACK(&OnExposeThunk), this);
-  Signals()->Connect(view_->native_view(), "size_allocate",
+  signals()->Connect(view_->native_view(), "size_allocate",
                      G_CALLBACK(&OnSizeAllocateThunk), this);
 }
 
@@ -192,10 +190,9 @@
   DCHECK(icon_);
   // Get the Browser object this infobar is attached to.
   GtkWindow* parent = platform_util::GetTopLevel(icon_);
-  if (!parent)
-    return NULL;
-
-  return BrowserWindowGtk::GetBrowserWindowForNativeWindow(parent)->browser();
+  return parent ?
+      BrowserWindowGtk::GetBrowserWindowForNativeWindow(parent)->browser() :
+      NULL;
 }
 
 ExtensionContextMenuModel* ExtensionInfoBarGtk::BuildMenuModel() {
@@ -214,8 +211,8 @@
                                          GtkAllocation* allocation) {
   gfx::Size new_size(allocation->width, allocation->height);
 
-  delegate_->extension_host()->view()->render_view_host()->GetView()
-      ->SetSize(new_size);
+  delegate_->extension_host()->view()->render_view_host()->GetView()->
+      SetSize(new_size);
 }
 
 gboolean ExtensionInfoBarGtk::OnButtonPress(GtkWidget* widget,
diff --git a/chrome/browser/ui/gtk/infobars/infobar_container_gtk.cc b/chrome/browser/ui/gtk/infobars/infobar_container_gtk.cc
index 60b4a31..5c5554a 100644
--- a/chrome/browser/ui/gtk/infobars/infobar_container_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/infobar_container_gtk.cc
@@ -23,9 +23,8 @@
 #include "ui/gfx/skia_utils_gtk.h"
 
 InfoBarContainerGtk::InfoBarContainerGtk(InfoBarContainer::Delegate* delegate,
-                                         SearchModel* search_model,
                                          Profile* profile)
-    : InfoBarContainer(delegate, search_model),
+    : InfoBarContainer(delegate),
       profile_(profile),
       container_(gtk_vbox_new(FALSE, 0)) {
   gtk_widget_show(widget());
diff --git a/chrome/browser/ui/gtk/infobars/infobar_container_gtk.h b/chrome/browser/ui/gtk/infobars/infobar_container_gtk.h
index a49c05c..850b580 100644
--- a/chrome/browser/ui/gtk/infobars/infobar_container_gtk.h
+++ b/chrome/browser/ui/gtk/infobars/infobar_container_gtk.h
@@ -38,7 +38,6 @@
 class InfoBarContainerGtk : public InfoBarContainer {
  public:
   InfoBarContainerGtk(InfoBarContainer::Delegate* delegate,
-                      SearchModel* search_model,
                       Profile* profile);
   virtual ~InfoBarContainerGtk();
 
diff --git a/chrome/browser/ui/gtk/infobars/infobar_gtk.cc b/chrome/browser/ui/gtk/infobars/infobar_gtk.cc
index 80e83d0..49907ea 100644
--- a/chrome/browser/ui/gtk/infobars/infobar_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/infobar_gtk.cc
@@ -6,6 +6,7 @@
 
 #include "base/debug/trace_event.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_properties.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
 #include "chrome/browser/ui/gtk/infobars/infobar_container_gtk.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/gtk/gtk_expanded_container.h"
@@ -118,10 +118,6 @@
   UpdateBorderColor();
 }
 
-GtkWidget* InfoBarGtk::widget() {
-  return widget_.get();
-}
-
 GdkColor InfoBarGtk::GetBorderColor() const {
   DCHECK(theme_service_);
   return theme_service_->GetBorderColor();
@@ -139,32 +135,20 @@
 
 void InfoBarGtk::GetTopColor(InfoBarDelegate::Type type,
                              double* r, double* g, double* b) {
-  DCHECK(theme_service_);
-  SkColor color = theme_service_->UsingNativeTheme() ?
-                  theme_service_->GetColor(ThemeProperties::COLOR_TOOLBAR) :
-                  GetInfoBarTopColor(type);
-  *r = SkColorGetR(color) / 255.0;
-  *g = SkColorGetG(color) / 255.0;
-  *b = SkColorGetB(color) / 255.0;
+  GetBackgroundColor(GetInfoBarTopColor(type), r, g, b);
 }
 
 void InfoBarGtk::GetBottomColor(InfoBarDelegate::Type type,
                                 double* r, double* g, double* b) {
-  DCHECK(theme_service_);
-  SkColor color = theme_service_->UsingNativeTheme() ?
-                  theme_service_->GetColor(ThemeProperties::COLOR_TOOLBAR) :
-                  GetInfoBarBottomColor(type);
-  *r = SkColorGetR(color) / 255.0;
-  *g = SkColorGetG(color) / 255.0;
-  *b = SkColorGetB(color) / 255.0;
+  GetBackgroundColor(GetInfoBarBottomColor(type), r, g, b);
 }
 
 void InfoBarGtk::PlatformSpecificShow(bool animate) {
   DCHECK(bg_box_);
 
   DCHECK(widget());
-  gtk_widget_show_all(widget_.get());
-  gtk_widget_set_size_request(widget_.get(), -1, bar_height());
+  gtk_widget_show_all(widget());
+  gtk_widget_set_size_request(widget(), -1, bar_height());
 
   GdkWindow* gdk_window = gtk_widget_get_window(bg_box_);
   if (gdk_window)
@@ -182,12 +166,12 @@
   DCHECK(bg_box_);
   DCHECK(widget());
   gtk_widget_set_size_request(bg_box_, -1, bar_target_height());
-  gtk_expanded_container_move(GTK_EXPANDED_CONTAINER(widget_.get()),
+  gtk_expanded_container_move(GTK_EXPANDED_CONTAINER(widget()),
                               bg_box_, 0,
                               bar_height() - bar_target_height());
 
-  gtk_widget_set_size_request(widget_.get(), -1, bar_height());
-  gtk_widget_queue_draw(widget_.get());
+  gtk_widget_set_size_request(widget(), -1, bar_height());
+  gtk_widget_queue_draw(widget());
 }
 
 void InfoBarGtk::Observe(int type,
@@ -197,8 +181,8 @@
   UpdateBorderColor();
 }
 
-ui::GtkSignalRegistrar* InfoBarGtk::Signals() {
-  return signals_.get();
+void InfoBarGtk::ForceCloseButtonToUseChromeTheme() {
+  close_button_->ForceChromeTheme();
 }
 
 GtkWidget* InfoBarGtk::CreateLabel(const std::string& text) {
@@ -276,6 +260,16 @@
   menu_->PopupForWidget(sender, 1, gtk_get_current_event_time());
 }
 
+void InfoBarGtk::GetBackgroundColor(SkColor color,
+                                    double* r, double* g, double* b) {
+  DCHECK(theme_service_);
+  if (theme_service_->UsingNativeTheme())
+    color = theme_service_->GetColor(ThemeProperties::COLOR_TOOLBAR);
+  *r = SkColorGetR(color) / 255.0;
+  *g = SkColorGetG(color) / 255.0;
+  *b = SkColorGetB(color) / 255.0;
+}
+
 void InfoBarGtk::UpdateBorderColor() {
   DCHECK(widget());
   gtk_widget_queue_draw(widget());
diff --git a/chrome/browser/ui/gtk/infobars/infobar_gtk.h b/chrome/browser/ui/gtk/infobars/infobar_gtk.h
index 0202989..9b77635 100644
--- a/chrome/browser/ui/gtk/infobars/infobar_gtk.h
+++ b/chrome/browser/ui/gtk/infobars/infobar_gtk.h
@@ -49,7 +49,7 @@
   virtual void InitWidgets();
 
   // Get the top level native GTK widget for this infobar.
-  GtkWidget* widget();
+  GtkWidget* widget() { return widget_.get(); }
 
   GdkColor GetBorderColor() const;
 
@@ -81,9 +81,14 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
+  // Styles the close button as if we're doing Chrome-stlye widget rendering.
+  void ForceCloseButtonToUseChromeTheme();
+
+  GtkWidget* hbox() { return hbox_; }
+
   // Returns the signal registrar for this infobar. All signals representing
   // user actions on visible widgets must go through this registrar!
-  ui::GtkSignalRegistrar* Signals();
+  ui::GtkSignalRegistrar* signals() { return signals_.get(); }
 
   // Creates a label with the appropriate font and color for the current
   // gtk-theme state. It is InfoBarGtk's responsibility to observe browser
@@ -111,6 +116,20 @@
                          MenuGtk::Delegate* delegate,
                          ui::MenuModel* model);
 
+ private:
+  void GetBackgroundColor(SkColor color, double* r, double* g, double* b);
+  void UpdateBorderColor();
+
+  CHROMEGTK_CALLBACK_0(InfoBarGtk, void, OnCloseButton);
+  CHROMEGTK_CALLBACK_1(InfoBarGtk, gboolean, OnBackgroundExpose,
+                       GdkEventExpose*);
+  CHROMEGTK_CALLBACK_2(InfoBarGtk, void, OnChildSizeRequest, GtkWidget*,
+                       GtkRequisition*);
+
+  // A GtkExpandedContainer that contains |bg_box_| so we can vary the height of
+  // the infobar.
+  ui::OwnedWidgetGtk widget_;
+
   // The second highest widget in the hierarchy (after the |widget_|).
   GtkWidget* bg_box_;
 
@@ -125,19 +144,6 @@
 
   content::NotificationRegistrar registrar_;
 
- private:
-  void UpdateBorderColor();
-
-  CHROMEGTK_CALLBACK_0(InfoBarGtk, void, OnCloseButton);
-  CHROMEGTK_CALLBACK_1(InfoBarGtk, gboolean, OnBackgroundExpose,
-                       GdkEventExpose*);
-  CHROMEGTK_CALLBACK_2(InfoBarGtk, void, OnChildSizeRequest, GtkWidget*,
-                       GtkRequisition*);
-
-  // A GtkExpandedContainer that contains |bg_box_| so we can varry the height
-  // of the infobar.
-  ui::OwnedWidgetGtk widget_;
-
   // A list of signals which we clear out once we're closing.
   scoped_ptr<ui::GtkSignalRegistrar> signals_;
 
diff --git a/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.cc b/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.cc
index 519b119..a31fc6f 100644
--- a/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.cc
@@ -22,22 +22,11 @@
 // TranslateInfoBarDelegate ---------------------------------------------------
 
 InfoBar* TranslateInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
-  TranslateInfoBarBase* infobar = NULL;
-  switch (infobar_type_) {
-    case BEFORE_TRANSLATE:
-      infobar = new BeforeTranslateInfoBar(owner, this);
-      break;
-    case AFTER_TRANSLATE:
-      infobar = new AfterTranslateInfoBar(owner, this);
-      break;
-    case TRANSLATING:
-    case TRANSLATION_ERROR:
-      infobar = new TranslateMessageInfoBar(owner, this);
-      break;
-    default:
-      NOTREACHED();
-  }
-  return infobar;
+  if (infobar_type_ == BEFORE_TRANSLATE)
+    return new BeforeTranslateInfoBar(owner, this);
+  if (infobar_type_ == AFTER_TRANSLATE)
+    return new AfterTranslateInfoBar(owner, this);
+  return new TranslateMessageInfoBar(owner, this);
 }
 
 
@@ -141,10 +130,10 @@
   // packed in hbox_.
   GtkWidget* options_menu_button = CreateMenuButton(
       l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_OPTIONS));
-  Signals()->Connect(options_menu_button, "clicked",
+  signals()->Connect(options_menu_button, "clicked",
                      G_CALLBACK(&OnOptionsClickedThunk), this);
   gtk_widget_show_all(options_menu_button);
-  gtk_util::CenterWidgetInHBox(hbox_, options_menu_button, true, 0);
+  gtk_util::CenterWidgetInHBox(hbox(), options_menu_button, true, 0);
 }
 
 bool TranslateInfoBarBase::ShowOptionsMenuButton() const {
diff --git a/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.h b/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.h
index eb48b10..43fa853 100644
--- a/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.h
+++ b/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.h
@@ -19,7 +19,7 @@
                        TranslateInfoBarDelegate* delegate);
   virtual ~TranslateInfoBarBase();
 
-  // InfoBar:
+  // InfoBarGtk:
   virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
   virtual void GetTopColor(InfoBarDelegate::Type type,
                            double* r, double* g, double* b) OVERRIDE;
@@ -27,7 +27,7 @@
                               double* r, double* g, double* b) OVERRIDE;
   virtual void InitWidgets() OVERRIDE;
 
-  // Sub-classes that want to have the options menu button showing sould
+  // Sub-classes that want to have the options menu button showing should
   // override and return true.
   virtual bool ShowOptionsMenuButton() const;
 
diff --git a/chrome/browser/ui/gtk/infobars/translate_message_infobar_gtk.cc b/chrome/browser/ui/gtk/infobars/translate_message_infobar_gtk.cc
index 541fe15..08f7897 100644
--- a/chrome/browser/ui/gtk/infobars/translate_message_infobar_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/translate_message_infobar_gtk.cc
@@ -22,18 +22,19 @@
 void TranslateMessageInfoBar::InitWidgets() {
   TranslateInfoBarBase::InitWidgets();
 
-  GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing);
-  gtk_util::CenterWidgetInHBox(hbox_, hbox, false, 0);
+  GtkWidget* new_hbox = gtk_hbox_new(FALSE, ui::kControlSpacing);
+  gtk_util::CenterWidgetInHBox(hbox(), new_hbox, false, 0);
 
   std::string text = UTF16ToUTF8(GetDelegate()->GetMessageInfoBarText());
-  gtk_box_pack_start(GTK_BOX(hbox), CreateLabel(text.c_str()), FALSE, FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(new_hbox), CreateLabel(text.c_str()), FALSE, FALSE,
+                     0);
   string16 button_text = GetDelegate()->GetMessageInfoBarButtonText();
   if (!button_text.empty()) {
     GtkWidget* button =
         gtk_button_new_with_label(UTF16ToUTF8(button_text).c_str());
-    Signals()->Connect(button, "clicked",G_CALLBACK(&OnButtonPressedThunk),
+    signals()->Connect(button, "clicked", G_CALLBACK(&OnButtonPressedThunk),
                        this);
-    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(new_hbox), button, FALSE, FALSE, 0);
   }
 }
 
diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.cc b/chrome/browser/ui/gtk/location_bar_view_gtk.cc
index 7e822fe..adf92b8 100644
--- a/chrome/browser/ui/gtk/location_bar_view_gtk.cc
+++ b/chrome/browser/ui/gtk/location_bar_view_gtk.cc
@@ -21,6 +21,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/accessibility/accessibility_events.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/defaults.h"
@@ -70,7 +71,6 @@
 #include "chrome/browser/ui/webui/extensions/extension_info_ui.h"
 #include "chrome/browser/ui/zoom/zoom_controller.h"
 #include "chrome/common/badge_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
@@ -316,6 +316,11 @@
   content_setting_bubble_ = NULL;
 }
 
+gfx::Rect AllocationToRect(const GtkAllocation& allocation) {
+  return gfx::Rect(allocation.x, allocation.y,
+                   allocation.width, allocation.height);
+}
+
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -629,7 +634,9 @@
 }
 
 gfx::Rect LocationBarViewGtk::GetOmniboxBounds() const {
-  return gfx::Rect();
+  GtkAllocation hbox_allocation;
+  gtk_widget_get_allocation(hbox_.get(), &hbox_allocation);
+  return AllocationToRect(hbox_allocation);
 }
 
 void LocationBarViewGtk::SetPreviewEnabledPageAction(
@@ -853,11 +860,6 @@
                  weak_ptr_factory_.GetWeakPtr()));
 }
 
-void LocationBarViewGtk::SetInstantSuggestion(
-    const InstantSuggestion& suggestion) {
-  location_entry_->model()->SetInstantSuggestion(suggestion);
-}
-
 string16 LocationBarViewGtk::GetInputString() const {
   return location_input_;
 }
@@ -962,6 +964,10 @@
   // Not implemented on Gtk.
 }
 
+void LocationBarViewGtk::UpdateAutofillCreditCardView() {
+  NOTIMPLEMENTED();
+}
+
 void LocationBarViewGtk::SaveStateToContents(WebContents* contents) {
   location_entry_->SaveStateToTab(contents);
 }
@@ -1398,7 +1404,7 @@
       return FALSE;
     }
     chrome::ShowWebsiteSettings(browser_, tab, nav_entry->GetURL(),
-                                nav_entry->GetSSL(), true);
+                                nav_entry->GetSSL());
     return TRUE;
   } else if (event->button == 2) {
     // When the user middle clicks on the location icon, try to open the
@@ -1460,6 +1466,10 @@
     hbox_width_ = allocation->width;
     UpdateEVCertificateLabelSize();
   }
+  if (browser_ && browser_->instant_controller()) {
+    browser_->instant_controller()->
+        SetOmniboxBounds(AllocationToRect(*allocation));
+  }
 }
 
 void LocationBarViewGtk::OnEntryBoxSizeAllocate(GtkWidget* sender,
diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.h b/chrome/browser/ui/gtk/location_bar_view_gtk.h
index 6e9ad28..c7253ec 100644
--- a/chrome/browser/ui/gtk/location_bar_view_gtk.h
+++ b/chrome/browser/ui/gtk/location_bar_view_gtk.h
@@ -29,12 +29,12 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/common/page_transition_types.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/animation/animation_delegate.h"
 #include "ui/base/animation/slide_animation.h"
 #include "ui/base/gtk/gtk_signal.h"
 #include "ui/base/gtk/owned_widget_gtk.h"
 #include "ui/base/window_open_disposition.h"
+#include "url/gurl.h"
 
 class ActionBoxButtonGtk;
 class Browser;
@@ -130,8 +130,6 @@
 
   // LocationBar:
   virtual void ShowFirstRunBubble() OVERRIDE;
-  virtual void SetInstantSuggestion(
-      const InstantSuggestion& suggestion) OVERRIDE;
   virtual string16 GetInputString() const OVERRIDE;
   virtual WindowOpenDisposition GetWindowOpenDisposition() const OVERRIDE;
   virtual content::PageTransition GetPageTransition() const OVERRIDE;
@@ -142,6 +140,7 @@
   virtual void UpdatePageActions() OVERRIDE;
   virtual void InvalidatePageActions() OVERRIDE;
   virtual void UpdateOpenPDFInReaderPrompt() OVERRIDE;
+  virtual void UpdateAutofillCreditCardView() OVERRIDE;
   virtual void SaveStateToContents(content::WebContents* contents) OVERRIDE;
   virtual void Revert() OVERRIDE;
   virtual const OmniboxView* GetLocationEntry() const OVERRIDE;
diff --git a/chrome/browser/ui/gtk/notifications/balloon_view_gtk.cc b/chrome/browser/ui/gtk/notifications/balloon_view_gtk.cc
index f8f6897..3fc960e 100644
--- a/chrome/browser/ui/gtk/notifications/balloon_view_gtk.cc
+++ b/chrome/browser/ui/gtk/notifications/balloon_view_gtk.cc
@@ -13,6 +13,7 @@
 #include "base/debug/trace_event.h"
 #include "base/message_loop.h"
 #include "base/strings/string_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/notifications/balloon.h"
@@ -29,7 +30,6 @@
 #include "chrome/browser/ui/gtk/menu_gtk.h"
 #include "chrome/browser/ui/gtk/notifications/balloon_view_host_gtk.h"
 #include "chrome/browser/ui/gtk/rounded_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_view_host.h"
diff --git a/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc b/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc
index 1647273..23ab592 100644
--- a/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc
+++ b/chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc
@@ -16,6 +16,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
 #include "chrome/browser/autocomplete/autocomplete_result.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
 #include "chrome/browser/ui/omnibox/omnibox_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/theme_resources.h"
 #include "ui/base/gtk/gtk_compat.h"
diff --git a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc
index a824049..5cc63a8 100644
--- a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc
+++ b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/autocomplete/autocomplete_input.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
 #include "chrome/browser/bookmarks/bookmark_node_data.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/platform_util.h"
@@ -32,11 +33,9 @@
 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/toolbar/toolbar_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "net/base/escape.h"
 #include "third_party/undoview/undo_view.h"
@@ -50,6 +49,7 @@
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/font.h"
 #include "ui/gfx/skia_utils_gtk.h"
+#include "url/gurl.h"
 
 using content::WebContents;
 
@@ -191,9 +191,9 @@
       secure_scheme_tag_(NULL),
       security_error_scheme_tag_(NULL),
       normal_text_tag_(NULL),
-      instant_anchor_tag_(NULL),
-      instant_view_(NULL),
-      instant_mark_(NULL),
+      gray_text_anchor_tag_(NULL),
+      gray_text_view_(NULL),
+      gray_text_mark_(NULL),
       popup_window_mode_(popup_window_mode),
       security_level_(ToolbarModel::NONE),
       mark_set_handler_id_(0),
@@ -362,46 +362,46 @@
   g_signal_connect(text_view_, "destroy",
                    G_CALLBACK(&gtk_widget_destroyed), &text_view_);
 
-  // Setup for the Instant suggestion text view.
+  // Setup for the gray suggestion text view.
   // GtkLabel is used instead of GtkTextView to get transparent background.
-  instant_view_ = gtk_label_new(NULL);
-  gtk_widget_set_no_show_all(instant_view_, TRUE);
-  gtk_label_set_selectable(GTK_LABEL(instant_view_), TRUE);
+  gray_text_view_ = gtk_label_new(NULL);
+  gtk_widget_set_no_show_all(gray_text_view_, TRUE);
+  gtk_label_set_selectable(GTK_LABEL(gray_text_view_), TRUE);
 
   GtkTextIter end_iter;
   gtk_text_buffer_get_end_iter(text_buffer_, &end_iter);
 
-  // Insert a Zero Width Space character just before the Instant anchor.
+  // Insert a Zero Width Space character just before the gray text anchor.
   // It's a hack to workaround a bug of GtkTextView which can not align the
   // pre-edit string and a child anchor correctly when there is no other content
   // around the pre-edit string.
   gtk_text_buffer_insert(text_buffer_, &end_iter, "\342\200\213", -1);
-  GtkTextChildAnchor* instant_anchor =
+  GtkTextChildAnchor* gray_text_anchor =
       gtk_text_buffer_create_child_anchor(text_buffer_, &end_iter);
 
   gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(text_view_),
-                                    instant_view_,
-                                    instant_anchor);
+                                    gray_text_view_,
+                                    gray_text_anchor);
 
-  instant_anchor_tag_ = gtk_text_buffer_create_tag(text_buffer_, NULL, NULL);
+  gray_text_anchor_tag_ = gtk_text_buffer_create_tag(text_buffer_, NULL, NULL);
 
   GtkTextIter anchor_iter;
   gtk_text_buffer_get_iter_at_child_anchor(text_buffer_, &anchor_iter,
-                                           instant_anchor);
-  gtk_text_buffer_apply_tag(text_buffer_, instant_anchor_tag_,
+                                           gray_text_anchor);
+  gtk_text_buffer_apply_tag(text_buffer_, gray_text_anchor_tag_,
                             &anchor_iter, &end_iter);
 
   GtkTextIter start_iter;
   gtk_text_buffer_get_start_iter(text_buffer_, &start_iter);
-  instant_mark_ =
+  gray_text_mark_ =
       gtk_text_buffer_create_mark(text_buffer_, NULL, &start_iter, FALSE);
 
-  // Hooking up this handler after setting up above hacks for Instant view, so
+  // Hooking up this handler after setting up above hacks for gray text view, so
   // that we won't filter out the special ZWP mark itself.
   g_signal_connect(text_buffer_, "insert-text",
                    G_CALLBACK(&HandleInsertTextThunk), this);
 
-  AdjustVerticalAlignmentOfInstantView();
+  AdjustVerticalAlignmentOfGrayTextView();
 
   registrar_.Add(this,
                  chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
@@ -425,10 +425,17 @@
 void OmniboxViewGtk::SetFocus() {
   DCHECK(text_view_);
   gtk_widget_grab_focus(text_view_);
+  // Restore caret visibility if focus is explicitly requested. This is
+  // necessary because if we already have invisible focus, the RequestFocus()
+  // call above will short-circuit, preventing us from reaching
+  // OmniboxEditModel::OnSetFocus(), which handles restoring visibility when the
+  // omnibox regains focus after losing focus.
+  model()->SetCaretVisibility(true);
 }
 
 void OmniboxViewGtk::ApplyCaretVisibility() {
-  // TODO(mathp): implement for Linux.
+  gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text_view_),
+                                   model()->is_caret_visible());
 }
 
 void OmniboxViewGtk::SaveStateToTab(WebContents* tab) {
@@ -599,16 +606,9 @@
   SetSelectedRange(saved_temporary_selection_);
   FinishUpdatingHighlightedText();
   // We got here because the user hit the Escape key. We explicitly don't call
-  // TextChanged(), since calling it breaks Instant-Extended, and isn't needed
-  // otherwise (in regular non-Instant or Instant-but-not-Extended modes).
-  //
-  // Why it breaks Instant-Extended: Instant handles the Escape key separately
-  // (cf: OmniboxEditModel::RevertTemporaryText). Calling TextChanged() makes
-  // the page think the user additionally typed some text, causing it to update
-  // its suggestions dropdown with new suggestions, which is wrong.
-  //
-  // Why it isn't needed: OmniboxPopupModel::ResetToDefaultMatch() has already
-  // been called by now; it would've called TextChanged() if it was warranted.
+  // TextChanged(), since OmniboxPopupModel::ResetToDefaultMatch() has already
+  // been called by now, and it would've called TextChanged() if it was
+  // warranted.
 }
 
 void OmniboxViewGtk::OnBeforePossibleChange() {
@@ -714,23 +714,23 @@
   return toplevel;
 }
 
-void OmniboxViewGtk::SetInstantSuggestion(const string16& suggestion) {
+void OmniboxViewGtk::SetGrayTextAutocompletion(const string16& suggestion) {
   std::string suggestion_utf8 = UTF16ToUTF8(suggestion);
 
-  gtk_label_set_text(GTK_LABEL(instant_view_), suggestion_utf8.c_str());
+  gtk_label_set_text(GTK_LABEL(gray_text_view_), suggestion_utf8.c_str());
 
   if (suggestion.empty()) {
-    gtk_widget_hide(instant_view_);
+    gtk_widget_hide(gray_text_view_);
     return;
   }
 
-  gtk_widget_show(instant_view_);
-  AdjustVerticalAlignmentOfInstantView();
-  UpdateInstantViewColors();
+  gtk_widget_show(gray_text_view_);
+  AdjustVerticalAlignmentOfGrayTextView();
+  UpdateGrayTextViewColors();
 }
 
-string16 OmniboxViewGtk::GetInstantSuggestion() const {
-  const gchar* suggestion = gtk_label_get_text(GTK_LABEL(instant_view_));
+string16 OmniboxViewGtk::GetGrayTextAutocompletion() const {
+  const gchar* suggestion = gtk_label_get_text(GTK_LABEL(gray_text_view_));
   return suggestion ? UTF8ToUTF16(suggestion) : string16();
 }
 
@@ -754,8 +754,8 @@
   GdkRectangle first_char_bounds, last_char_bounds;
   gtk_text_buffer_get_start_iter(text_buffer_, &start);
 
-  // Use the real end iterator here to take the width of Instant suggestion
-  // text into account, so that location bar can layout its children correctly.
+  // Use the real end iterator here to take the width of gray suggestion text
+  // into account, so that location bar can layout its children correctly.
   gtk_text_buffer_get_end_iter(text_buffer_, &end);
   gtk_text_view_get_iter_location(GTK_TEXT_VIEW(text_view_),
                                   &start, &first_char_bounds);
@@ -804,7 +804,7 @@
     gtk_widget_modify_text(text_view_, GTK_STATE_ACTIVE, NULL);
 
     gtk_util::UndoForceFontSize(text_view_);
-    gtk_util::UndoForceFontSize(instant_view_);
+    gtk_util::UndoForceFontSize(gray_text_view_);
 
     // Grab the text colors out of the style and set our tags to use them.
     GtkStyle* style = gtk_rc_get_style(text_view_);
@@ -844,26 +844,26 @@
 
     // Until we switch to vector graphics, force the font size.
     gtk_util::ForceFontSizePixels(text_view_, GetFont().GetFontSize());
-    gtk_util::ForceFontSizePixels(instant_view_, GetFont().GetFontSize());
+    gtk_util::ForceFontSizePixels(gray_text_view_, GetFont().GetFontSize());
 
     g_object_set(faded_text_tag_, "foreground", kTextBaseColor, NULL);
     g_object_set(normal_text_tag_, "foreground", "#000000", NULL);
   }
 
-  AdjustVerticalAlignmentOfInstantView();
-  UpdateInstantViewColors();
+  AdjustVerticalAlignmentOfGrayTextView();
+  UpdateGrayTextViewColors();
 }
 
-void OmniboxViewGtk::UpdateInstantViewColors() {
+void OmniboxViewGtk::UpdateGrayTextViewColors() {
   GdkColor faded_text;
   if (theme_service_->UsingNativeTheme()) {
-    GtkStyle* style = gtk_rc_get_style(instant_view_);
+    GtkStyle* style = gtk_rc_get_style(gray_text_view_);
     faded_text = gtk_util::AverageColors(
         style->text[GTK_STATE_NORMAL], style->base[GTK_STATE_NORMAL]);
   } else {
     gdk_color_parse(kTextBaseColor, &faded_text);
   }
-  gtk_widget_modify_fg(instant_view_, GTK_STATE_NORMAL, &faded_text);
+  gtk_widget_modify_fg(gray_text_view_, GTK_STATE_NORMAL, &faded_text);
 }
 
 void OmniboxViewGtk::HandleBeginUserAction(GtkTextBuffer* sender) {
@@ -1045,6 +1045,13 @@
 
   DCHECK(text_view_);
 
+  // Restore caret visibility whenever the user clicks in the omnibox in a way
+  // that would give it focus.  We must handle this case separately here because
+  // if the omnibox currently has invisible focus, the mouse event won't trigger
+  // either SetFocus() or OmniboxEditModel::OnSetFocus().
+  if (event->button == 1 || event->button == 2)
+    model()->SetCaretVisibility(true);
+
   if (event->button == 1) {
     button_1_pressed_ = true;
 
@@ -1458,7 +1465,7 @@
        p = g_utf8_next_char(p)) {
     gunichar c = g_utf8_get_char(p);
 
-    // 0x200B is Zero Width Space, which is inserted just before the Instant
+    // 0x200B is Zero Width Space, which is inserted just before the gray text
     // anchor for working around the GtkTextView's misalignment bug.
     // This character might be captured and inserted into the content by undo
     // manager, so we need to filter it out here.
@@ -1475,7 +1482,7 @@
   }
 
   if (!filtered_text.empty()) {
-    // Avoid inserting the text after the Instant anchor.
+    // Avoid inserting the text after the gray text anchor.
     ValidateTextBufferIter(location);
 
     // Call the default handler to insert filtered text.
@@ -1544,7 +1551,7 @@
   if (supports_pre_edit_ && !handled && !pre_edit_.empty())
     handled = true;
 
-  if (!handled && gtk_widget_get_visible(instant_view_))
+  if (!handled && gtk_widget_get_visible(gray_text_view_))
     handled = model()->CommitSuggestedText();
 
   if (handled) {
@@ -1611,7 +1618,7 @@
 
 int OmniboxViewGtk::GetOmniboxTextLength() const {
   GtkTextIter end;
-  gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, instant_mark_);
+  gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, gray_text_mark_);
   if (supports_pre_edit_) {
     // We need to count the length of the text being composed, because we treat
     // it as part of the content in GetText().
@@ -1979,9 +1986,9 @@
 void OmniboxViewGtk::HandleDeleteRange(GtkTextBuffer* buffer,
                                        GtkTextIter* start,
                                        GtkTextIter* end) {
-  // Prevent the user from deleting the Instant anchor. We can't simply set the
-  // Instant anchor readonly by applying a tag with "editable" = FALSE, because
-  // it'll prevent the insert caret from blinking.
+  // Prevent the user from deleting the gray text anchor. We can't simply set
+  // the gray text anchor readonly by applying a tag with "editable" = FALSE,
+  // because it'll prevent the insert caret from blinking.
   ValidateTextBufferIter(start);
   ValidateTextBufferIter(end);
   if (!gtk_text_iter_compare(start, end)) {
@@ -1994,7 +2001,7 @@
 void OmniboxViewGtk::HandleMarkSetAlways(GtkTextBuffer* buffer,
                                          GtkTextIter* location,
                                          GtkTextMark* mark) {
-  if (mark == instant_mark_ || !instant_mark_)
+  if (mark == gray_text_mark_ || !gray_text_mark_)
     return;
 
   GtkTextIter new_iter = *location;
@@ -2003,7 +2010,7 @@
   static guint signal_id = g_signal_lookup("mark-set", GTK_TYPE_TEXT_BUFFER);
 
   // "mark-set" signal is actually emitted after the mark's location is already
-  // set, so if the location is beyond the Instant anchor, we need to move the
+  // set, so if the location is beyond the gray text anchor, we need to move the
   // mark again, which will emit the signal again. In order to prevent other
   // signal handlers from being called twice, we need to stop signal emission
   // before moving the mark again.
@@ -2027,7 +2034,7 @@
                                    gtk_text_buffer_get_selection_bound(buffer));
 
   GtkTextIter end;
-  gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, instant_mark_);
+  gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, gray_text_mark_);
 
   if (gtk_text_iter_compare(&insert, &end) > 0 ||
       gtk_text_iter_compare(&selection_bound, &end) > 0) {
@@ -2123,26 +2130,26 @@
 void OmniboxViewGtk::GetTextBufferBounds(GtkTextIter* start,
                                          GtkTextIter* end) const {
   gtk_text_buffer_get_start_iter(text_buffer_, start);
-  gtk_text_buffer_get_iter_at_mark(text_buffer_, end, instant_mark_);
+  gtk_text_buffer_get_iter_at_mark(text_buffer_, end, gray_text_mark_);
 }
 
 void OmniboxViewGtk::ValidateTextBufferIter(GtkTextIter* iter) const {
-  if (!instant_mark_)
+  if (!gray_text_mark_)
     return;
 
   GtkTextIter end;
-  gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, instant_mark_);
+  gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, gray_text_mark_);
   if (gtk_text_iter_compare(iter, &end) > 0)
     *iter = end;
 }
 
-void OmniboxViewGtk::AdjustVerticalAlignmentOfInstantView() {
+void OmniboxViewGtk::AdjustVerticalAlignmentOfGrayTextView() {
   // By default, GtkTextView layouts an anchored child widget just above the
-  // baseline, so we need to move the |instant_view_| down to make sure it
+  // baseline, so we need to move the |gray_text_view_| down to make sure it
   // has the same baseline as the |text_view_|.
-  PangoLayout* layout = gtk_label_get_layout(GTK_LABEL(instant_view_));
+  PangoLayout* layout = gtk_label_get_layout(GTK_LABEL(gray_text_view_));
   int height;
   pango_layout_get_size(layout, NULL, &height);
   int baseline = pango_layout_get_baseline(layout);
-  g_object_set(instant_anchor_tag_, "rise", baseline - height, NULL);
+  g_object_set(gray_text_anchor_tag_, "rise", baseline - height, NULL);
 }
diff --git a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h
index b19343d..8ec060f 100644
--- a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h
+++ b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h
@@ -97,8 +97,8 @@
   virtual bool OnAfterPossibleChange() OVERRIDE;
   virtual gfx::NativeView GetNativeView() const OVERRIDE;
   virtual gfx::NativeView GetRelativeWindowForPopup() const OVERRIDE;
-  virtual void SetInstantSuggestion(const string16& suggestion) OVERRIDE;
-  virtual string16 GetInstantSuggestion() const OVERRIDE;
+  virtual void SetGrayTextAutocompletion(const string16& suggestion) OVERRIDE;
+  virtual string16 GetGrayTextAutocompletion() const OVERRIDE;
   virtual int TextWidth() const OVERRIDE;
   virtual bool IsImeComposing() const OVERRIDE;
 
@@ -109,8 +109,8 @@
 
   // Sets the colors of the text view according to the theme.
   void SetBaseColor();
-  // Sets the colors of the Instant suggestion view according to the theme.
-  void UpdateInstantViewColors();
+  // Sets the colors of the gray text suggestion view according to the theme.
+  void UpdateGrayTextViewColors();
 
   // Returns the text view gtk widget. May return NULL if the widget
   // has already been destroyed.
@@ -283,16 +283,16 @@
   void UpdatePrimarySelectionIfValidURL();
 
   // Retrieves the first and last iterators in the |text_buffer_|, but excludes
-  // the anchor holding the |instant_view_| widget.
+  // the anchor holding the |gray_text_view_| widget.
   void GetTextBufferBounds(GtkTextIter* start, GtkTextIter* end) const;
 
   // Validates an iterator in the |text_buffer_|, to make sure it doesn't go
-  // beyond the anchor for holding the |instant_view_| widget.
+  // beyond the anchor for holding the |gray_text_view_| widget.
   void ValidateTextBufferIter(GtkTextIter* iter) const;
 
-  // Adjusts vertical alignment of the |instant_view_| in the |text_view_|, to
+  // Adjusts vertical alignment of the |gray_text_view_| in the |text_view_|, to
   // make sure they have the same baseline.
-  void AdjustVerticalAlignmentOfInstantView();
+  void AdjustVerticalAlignmentOfGrayTextView();
 
   // The Browser that contains this omnibox.
   Browser* browser_;
@@ -314,17 +314,17 @@
   GtkTextTag* security_error_scheme_tag_;
   GtkTextTag* normal_text_tag_;
 
-  // Objects for the Instant suggestion text view.
-  GtkTextTag* instant_anchor_tag_;
+  // Objects for the gray suggestion text view.
+  GtkTextTag* gray_text_anchor_tag_;
 
-  // A widget for displaying Instant suggestion text. It'll be attached to a
+  // A widget for displaying gray autocompletion text. It'll be attached to a
   // child anchor in the |text_buffer_| object.
-  GtkWidget* instant_view_;
+  GtkWidget* gray_text_view_;
 
-  // A mark to split the content and the Instant anchor. Wherever the end
+  // A mark to split the content and the gray text anchor. Wherever the end
   // iterator of the text buffer is required, the iterator to this mark should
   // be used.
-  GtkTextMark* instant_mark_;
+  GtkTextMark* gray_text_mark_;
 
   scoped_ptr<OmniboxPopupView> popup_view_;
 
diff --git a/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.cc b/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.cc
index 9f4571a..581427b 100644
--- a/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.cc
@@ -151,8 +151,7 @@
   // Main dialog/bubble message.
   std::string label_text;
   if (is_sync_dialog_) {
-    label_text = email_.empty() ?
-        l10n_util::GetStringUTF8(IDS_ONE_CLICK_SIGNIN_DIALOG_MESSAGE) :
+    label_text =
         l10n_util::GetStringFUTF8(IDS_ONE_CLICK_SIGNIN_DIALOG_MESSAGE_NEW,
                                   email_);
   } else {
@@ -206,8 +205,8 @@
 
   g_object_unref(size_group);
 
-  header_label_ = theme_provider->BuildLabel(email_.empty() ?
-      l10n_util::GetStringUTF8(IDS_ONE_CLICK_SIGNIN_DIALOG_TITLE) :
+  // The email is always set for the sync dialog.
+  header_label_ = theme_provider->BuildLabel(
       l10n_util::GetStringFUTF8(IDS_ONE_CLICK_SIGNIN_DIALOG_TITLE_NEW, email_),
       ui::kGdkBlack);
 
diff --git a/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.h b/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.h
index 8f6df10..c823ae8 100644
--- a/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.h
+++ b/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.h
@@ -61,8 +61,10 @@
 
   BubbleGtk* bubble_;
 
+  // The user's email address to be used for sync.
   const string16 email_;
 
+  // Alternate error message to be displayed.
   const string16 error_message_;
 
   // This callback is nulled once its called, so that it is called only once.
diff --git a/chrome/browser/ui/gtk/overflow_button.cc b/chrome/browser/ui/gtk/overflow_button.cc
index 7b2d584..e1648b9 100644
--- a/chrome/browser/ui/gtk/overflow_button.cc
+++ b/chrome/browser/ui/gtk/overflow_button.cc
@@ -6,9 +6,9 @@
 
 #include <gtk/gtk.h>
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/theme_resources.h"
 #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/ui/gtk/panels/panel_gtk.cc b/chrome/browser/ui/gtk/panels/panel_gtk.cc
index 26ae46d..175cc61 100644
--- a/chrome/browser/ui/gtk/panels/panel_gtk.cc
+++ b/chrome/browser/ui/gtk/panels/panel_gtk.cc
@@ -14,6 +14,7 @@
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
 #include "chrome/browser/ui/gtk/custom_button.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/ui/panels/panel_manager.h"
 #include "chrome/browser/ui/panels/stacked_panel_collection.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
@@ -1091,6 +1091,7 @@
   virtual bool IsButtonVisible(
       panel::TitlebarButtonType button_type) const OVERRIDE;
   virtual panel::CornerStyle GetWindowCornerStyle() const OVERRIDE;
+  virtual bool EnsureApplicationRunOnForeground() OVERRIDE;
 
   PanelGtk* panel_gtk_;
 };
@@ -1165,8 +1166,7 @@
 }
 
 bool GtkNativePanelTesting::VerifyActiveState(bool is_active) {
-  // TODO(jianli): to be implemented. http://crbug.com/102737
-  return false;
+  return gtk_window_is_active(panel_gtk_->GetNativePanelWindow()) == is_active;
 }
 
 bool GtkNativePanelTesting::VerifyAppIcon() const {
@@ -1213,3 +1213,8 @@
 panel::CornerStyle GtkNativePanelTesting::GetWindowCornerStyle() const {
   return panel_gtk_->corner_style_;
 }
+
+bool GtkNativePanelTesting::EnsureApplicationRunOnForeground() {
+  // Not needed on GTK.
+  return true;
+}
diff --git a/chrome/browser/ui/gtk/protocol_dialog_gtk.h b/chrome/browser/ui/gtk/protocol_dialog_gtk.h
index 0685b3e..d69b644 100644
--- a/chrome/browser/ui/gtk/protocol_dialog_gtk.h
+++ b/chrome/browser/ui/gtk/protocol_dialog_gtk.h
@@ -9,8 +9,8 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
 #include "chrome/browser/ui/protocol_dialog_delegate.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/gtk/gtk_signal.h"
+#include "url/gurl.h"
 
 typedef struct _GtkWidget GtkWidget;
 
diff --git a/chrome/browser/ui/gtk/reload_button_gtk.cc b/chrome/browser/ui/gtk/reload_button_gtk.cc
index bd26518..0557887 100644
--- a/chrome/browser/ui/gtk/reload_button_gtk.cc
+++ b/chrome/browser/ui/gtk/reload_button_gtk.cc
@@ -10,6 +10,7 @@
 #include "base/logging.h"
 #include "base/message_loop.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/gtk/accelerators_gtk.h"
@@ -18,7 +19,6 @@
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
diff --git a/chrome/browser/ui/gtk/status_bubble_gtk.cc b/chrome/browser/ui/gtk/status_bubble_gtk.cc
index ba04015..6938606 100644
--- a/chrome/browser/ui/gtk/status_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/status_bubble_gtk.cc
@@ -11,11 +11,11 @@
 #include "base/i18n/rtl.h"
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/gtk_util.h"
 #include "chrome/browser/ui/gtk/rounded_window.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "ui/base/animation/slide_animation.h"
 #include "ui/base/gtk/gtk_compat.h"
diff --git a/chrome/browser/ui/gtk/status_bubble_gtk.h b/chrome/browser/ui/gtk/status_bubble_gtk.h
index dbc2b5b..fc5a4e8 100644
--- a/chrome/browser/ui/gtk/status_bubble_gtk.h
+++ b/chrome/browser/ui/gtk/status_bubble_gtk.h
@@ -15,11 +15,11 @@
 #include "chrome/browser/ui/status_bubble.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/animation/animation_delegate.h"
 #include "ui/base/gtk/gtk_signal.h"
 #include "ui/base/gtk/owned_widget_gtk.h"
 #include "ui/gfx/point.h"
+#include "url/gurl.h"
 
 class GtkThemeService;
 class Profile;
diff --git a/chrome/browser/ui/gtk/tab_contents_container_gtk.cc b/chrome/browser/ui/gtk/tab_contents_container_gtk.cc
index 1927fc5..cda69a8 100644
--- a/chrome/browser/ui/gtk/tab_contents_container_gtk.cc
+++ b/chrome/browser/ui/gtk/tab_contents_container_gtk.cc
@@ -7,8 +7,8 @@
 #include <algorithm>
 
 #include "base/i18n/rtl.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/gtk/status_bubble_gtk.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc b/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc
index aca50c6..07f962e 100644
--- a/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc
+++ b/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/i18n/rtl.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.h"
 #include "chrome/browser/ui/browser.h"
@@ -18,7 +19,6 @@
 #include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_view.h"
diff --git a/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc
index 02ef069..f8e9827 100644
--- a/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc
+++ b/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc
@@ -9,6 +9,7 @@
 
 #include "base/debug/trace_event.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/favicon/favicon_tab_helper.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/ui/gtk/gtk_util.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
 #include "chrome/browser/ui/tabs/tab_utils.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents.h"
 #include "grit/generated_resources.h"
diff --git a/chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc
index f0caf47..10bd53c 100644
--- a/chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc
+++ b/chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/autocomplete/autocomplete_classifier.h"
 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/themes/theme_service.h"
@@ -32,7 +33,6 @@
 #include "chrome/browser/ui/gtk/tabs/tab_strip_menu_controller.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/gtk/throbber_gtk.cc b/chrome/browser/ui/gtk/throbber_gtk.cc
index 7b60a5e..099d2a1 100644
--- a/chrome/browser/ui/gtk/throbber_gtk.cc
+++ b/chrome/browser/ui/gtk/throbber_gtk.cc
@@ -5,8 +5,8 @@
 #include "chrome/browser/ui/gtk/throbber_gtk.h"
 
 #include "base/logging.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "grit/ui_resources.h"
 #include "ui/base/animation/tween.h"
diff --git a/chrome/browser/ui/gtk/view_id_util_browsertest.cc b/chrome/browser/ui/gtk/view_id_util_browsertest.cc
index b3f1b03..9e71fcd 100644
--- a/chrome/browser/ui/gtk/view_id_util_browsertest.cc
+++ b/chrome/browser/ui/gtk/view_id_util_browsertest.cc
@@ -44,7 +44,8 @@
         i == VIEW_ID_BOOKMARK_BAR_ELEMENT ||
         i == VIEW_ID_TAB ||
         i == VIEW_ID_FEEDBACK_BUTTON ||
-        i == VIEW_ID_SCRIPT_BUBBLE) {
+        i == VIEW_ID_SCRIPT_BUBBLE ||
+        i == VIEW_ID_MIC_SEARCH_BUTTON) {
       continue;
     }
 
diff --git a/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc b/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc
index 4ec5151..1e25c90 100644
--- a/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc
+++ b/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc
@@ -8,6 +8,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/certificate_viewer.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
@@ -22,12 +23,10 @@
 #include "chrome/browser/ui/gtk/website_settings/permission_selector.h"
 #include "chrome/browser/ui/website_settings/website_settings.h"
 #include "chrome/browser/ui/website_settings/website_settings_utils.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/cert_store.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/user_metrics.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/locale_settings.h"
@@ -38,6 +37,7 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/image/cairo_cached_surface.h"
 #include "ui/gfx/image/image.h"
+#include "url/gurl.h"
 
 using content::OpenURLParams;
 
@@ -246,15 +246,10 @@
     return;
   }
 
-  TabSpecificContentSettings* content_settings =
-      TabSpecificContentSettings::FromWebContents(web_contents);
-  InfoBarService* infobar_service =
-      InfoBarService::FromWebContents(web_contents);
-  presenter_.reset(new WebsiteSettings(this, profile,
-                                       content_settings,
-                                       infobar_service,
-                                       url, ssl,
-                                       content::CertStore::GetInstance()));
+  presenter_.reset(new WebsiteSettings(
+      this, profile, TabSpecificContentSettings::FromWebContents(web_contents),
+      InfoBarService::FromWebContents(web_contents), url, ssl,
+      content::CertStore::GetInstance()));
 }
 
 WebsiteSettingsPopupGtk::~WebsiteSettingsPopupGtk() {
diff --git a/chrome/browser/ui/gtk/zoom_bubble_gtk.cc b/chrome/browser/ui/gtk/zoom_bubble_gtk.cc
index 5086e13..cc66370 100644
--- a/chrome/browser/ui/gtk/zoom_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/zoom_bubble_gtk.cc
@@ -7,6 +7,7 @@
 #include "base/i18n/rtl.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h"
 #include "chrome/browser/ui/zoom/zoom_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/ui/hung_plugin_tab_helper.cc b/chrome/browser/ui/hung_plugin_tab_helper.cc
index c656f63..648cba4 100644
--- a/chrome/browser/ui/hung_plugin_tab_helper.cc
+++ b/chrome/browser/ui/hung_plugin_tab_helper.cc
@@ -11,11 +11,10 @@
 #include "base/process_util.h"
 #include "base/rand_util.h"
 #include "build/build_config.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar.h"
 #include "chrome/browser/infobars/infobar_service.h"
-#include "chrome/common/chrome_process_type.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_version_info.h"
 #include "content/public/browser/browser_child_process_host_iterator.h"
 #include "content/public/browser/browser_thread.h"
@@ -24,6 +23,7 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/browser/render_process_host.h"
+#include "content/public/common/process_type.h"
 #include "content/public/common/result_codes.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
@@ -45,13 +45,14 @@
 
 class OwnedHandleVector {
  public:
+  typedef std::vector<HANDLE> Handles;
   OwnedHandleVector();
   ~OwnedHandleVector();
 
-  std::vector<HANDLE>& data() { return data_; }
+  Handles* data() { return &data_; }
 
  private:
-  std::vector<HANDLE> data_;
+  Handles data_;
 
   DISALLOW_COPY_AND_ASSIGN(OwnedHandleVector);
 };
@@ -60,10 +61,8 @@
 }
 
 OwnedHandleVector::~OwnedHandleVector() {
-  for (std::vector<HANDLE>::const_iterator iter = data_.begin();
-       iter != data_.end(); ++iter) {
+  for (Handles::iterator iter = data_.begin(); iter != data_.end(); ++iter)
     ::CloseHandle(*iter);
-  }
 }
 
 
@@ -76,9 +75,9 @@
 }
 
 void DumpRenderersInBlockingPool(OwnedHandleVector* renderer_handles) {
-  for (std::vector<HANDLE>::const_iterator iter =
-           renderer_handles->data().begin();
-       iter != renderer_handles->data().end(); ++iter) {
+  for (OwnedHandleVector::Handles::const_iterator iter =
+           renderer_handles->data()->begin();
+       iter != renderer_handles->data()->end(); ++iter) {
     CrashDumpForHangDebugging(*iter);
   }
 }
@@ -88,7 +87,7 @@
   CrashDumpAndTerminateHungChildProcess(plugin_handle->Get());
 }
 
-#endif
+#endif  // defined(OS_WIN)
 
 // Called on the I/O thread to actually kill the plugin with the given child
 // ID. We specifically don't want this to be a member function since if the
@@ -178,11 +177,11 @@
     const string16& plugin_name)
     : ConfirmInfoBarDelegate(infobar_service),
       helper_(helper),
-      plugin_child_id_(plugin_child_id) {
-  message_ = l10n_util::GetStringFUTF16(IDS_BROWSER_HANGMONITOR_PLUGIN_INFOBAR,
-                                        plugin_name);
-  button_text_ = l10n_util::GetStringUTF16(
-      IDS_BROWSER_HANGMONITOR_PLUGIN_INFOBAR_KILLBUTTON);
+      plugin_child_id_(plugin_child_id),
+      message_(l10n_util::GetStringFUTF16(
+          IDS_BROWSER_HANGMONITOR_PLUGIN_INFOBAR, plugin_name)),
+      button_text_(l10n_util::GetStringUTF16(
+          IDS_BROWSER_HANGMONITOR_PLUGIN_INFOBAR_KILLBUTTON)) {
 }
 
 HungPluginInfoBarDelegate::~HungPluginInfoBarDelegate() {
@@ -225,7 +224,7 @@
   string16 name;
 
   // Possibly-null if we're not showing an infobar right now.
-  InfoBarDelegate* info_bar;
+  InfoBarDelegate* infobar;
 
   // Time to delay before re-showing the infobar for a hung plugin. This is
   // increased each time the user cancels it.
@@ -251,7 +250,7 @@
                                               const string16& n)
     : path(p),
       name(n),
-      info_bar(NULL),
+      infobar(NULL),
       next_reshow_delay(base::TimeDelta::FromSeconds(kInitialReshowDelaySec)),
       timer(false, false) {
 }
@@ -288,8 +287,8 @@
   for (PluginStateMap::iterator i = hung_plugins_.begin();
        i != hung_plugins_.end(); ++i) {
     if (i->second->path == plugin_path) {
-      if (i->second->info_bar)
-        infobar_service->RemoveInfoBar(i->second->info_bar);
+      if (i->second->infobar)
+        infobar_service->RemoveInfoBar(i->second->infobar);
       hung_plugins_.erase(i);
       break;
     }
@@ -309,8 +308,8 @@
   if (found != hung_plugins_.end()) {
     if (!is_hung) {
       // Hung plugin became un-hung, close the infobar and delete our info.
-      if (found->second->info_bar)
-        infobar_service->RemoveInfoBar(found->second->info_bar);
+      if (found->second->infobar)
+        infobar_service->RemoveInfoBar(found->second->infobar);
       hung_plugins_.erase(found);
     }
     return;
@@ -337,14 +336,14 @@
   //
   // TODO(pkasting): This comment will be incorrect and should be removed once
   // InfoBars own their delegates.
-  InfoBarDelegate* delegate =
+  InfoBarDelegate* infobar =
       content::Details<InfoBarRemovedDetails>(details)->first;
 
   for (PluginStateMap::iterator i = hung_plugins_.begin();
        i != hung_plugins_.end(); ++i) {
     PluginState* state = i->second.get();
-    if (state->info_bar == delegate) {
-      state->info_bar = NULL;
+    if (state->infobar == infobar) {
+      state->infobar = NULL;
 
       // Schedule the timer to re-show the infobar if the plugin continues to be
       // hung.
@@ -377,14 +376,14 @@
         HANDLE handle = NULL;
         ::DuplicateHandle(current_process, host->GetHandle(), current_process,
                           &handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
-        renderer_handles->data().push_back(handle);
+        renderer_handles->data()->push_back(handle);
       }
       // If there are a lot of renderer processes, it is likely that we will
       // generate too many crash dumps. They might not all be uploaded/recorded
       // due to our crash dump uploading restrictions. So we just don't generate
       // renderer crash dumps in that case.
-      if (renderer_handles->data().size() > 0 &&
-          renderer_handles->data().size() < 4) {
+      if (renderer_handles->data()->size() > 0 &&
+          renderer_handles->data()->size() < 4) {
         content::BrowserThread::PostBlockingPoolSequencedTask(
             kDumpChildProcessesSequenceName, FROM_HERE,
             base::Bind(&DumpBrowserInBlockingPool));
@@ -398,10 +397,7 @@
 #endif
 
   PluginStateMap::iterator found = hung_plugins_.find(child_id);
-  if (found == hung_plugins_.end()) {
-    NOTREACHED();
-    return;
-  }
+  DCHECK(found != hung_plugins_.end());
 
   content::BrowserThread::PostTask(content::BrowserThread::IO,
                                    FROM_HERE,
@@ -410,12 +406,11 @@
 }
 
 void HungPluginTabHelper::OnReshowTimer(int child_id) {
+  // The timer should have been cancelled if the record isn't in our map
+  // anymore.
   PluginStateMap::iterator found = hung_plugins_.find(child_id);
-  if (found == hung_plugins_.end() || found->second->info_bar) {
-    // The timer should be cancelled if the record isn't in our map anymore.
-    NOTREACHED();
-    return;
-  }
+  DCHECK(found != hung_plugins_.end());
+  DCHECK(!found->second->infobar);
   ShowBar(child_id, found->second.get());
 }
 
@@ -425,8 +420,8 @@
   if (!infobar_service)
     return;
 
-  DCHECK(!state->info_bar);
-  state->info_bar =
+  DCHECK(!state->infobar);
+  state->infobar =
       HungPluginInfoBarDelegate::Create(infobar_service, this, child_id,
                                         state->name);
 }
@@ -434,11 +429,8 @@
 void HungPluginTabHelper::CloseBar(PluginState* state) {
   InfoBarService* infobar_service =
       InfoBarService::FromWebContents(web_contents());
-  if (!infobar_service)
-    return;
-
-  if (state->info_bar) {
-    infobar_service->RemoveInfoBar(state->info_bar);
-    state->info_bar = NULL;
+  if (infobar_service && state->infobar) {
+    infobar_service->RemoveInfoBar(state->infobar);
+    state->infobar = NULL;
   }
 }
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
index c249cc6..de66141 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
+++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
@@ -146,9 +146,10 @@
 
 // The image resources that will be tinted by the 'button' tint value.
 const int kOtherToolbarButtonIDs[] = {
-  IDR_TOOLS,
-  IDR_TOOLS_H,
-  IDR_TOOLS_P,
+  IDR_TOOLBAR_BEZEL_HOVER,
+  IDR_TOOLBAR_BEZEL_PRESSED,
+  IDR_BROWSER_ACTION_H,
+  IDR_BROWSER_ACTION_P,
   IDR_BROWSER_ACTIONS_OVERFLOW,
   IDR_BROWSER_ACTIONS_OVERFLOW_H,
   IDR_BROWSER_ACTIONS_OVERFLOW_P,
@@ -781,11 +782,14 @@
     case IDR_STOP_P: {
       return GenerateGTKIcon(id);
     }
-    case IDR_TOOLS:
-    case IDR_TOOLS_H:
-    case IDR_TOOLS_P: {
-      return GenerateWrenchIcon(id);
-    }
+    case IDR_TOOLBAR_BEZEL_HOVER:
+      return GenerateToolbarBezel(GTK_STATE_PRELIGHT, IDR_TOOLBAR_BEZEL_HOVER);
+    case IDR_TOOLBAR_BEZEL_PRESSED:
+      return GenerateToolbarBezel(GTK_STATE_ACTIVE, IDR_TOOLBAR_BEZEL_PRESSED);
+    case IDR_BROWSER_ACTION_H:
+      return GenerateToolbarBezel(GTK_STATE_PRELIGHT, IDR_BROWSER_ACTION_H);
+    case IDR_BROWSER_ACTION_P:
+      return GenerateToolbarBezel(GTK_STATE_ACTIVE, IDR_BROWSER_ACTION_P);
     default: {
       return GenerateTintedIcon(id, button_tint_);
     }
@@ -914,17 +918,10 @@
   return retval;
 }
 
-SkBitmap Gtk2UI::GenerateWrenchIcon(int base_id) const {
+SkBitmap Gtk2UI::GenerateToolbarBezel(int gtk_state, int sizing_idr) const {
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  SkBitmap default_bitmap = rb.GetImageNamed(IDR_TOOLS).AsBitmap();
-
-  // Part 1: Tint the wrench icon according to the button tint.
-  SkBitmap shifted = SkBitmapOperations::CreateHSLShiftedBitmap(
-      default_bitmap, button_tint_);
-
-  // The unhighlighted icon doesn't need to have a border composed onto it.
-  if (base_id == IDR_TOOLS)
-    return shifted;
+  SkBitmap default_bitmap =
+      rb.GetImageNamed(sizing_idr).AsBitmap();
 
   SkBitmap retval;
   retval.setConfig(SkBitmap::kARGB_8888_Config,
@@ -935,11 +932,10 @@
 
   SkCanvas canvas(retval);
   SkBitmap border = DrawGtkButtonBorder(
-      base_id == IDR_TOOLS_H ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE,
+      gtk_state,
       default_bitmap.width(),
       default_bitmap.height());
   canvas.drawBitmap(border, 0, 0);
-  canvas.drawBitmap(shifted, 0, 0);
 
   return retval;
 }
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.h b/chrome/browser/ui/libgtk2ui/gtk2_ui.h
index e53ff6b..b1db13a 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_ui.h
+++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.h
@@ -106,8 +106,9 @@
   // appropriate.
   SkBitmap GenerateGTKIcon(int base_id) const;
 
-  // Renders a GTK button border around a tinted wrench icon.
-  SkBitmap GenerateWrenchIcon(int base_id) const;
+  // Renders a GTK button border the size of the image |sizing_idr| in
+  // |gtk_state|.
+  SkBitmap GenerateToolbarBezel(int gtk_state, int sizing_idr) const;
 
   // Returns the tint for buttons that contrasts with the normal window
   // background color.
diff --git a/chrome/browser/ui/libgtk2ui/select_file_dialog_impl.cc b/chrome/browser/ui/libgtk2ui/select_file_dialog_impl.cc
index c3e5e9b..450f2b4 100644
--- a/chrome/browser/ui/libgtk2ui/select_file_dialog_impl.cc
+++ b/chrome/browser/ui/libgtk2ui/select_file_dialog_impl.cc
@@ -90,7 +90,7 @@
 bool SelectFileDialogImpl::CallDirectoryExistsOnUIThread(
     const base::FilePath& path) {
   base::ThreadRestrictions::ScopedAllowIO allow_io;
-  return file_util::DirectoryExists(path);
+  return base::DirectoryExists(path);
 }
 
 }  // namespace libgtk2ui
diff --git a/chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h b/chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h
index 55f1c30..89db17c 100644
--- a/chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h
+++ b/chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h
@@ -59,7 +59,7 @@
       gfx::NativeWindow owning_window,
       void* params) = 0;
 
-  // Wrapper for file_util::DirectoryExists() that allow access on the UI
+  // Wrapper for base::DirectoryExists() that allow access on the UI
   // thread. Use this only in the file dialog functions, where it's ok
   // because the file dialog has to do many stats anyway. One more won't
   // hurt too badly and it's likely already cached.
diff --git a/chrome/browser/ui/login/login_prompt.cc b/chrome/browser/ui/login/login_prompt.cc
index b2dda10..f588871 100644
--- a/chrome/browser/ui/login/login_prompt.cc
+++ b/chrome/browser/ui/login/login_prompt.cc
@@ -10,9 +10,9 @@
 #include "base/command_line.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/lock.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/password_manager/password_manager.h"
 #include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/login/login_prompt_browsertest.cc b/chrome/browser/ui/login/login_prompt_browsertest.cc
index 5220c8b..362ffde 100644
--- a/chrome/browser/ui/login/login_prompt_browsertest.cc
+++ b/chrome/browser/ui/login/login_prompt_browsertest.cc
@@ -7,12 +7,12 @@
 #include <map>
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prerender/prerender_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/login/login_prompt.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/ui/login/login_prompt_unittest.cc b/chrome/browser/ui/login/login_prompt_unittest.cc
index 109cbca..b2bb2c4 100644
--- a/chrome/browser/ui/login/login_prompt_unittest.cc
+++ b/chrome/browser/ui/login/login_prompt_unittest.cc
@@ -3,9 +3,9 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/ui/login/login_prompt.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/auth.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 TEST(LoginPromptTest, GetSignonRealm) {
   scoped_refptr<net::AuthChallengeInfo> auth_info = new net::AuthChallengeInfo;
diff --git a/chrome/browser/ui/metro_pin_tab_helper_win.cc b/chrome/browser/ui/metro_pin_tab_helper_win.cc
index a11664e..aa0f1d8 100644
--- a/chrome/browser/ui/metro_pin_tab_helper_win.cc
+++ b/chrome/browser/ui/metro_pin_tab_helper_win.cc
@@ -57,7 +57,7 @@
     return base::FilePath();
 
   tile_images_dir = tile_images_dir.Append(L"TileImages");
-  if (!file_util::DirectoryExists(tile_images_dir) &&
+  if (!base::DirectoryExists(tile_images_dir) &&
       !file_util::CreateDirectory(tile_images_dir))
     return base::FilePath();
 
@@ -124,7 +124,7 @@
                          base::FilePath* logo_path) {
   const wchar_t kDefaultLogoFileName[] = L"SecondaryTile.png";
   *logo_path = logo_dir.Append(kDefaultLogoFileName);
-  if (file_util::PathExists(*logo_path))
+  if (base::PathExists(*logo_path))
     return true;
 
   base::FilePath default_logo_path;
@@ -132,7 +132,7 @@
     return false;
 
   default_logo_path = default_logo_path.Append(kDefaultLogoFileName);
-  return file_util::CopyFile(default_logo_path, *logo_path);
+  return base::CopyFile(default_logo_path, *logo_path);
 }
 
 // UMA reporting callback for site-specific secondary tile creation.
diff --git a/chrome/browser/ui/network_profile_bubble.cc b/chrome/browser/ui/network_profile_bubble.cc
index 9152e84..c2169b1 100644
--- a/chrome/browser/ui/network_profile_bubble.cc
+++ b/chrome/browser/ui/network_profile_bubble.cc
@@ -135,7 +135,7 @@
       } else {
         RecordUmaEvent(METRIC_CHECK_IO_FAILED);
       }
-      base::Delete(temp_file, false);
+      base::DeleteFile(temp_file, false);
     }
     if (profile_on_network) {
       RecordUmaEvent(METRIC_PROFILE_ON_NETWORK);
@@ -157,7 +157,7 @@
 }
 
 // static
-void NetworkProfileBubble::RegisterUserPrefs(
+void NetworkProfileBubble::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       prefs::kNetworkProfileWarningsLeft,
diff --git a/chrome/browser/ui/network_profile_bubble.h b/chrome/browser/ui/network_profile_bubble.h
index a49895c..fb43906 100644
--- a/chrome/browser/ui/network_profile_bubble.h
+++ b/chrome/browser/ui/network_profile_bubble.h
@@ -61,7 +61,7 @@
   static void SetNotificationShown(bool shown);
 
   // Register the pref that controls whether the bubble should be shown anymore.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Helper function wrapping the UMA_HISTOGRAM_ENUMERATION macro.
   static void RecordUmaEvent(MetricNetworkedProfileCheck event);
diff --git a/chrome/browser/ui/omnibox/action_box_browsertest.cc b/chrome/browser/ui/omnibox/action_box_browsertest.cc
index 64aae20..325594f 100644
--- a/chrome/browser/ui/omnibox/action_box_browsertest.cc
+++ b/chrome/browser/ui/omnibox/action_box_browsertest.cc
@@ -10,13 +10,13 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/omnibox/location_bar.h"
 #include "chrome/browser/ui/toolbar/action_box_menu_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.cc b/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.cc
index fe7e38a..0002aec 100644
--- a/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.cc
+++ b/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.cc
@@ -41,14 +41,11 @@
 
 bool AlternateNavInfoBarDelegate::LinkClicked(
     WindowOpenDisposition disposition) {
-  content::OpenURLParams params(
+  // Pretend the user typed this URL, so that navigating to it will be the
+  // default action when it's typed again in the future.
+  web_contents()->OpenURL(content::OpenURLParams(
       alternate_nav_url_, content::Referrer(), disposition,
-      // Pretend the user typed this URL, so that navigating to
-      // it will be the default action when it's typed again in
-      // the future.
-      content::PAGE_TRANSITION_TYPED,
-      false);
-  web_contents()->OpenURL(params);
+      content::PAGE_TRANSITION_TYPED, false));
 
   // We should always close, even if the navigation did not occur within this
   // WebContents.
diff --git a/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h b/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h
index 3c3c5d2..5b5f594 100644
--- a/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h
+++ b/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h
@@ -8,7 +8,7 @@
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "chrome/browser/infobars/infobar_delegate.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class AlternateNavInfoBarDelegate : public InfoBarDelegate {
  public:
diff --git a/chrome/browser/ui/omnibox/alternate_nav_url_fetcher.cc b/chrome/browser/ui/omnibox/alternate_nav_url_fetcher.cc
index 2b302c0..1d97190 100644
--- a/chrome/browser/ui/omnibox/alternate_nav_url_fetcher.cc
+++ b/chrome/browser/ui/omnibox/alternate_nav_url_fetcher.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/ui/omnibox/alternate_nav_url_fetcher.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/intranet_redirect_detector.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
diff --git a/chrome/browser/ui/omnibox/alternate_nav_url_fetcher.h b/chrome/browser/ui/omnibox/alternate_nav_url_fetcher.h
index 8460fef..933a6b1 100644
--- a/chrome/browser/ui/omnibox/alternate_nav_url_fetcher.h
+++ b/chrome/browser/ui/omnibox/alternate_nav_url_fetcher.h
@@ -10,8 +10,8 @@
 #include "base/memory/scoped_ptr.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_fetcher_delegate.h"
+#include "url/gurl.h"
 
 namespace content {
 class NavigationController;
diff --git a/chrome/browser/ui/omnibox/location_bar.h b/chrome/browser/ui/omnibox/location_bar.h
index 119e29e..eeeb843 100644
--- a/chrome/browser/ui/omnibox/location_bar.h
+++ b/chrome/browser/ui/omnibox/location_bar.h
@@ -14,7 +14,6 @@
 #include <string>
 
 #include "base/strings/string16.h"
-#include "chrome/common/instant_types.h"
 #include "content/public/common/page_transition_types.h"
 #include "ui/base/window_open_disposition.h"
 
@@ -31,10 +30,6 @@
   // Shows the first run bubble anchored to the location bar.
   virtual void ShowFirstRunBubble() = 0;
 
-  // Sets the suggested text to show in the omnibox. This is shown in addition
-  // to the current text of the omnibox.
-  virtual void SetInstantSuggestion(const InstantSuggestion& suggestion) = 0;
-
   // Returns the string of text entered in the location bar.
   virtual string16 GetInputString() const = 0;
 
@@ -69,6 +64,11 @@
   // Updates the state of the button to open a PDF in Adobe Reader.
   virtual void UpdateOpenPDFInReaderPrompt() = 0;
 
+  // Updates the Autofill credit card view. This views serves as an anchor for
+  // the Autofill credit card bubble, which might show on successful run of the
+  // Autofill dialog.
+  virtual void UpdateAutofillCreditCardView() = 0;
+
   // Saves the state of the location bar to the specified WebContents, so that
   // it can be restored later. (Done when switching tabs).
   virtual void SaveStateToContents(content::WebContents* contents) = 0;
diff --git a/chrome/browser/ui/omnibox/omnibox_controller.cc b/chrome/browser/ui/omnibox/omnibox_controller.cc
index cd75dda..196fef7 100644
--- a/chrome/browser/ui/omnibox/omnibox_controller.cc
+++ b/chrome/browser/ui/omnibox/omnibox_controller.cc
@@ -15,13 +15,10 @@
 #include "chrome/browser/prerender/prerender_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/search.h"
-#include "chrome/browser/search_engines/template_url_service.h"
-#include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/ui/omnibox/omnibox_edit_controller.h"
 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
 #include "chrome/browser/ui/omnibox/omnibox_popup_view.h"
-#include "chrome/browser/ui/search/instant_controller.h"
 #include "extensions/common/constants.h"
 #include "ui/gfx/rect.h"
 
@@ -64,8 +61,6 @@
 }
 
 void OmniboxController::OnResultChanged(bool default_match_changed) {
-  // TODO(beaudoin): There should be no need to access the popup when using
-  // instant extended, remove this reference.
   const bool was_open = popup_->IsOpen();
   if (default_match_changed) {
     // The default match has changed, we need to let the OmniboxEditModel know
@@ -109,11 +104,6 @@
   }
 }
 
-void OmniboxController::SetInstantSuggestion(
-    const InstantSuggestion& suggestion) {
-  // TODO(jered): Delete this.
-}
-
 void OmniboxController::InvalidateCurrentMatch() {
   current_match_ = AutocompleteMatch();
 }
@@ -139,46 +129,3 @@
     // the OS DNS cache could suffer eviction problems for minimal gain.
   }
 }
-
-bool OmniboxController::UseVerbatimInstant(bool just_deleted_text) const {
-#if defined(OS_MACOSX)
-  // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView,
-  // so that we can display Instant suggest along with composition text.
-  const AutocompleteInput& input = autocomplete_controller_->input();
-  if (input.prevent_inline_autocomplete())
-    return true;
-#endif
-
-  // The value of input.prevent_inline_autocomplete() is determined by the
-  // following conditions:
-  // 1. If the caret is at the end of the text.
-  // 2. If it's in IME composition mode.
-  // We send the caret position to Instant (so it can determine #1 itself), and
-  // we use a separated widget for displaying the Instant suggest (so it doesn't
-  // interfere with #2). So, we don't need to care about the value of
-  // input.prevent_inline_autocomplete() here.
-  return just_deleted_text || popup_->selected_line() != 0;
-}
-
-InstantController* OmniboxController::GetInstantController() const {
-  return omnibox_edit_model_->GetInstantController();
-}
-
-void OmniboxController::CreateAndSetInstantMatch(
-    string16 query_string,
-    string16 input_text,
-    AutocompleteMatchType::Type match_type) {
-  TemplateURLService* template_url_service =
-      TemplateURLServiceFactory::GetForProfile(profile_);
-  if (!template_url_service)
-    return;
-
-  TemplateURL* template_url =
-      template_url_service->GetDefaultSearchProvider();
-  if (!template_url)
-    return;
-
-  current_match_ = SearchProvider::CreateSearchSuggestion(
-      NULL, 0, match_type, template_url, query_string, input_text,
-      AutocompleteInput(), false, 0, -1, true);
-}
diff --git a/chrome/browser/ui/omnibox/omnibox_controller.h b/chrome/browser/ui/omnibox/omnibox_controller.h
index 2259ae7..690acab 100644
--- a/chrome/browser/ui/omnibox/omnibox_controller.h
+++ b/chrome/browser/ui/omnibox/omnibox_controller.h
@@ -17,7 +17,6 @@
 class AutocompleteResult;
 class GURL;
 class InstantController;
-struct InstantSuggestion;
 class OmniboxEditModel;
 class OmniboxPopupModel;
 class Profile;
@@ -35,7 +34,6 @@
 //     As the refactor progresses, keep the class comment up-to-date to
 //     precisely explain what this class is doing.
 class OmniboxController : public AutocompleteControllerDelegate {
-
  public:
   OmniboxController(OmniboxEditModel* omnibox_edit_model,
                     Profile* profile);
@@ -57,9 +55,6 @@
     return autocomplete_controller_.get();
   }
 
-  // Sets the suggestion text.
-  void SetInstantSuggestion(const InstantSuggestion& suggestion);
-
   // Set |current_match_| to an invalid value, indicating that we do not yet
   // have a valid match for the current text in the omnibox.
   void InvalidateCurrentMatch();
@@ -85,22 +80,6 @@
   void DoPreconnect(const AutocompleteMatch& match);
 
  private:
-
-  // Returns true if a verbatim query should be used for Instant. A verbatim
-  // query is forced in certain situations, such as pressing delete at the end
-  // of the edit.
-  bool UseVerbatimInstant(bool just_deleted_text) const;
-
-  // Access the instant controller from the OmniboxEditModel. We need to do this
-  // because the only valid pointer to InstantController is kept in Browser,
-  // which OmniboxEditModel has some ways of reaching.
-  InstantController* GetInstantController() const;
-
-  // Creates an AutocompleteMatch for an instant result and sets it into
-  // |current_match_|.
-  void CreateAndSetInstantMatch(string16 query_string,
-                                string16 input_text,
-                                AutocompleteMatchType::Type match_type);
   // Weak, it owns us.
   // TODO(beaudoin): Consider defining a delegate to ease unit testing.
   OmniboxEditModel* omnibox_edit_model_;
@@ -109,8 +88,6 @@
 
   OmniboxPopupModel* popup_;
 
-  InstantController* instant_controller_;
-
   scoped_ptr<AutocompleteController> autocomplete_controller_;
 
   // TODO(beaudoin): This AutocompleteMatch is used to let the OmniboxEditModel
diff --git a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
index 4ef46f3..0af1195 100644
--- a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
+++ b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
@@ -16,8 +16,8 @@
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_view.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/window_open_disposition.h"
+#include "url/gurl.h"
 
 OmniboxCurrentPageDelegateImpl::OmniboxCurrentPageDelegateImpl(
     OmniboxEditController* controller,
diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.cc b/chrome/browser/ui/omnibox/omnibox_edit_model.cc
index 405e407..6ba8740 100644
--- a/chrome/browser/ui/omnibox/omnibox_edit_model.cc
+++ b/chrome/browser/ui/omnibox/omnibox_edit_model.cc
@@ -23,6 +23,7 @@
 #include "chrome/browser/autocomplete/keyword_provider.h"
 #include "chrome/browser/autocomplete/search_provider.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/extensions/api/omnibox/omnibox_api.h"
 #include "chrome/browser/google/google_url_tracker.h"
@@ -49,7 +50,6 @@
 #include "chrome/browser/ui/omnibox/omnibox_view.h"
 #include "chrome/browser/ui/search/instant_controller.h"
 #include "chrome/browser/ui/search/search_tab_helper.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -59,8 +59,8 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/user_metrics.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/url_util.h"
 #include "ui/gfx/image/image.h"
+#include "url/url_util.h"
 
 using content::UserMetricsAction;
 using predictors::AutocompleteActionPredictor;
@@ -93,6 +93,45 @@
 // in the EnteredKeywordModeMethod enum which is defined in the .h file.
 const char kEnteredKeywordModeHistogram[] = "Omnibox.EnteredKeywordMode";
 
+// Histogram name which counts the number of milliseconds a user takes
+// between focusing and editing the omnibox.
+const char kFocusToEditTimeHistogram[] = "Omnibox.FocusToEditTime";
+
+void RecordPercentageMatchHistogram(const string16& old_text,
+                                    const string16& new_text,
+                                    bool search_term_replacement_active,
+                                    content::PageTransition transition) {
+  size_t avg_length = (old_text.length() + new_text.length()) / 2;
+
+  int percent = 0;
+  if (!old_text.empty() && !new_text.empty()) {
+    size_t shorter_length = std::min(old_text.length(), new_text.length());
+    string16::const_iterator end(old_text.begin() + shorter_length);
+    string16::const_iterator mismatch(
+        std::mismatch(old_text.begin(), end, new_text.begin()).first);
+    size_t matching_characters = mismatch - old_text.begin();
+    percent = static_cast<float>(matching_characters) / avg_length * 100;
+  }
+
+  if (search_term_replacement_active) {
+    if (transition == content::PAGE_TRANSITION_TYPED) {
+      UMA_HISTOGRAM_PERCENTAGE(
+          "InstantExtended.PercentageMatchQuerytoURL", percent);
+    } else {
+      UMA_HISTOGRAM_PERCENTAGE(
+          "InstantExtended.PercentageMatchQuerytoQuery", percent);
+    }
+  } else {
+    if (transition == content::PAGE_TRANSITION_TYPED) {
+      UMA_HISTOGRAM_PERCENTAGE(
+          "InstantExtended.PercentageMatchURLtoURL", percent);
+    } else {
+      UMA_HISTOGRAM_PERCENTAGE(
+          "InstantExtended.PercentageMatchURLtoQuery", percent);
+    }
+  }
+}
+
 }  // namespace
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -100,13 +139,13 @@
 
 OmniboxEditModel::State::State(bool user_input_in_progress,
                                const string16& user_text,
-                               const string16& instant_suggestion,
+                               const string16& gray_text,
                                const string16& keyword,
                                bool is_keyword_hint,
                                OmniboxFocusState focus_state)
     : user_input_in_progress(user_input_in_progress),
       user_text(user_text),
-      instant_suggestion(instant_suggestion),
+      gray_text(gray_text),
       keyword(keyword),
       is_keyword_hint(is_keyword_hint),
       focus_state(focus_state) {
@@ -160,7 +199,7 @@
 
   return State(user_input_in_progress_,
                user_text_,
-               view_->GetInstantSuggestion(),
+               view_->GetGrayTextAutocompletion(),
                keyword_,
                is_keyword_hint_,
                focus_state_);
@@ -176,7 +215,7 @@
     is_keyword_hint_ = state.is_keyword_hint;
     view_->SetUserText(state.user_text,
         DisplayTextFromUserText(state.user_text), false);
-    view_->SetInstantSuggestion(state.instant_suggestion);
+    view_->SetGrayTextAutocompletion(state.gray_text);
   }
 }
 
@@ -200,19 +239,19 @@
   // common case where the edit doesn't have focus is when the user has started
   // an edit and then abandoned it and clicked a link on the page.)
   //
-  // If the page is auto-committing an instant suggestion, however, we generally
-  // don't want to make any change to the edit.  While auto-commits modify the
-  // underlying permanent URL, they're intended to have no effect on the user's
-  // editing process -- before and after the auto-commit, the omnibox should
-  // show the same user text and the same instant suggestion, even if the
-  // auto-commit happens while the edit doesn't have focus.
-  string16 instant_suggestion = view_->GetInstantSuggestion();
+  // If the page is auto-committing gray text, however, we generally don't want
+  // to make any change to the edit.  While auto-commits modify the underlying
+  // permanent URL, they're intended to have no effect on the user's editing
+  // process -- before and after the auto-commit, the omnibox should show the
+  // same user text and the same instant suggestion, even if the auto-commit
+  // happens while the edit doesn't have focus.
+  string16 gray_text = view_->GetGrayTextAutocompletion();
   const bool visibly_changed_permanent_text =
       (permanent_text_ != new_permanent_text) &&
       (!has_focus() ||
        (!user_input_in_progress_ && !popup_model()->IsOpen())) &&
-      (instant_suggestion.empty() ||
-       new_permanent_text != user_text_ + instant_suggestion);
+      (gray_text.empty() ||
+       new_permanent_text != user_text_ + gray_text);
 
   permanent_text_ = new_permanent_text;
   return visibly_changed_permanent_text;
@@ -230,16 +269,11 @@
   has_temporary_text_ = false;
 }
 
-void OmniboxEditModel::SetInstantSuggestion(
-    const InstantSuggestion& suggestion) {
-}
-
 bool OmniboxEditModel::CommitSuggestedText() {
-  const string16 suggestion = view_->GetInstantSuggestion();
+  const string16 suggestion = view_->GetGrayTextAutocompletion();
   if (suggestion.empty())
     return false;
 
-  // Assume that the gray text we are committing is a search suggestion.
   const string16 final_text = view_->GetText() + suggestion;
   view_->OnBeforePossibleChange();
   view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false,
@@ -277,7 +311,7 @@
                             AutocompleteActionPredictor::LAST_PREDICT_ACTION);
 
   // Hide any suggestions we might be showing.
-  view_->SetInstantSuggestion(string16());
+  view_->SetGrayTextAutocompletion(string16());
 
   switch (recommended_action) {
     case AutocompleteActionPredictor::ACTION_PRERENDER:
@@ -380,6 +414,16 @@
 }
 
 void OmniboxEditModel::SetInputInProgress(bool in_progress) {
+  if (in_progress && !last_omnibox_focus_without_user_input_.is_null()) {
+    base::TimeTicks now = base::TimeTicks::Now();
+    DCHECK(last_omnibox_focus_without_user_input_ <= now);
+    UMA_HISTOGRAM_TIMES(kFocusToEditTimeHistogram,
+                        now - last_omnibox_focus_without_user_input_);
+    // We only want to count the time from focus to the first user input, so
+    // reset |last_omnibox_focus_without_user_input_| to null.
+    last_omnibox_focus_without_user_input_ = base::TimeTicks();
+  }
+
   if (user_input_in_progress_ == in_progress)
     return;
 
@@ -671,6 +715,11 @@
     const GURL destination_url = autocomplete_controller()->
         GetDestinationURL(match, query_formulation_time);
 
+    RecordPercentageMatchHistogram(
+        permanent_text_, match.contents,
+        view_->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(),
+        match.transition);
+
     // Track whether the destination URL sends us to a search results page
     // using the default search provider.
     TemplateURL* default_provider =
@@ -750,6 +799,8 @@
 }
 
 void OmniboxEditModel::OnSetFocus(bool control_down) {
+  last_omnibox_focus_without_user_input_ = base::TimeTicks::Now();
+
   // If the omnibox lost focus while the caret was hidden and then regained
   // focus, OnSetFocus() is called and should restore visibility. Note that
   // focus can be regained without an accompanying call to
@@ -1199,11 +1250,8 @@
   // Then check if the text before the inserted space matches a keyword.
   string16 keyword;
   TrimWhitespace(new_text.substr(0, space_position), TRIM_LEADING, &keyword);
-  // TODO(sreeram): Once the Instant extended API supports keywords properly,
-  // keyword_provider() should never be NULL. Remove that clause.
-  return !keyword.empty() && autocomplete_controller()->keyword_provider() &&
-      !autocomplete_controller()->keyword_provider()->
-          GetKeywordForText(keyword).empty();
+  return !keyword.empty() && !autocomplete_controller()->keyword_provider()->
+      GetKeywordForText(keyword).empty();
 }
 
 //  static
diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.h b/chrome/browser/ui/omnibox/omnibox_edit_model.h
index d9f40c8..4dff4ef 100644
--- a/chrome/browser/ui/omnibox/omnibox_edit_model.h
+++ b/chrome/browser/ui/omnibox/omnibox_edit_model.h
@@ -16,13 +16,12 @@
 #include "chrome/common/metrics/proto/omnibox_event.pb.h"
 #include "chrome/common/omnibox_focus_state.h"
 #include "content/public/common/page_transition_types.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/window_open_disposition.h"
 #include "ui/gfx/native_widget_types.h"
+#include "url/gurl.h"
 
 class AutocompleteController;
 class AutocompleteResult;
-struct InstantSuggestion;
 class OmniboxCurrentPageDelegate;
 class OmniboxEditController;
 class OmniboxPopupModel;
@@ -48,7 +47,7 @@
   struct State {
     State(bool user_input_in_progress,
           const string16& user_text,
-          const string16& instant_suggestion,
+          const string16& gray_text,
           const string16& keyword,
           bool is_keyword_hint,
           OmniboxFocusState focus_state);
@@ -56,7 +55,7 @@
 
     bool user_input_in_progress;
     const string16 user_text;
-    const string16 instant_suggestion;
+    const string16 gray_text;
     const string16 keyword;
     const bool is_keyword_hint;
     OmniboxFocusState focus_state;
@@ -140,16 +139,13 @@
   // Sets the user_text_ to |text|.  Only the View should call this.
   void SetUserText(const string16& text);
 
-  // Sets the suggestion text.
-  void SetInstantSuggestion(const InstantSuggestion& suggestion);
-
   // Commits the gray suggested text as if it's been input by the user.
   // Returns true if the text was committed.
   // TODO: can the return type be void?
   bool CommitSuggestedText();
 
-  // Invoked any time the text may have changed in the edit. Updates Instant and
-  // notifies the controller.
+  // Invoked any time the text may have changed in the edit. Notifies the
+  // controller.
   void OnChanged();
 
   // Reverts the edit model back to its unedited state (permanent text showing,
@@ -312,7 +308,6 @@
   InstantController* GetInstantController() const;
 
  private:
-  friend class InstantTestBase;
   friend class OmniboxControllerTest;
 
   enum PasteState {
@@ -433,6 +428,10 @@
   // autocomplete text that has not yet been accepted.
   string16 user_text_;
 
+  // We keep track of when the user last focused on the omnibox, but reset it
+  // to null when user input occurs.
+  base::TimeTicks last_omnibox_focus_without_user_input_;
+
   // We keep track of when the user began modifying the omnibox text.
   // This should be valid whenever user_input_in_progress_ is true.
   base::TimeTicks time_user_first_modified_omnibox_;
@@ -504,21 +503,8 @@
 
   Profile* profile_;
 
-  // This is needed as prior to accepting the current text the model is
-  // reverted, which triggers resetting Instant. We don't want to update Instant
-  // in this case, so we use the flag to determine if this is happening.
-  //
-  // For example: The permanent text is "foo". The user has typed "bar" and
-  // Instant is showing a search results preview for "bar". The user hits Enter.
-  // in_revert_ is used to tell Instant, "The omnibox text is about to change to
-  // 'foo', thus TextChanged() will be called, leading to DoInstant(), but
-  // please don't change what you are showing. I'll commit the real match
-  // ("bar") immediately after the revert."
-  //
-  // Without in_revert_, Instant would erroneously change its search results to
-  // "foo". Because of the way the code is structured (specifically, DoInstant()
-  // is NOT called for "bar" again), this leaves Instant showing results for
-  // "foo", which is wrong.
+  // This is needed to properly update the SearchModel state when the user
+  // presses escape.
   bool in_revert_;
 
   // Indicates if the upcoming autocomplete search is allowed to be treated as
diff --git a/chrome/browser/ui/omnibox/omnibox_edit_unittest.cc b/chrome/browser/ui/omnibox/omnibox_edit_unittest.cc
index cd1e0d7..7fd366a 100644
--- a/chrome/browser/ui/omnibox/omnibox_edit_unittest.cc
+++ b/chrome/browser/ui/omnibox/omnibox_edit_unittest.cc
@@ -63,8 +63,10 @@
   virtual gfx::NativeView GetRelativeWindowForPopup() const OVERRIDE {
     return NULL;
   }
-  virtual void SetInstantSuggestion(const string16& input) OVERRIDE {}
-  virtual string16 GetInstantSuggestion() const OVERRIDE { return string16(); }
+  virtual void SetGrayTextAutocompletion(const string16& input) OVERRIDE {}
+  virtual string16 GetGrayTextAutocompletion() const OVERRIDE {
+    return string16();
+  }
   virtual int TextWidth() const OVERRIDE { return 0; }
   virtual bool IsImeComposing() const OVERRIDE { return false; }
 
diff --git a/chrome/browser/ui/omnibox/omnibox_popup_model.cc b/chrome/browser/ui/omnibox/omnibox_popup_model.cc
index 930a0a6..30d1825 100644
--- a/chrome/browser/ui/omnibox/omnibox_popup_model.cc
+++ b/chrome/browser/ui/omnibox/omnibox_popup_model.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
+#include "chrome/browser/ui/omnibox/omnibox_popup_model_observer.h"
 #include "chrome/browser/ui/omnibox/omnibox_popup_view.h"
 #include "third_party/icu/public/common/unicode/ubidi.h"
 #include "ui/gfx/image/image.h"
@@ -218,5 +219,19 @@
   if ((hovered_line_ != kNoMatch) && (result.size() <= hovered_line_))
     SetHoveredLine(kNoMatch);
 
+  bool popup_was_open = view_->IsOpen();
   view_->UpdatePopupAppearance();
+  // If popup has just been shown or hidden, notify observers.
+  if (view_->IsOpen() != popup_was_open) {
+    FOR_EACH_OBSERVER(OmniboxPopupModelObserver, observers_,
+                      OnOmniboxPopupShownOrHidden());
+  }
+}
+
+void OmniboxPopupModel::AddObserver(OmniboxPopupModelObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void OmniboxPopupModel::RemoveObserver(OmniboxPopupModelObserver* observer) {
+  observers_.RemoveObserver(observer);
 }
diff --git a/chrome/browser/ui/omnibox/omnibox_popup_model.h b/chrome/browser/ui/omnibox/omnibox_popup_model.h
index 85934b4..02de7ad 100644
--- a/chrome/browser/ui/omnibox/omnibox_popup_model.h
+++ b/chrome/browser/ui/omnibox/omnibox_popup_model.h
@@ -6,10 +6,12 @@
 #define CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_MODEL_H_
 
 #include "base/basictypes.h"
+#include "base/observer_list.h"
 #include "chrome/browser/autocomplete/autocomplete_controller.h"
 #include "chrome/browser/autocomplete/autocomplete_result.h"
 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
 
+class OmniboxPopupModelObserver;
 class OmniboxPopupView;
 
 namespace gfx {
@@ -96,6 +98,10 @@
   // changes.
   void OnResultChanged();
 
+  // Add and remove observers.
+  void AddObserver(OmniboxPopupModelObserver* observer);
+  void RemoveObserver(OmniboxPopupModelObserver* observer);
+
   // The token value for selected_line_, hover_line_ and functions dealing with
   // a "line number" that indicates "no line".
   static const size_t kNoMatch;
@@ -121,6 +127,9 @@
   // The match the user has manually chosen, if any.
   AutocompleteResult::Selection manually_selected_match_;
 
+  // Observers.
+  ObserverList<OmniboxPopupModelObserver> observers_;
+
   DISALLOW_COPY_AND_ASSIGN(OmniboxPopupModel);
 };
 
diff --git a/chrome/browser/ui/omnibox/omnibox_popup_model_observer.h b/chrome/browser/ui/omnibox/omnibox_popup_model_observer.h
new file mode 100644
index 0000000..f162125
--- /dev/null
+++ b/chrome/browser/ui/omnibox/omnibox_popup_model_observer.h
@@ -0,0 +1,16 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_MODEL_OBSERVER_H_
+#define CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_MODEL_OBSERVER_H_
+
+// Allows observers to react and update accordingly when state of
+// |OmniboxPopupModel| changes, e.g. when the omnibox popup is shown or hidden.
+class OmniboxPopupModelObserver {
+ public:
+  // Informs observers that omnibox popup has been shown or hidden.
+  virtual void OnOmniboxPopupShownOrHidden() = 0;
+};
+
+#endif  // CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_MODEL_OBSERVER_H_
diff --git a/chrome/browser/ui/omnibox/omnibox_view.h b/chrome/browser/ui/omnibox/omnibox_view.h
index 972cac8..9fb5b94 100644
--- a/chrome/browser/ui/omnibox/omnibox_view.h
+++ b/chrome/browser/ui/omnibox/omnibox_view.h
@@ -196,11 +196,11 @@
   // the top-most window is the relative window.
   virtual gfx::NativeView GetRelativeWindowForPopup() const = 0;
 
-  // Shows the instant suggestion text.
-  virtual void SetInstantSuggestion(const string16& input) = 0;
+  // Shows |input| as gray suggested text after what the user has typed.
+  virtual void SetGrayTextAutocompletion(const string16& input) = 0;
 
-  // Returns the current instant suggestion text.
-  virtual string16 GetInstantSuggestion() const = 0;
+  // Returns the current gray suggested text.
+  virtual string16 GetGrayTextAutocompletion() const = 0;
 
   // Returns the width in pixels needed to display the current text. The
   // returned value includes margins.
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
index 0cda639..42639d1 100644
--- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
+++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
@@ -29,7 +30,6 @@
 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
 #include "chrome/browser/ui/omnibox/omnibox_view.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/ui/panels/base_panel_browser_test.cc b/chrome/browser/ui/panels/base_panel_browser_test.cc
index 8277ce2..25dc290 100644
--- a/chrome/browser/ui/panels/base_panel_browser_test.cc
+++ b/chrome/browser/ui/panels/base_panel_browser_test.cc
@@ -10,6 +10,7 @@
 #include "base/message_loop.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
@@ -22,7 +23,6 @@
 #include "chrome/browser/ui/panels/stacked_panel_collection.h"
 #include "chrome/browser/ui/panels/test_panel_active_state_observer.h"
 #include "chrome/browser/ui/panels/test_panel_mouse_watcher.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
@@ -38,6 +38,10 @@
 #include "ui/base/x/x11_util.h"
 #endif
 
+#if defined(OS_LINUX) && !defined(USE_AURA)
+#include "ui/base/x/active_window_watcher_x.h"
+#endif
+
 #if defined(OS_MACOSX)
 #include "base/mac/scoped_nsautorelease_pool.h"
 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
@@ -283,6 +287,14 @@
     Panel* panel, ActiveState expected_state) {
   DCHECK(expected_state == SHOW_AS_ACTIVE ||
          expected_state == SHOW_AS_INACTIVE);
+
+#if defined(OS_MACOSX)
+  scoped_ptr<NativePanelTesting> panel_testing(
+      CreateNativePanelTesting(panel));
+  ASSERT_TRUE(panel_testing->EnsureApplicationRunOnForeground()) <<
+      "Failed to bring application to foreground. Bail out.";
+#endif
+
   PanelActiveStateObserver signal(panel, expected_state == SHOW_AS_ACTIVE);
   signal.Wait();
 }
@@ -460,6 +472,19 @@
   return panel;
 }
 
+Panel* BasePanelBrowserTest::CreateInactiveDockedPanel(
+    const std::string& name, const gfx::Rect& bounds) {
+  // Create an active panel first, instead of inactive panel. This is because
+  // certain window managers on Linux, like icewm, will always activate the
+  // new window.
+  Panel* panel = CreateDockedPanel(name, bounds);
+
+  DeactivatePanel(panel);
+  WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);
+
+  return panel;
+}
+
 Panel* BasePanelBrowserTest::CreateInactiveDetachedPanel(
     const std::string& name, const gfx::Rect& bounds) {
   // Create an active panel first, instead of inactive panel. This is because
@@ -473,6 +498,23 @@
   return panel;
 }
 
+void BasePanelBrowserTest::ActivatePanel(Panel* panel) {
+  // For certain window managers on Linux, the window activation/deactivation
+  // signals might not be sent. To work around this, we explicitly deactivate
+  // all other panels first.
+#if defined(OS_LINUX)
+  std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
+  for (std::vector<Panel*>::const_iterator iter = panels.begin();
+       iter != panels.end(); ++iter) {
+    Panel* current_panel = *iter;
+    if (panel != current_panel)
+      current_panel->Deactivate();
+  }
+#endif
+
+  panel->Activate();
+}
+
 void BasePanelBrowserTest::DeactivatePanel(Panel* panel) {
 #if defined(OS_LINUX)
   // For certain window managers on Linux, like icewm, panel activation and
@@ -563,3 +605,11 @@
   std::string panel_name("Panel");
   return panel_name + base::IntToString(index);
 }
+
+bool BasePanelBrowserTest::WmSupportWindowActivation() {
+#if defined(OS_LINUX) && !defined(USE_AURA)
+  return ui::ActiveWindowWatcherX::WMSupportsActivation();
+#else
+  return true;
+#endif
+}
diff --git a/chrome/browser/ui/panels/base_panel_browser_test.h b/chrome/browser/ui/panels/base_panel_browser_test.h
index c5e21b2..cb225c9 100644
--- a/chrome/browser/ui/panels/base_panel_browser_test.h
+++ b/chrome/browser/ui/panels/base_panel_browser_test.h
@@ -87,9 +87,12 @@
                             StackedPanelCollection* stack);
 
   Panel* CreateInactivePanel(const std::string& name);
+  Panel* CreateInactiveDockedPanel(const std::string& name,
+                                   const gfx::Rect& bounds);
   Panel* CreateInactiveDetachedPanel(const std::string& name,
                                      const gfx::Rect& bounds);
 
+  void ActivatePanel(Panel* panel);
   void DeactivatePanel(Panel* panel);
 
   static NativePanelTesting* CreateNativePanelTesting(Panel* panel);
@@ -109,6 +112,10 @@
   void CloseWindowAndWait(Panel* panel);
   static std::string MakePanelName(int index);
 
+  // Checks if the WM supports activation. This may not be true sometimes on
+  // buildbots for example when the wm has crashed.
+  static bool WmSupportWindowActivation();
+
   MockDisplaySettingsProvider* mock_display_settings_provider() const {
     return mock_display_settings_provider_;
   }
diff --git a/chrome/browser/ui/panels/docked_panel_browsertest.cc b/chrome/browser/ui/panels/docked_panel_browsertest.cc
index 6d8bba5..05df79d 100644
--- a/chrome/browser/ui/panels/docked_panel_browsertest.cc
+++ b/chrome/browser/ui/panels/docked_panel_browsertest.cc
@@ -3,12 +3,12 @@
 // found in the LICENSE file.
 
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/panels/base_panel_browser_test.h"
 #include "chrome/browser/ui/panels/docked_panel_collection.h"
 #include "chrome/browser/ui/panels/panel.h"
 #include "chrome/browser/ui/panels/panel_manager.h"
 #include "chrome/browser/ui/panels/test_panel_collection_squeeze_observer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/test/test_utils.h"
 
@@ -37,9 +37,9 @@
   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
 
   // Create some docked panels.
-  Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 100));
-  Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 200, 100));
-  Panel* panel3 = CreateDockedPanel("3", gfx::Rect(0, 0, 200, 100));
+  Panel* panel1 = CreateInactiveDockedPanel("1", gfx::Rect(0, 0, 200, 100));
+  Panel* panel2 = CreateInactiveDockedPanel("2", gfx::Rect(0, 0, 200, 100));
+  Panel* panel3 = CreateInactiveDockedPanel("3", gfx::Rect(0, 0, 200, 100));
   ASSERT_EQ(3, docked_collection->num_panels());
 
   // Check that nothing has been squeezed so far.
@@ -48,9 +48,9 @@
   EXPECT_EQ(panel3->GetBounds().width(), panel3->GetRestoredBounds().width());
 
   // Create more panels so they start getting squeezed.
-  Panel* panel4 = CreateDockedPanel("4", gfx::Rect(0, 0, 200, 100));
-  Panel* panel5 = CreateDockedPanel("5", gfx::Rect(0, 0, 200, 100));
-  Panel* panel6 = CreateDockedPanel("6", gfx::Rect(0, 0, 200, 100));
+  Panel* panel4 = CreateInactiveDockedPanel("4", gfx::Rect(0, 0, 200, 100));
+  Panel* panel5 = CreateInactiveDockedPanel("5", gfx::Rect(0, 0, 200, 100));
+  Panel* panel6 = CreateInactiveDockedPanel("6", gfx::Rect(0, 0, 200, 100));
   Panel* panel7 = CreateDockedPanel("7", gfx::Rect(0, 0, 200, 100));
 
   // Wait for active states to settle.
@@ -70,7 +70,7 @@
   EXPECT_LT(panel6->GetBounds().width(), panel6->GetRestoredBounds().width());
 
   // Activate a different panel.
-  panel2->Activate();
+  ActivatePanel(panel2);
   WaitForPanelActiveState(panel2, SHOW_AS_ACTIVE);
 
   // Wait for active states to settle.
@@ -91,23 +91,17 @@
   panel_manager->CloseAll();
 }
 
-// http://crbug.com/143247
-#if !defined(OS_WIN)
-#define MAYBE_SqueezeAndThenSomeMore DISABLED_SqueezeAndThenSomeMore
-#else
-#define MAYBE_SqueezeAndThenSomeMore SqueezeAndThenSomeMore
-#endif
-IN_PROC_BROWSER_TEST_F(DockedPanelBrowserTest, MAYBE_SqueezeAndThenSomeMore) {
+IN_PROC_BROWSER_TEST_F(DockedPanelBrowserTest, SqueezeAndThenSomeMore) {
   PanelManager* panel_manager = PanelManager::GetInstance();
   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
 
   // Create enough docked panels to get into squeezing.
-  Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 100));
-  Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 200, 100));
-  Panel* panel3 = CreateDockedPanel("3", gfx::Rect(0, 0, 200, 100));
-  Panel* panel4 = CreateDockedPanel("4", gfx::Rect(0, 0, 200, 100));
-  Panel* panel5 = CreateDockedPanel("5", gfx::Rect(0, 0, 200, 100));
-  Panel* panel6 = CreateDockedPanel("6", gfx::Rect(0, 0, 200, 100));
+  Panel* panel1 = CreateInactiveDockedPanel("1", gfx::Rect(0, 0, 200, 100));
+  Panel* panel2 = CreateInactiveDockedPanel("2", gfx::Rect(0, 0, 200, 100));
+  Panel* panel3 = CreateInactiveDockedPanel("3", gfx::Rect(0, 0, 200, 100));
+  Panel* panel4 = CreateInactiveDockedPanel("4", gfx::Rect(0, 0, 200, 100));
+  Panel* panel5 = CreateInactiveDockedPanel("5", gfx::Rect(0, 0, 200, 100));
+  Panel* panel6 = CreateInactiveDockedPanel("6", gfx::Rect(0, 0, 200, 100));
 
   // Wait for active states to settle.
   PanelCollectionSqueezeObserver panel6_settled(docked_collection, panel6);
@@ -146,23 +140,17 @@
   panel_manager->CloseAll();
 }
 
-// http://crbug.com/143247
-#if !defined(OS_WIN)
-#define MAYBE_MinimizeSqueezedActive DISABLED_MinimizeSqueezedActive
-#else
-#define MAYBE_MinimizeSqueezedActive MinimizeSqueezedActive
-#endif
-IN_PROC_BROWSER_TEST_F(DockedPanelBrowserTest, MAYBE_MinimizeSqueezedActive) {
+IN_PROC_BROWSER_TEST_F(DockedPanelBrowserTest, MinimizeSqueezedActive) {
   PanelManager* panel_manager = PanelManager::GetInstance();
   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
 
   // Create enough docked panels to get into squeezing.
-  Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 100));
-  Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 200, 100));
-  Panel* panel3 = CreateDockedPanel("3", gfx::Rect(0, 0, 200, 100));
-  Panel* panel4 = CreateDockedPanel("4", gfx::Rect(0, 0, 200, 100));
-  Panel* panel5 = CreateDockedPanel("5", gfx::Rect(0, 0, 200, 100));
-  Panel* panel6 = CreateDockedPanel("6", gfx::Rect(0, 0, 200, 100));
+  Panel* panel1 = CreateInactiveDockedPanel("1", gfx::Rect(0, 0, 200, 100));
+  Panel* panel2 = CreateInactiveDockedPanel("2", gfx::Rect(0, 0, 200, 100));
+  Panel* panel3 = CreateInactiveDockedPanel("3", gfx::Rect(0, 0, 200, 100));
+  Panel* panel4 = CreateInactiveDockedPanel("4", gfx::Rect(0, 0, 200, 100));
+  Panel* panel5 = CreateInactiveDockedPanel("5", gfx::Rect(0, 0, 200, 100));
+  Panel* panel6 = CreateInactiveDockedPanel("6", gfx::Rect(0, 0, 200, 100));
   Panel* panel7 = CreateDockedPanel("7", gfx::Rect(0, 0, 200, 100));
 
   // Wait for active states to settle.
@@ -205,23 +193,17 @@
   panel_manager->CloseAll();
 }
 
-// http://crbug.com/143247
-#if !defined(OS_WIN)
-#define MAYBE_CloseSqueezedPanels DISABLED_CloseSqueezedPanels
-#else
-#define MAYBE_CloseSqueezedPanels CloseSqueezedPanels
-#endif
-IN_PROC_BROWSER_TEST_F(DockedPanelBrowserTest, MAYBE_CloseSqueezedPanels) {
+IN_PROC_BROWSER_TEST_F(DockedPanelBrowserTest, CloseSqueezedPanels) {
   PanelManager* panel_manager = PanelManager::GetInstance();
   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
 
   // Create enough docked panels to get into squeezing.
-  Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 100));
-  Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 200, 100));
-  Panel* panel3 = CreateDockedPanel("3", gfx::Rect(0, 0, 200, 100));
-  Panel* panel4 = CreateDockedPanel("4", gfx::Rect(0, 0, 200, 100));
-  Panel* panel5 = CreateDockedPanel("5", gfx::Rect(0, 0, 200, 100));
-  Panel* panel6 = CreateDockedPanel("6", gfx::Rect(0, 0, 200, 100));
+  Panel* panel1 = CreateInactiveDockedPanel("1", gfx::Rect(0, 0, 200, 100));
+  Panel* panel2 = CreateInactiveDockedPanel("2", gfx::Rect(0, 0, 200, 100));
+  Panel* panel3 = CreateInactiveDockedPanel("3", gfx::Rect(0, 0, 200, 100));
+  Panel* panel4 = CreateInactiveDockedPanel("4", gfx::Rect(0, 0, 200, 100));
+  Panel* panel5 = CreateInactiveDockedPanel("5", gfx::Rect(0, 0, 200, 100));
+  Panel* panel6 = CreateInactiveDockedPanel("6", gfx::Rect(0, 0, 200, 100));
   Panel* panel7 = CreateDockedPanel("7", gfx::Rect(0, 0, 200, 100));
 
   // Wait for active states to settle.
diff --git a/chrome/browser/ui/panels/docked_panel_collection.cc b/chrome/browser/ui/panels/docked_panel_collection.cc
index e688b0c..d1d34d3 100644
--- a/chrome/browser/ui/panels/docked_panel_collection.cc
+++ b/chrome/browser/ui/panels/docked_panel_collection.cc
@@ -13,10 +13,10 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/panels/panel_drag_controller.h"
 #include "chrome/browser/ui/panels/panel_manager.h"
 #include "chrome/browser/ui/panels/panel_mouse_watcher.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
 
diff --git a/chrome/browser/ui/panels/native_panel.h b/chrome/browser/ui/panels/native_panel.h
index 958fdbb..69ccc5f 100644
--- a/chrome/browser/ui/panels/native_panel.h
+++ b/chrome/browser/ui/panels/native_panel.h
@@ -136,6 +136,10 @@
   virtual bool IsButtonVisible(panel::TitlebarButtonType button_type) const = 0;
 
   virtual panel::CornerStyle GetWindowCornerStyle() const = 0;
+
+  // Makes sure that the application is running on foreground. Returns false
+  // if the effort fails.
+  virtual bool EnsureApplicationRunOnForeground() = 0;
 };
 
 #endif  // CHROME_BROWSER_UI_PANELS_NATIVE_PANEL_H_
diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc
index 752242d..45fc111 100644
--- a/chrome/browser/ui/panels/panel.cc
+++ b/chrome/browser/ui/panels/panel.cc
@@ -8,6 +8,7 @@
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/ui/panels/panel_manager.h"
 #include "chrome/browser/ui/panels/stacked_panel_collection.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/panels/panel_browsertest.cc b/chrome/browser/ui/panels/panel_browsertest.cc
index 6b5dccf..276b064 100644
--- a/chrome/browser/ui/panels/panel_browsertest.cc
+++ b/chrome/browser/ui/panels/panel_browsertest.cc
@@ -6,6 +6,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/net/url_request_mock_util.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/ui/panels/panel_manager.h"
 #include "chrome/browser/ui/panels/test_panel_active_state_observer.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "chrome/common/pref_names.h"
@@ -947,13 +947,12 @@
   panel->Close();
 }
 
-// http://crbug.com/143247
-#if !defined(OS_WIN)
-#define MAYBE_ActivatePanelOrTabbedWindow DISABLED_ActivatePanelOrTabbedWindow
-#else
-#define MAYBE_ActivatePanelOrTabbedWindow ActivatePanelOrTabbedWindow
-#endif
-IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_ActivatePanelOrTabbedWindow) {
+IN_PROC_BROWSER_TEST_F(PanelBrowserTest, ActivatePanelOrTabbedWindow) {
+  if (!WmSupportWindowActivation()) {
+    LOG(WARNING) << "Skipping test due to WM problems.";
+    return;
+  }
+
   Panel* panel1 = CreatePanel("Panel1");
   Panel* panel2 = CreatePanel("Panel2");
 
@@ -983,12 +982,17 @@
 }
 
 // TODO(jianli): To be enabled for other platforms.
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_LINUX)
 #define MAYBE_ActivateDeactivateBasic ActivateDeactivateBasic
 #else
 #define MAYBE_ActivateDeactivateBasic DISABLED_ActivateDeactivateBasic
 #endif
 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_ActivateDeactivateBasic) {
+  if (!WmSupportWindowActivation()) {
+    LOG(WARNING) << "Skipping test due to WM problems.";
+    return;
+  }
+
   // Create an active panel.
   Panel* panel = CreatePanel("PanelTest");
   scoped_ptr<NativePanelTesting> native_panel_testing(
@@ -1000,19 +1004,23 @@
   // Deactivate the panel.
   panel->Deactivate();
   WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);
+
+  // On GTK there is no way to deactivate a window. So the Deactivate() call
+  // above does not actually deactivate the window, but simply lowers it.
+#if !defined(OS_LINUX)
   EXPECT_TRUE(native_panel_testing->VerifyActiveState(false));
+#endif
 
   // This test does not reactivate the panel because the panel might not be
   // reactivated programmatically once it is deactivated.
 }
 
-// http://crbug.com/143247
-#if !defined(OS_WIN)
-#define MAYBE_ActivateDeactivateMultiple DISABLED_ActivateDeactivateMultiple
-#else
-#define MAYBE_ActivateDeactivateMultiple ActivateDeactivateMultiple
-#endif
-IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_ActivateDeactivateMultiple) {
+IN_PROC_BROWSER_TEST_F(PanelBrowserTest, ActivateDeactivateMultiple) {
+  if (!WmSupportWindowActivation()) {
+    LOG(WARNING) << "Skipping test due to WM problems.";
+    return;
+  }
+
   BrowserWindow* tabbed_window = browser()->window();
 
   // Create 4 panels in the following screen layout:
@@ -1307,19 +1315,8 @@
   panel->Close();
 }
 
-// http://crbug.com/143247
-#if !defined(OS_WIN)
-#define MAYBE_CreateInactiveSwitchToActive DISABLED_CreateInactiveSwitchToActive
-#else
-#define MAYBE_CreateInactiveSwitchToActive CreateInactiveSwitchToActive
-#endif
-IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_CreateInactiveSwitchToActive) {
-  // Compiz will not activate initially inactive window.
-  if (SkipTestIfCompizWM())
-    return;
-
-  CreatePanelParams params("Initially Inactive", gfx::Rect(), SHOW_AS_INACTIVE);
-  Panel* panel = CreatePanelWithParams(params);
+IN_PROC_BROWSER_TEST_F(PanelBrowserTest, CreateInactiveSwitchToActive) {
+  Panel* panel = CreateInactivePanel("1");
 
   panel->Activate();
   WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
diff --git a/chrome/browser/ui/panels/panel_drag_browsertest.cc b/chrome/browser/ui/panels/panel_drag_browsertest.cc
index f88a649..a243526 100644
--- a/chrome/browser/ui/panels/panel_drag_browsertest.cc
+++ b/chrome/browser/ui/panels/panel_drag_browsertest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/panels/base_panel_browser_test.h"
 #include "chrome/browser/ui/panels/detached_panel_collection.h"
 #include "chrome/browser/ui/panels/docked_panel_collection.h"
@@ -12,7 +13,6 @@
 #include "chrome/browser/ui/panels/panel_manager.h"
 #include "chrome/browser/ui/panels/stacked_panel_collection.h"
 #include "chrome/browser/ui/panels/test_panel_collection_squeeze_observer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/test/test_utils.h"
 
@@ -1325,13 +1325,7 @@
   panel_manager->CloseAll();
 }
 
-// http://crbug.com/143247, http://crbug.com/175760
-#if defined(OS_LINUX) || defined(OS_MACOSX)
-#define MAYBE_AttachWithSqueeze DISABLED_AttachWithSqueeze
-#else
-#define MAYBE_AttachWithSqueeze AttachWithSqueeze
-#endif
-IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_AttachWithSqueeze) {
+IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, AttachWithSqueeze) {
   PanelManager* panel_manager = PanelManager::GetInstance();
   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
   DetachedPanelCollection* detached_collection =
@@ -1340,12 +1334,15 @@
   // Create some detached, docked panels.
   //   detached:  P1  P2  P3
   //   docked:    P4  P5  P6  P7
-  Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(100, 300, 200, 100));
-  Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(200, 300, 200, 100));
-  Panel* panel3 = CreateDetachedPanel("3", gfx::Rect(400, 300, 200, 100));
-  Panel* panel4 = CreateDockedPanel("4", gfx::Rect(0, 0, 200, 100));
-  Panel* panel5 = CreateDockedPanel("5", gfx::Rect(0, 0, 200, 100));
-  Panel* panel6 = CreateDockedPanel("6", gfx::Rect(0, 0, 200, 100));
+  Panel* panel1 = CreateInactiveDetachedPanel(
+      "1", gfx::Rect(100, 300, 200, 100));
+  Panel* panel2 = CreateInactiveDetachedPanel(
+      "2", gfx::Rect(200, 300, 200, 100));
+  Panel* panel3 = CreateInactiveDetachedPanel(
+      "3", gfx::Rect(400, 300, 200, 100));
+  Panel* panel4 = CreateInactiveDockedPanel("4", gfx::Rect(0, 0, 200, 100));
+  Panel* panel5 = CreateInactiveDockedPanel("5", gfx::Rect(0, 0, 200, 100));
+  Panel* panel6 = CreateInactiveDockedPanel("6", gfx::Rect(0, 0, 200, 100));
   Panel* panel7 = CreateDockedPanel("7", gfx::Rect(0, 0, 200, 100));
   ASSERT_EQ(3, detached_collection->num_panels());
   ASSERT_EQ(4, docked_collection->num_panels());
diff --git a/chrome/browser/ui/panels/panel_extension_browsertest.cc b/chrome/browser/ui/panels/panel_extension_browsertest.cc
index 6b6d5d0..b63a8c8 100644
--- a/chrome/browser/ui/panels/panel_extension_browsertest.cc
+++ b/chrome/browser/ui/panels/panel_extension_browsertest.cc
@@ -6,6 +6,7 @@
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_test_message_listener.h"
 #include "chrome/browser/profiles/profile.h"
@@ -16,7 +17,6 @@
 #include "chrome/browser/ui/panels/panel_constants.h"
 #include "chrome/browser/ui/panels/panel_manager.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
@@ -102,17 +102,8 @@
 }
 #endif
 
-// Tests that icon loading might not be completed when the panel is closed.
-// (crbug.com/151484)
-//
-// TODO(linux_aura) http://crbug.com/163931
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
-#define MAYBE_ClosePanelBeforeIconLoadingCompleted DISABLED_ClosePanelBeforeIconLoadingCompleted
-#else
-#define MAYBE_ClosePanelBeforeIconLoadingCompleted ClosePanelBeforeIconLoadingCompleted
-#endif
 IN_PROC_BROWSER_TEST_F(PanelExtensionBrowserTest,
-                       MAYBE_ClosePanelBeforeIconLoadingCompleted) {
+                       ClosePanelBeforeIconLoadingCompleted) {
   const Extension* extension =
       LoadExtension(test_data_dir_.AppendASCII("test_extension"));
   Panel* panel = CreatePanelFromExtension(extension);
diff --git a/chrome/browser/ui/panels/panel_host.cc b/chrome/browser/ui/panels/panel_host.cc
index 60658da..9ea58cb 100644
--- a/chrome/browser/ui/panels/panel_host.cc
+++ b/chrome/browser/ui/panels/panel_host.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chrome_page_zoom.h"
 #include "chrome/browser/extensions/window_controller.h"
 #include "chrome/browser/favicon/favicon_tab_helper.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/panels/panel.h"
 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_messages.h"
 #include "content/public/browser/invalidate_type.h"
 #include "content/public/browser/navigation_controller.h"
@@ -201,7 +201,7 @@
       render_view_host->GetRoutingID(), window->GetWindowId()));
 }
 
-void PanelHost::RenderViewGone(base::TerminationStatus status) {
+void PanelHost::RenderProcessGone(base::TerminationStatus status) {
   CloseContents(web_contents_.get());
 }
 
diff --git a/chrome/browser/ui/panels/panel_host.h b/chrome/browser/ui/panels/panel_host.h
index e7344cf..3c94c0f 100644
--- a/chrome/browser/ui/panels/panel_host.h
+++ b/chrome/browser/ui/panels/panel_host.h
@@ -78,7 +78,7 @@
   // content::WebContentsObserver overrides.
   virtual void RenderViewCreated(
       content::RenderViewHost* render_view_host) OVERRIDE;
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
   virtual void WebContentsDestroyed(
       content::WebContents* web_contents) OVERRIDE;
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
diff --git a/chrome/browser/ui/panels/panel_manager.cc b/chrome/browser/ui/panels/panel_manager.cc
index 0b1269b..a62cadc 100644
--- a/chrome/browser/ui/panels/panel_manager.cc
+++ b/chrome/browser/ui/panels/panel_manager.cc
@@ -9,13 +9,13 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/panels/detached_panel_collection.h"
 #include "chrome/browser/ui/panels/docked_panel_collection.h"
 #include "chrome/browser/ui/panels/panel_drag_controller.h"
 #include "chrome/browser/ui/panels/panel_mouse_watcher.h"
 #include "chrome/browser/ui/panels/panel_resize_controller.h"
 #include "chrome/browser/ui/panels/stacked_panel_collection.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/panels/stacked_panel_browsertest.cc b/chrome/browser/ui/panels/stacked_panel_browsertest.cc
index dbc55e4..48fbea4 100644
--- a/chrome/browser/ui/panels/stacked_panel_browsertest.cc
+++ b/chrome/browser/ui/panels/stacked_panel_browsertest.cc
@@ -443,9 +443,7 @@
   panel_manager->CloseAll();
 }
 
-// Disabled, http://crbug.com/240745 .
-IN_PROC_BROWSER_TEST_F(StackedPanelBrowserTest,
-                       DISABLED_ExpandAllToFitWithinScreen) {
+IN_PROC_BROWSER_TEST_F(StackedPanelBrowserTest, ExpandAllToFitWithinScreen) {
   PanelManager* panel_manager = PanelManager::GetInstance();
   gfx::Rect work_area =
       panel_manager->display_settings_provider()->GetPrimaryWorkArea();
diff --git a/chrome/browser/ui/panels/test_panel_active_state_observer.cc b/chrome/browser/ui/panels/test_panel_active_state_observer.cc
index b26a46a..05143c6 100644
--- a/chrome/browser/ui/panels/test_panel_active_state_observer.cc
+++ b/chrome/browser/ui/panels/test_panel_active_state_observer.cc
@@ -4,8 +4,8 @@
 
 #include "chrome/browser/ui/panels/test_panel_active_state_observer.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/panels/panel.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 
 PanelActiveStateObserver::PanelActiveStateObserver(
diff --git a/chrome/browser/ui/panels/test_panel_collection_squeeze_observer.cc b/chrome/browser/ui/panels/test_panel_collection_squeeze_observer.cc
index 23d2fc1..f64b52d 100644
--- a/chrome/browser/ui/panels/test_panel_collection_squeeze_observer.cc
+++ b/chrome/browser/ui/panels/test_panel_collection_squeeze_observer.cc
@@ -4,9 +4,9 @@
 
 #include "chrome/browser/ui/panels/test_panel_collection_squeeze_observer.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/panels/docked_panel_collection.h"
 #include "chrome/browser/ui/panels/panel.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 
 PanelCollectionSqueezeObserver::PanelCollectionSqueezeObserver(
diff --git a/chrome/browser/ui/panels/test_panel_notification_observer.cc b/chrome/browser/ui/panels/test_panel_notification_observer.cc
index efd6793..c685e2f 100644
--- a/chrome/browser/ui/panels/test_panel_notification_observer.cc
+++ b/chrome/browser/ui/panels/test_panel_notification_observer.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ui/panels/test_panel_notification_observer.h"
 
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/ui/pdf/pdf_browsertest.cc b/chrome/browser/ui/pdf/pdf_browsertest.cc
index e7b0c14..addcfc7 100644
--- a/chrome/browser/ui/pdf/pdf_browsertest.cc
+++ b/chrome/browser/ui/pdf/pdf_browsertest.cc
@@ -9,10 +9,10 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/ui/prefs/prefs_tab_helper.cc b/chrome/browser/ui/prefs/prefs_tab_helper.cc
index bded9d8..30feabb 100644
--- a/chrome/browser/ui/prefs/prefs_tab_helper.cc
+++ b/chrome/browser/ui/prefs/prefs_tab_helper.cc
@@ -12,9 +12,9 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/renderer_preferences_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_font_webkit_names.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/pref_names_util.h"
@@ -491,7 +491,7 @@
 }
 
 // static
-void PrefsTabHelper::RegisterUserPrefs(
+void PrefsTabHelper::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   WebPreferences pref_defaults;
   registry->RegisterBooleanPref(
diff --git a/chrome/browser/ui/prefs/prefs_tab_helper.h b/chrome/browser/ui/prefs/prefs_tab_helper.h
index 72a89ad..09086b5 100644
--- a/chrome/browser/ui/prefs/prefs_tab_helper.h
+++ b/chrome/browser/ui/prefs/prefs_tab_helper.h
@@ -30,7 +30,7 @@
   virtual ~PrefsTabHelper();
 
   static void InitIncognitoUserPrefStore(OverlayUserPrefStore* pref_store);
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
   static void MigrateUserPrefs(PrefService* prefs);
 
  protected:
diff --git a/chrome/browser/ui/prefs/prefs_tab_helper_browsertest.cc b/chrome/browser/ui/prefs/prefs_tab_helper_browsertest.cc
index 00dafa7..d6cd780 100644
--- a/chrome/browser/ui/prefs/prefs_tab_helper_browsertest.cc
+++ b/chrome/browser/ui/prefs/prefs_tab_helper_browsertest.cc
@@ -35,13 +35,13 @@
       return false;
     }
     base::FilePath non_global_pref_file = GetPreferencesFilePath();
-    if (!file_util::PathExists(non_global_pref_file)) {
+    if (!base::PathExists(non_global_pref_file)) {
       LOG(ERROR) << "Doesn't exist " << non_global_pref_file.MaybeAsASCII();
       return false;
     }
     base::FilePath default_pref_file =
         default_profile.Append(chrome::kPreferencesFilename);
-    if (!file_util::CopyFile(non_global_pref_file, default_pref_file)) {
+    if (!base::CopyFile(non_global_pref_file, default_pref_file)) {
       LOG(ERROR) << "Copy error from " << non_global_pref_file.MaybeAsASCII()
                  << " to " << default_pref_file.MaybeAsASCII();
       return false;
diff --git a/chrome/browser/ui/protocol_dialog_delegate.h b/chrome/browser/ui/protocol_dialog_delegate.h
index 81b5367..87140c1 100644
--- a/chrome/browser/ui/protocol_dialog_delegate.h
+++ b/chrome/browser/ui/protocol_dialog_delegate.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_PROTOCOL_DIALOG_DELEGATE_H_
 
 #include "base/basictypes.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 // Interface implemented by objects that wish to show a dialog box Window for
 // handling special protocols. The window that is displayed uses this interface
diff --git a/chrome/browser/ui/sad_tab_helper.cc b/chrome/browser/ui/sad_tab_helper.cc
index 9d834a6..dfcb1cf 100644
--- a/chrome/browser/ui/sad_tab_helper.cc
+++ b/chrome/browser/ui/sad_tab_helper.cc
@@ -23,7 +23,7 @@
                  content::Source<content::WebContents>(web_contents));
 }
 
-void SadTabHelper::RenderViewGone(base::TerminationStatus status) {
+void SadTabHelper::RenderProcessGone(base::TerminationStatus status) {
   // Only show the sad tab if we're not in browser shutdown, so that WebContents
   // objects that are not in a browser (e.g., HTML dialogs) and thus are
   // visible do not flash a sad tab page.
diff --git a/chrome/browser/ui/sad_tab_helper.h b/chrome/browser/ui/sad_tab_helper.h
index e375e8b..0ea35d0 100644
--- a/chrome/browser/ui/sad_tab_helper.h
+++ b/chrome/browser/ui/sad_tab_helper.h
@@ -34,7 +34,7 @@
   void InstallSadTab(base::TerminationStatus status);
 
   // Overridden from content::WebContentsObserver:
-  virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
 
   // Overridden from content::NotificationObserver:
   virtual void Observe(int type,
diff --git a/chrome/browser/ui/search/instant_controller.cc b/chrome/browser/ui/search/instant_controller.cc
index a3f465b..b283229 100644
--- a/chrome/browser/ui/search/instant_controller.cc
+++ b/chrome/browser/ui/search/instant_controller.cc
@@ -7,6 +7,7 @@
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_provider.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/platform_util.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/ui/search/instant_ntp.h"
 #include "chrome/browser/ui/search/instant_tab.h"
 #include "chrome/browser/ui/search/search_tab_helper.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/content_settings_types.h"
 #include "chrome/common/pref_names.h"
@@ -285,6 +285,10 @@
 }
 
 void InstantController::TabDeactivated(content::WebContents* contents) {
+  // If user is deactivating an NTP tab, log the number of mouseovers for this
+  // NTP session.
+  if (chrome::IsInstantNTP(contents))
+    InstantNTP::EmitMouseoverCount(contents);
 }
 
 void InstantController::ThemeInfoChanged(
@@ -400,11 +404,6 @@
 
 void InstantController::InstantSupportChanged(
     InstantSupportState instant_support) {
-  // Instant support determined. Update location bar contents to reflect the
-  // page Instant support state.
-  if (instant_support != INSTANT_SUPPORT_UNKNOWN)
-    browser_->UpdateLocationBar();
-
   // Handle INSTANT_SUPPORT_YES here because InstantPage is not hooked up to the
   // active tab. Search model changed listener in InstantPage will handle other
   // cases.
@@ -445,7 +444,7 @@
   }
 }
 
-void InstantController::InstantPageRenderViewGone(
+void InstantController::InstantPageRenderProcessGone(
     const content::WebContents* contents) {
   if (IsContentsFrom(ntp(), contents)) {
     DeletePageSoon(ntp_.Pass());
@@ -490,8 +489,7 @@
       browser_->FocusOmnibox(false);
       break;
     case OMNIBOX_FOCUS_NONE:
-      if (omnibox_focus_state_ != OMNIBOX_FOCUS_INVISIBLE)
-        contents->GetView()->Focus();
+      contents->GetView()->Focus();
       break;
   }
 }
diff --git a/chrome/browser/ui/search/instant_controller.h b/chrome/browser/ui/search/instant_controller.h
index 8dd8bb9..7964d87 100644
--- a/chrome/browser/ui/search/instant_controller.h
+++ b/chrome/browser/ui/search/instant_controller.h
@@ -19,11 +19,12 @@
 #include "chrome/common/instant_types.h"
 #include "chrome/common/omnibox_focus_state.h"
 #include "chrome/common/search_types.h"
-#include "googleurl/src/gurl.h"
+#include "content/public/common/page_transition_types.h"
 #include "net/base/network_change_notifier.h"
 #include "ui/base/window_open_disposition.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/rect.h"
+#include "url/gurl.h"
 
 class BrowserInstantController;
 class InstantNTP;
@@ -166,7 +167,7 @@
   FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, PreloadedNTPIsUsedInNewTab);
   FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, PreloadedNTPIsUsedInSameTab);
   FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, PreloadedNTPForWrongProvider);
-  FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, PreloadedNTPRenderViewGone);
+  FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, PreloadedNTPRenderProcessGone);
   FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest,
                            PreloadedNTPDoesntSupportInstant);
   FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, ProcessIsolation);
@@ -199,7 +200,7 @@
   virtual void InstantSupportDetermined(
       const content::WebContents* contents,
       bool supports_instant) OVERRIDE;
-  virtual void InstantPageRenderViewGone(
+  virtual void InstantPageRenderProcessGone(
       const content::WebContents* contents) OVERRIDE;
   virtual void InstantPageAboutToNavigateMainFrame(
       const content::WebContents* contents,
diff --git a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
index 344b7e4..2c25a3e 100644
--- a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
+++ b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/autocomplete/search_provider.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/favicon/favicon_tab_helper.h"
@@ -49,7 +50,6 @@
 #include "chrome/browser/ui/search/search_tab_helper.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/theme_source.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/instant_types.h"
 #include "chrome/common/pref_names.h"
@@ -457,7 +457,7 @@
   EXPECT_NE(ntp_url, active_tab->GetURL());
 }
 
-IN_PROC_BROWSER_TEST_F(InstantExtendedTest, PreloadedNTPRenderViewGone) {
+IN_PROC_BROWSER_TEST_F(InstantExtendedTest, PreloadedNTPRenderProcessGone) {
   // Setup Instant.
   ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
   FocusOmniboxAndWaitForInstantNTPSupport();
@@ -467,7 +467,7 @@
   EXPECT_FALSE(instant()->ntp()->IsLocal());
 
   // NTP not reloaded after being killed.
-  instant()->InstantPageRenderViewGone(instant()->ntp()->contents());
+  instant()->InstantPageRenderProcessGone(instant()->ntp()->contents());
   EXPECT_EQ(NULL, instant()->ntp());
 
   // Open new tab. Should use local NTP.
@@ -1284,13 +1284,6 @@
   ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
   FocusOmniboxAndWaitForInstantNTPSupport();
 
-  // Open new tab. Preloaded NTP contents should have been used.
-  ui_test_utils::NavigateToURLWithDisposition(
-      browser(),
-      GURL(chrome::kChromeUINewTabURL),
-      NEW_FOREGROUND_TAB,
-      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
-
   content::WindowedNotificationObserver observer(
       chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
       content::NotificationService::AllSources());
@@ -1338,13 +1331,6 @@
   ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
   FocusOmniboxAndWaitForInstantNTPSupport();
 
-  // Open new tab. Preloaded NTP contents should have been used.
-  ui_test_utils::NavigateToURLWithDisposition(
-      browser(),
-      GURL(chrome::kChromeUINewTabURL),
-      NEW_FOREGROUND_TAB,
-      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
-
   // Create an observer to wait for the instant tab to support Instant.
   content::WindowedNotificationObserver observer_1(
       chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
@@ -1377,13 +1363,6 @@
   ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
   FocusOmniboxAndWaitForInstantNTPSupport();
 
-  // Open new tab. Preloaded NTP contents should have been used.
-  ui_test_utils::NavigateToURLWithDisposition(
-      browser(),
-      GURL(chrome::kChromeUINewTabURL),
-      NEW_FOREGROUND_TAB,
-      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
-
   // Create an observer to wait for the instant tab to support Instant.
   content::WindowedNotificationObserver observer(
       chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
@@ -1555,13 +1534,6 @@
   // Focus omnibox and confirm overlay isn't shown.
   FocusOmniboxAndWaitForInstantNTPSupport();
 
-  // Open new tab. Preloaded NTP contents should have been used.
-  ui_test_utils::NavigateToURLWithDisposition(
-      browser(),
-      GURL(chrome::kChromeUINewTabURL),
-      NEW_FOREGROUND_TAB,
-      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
-
   // Create an observer to wait for the instant tab to support Instant.
   content::WindowedNotificationObserver observer(
       chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
@@ -1614,13 +1586,6 @@
   // Focus omnibox and confirm overlay isn't shown.
   FocusOmniboxAndWaitForInstantNTPSupport();
 
-  // Open new tab. Preloaded NTP contents should have been used.
-  ui_test_utils::NavigateToURLWithDisposition(
-      browser(),
-      GURL(chrome::kChromeUINewTabURL),
-      NEW_FOREGROUND_TAB,
-      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
-
   // Create an observer to wait for the instant tab to support Instant.
   content::WindowedNotificationObserver observer(
       chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
diff --git a/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc b/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc
index 6ee7e94..6035c1b 100644
--- a/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc
+++ b/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/strings/string_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/task_manager/task_manager.h"
 #include "chrome/browser/task_manager/task_manager_browsertest_util.h"
@@ -13,7 +14,6 @@
 #include "chrome/browser/ui/search/instant_ntp.h"
 #include "chrome/browser/ui/search/instant_test_utils.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/omnibox_focus_state.h"
 #include "chrome/common/search_types.h"
 #include "chrome/common/url_constants.h"
@@ -26,9 +26,9 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/network_change_notifier.h"
 #include "net/dns/mock_host_resolver.h"
+#include "url/gurl.h"
 
 // !!! IMPORTANT !!!
 // These tests are run against a mock GWS using the web-page-replay system.
diff --git a/chrome/browser/ui/search/instant_ipc_sender.h b/chrome/browser/ui/search/instant_ipc_sender.h
index 8319f2c..d9e4cd8 100644
--- a/chrome/browser/ui/search/instant_ipc_sender.h
+++ b/chrome/browser/ui/search/instant_ipc_sender.h
@@ -34,8 +34,8 @@
   // Tells the page that the user pressed Enter in the omnibox.
   virtual void Submit(const string16& text) {}
 
-  // Tells the page the bounds of the omnibox (in screen coordinates). This is
-  // used by the page to align text or assets properly with the omnibox.
+  // Tells the page the left and right margins of the omnibox. This is used by
+  // the page to align text or assets properly with the omnibox.
   virtual void SetOmniboxBounds(const gfx::Rect& bounds) {}
 
   // Tells the page about the font information.
diff --git a/chrome/browser/ui/search/instant_ntp.cc b/chrome/browser/ui/search/instant_ntp.cc
index 5813ae0..0bf6f17 100644
--- a/chrome/browser/ui/search/instant_ntp.cc
+++ b/chrome/browser/ui/search/instant_ntp.cc
@@ -4,9 +4,70 @@
 
 #include "chrome/browser/ui/search/instant_ntp.h"
 
+#include "base/metrics/histogram.h"
+#include "chrome/browser/search/search.h"
 #include "chrome/browser/ui/search/search_tab_helper.h"
+#include "content/public/browser/navigation_details.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+#include "url/gurl.h"
+
+namespace {
+
+// Helper class for logging data from the NTP. Attached to each InstantNTP
+// instance.
+class NTPLoggingUserData
+    : public content::WebContentsObserver,
+      public content::WebContentsUserData<NTPLoggingUserData> {
+ public:
+  virtual ~NTPLoggingUserData() {}
+
+  // Called each time the mouse hovers over an iframe or title.
+  void increment_number_of_mouseovers() {
+    number_of_mouseovers_++;
+  }
+
+  void set_instant_url(const GURL& url) {
+    instant_url_ = url;
+  }
+
+  // Logs total number of mouseovers per NTP session to UMA histogram. Called
+  // when an NTP tab is about to be deactivated (be it by switching tabs, losing
+  // focus or closing the tab/shutting down Chrome) or when the user navigates
+  // to a URL.
+  void EmitMouseoverCount() {
+    UMA_HISTOGRAM_COUNTS("NewTabPage.NumberOfMouseOvers",
+                         number_of_mouseovers_);
+    number_of_mouseovers_ = 0;
+  }
+
+  // content::WebContentsObserver override
+  virtual void NavigationEntryCommitted(
+      const content::LoadCommittedDetails& load_details) OVERRIDE {
+    if (!load_details.previous_url.is_valid())
+      return;
+
+    if (chrome::MatchesOriginAndPath(instant_url_, load_details.previous_url))
+      EmitMouseoverCount();
+  }
+
+ private:
+  explicit NTPLoggingUserData(content::WebContents* contents)
+      : content::WebContentsObserver(contents),
+        number_of_mouseovers_(0) {}
+  friend class content::WebContentsUserData<NTPLoggingUserData>;
+
+  int number_of_mouseovers_;
+  GURL instant_url_;
+
+  DISALLOW_COPY_AND_ASSIGN(NTPLoggingUserData);
+};
+
+}  // namespace
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(NTPLoggingUserData);
 
 InstantNTP::InstantNTP(InstantPage::Delegate* delegate,
                        const std::string& instant_url,
@@ -22,9 +83,15 @@
 void InstantNTP::InitContents(Profile* profile,
                               const content::WebContents* active_tab,
                               const base::Closure& on_stale_callback) {
-  loader_.Init(GURL(instant_url()), profile, active_tab, on_stale_callback);
+  GURL instantNTP_url(instant_url());
+  loader_.Init(instantNTP_url, profile, active_tab, on_stale_callback);
   SetContents(loader_.contents());
-  SearchTabHelper::FromWebContents(contents())->InitForPreloadedNTP();
+  content::WebContents* content = contents();
+  SearchTabHelper::FromWebContents(content)->InitForPreloadedNTP();
+
+  NTPLoggingUserData::CreateForWebContents(content);
+  NTPLoggingUserData::FromWebContents(content)->set_instant_url(instantNTP_url);
+
   loader_.Load();
 }
 
@@ -37,8 +104,22 @@
   delegate()->InstantPageRenderViewCreated(contents());
 }
 
-void InstantNTP::RenderViewGone(base::TerminationStatus /* status */) {
-  delegate()->InstantPageRenderViewGone(contents());
+void InstantNTP::RenderProcessGone(base::TerminationStatus /* status */) {
+  delegate()->InstantPageRenderProcessGone(contents());
+}
+
+// static
+void InstantNTP::CountMouseover(content::WebContents* contents) {
+  NTPLoggingUserData* data = NTPLoggingUserData::FromWebContents(contents);
+  if (data)
+    data->increment_number_of_mouseovers();
+}
+
+// static
+void InstantNTP::EmitMouseoverCount(content::WebContents* contents) {
+  NTPLoggingUserData* data = NTPLoggingUserData::FromWebContents(contents);
+  if (data)
+    data->EmitMouseoverCount();
 }
 
 void InstantNTP::OnSwappedContents() {
diff --git a/chrome/browser/ui/search/instant_ntp.h b/chrome/browser/ui/search/instant_ntp.h
index 3000ee5..d9382f5 100644
--- a/chrome/browser/ui/search/instant_ntp.h
+++ b/chrome/browser/ui/search/instant_ntp.h
@@ -42,11 +42,17 @@
   // the page is about to be committed.
   scoped_ptr<content::WebContents> ReleaseContents();
 
+  // Used to log each time the user mouses over NTP tiles or titles.
+  static void CountMouseover(content::WebContents* contents);
+
+  // Used to log in UMA the total number of mouseovers over NTP tiles/titles.
+  static void EmitMouseoverCount(content::WebContents* contents);
+
  private:
   // Overridden from content::WebContentsObserver:
   virtual void RenderViewCreated(
       content::RenderViewHost* render_view_host) OVERRIDE;
-  virtual void RenderViewGone(
+  virtual void RenderProcessGone(
       base::TerminationStatus status) OVERRIDE;
 
   // Overriden from InstantLoader::Delegate:
diff --git a/chrome/browser/ui/search/instant_page.cc b/chrome/browser/ui/search/instant_page.cc
index 121300a..2a26a78 100644
--- a/chrome/browser/ui/search/instant_page.cc
+++ b/chrome/browser/ui/search/instant_page.cc
@@ -7,6 +7,7 @@
 #include "apps/app_launcher.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/search/search.h"
+#include "chrome/browser/ui/search/instant_ntp.h"
 #include "chrome/browser/ui/search/search_model.h"
 #include "chrome/browser/ui/search/search_tab_helper.h"
 #include "chrome/common/render_messages.h"
@@ -118,6 +119,7 @@
     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FocusOmnibox, OnFocusOmnibox)
     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxNavigate,
                         OnSearchBoxNavigate);
+    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_CountMouseover, OnCountMouseover);
     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxDeleteMostVisitedItem,
                         OnDeleteMostVisitedItem);
     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxUndoMostVisitedDeletion,
@@ -201,6 +203,13 @@
       contents(), url, transition, disposition, is_search_type);
 }
 
+void InstantPage::OnCountMouseover(int page_id) {
+  if (!contents()->IsActiveEntry(page_id))
+    return;
+
+  InstantNTP::CountMouseover(contents());
+}
+
 void InstantPage::OnDeleteMostVisitedItem(int page_id, const GURL& url) {
   if (!contents()->IsActiveEntry(page_id))
     return;
diff --git a/chrome/browser/ui/search/instant_page.h b/chrome/browser/ui/search/instant_page.h
index bf60ccb..f26e940 100644
--- a/chrome/browser/ui/search/instant_page.h
+++ b/chrome/browser/ui/search/instant_page.h
@@ -52,8 +52,8 @@
     virtual void InstantSupportDetermined(const content::WebContents* contents,
                                           bool supports_instant) = 0;
 
-    // Called when the underlying RenderView crashed.
-    virtual void InstantPageRenderViewGone(
+    // Called when the underlying RenderView's process crashed.
+    virtual void InstantPageRenderProcessGone(
         const content::WebContents* contents) = 0;
 
     // Called when the page is about to navigate to |url|.
@@ -185,6 +185,7 @@
                            content::PageTransition transition,
                            WindowOpenDisposition disposition,
                            bool is_search_type);
+  void OnCountMouseover(int page_id);
   void OnDeleteMostVisitedItem(int page_id, const GURL& url);
   void OnUndoMostVisitedDeletion(int page_id, const GURL& url);
   void OnUndoAllMostVisitedDeletions(int page_id);
diff --git a/chrome/browser/ui/search/instant_page_unittest.cc b/chrome/browser/ui/search/instant_page_unittest.cc
index a73ffc9..effa9c6 100644
--- a/chrome/browser/ui/search/instant_page_unittest.cc
+++ b/chrome/browser/ui/search/instant_page_unittest.cc
@@ -15,10 +15,10 @@
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/mock_render_process_host.h"
-#include "googleurl/src/gurl.h"
 #include "ipc/ipc_test_sink.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace {
 
@@ -32,7 +32,7 @@
   MOCK_METHOD2(InstantSupportDetermined,
                void(const content::WebContents* contents,
                     bool supports_instant));
-  MOCK_METHOD1(InstantPageRenderViewGone,
+  MOCK_METHOD1(InstantPageRenderProcessGone,
                void(const content::WebContents* contents));
   MOCK_METHOD2(InstantPageAboutToNavigateMainFrame,
                void(const content::WebContents* contents,
diff --git a/chrome/browser/ui/search/instant_test_utils.cc b/chrome/browser/ui/search/instant_test_utils.cc
index 1ccbd03..5c94421 100644
--- a/chrome/browser/ui/search/instant_test_utils.cc
+++ b/chrome/browser/ui/search/instant_test_utils.cc
@@ -7,12 +7,12 @@
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/ui/omnibox/omnibox_view.h"
 #include "chrome/browser/ui/search/instant_ntp.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/interactive_test_utils.h"
@@ -139,14 +139,6 @@
       actual == expected;
 }
 
-bool InstantTestBase::HasUserInputInProgress() {
-  return omnibox()->model()->user_input_in_progress_;
-}
-
-bool InstantTestBase::HasTemporaryText() {
-  return omnibox()->model()->has_temporary_text_;
-}
-
 std::string InstantTestBase::GetOmniboxText() {
   return UTF16ToUTF8(omnibox()->GetText());
 }
@@ -169,7 +161,3 @@
     std::swap(start, end);
   return omnibox()->GetText().substr(start, end - start);
 }
-
-string16 InstantTestBase::GetGrayText() {
-  return omnibox()->GetInstantSuggestion();
-}
diff --git a/chrome/browser/ui/search/instant_test_utils.h b/chrome/browser/ui/search/instant_test_utils.h
index 5072443..47c273d 100644
--- a/chrome/browser/ui/search/instant_test_utils.h
+++ b/chrome/browser/ui/search/instant_test_utils.h
@@ -17,8 +17,8 @@
 #include "chrome/browser/ui/omnibox/location_bar.h"
 #include "chrome/browser/ui/search/instant_controller.h"
 #include "chrome/common/search_types.h"
-#include "googleurl/src/gurl.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
+#include "url/gurl.h"
 
 class BrowserInstantController;
 class InstantController;
@@ -88,8 +88,6 @@
   bool ExecuteScript(const std::string& script) WARN_UNUSED_RESULT;
   bool CheckVisibilityIs(content::WebContents* contents,
                          bool expected) WARN_UNUSED_RESULT;
-  bool HasUserInputInProgress();
-  bool HasTemporaryText();
 
   std::string GetOmniboxText();
 
@@ -103,9 +101,6 @@
   // Returns the omnibox's inline autocompletion (shown in blue highlight).
   string16 GetBlueText();
 
-  // Returns the omnibox's suggest text (shown as gray text).
-  string16 GetGrayText();
-
  private:
   GURL instant_url_;
 
diff --git a/chrome/browser/ui/search/local_ntp_browsertest.cc b/chrome/browser/ui/search/local_ntp_browsertest.cc
index 84decce..d811aff 100644
--- a/chrome/browser/ui/search/local_ntp_browsertest.cc
+++ b/chrome/browser/ui/search/local_ntp_browsertest.cc
@@ -42,8 +42,7 @@
       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   content::WebContents* active_tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(chrome::ShouldAssignURLToInstantRenderer(active_tab->GetURL(),
-                                                       browser()->profile()));
+  ASSERT_TRUE(chrome::IsInstantNTP(active_tab));
   bool success = false;
   ASSERT_TRUE(GetBoolFromJS(active_tab, "!!runTests()", &success));
   EXPECT_TRUE(success);
diff --git a/chrome/browser/ui/search/search_model.cc b/chrome/browser/ui/search/search_model.cc
index 840fbfa..694f456 100644
--- a/chrome/browser/ui/search/search_model.cc
+++ b/chrome/browser/ui/search/search_model.cc
@@ -35,19 +35,6 @@
 SearchModel::~SearchModel() {
 }
 
-// static.
-bool SearchModel::ShouldChangeTopBarsVisibility(const State& old_state,
-                                                const State& new_state) {
-  // If mode has changed, only change top bars visibility if new mode is not
-  // |SEARCH_SUGGESTIONS| or |SEARCH_RESULTS|.  Top bars visibility for
-  // these 2 modes is determined when the mode stays the same, and:
-  // - for |NTP/SERP| pages: by SearchBox API, or
-  // - for |DEFAULT| pages: by platform-specific implementation of
-  //   |InstantOverlayController| when it shows/hides the Instant overlay.
-  return old_state.mode != new_state.mode ?
-      !new_state.mode.is_search() : new_state.mode.is_search();
-}
-
 void SearchModel::SetState(const State& new_state) {
   DCHECK(chrome::IsInstantExtendedAPIEnabled())
       << "Please do not try to set the SearchModel mode without first "
diff --git a/chrome/browser/ui/search/search_model.h b/chrome/browser/ui/search/search_model.h
index b9a62fb..3ddb58e 100644
--- a/chrome/browser/ui/search/search_model.h
+++ b/chrome/browser/ui/search/search_model.h
@@ -47,11 +47,6 @@
   SearchModel();
   ~SearchModel();
 
-  // Returns true if visibility in top bars should be changed based on
-  // |old_state| and |new_state|.
-  static bool ShouldChangeTopBarsVisibility(const State& old_state,
-                                            const State& new_state);
-
   // Change the state.  Change notifications are sent to observers.
   void SetState(const State& state);
 
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc
index 881b22e..c81a1c8 100644
--- a/chrome/browser/ui/search/search_tab_helper.cc
+++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -164,10 +164,6 @@
 bool SearchTabHelper::OnMessageReceived(const IPC::Message& message) {
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(SearchTabHelper, message)
-    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxShowBars,
-                        OnSearchBoxShowBars)
-    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxHideBars,
-                        OnSearchBoxHideBars)
     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_InstantSupportDetermined,
                         OnInstantSupportDetermined)
     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SetVoiceSearchSupported,
@@ -244,18 +240,6 @@
   InstantSupportChanged(instant_support);
 }
 
-void SearchTabHelper::OnSearchBoxShowBars(int page_id) {
-  if (web_contents()->IsActiveEntry(page_id))
-    model_.SetTopBarsVisible(true);
-}
-
-void SearchTabHelper::OnSearchBoxHideBars(int page_id) {
-  if (web_contents()->IsActiveEntry(page_id)) {
-    model_.SetTopBarsVisible(false);
-    Send(new ChromeViewMsg_SearchBoxBarsHidden(routing_id()));
-  }
-}
-
 void SearchTabHelper::OnSetVoiceSearchSupported(int page_id, bool supported) {
   if (web_contents()->IsActiveEntry(page_id))
     model_.SetVoiceSearchSupported(supported);
diff --git a/chrome/browser/ui/search/search_tab_helper.h b/chrome/browser/ui/search/search_tab_helper.h
index 8d3ae48..ca05de1 100644
--- a/chrome/browser/ui/search/search_tab_helper.h
+++ b/chrome/browser/ui/search/search_tab_helper.h
@@ -37,10 +37,6 @@
     return &model_;
   }
 
-  const SearchModel* model() const {
-    return &model_;
-  }
-
   // Sets up the initial state correctly for a preloaded NTP.
   void InitForPreloadedNTP();
 
@@ -108,11 +104,6 @@
   // Handler for when Instant support has been determined.
   void OnInstantSupportDetermined(int page_id, bool supports_instant);
 
-  // Handlers for SearchBox API to show and hide top bars (bookmark and info
-  // bars).
-  void OnSearchBoxShowBars(int page_id);
-  void OnSearchBoxHideBars(int page_id);
-
   // Sets whether the page supports voice search on the model.
   void OnSetVoiceSearchSupported(int page_id, bool supported);
 
diff --git a/chrome/browser/ui/search_engines/edit_search_engine_controller.cc b/chrome/browser/ui/search_engines/edit_search_engine_controller.cc
index 318ae3d..241da08 100644
--- a/chrome/browser/ui/search_engines/edit_search_engine_controller.cc
+++ b/chrome/browser/ui/search_engines/edit_search_engine_controller.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "content/public/browser/user_metrics.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::UserMetricsAction;
 
diff --git a/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc b/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc
index 1c29fbb..9728fc0 100644
--- a/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc
+++ b/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc
@@ -5,13 +5,13 @@
 #include "base/message_loop.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/ui/search_engines/keyword_editor_controller.h"
 #include "chrome/browser/ui/search_engines/template_url_table_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_pref_service_syncable.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/ui/startup/autolaunch_prompt_win.cc b/chrome/browser/ui/startup/autolaunch_prompt_win.cc
index 5974ac1..5cd9c1b 100644
--- a/chrome/browser/ui/startup/autolaunch_prompt_win.cc
+++ b/chrome/browser/ui/startup/autolaunch_prompt_win.cc
@@ -28,28 +28,23 @@
 #include "grit/theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
-using content::BrowserThread;
-
 
 // AutolaunchInfoBarDelegate --------------------------------------------------
 
 namespace {
 
-// The delegate for the infobar shown when Chrome was auto-launched.
+// The delegate for the infobar shown when Chrome is auto-launched.
 class AutolaunchInfoBarDelegate : public ConfirmInfoBarDelegate {
  public:
   // Creates an autolaunch delegate and adds it to |infobar_service|.
-  static void Create(InfoBarService* infobar_service,
-                     PrefService* prefs,
-                     Profile* profile);
+  static void Create(InfoBarService* infobar_service, Profile* profile);
 
  private:
   AutolaunchInfoBarDelegate(InfoBarService* infobar_service,
-                            PrefService* prefs,
                             Profile* profile);
   virtual ~AutolaunchInfoBarDelegate();
 
-  void AllowExpiry() { should_expire_ = true; }
+  void set_should_expire() { should_expire_ = true; }
 
   // ConfirmInfoBarDelegate:
   virtual int GetIconID() const OVERRIDE;
@@ -60,15 +55,12 @@
   virtual bool ShouldExpireInternal(
       const content::LoadCommittedDetails& details) const OVERRIDE;
 
-  // The prefs to use.
-  PrefService* prefs_;
+  // Weak pointer to the profile, not owned by us.
+  Profile* profile_;
 
   // Whether the info-bar should be dismissed on the next navigation.
   bool should_expire_;
 
-  // Weak pointer to the profile, not owned by us.
-  Profile* profile_;
-
   // Used to delay the expiration of the info-bar.
   base::WeakPtrFactory<AutolaunchInfoBarDelegate> weak_factory_;
 
@@ -77,29 +69,27 @@
 
 // static
 void AutolaunchInfoBarDelegate::Create(InfoBarService* infobar_service,
-                                       PrefService* prefs,
                                        Profile* profile) {
   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
-      new AutolaunchInfoBarDelegate(infobar_service, prefs, profile)));
+      new AutolaunchInfoBarDelegate(infobar_service, profile)));
 }
 
 AutolaunchInfoBarDelegate::AutolaunchInfoBarDelegate(
     InfoBarService* infobar_service,
-    PrefService* prefs,
     Profile* profile)
     : ConfirmInfoBarDelegate(infobar_service),
-      prefs_(prefs),
-      should_expire_(false),
       profile_(profile),
+      should_expire_(false),
       weak_factory_(this) {
-  int count = prefs_->GetInteger(prefs::kShownAutoLaunchInfobar);
-  prefs_->SetInteger(prefs::kShownAutoLaunchInfobar, count + 1);
+  PrefService* prefs = profile->GetPrefs();
+  prefs->SetInteger(prefs::kShownAutoLaunchInfobar,
+                    prefs->GetInteger(prefs::kShownAutoLaunchInfobar) + 1);
 
   // We want the info-bar to stick-around for a few seconds and then be hidden
   // on the next navigation after that.
   base::MessageLoop::current()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&AutolaunchInfoBarDelegate::AllowExpiry,
+      base::Bind(&AutolaunchInfoBarDelegate::set_should_expire,
                  weak_factory_.GetWeakPtr()),
       base::TimeDelta::FromSeconds(8));
 }
@@ -158,8 +148,8 @@
 
   int infobar_shown =
       profile->GetPrefs()->GetInteger(prefs::kShownAutoLaunchInfobar);
-  const int kMaxInfobarShown = 5;
-  if (infobar_shown >= kMaxInfobarShown)
+  const int kMaxTimesToShowInfoBar = 5;
+  if (infobar_shown >= kMaxTimesToShowInfoBar)
     return false;
 
   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
@@ -173,17 +163,15 @@
 
   content::WebContents* web_contents =
       browser->tab_strip_model()->GetActiveWebContents();
-  profile = Profile::FromBrowserContext(web_contents->GetBrowserContext());
   AutolaunchInfoBarDelegate::Create(
-      InfoBarService::FromWebContents(web_contents), profile->GetPrefs(),
-      profile);
+      InfoBarService::FromWebContents(web_contents),
+      Profile::FromBrowserContext(web_contents->GetBrowserContext()));
   return true;
 }
 
 void RegisterAutolaunchUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
-      prefs::kShownAutoLaunchInfobar,
-      0,
+      prefs::kShownAutoLaunchInfobar, 0,
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 }
 
diff --git a/chrome/browser/ui/startup/bad_flags_prompt.cc b/chrome/browser/ui/startup/bad_flags_prompt.cc
index 527e3aa..71c977a 100644
--- a/chrome/browser/ui/startup/bad_flags_prompt.cc
+++ b/chrome/browser/ui/startup/bad_flags_prompt.cc
@@ -17,6 +17,11 @@
 namespace chrome {
 
 void ShowBadFlagsPrompt(Browser* browser) {
+  content::WebContents* web_contents =
+      browser->tab_strip_model()->GetActiveWebContents();
+  if (!web_contents)
+    return;
+
   // Unsupported flags for which to display a warning that "stability and
   // security will suffer".
   static const char* kBadFlags[] = {
@@ -33,25 +38,17 @@
     NULL
   };
 
-  const char* bad_flag = NULL;
   for (const char** flag = kBadFlags; *flag; ++flag) {
     if (CommandLine::ForCurrentProcess()->HasSwitch(*flag)) {
-      bad_flag = *flag;
-      break;
-    }
-  }
+      SimpleAlertInfoBarDelegate::Create(
+          InfoBarService::FromWebContents(web_contents),
+          InfoBarDelegate::kNoIconID,
+          l10n_util::GetStringFUTF16(IDS_BAD_FLAGS_WARNING_MESSAGE,
+                                      UTF8ToUTF16(std::string("--") + *flag)),
+          false);
 
-  if (bad_flag) {
-    content::WebContents* web_contents =
-        browser->tab_strip_model()->GetActiveWebContents();
-    if (!web_contents)
       return;
-    SimpleAlertInfoBarDelegate::Create(
-        InfoBarService::FromWebContents(web_contents),
-        InfoBarDelegate::kNoIconID,
-        l10n_util::GetStringFUTF16(IDS_BAD_FLAGS_WARNING_MESSAGE,
-                                    UTF8ToUTF16(std::string("--") + bad_flag)),
-        false);
+    }
   }
 }
 
diff --git a/chrome/browser/ui/startup/default_browser_prompt.cc b/chrome/browser/ui/startup/default_browser_prompt.cc
index e0a658a..78bdcee 100644
--- a/chrome/browser/ui/startup/default_browser_prompt.cc
+++ b/chrome/browser/ui/startup/default_browser_prompt.cc
@@ -31,7 +31,6 @@
 #include "grit/theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
-using content::BrowserThread;
 
 namespace {
 
@@ -155,9 +154,8 @@
 
 bool DefaultBrowserInfoBarDelegate::Accept() {
   action_taken_ = true;
-  BrowserThread::PostTask(
-      BrowserThread::FILE,
-      FROM_HERE,
+  content::BrowserThread::PostTask(
+      content::BrowserThread::FILE, FROM_HERE,
       base::Bind(&SetChromeAsDefaultBrowser, interactive_flow_required_,
                  prefs_));
 
@@ -189,13 +187,12 @@
   if (!web_contents)
     return;
 
-  bool interactive_flow = ShellIntegration::CanSetAsDefaultBrowser() ==
-      ShellIntegration::SET_DEFAULT_INTERACTIVE;
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents->GetBrowserContext());
   DefaultBrowserInfoBarDelegate::Create(
-      InfoBarService::FromWebContents(web_contents), profile->GetPrefs(),
-      interactive_flow);
+      InfoBarService::FromWebContents(web_contents),
+      Profile::FromBrowserContext(
+          web_contents->GetBrowserContext())->GetPrefs(),
+      (ShellIntegration::CanSetAsDefaultBrowser() ==
+          ShellIntegration::SET_DEFAULT_INTERACTIVE));
 }
 
 void CheckDefaultBrowserCallback(chrome::HostDesktopType desktop_type) {
@@ -204,7 +201,8 @@
         ShellIntegration::CanSetAsDefaultBrowser();
 
     if (default_change_mode != ShellIntegration::SET_DEFAULT_NOT_ALLOWED) {
-      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+      content::BrowserThread::PostTask(
+          content::BrowserThread::UI, FROM_HERE,
           base::Bind(&NotifyNotDefaultBrowserCallback, desktop_type));
     }
   }
@@ -232,8 +230,8 @@
       prefs::kDefaultBrowserSettingEnabled)) {
     if (g_browser_process->local_state()->GetBoolean(
         prefs::kDefaultBrowserSettingEnabled)) {
-      BrowserThread::PostTask(
-          BrowserThread::FILE, FROM_HERE,
+      content::BrowserThread::PostTask(
+          content::BrowserThread::FILE, FROM_HERE,
           base::Bind(
               base::IgnoreResult(&ShellIntegration::SetAsDefaultBrowser)));
     } else {
@@ -247,18 +245,16 @@
       g_browser_process->local_state()->GetString(
           prefs::kBrowserSuppressDefaultBrowserPrompt);
   const Version disable_version(disable_version_string);
-
   DCHECK(disable_version_string.empty() || disable_version.IsValid());
   if (disable_version.IsValid()) {
     const chrome::VersionInfo version_info;
-    const Version chrome_version(version_info.Version());
-    if (disable_version.Equals(chrome_version))
+    if (disable_version.Equals(Version(version_info.Version())))
       return;
   }
 
-  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
-                          base::Bind(&CheckDefaultBrowserCallback,
-                                     desktop_type));
+  content::BrowserThread::PostTask(
+      content::BrowserThread::FILE, FROM_HERE,
+      base::Bind(&CheckDefaultBrowserCallback, desktop_type));
 
 }
 
diff --git a/chrome/browser/ui/startup/google_api_keys_infobar_delegate.h b/chrome/browser/ui/startup/google_api_keys_infobar_delegate.h
index 0c43ef1..6b01f78 100644
--- a/chrome/browser/ui/startup/google_api_keys_infobar_delegate.h
+++ b/chrome/browser/ui/startup/google_api_keys_infobar_delegate.h
@@ -8,7 +8,7 @@
 #include "base/compiler_specific.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class InfoBarService;
 
diff --git a/chrome/browser/ui/startup/obsolete_os_infobar_delegate.cc b/chrome/browser/ui/startup/obsolete_os_infobar_delegate.cc
index b4799ef..359e755 100644
--- a/chrome/browser/ui/startup/obsolete_os_infobar_delegate.cc
+++ b/chrome/browser/ui/startup/obsolete_os_infobar_delegate.cc
@@ -14,10 +14,6 @@
 #include <gtk/gtk.h>
 #endif
 
-using content::OpenURLParams;
-using content::Referrer;
-
-namespace chrome {
 
 // static
 void ObsoleteOSInfoBarDelegate::Create(InfoBarService* infobar_service) {
@@ -39,29 +35,20 @@
   return;
 #endif
 
-  string16 message = l10n_util::GetStringUTF16(IDS_SYSTEM_OBSOLETE_MESSAGE);
-  // Link to an article in the help center on minimum system requirements.
-  const char* kLearnMoreURL =
-      "http://www.google.com/support/chrome/bin/answer.py?answer=95411";
   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
-      new ObsoleteOSInfoBarDelegate(infobar_service, message,
-                                    GURL(kLearnMoreURL))));
+      new ObsoleteOSInfoBarDelegate(infobar_service)));
 }
 
 ObsoleteOSInfoBarDelegate::ObsoleteOSInfoBarDelegate(
-    InfoBarService* infobar_service,
-    const string16& message,
-    const GURL& url)
-    : ConfirmInfoBarDelegate(infobar_service),
-      message_(message),
-      learn_more_url_(url) {
+    InfoBarService* infobar_service)
+    : ConfirmInfoBarDelegate(infobar_service) {
 }
 
 ObsoleteOSInfoBarDelegate::~ObsoleteOSInfoBarDelegate() {
 }
 
 string16 ObsoleteOSInfoBarDelegate::GetMessageText() const {
-  return message_;
+  return l10n_util::GetStringUTF16(IDS_SYSTEM_OBSOLETE_MESSAGE);
 }
 
 int ObsoleteOSInfoBarDelegate::GetButtons() const {
@@ -73,11 +60,10 @@
 }
 
 bool ObsoleteOSInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition) {
-  OpenURLParams params(learn_more_url_, Referrer(),
+  web_contents()->OpenURL(content::OpenURLParams(
+      GURL("http://www.google.com/support/chrome/bin/answer.py?answer=95411"),
+      content::Referrer(),
       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
-      content::PAGE_TRANSITION_LINK, false);
-  web_contents()->OpenURL(params);
+      content::PAGE_TRANSITION_LINK, false));
   return false;
 }
-
-}  // namespace chrome
diff --git a/chrome/browser/ui/startup/obsolete_os_infobar_delegate.h b/chrome/browser/ui/startup/obsolete_os_infobar_delegate.h
index 1a654bf..eedaac9 100644
--- a/chrome/browser/ui/startup/obsolete_os_infobar_delegate.h
+++ b/chrome/browser/ui/startup/obsolete_os_infobar_delegate.h
@@ -8,22 +8,19 @@
 #include "base/compiler_specific.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class InfoBarService;
 
-namespace chrome {
-
-// An infobar that is run with a string and a "Learn More" link.
+// An infobar that displays a message saying the system is obsolete, along with
+// a "Learn More" link.
 class ObsoleteOSInfoBarDelegate : public ConfirmInfoBarDelegate {
  public:
   // Creates an obsolete OS delegate and adds it to |infobar_service|.
   static void Create(InfoBarService* infobar_service);
 
  private:
-  ObsoleteOSInfoBarDelegate(InfoBarService* infobar_service,
-                            const string16& message,
-                            const GURL& url);
+  explicit ObsoleteOSInfoBarDelegate(InfoBarService* infobar_service);
   virtual ~ObsoleteOSInfoBarDelegate();
 
   virtual string16 GetMessageText() const OVERRIDE;
@@ -31,12 +28,7 @@
   virtual string16 GetLinkText() const OVERRIDE;
   virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE;
 
-  const string16 message_;
-  const GURL learn_more_url_;
-
   DISALLOW_COPY_AND_ASSIGN(ObsoleteOSInfoBarDelegate);
 };
 
-}  // namespace chrome
-
 #endif  // CHROME_BROWSER_UI_STARTUP_OBSOLETE_OS_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/ui/startup/session_crashed_prompt.cc b/chrome/browser/ui/startup/session_crashed_prompt.cc
index 3e9ec23..d504839 100644
--- a/chrome/browser/ui/startup/session_crashed_prompt.cc
+++ b/chrome/browser/ui/startup/session_crashed_prompt.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/startup/session_crashed_prompt.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/search.h"
@@ -11,7 +12,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/dom_storage_context.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc
index f90004a..b41a339 100644
--- a/chrome/browser/ui/startup/startup_browser_creator.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -31,6 +31,7 @@
 #include "chrome/browser/automation/automation_provider_list.h"
 #include "chrome/browser/automation/testing_automation_provider.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
 #include "chrome/browser/extensions/startup_helper.h"
 #include "chrome/browser/extensions/unpacked_installer.h"
@@ -51,7 +52,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_result_codes.h"
 #include "chrome/common/chrome_switches.h"
diff --git a/chrome/browser/ui/startup/startup_browser_creator.h b/chrome/browser/ui/startup/startup_browser_creator.h
index c9a5d0b..beb4f89 100644
--- a/chrome/browser/ui/startup/startup_browser_creator.h
+++ b/chrome/browser/ui/startup/startup_browser_creator.h
@@ -15,7 +15,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/startup/startup_tab.h"
 #include "chrome/browser/ui/startup/startup_types.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Browser;
 class CommandLine;
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
index f761bf8..1126df4 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -46,9 +46,11 @@
 #endif  // defined(ENABLE_MANAGED_USERS)
 
 #if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS)
+#include "base/callback.h"
 #include "base/run_loop.h"
 #include "base/values.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_types.h"
@@ -1028,7 +1030,7 @@
   // Set a policy that prevents the first-run dialog from being shown.
   policy_map_.Set(policy::key::kMetricsReportingEnabled,
                   policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
-                  base::Value::CreateBooleanValue(false));
+                  base::Value::CreateBooleanValue(false), NULL);
   provider_.UpdateChromePolicy(policy_map_);
 #endif  // defined(OS_LINUX) && defined(GOOGLE_CHROME_BUILD)
 
@@ -1315,13 +1317,14 @@
   policy_map_.Set(policy::key::kRestoreOnStartup,
                   policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
                   base::Value::CreateIntegerValue(
-                      SessionStartupPref::kPrefValueURLs));
+                      SessionStartupPref::kPrefValueURLs),
+                  NULL);
   base::ListValue startup_urls;
   startup_urls.Append(base::Value::CreateStringValue(
       test_server()->GetURL("files/title1.html").spec()));
   policy_map_.Set(policy::key::kRestoreOnStartupURLs,
                   policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
-                  startup_urls.DeepCopy());
+                  startup_urls.DeepCopy(), NULL);
   provider_.UpdateChromePolicy(policy_map_);
   base::RunLoop().RunUntilIdle();
 
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
index fb78c6a..0b09eba 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -26,6 +26,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/auto_launch_trial.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
 #include "chrome/browser/defaults.h"
@@ -71,7 +72,6 @@
 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
 #include "chrome/browser/ui/webui/sync_promo/sync_promo_trial.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_result_codes.h"
 #include "chrome/common/chrome_switches.h"
@@ -873,15 +873,13 @@
   if (is_process_startup == chrome::startup::IS_PROCESS_STARTUP) {
     chrome::ShowBadFlagsPrompt(browser);
     if (!command_line_.HasSwitch(switches::kTestType)) {
-      GoogleApiKeysInfoBarDelegate::Create(
-          InfoBarService::FromWebContents(
-              browser->tab_strip_model()->GetActiveWebContents()));
+      GoogleApiKeysInfoBarDelegate::Create(InfoBarService::FromWebContents(
+          browser->tab_strip_model()->GetActiveWebContents()));
 
       // TODO(phajdan.jr): Always enable after migrating bots:
       // http://crbug.com/170262 .
-      chrome::ObsoleteOSInfoBarDelegate::Create(
-          InfoBarService::FromWebContents(
-              browser->tab_strip_model()->GetActiveWebContents()));
+      ObsoleteOSInfoBarDelegate::Create(InfoBarService::FromWebContents(
+          browser->tab_strip_model()->GetActiveWebContents()));
     }
 
     if (browser_defaults::kOSSupportsOtherBrowsers &&
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.h b/chrome/browser/ui/startup/startup_browser_creator_impl.h
index f27a18e..a5ae458 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.h
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.h
@@ -13,7 +13,7 @@
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/startup/startup_tab.h"
 #include "chrome/browser/ui/startup/startup_types.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Browser;
 class CommandLine;
diff --git a/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc b/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc
index 2fc1888..279ebb6 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc
@@ -17,8 +17,8 @@
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 typedef InProcessBrowserTest StartupBrowserCreatorTest;
 
diff --git a/chrome/browser/ui/startup/startup_tab.h b/chrome/browser/ui/startup/startup_tab.h
index ea8916c..c948725 100644
--- a/chrome/browser/ui/startup/startup_tab.h
+++ b/chrome/browser/ui/startup/startup_tab.h
@@ -8,7 +8,7 @@
 #include <string>
 #include <vector>
 
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 // Represents tab data at startup.
 struct StartupTab {
diff --git a/chrome/browser/ui/sync/inline_login_dialog.cc b/chrome/browser/ui/sync/inline_login_dialog.cc
index bb19ca1..73c9eeb 100644
--- a/chrome/browser/ui/sync/inline_login_dialog.cc
+++ b/chrome/browser/ui/sync/inline_login_dialog.cc
@@ -7,8 +7,8 @@
 #include "chrome/browser/profiles/profile.h"

 #include "chrome/browser/ui/browser_dialogs.h"

 #include "chrome/common/url_constants.h"

-#include "googleurl/src/gurl.h"

 #include "ui/gfx/size.h"

+#include "url/gurl.h"

 

 // static

 void InlineLoginDialog::Show(Profile* profile) {

diff --git a/chrome/browser/ui/sync/one_click_signin_helper.cc b/chrome/browser/ui/sync/one_click_signin_helper.cc
index b614c93..992b88a 100644
--- a/chrome/browser/ui/sync/one_click_signin_helper.cc
+++ b/chrome/browser/ui/sync/one_click_signin_helper.cc
@@ -22,6 +22,7 @@
 #include "base/supports_user_data.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/infobars/infobar_service.h"
@@ -48,7 +49,6 @@
 #include "chrome/browser/ui/sync/signin_histogram.h"
 #include "chrome/browser/ui/tab_modal_confirm_dialog.h"
 #include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/net/url_util.h"
@@ -56,6 +56,7 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
@@ -65,7 +66,6 @@
 #include "content/public/common/password_form.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "google_apis/gaia/gaia_urls.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
@@ -75,6 +75,7 @@
 #include "net/url_request/url_request.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "url/gurl.h"
 
 
 namespace {
@@ -84,16 +85,15 @@
 // Arguments used with StartSync function.  base::Bind() cannot support too
 // many args for performance reasons, so they are packaged up into a struct.
 struct StartSyncArgs {
-  StartSyncArgs(
-      Profile* profile,
-      Browser* browser,
-      OneClickSigninHelper::AutoAccept auto_accept,
-      const std::string& session_index,
-      const std::string& email,
-      const std::string& password,
-      bool force_same_tab_navigation,
-      bool untrusted_confirmation_required,
-      SyncPromoUI::Source source);
+  StartSyncArgs(Profile* profile,
+                Browser* browser,
+                OneClickSigninHelper::AutoAccept auto_accept,
+                const std::string& session_index,
+                const std::string& email,
+                const std::string& password,
+                bool force_same_tab_navigation,
+                bool untrusted_confirmation_required,
+                SyncPromoUI::Source source);
 
   Profile* profile;
   Browser* browser;
@@ -106,16 +106,15 @@
   SyncPromoUI::Source source;
 };
 
-StartSyncArgs::StartSyncArgs(
-    Profile* profile,
-    Browser* browser,
-    OneClickSigninHelper::AutoAccept auto_accept,
-    const std::string& session_index,
-    const std::string& email,
-    const std::string& password,
-    bool force_same_tab_navigation,
-    bool untrusted_confirmation_required,
-    SyncPromoUI::Source source)
+StartSyncArgs::StartSyncArgs(Profile* profile,
+                             Browser* browser,
+                             OneClickSigninHelper::AutoAccept auto_accept,
+                             const std::string& session_index,
+                             const std::string& email,
+                             const std::string& password,
+                             bool force_same_tab_navigation,
+                             bool untrusted_confirmation_required,
+                             SyncPromoUI::Source source)
     : profile(profile),
       browser(browser),
       auto_accept(auto_accept),
@@ -142,8 +141,7 @@
 // sign-in, for this profile.
 void AddEmailToOneClickRejectedList(Profile* profile,
                                     const std::string& email) {
-  PrefService* pref_service = profile->GetPrefs();
-  ListPrefUpdate updater(pref_service,
+  ListPrefUpdate updater(profile->GetPrefs(),
                          prefs::kReverseAutologinRejectedEmailList);
   updater->AppendIfNotPresent(new base::StringValue(email));
 }
@@ -384,6 +382,7 @@
                              const std::string& last_email,
                              const std::string& email,
                              Callback callback);
+  virtual ~ConfirmEmailDialogDelegate();
 
   // TabModalConfirmDialogDelegate:
   virtual string16 GetTitle() OVERRIDE;
@@ -422,6 +421,9 @@
     callback_(callback) {
 }
 
+ConfirmEmailDialogDelegate::~ConfirmEmailDialogDelegate() {
+}
+
 string16 ConfirmEmailDialogDelegate::GetTitle() {
   return l10n_util::GetStringUTF16(
       IDS_ONE_CLICK_SIGNIN_CONFIRM_EMAIL_DIALOG_TITLE);
@@ -430,8 +432,7 @@
 string16 ConfirmEmailDialogDelegate::GetMessage() {
   return l10n_util::GetStringFUTF16(
       IDS_ONE_CLICK_SIGNIN_CONFIRM_EMAIL_DIALOG_MESSAGE,
-      UTF8ToUTF16(last_email_),
-      UTF8ToUTF16(email_));
+      UTF8ToUTF16(last_email_), UTF8ToUTF16(email_));
 }
 
 string16 ConfirmEmailDialogDelegate::GetAcceptButtonTitle() {
@@ -464,10 +465,12 @@
 class CurrentHistoryCleaner : public content::WebContentsObserver {
  public:
   explicit CurrentHistoryCleaner(content::WebContents* contents);
+  virtual ~CurrentHistoryCleaner();
 
+  // content::WebContentsObserver:
   virtual void WebContentsDestroyed(content::WebContents* contents) OVERRIDE;
-  virtual void DidStopLoading(content::RenderViewHost* render_view_host)
-      OVERRIDE;
+  virtual void DidStopLoading(
+      content::RenderViewHost* render_view_host) OVERRIDE;
 
  private:
   scoped_ptr<content::WebContents> contents_;
@@ -478,23 +481,26 @@
 
 CurrentHistoryCleaner::CurrentHistoryCleaner(content::WebContents* contents)
     : WebContentsObserver(contents) {
-  content::NavigationController& nc = web_contents()->GetController();
-  history_index_to_remove_ = nc.GetLastCommittedEntryIndex();
+  history_index_to_remove_ =
+      web_contents()->GetController().GetLastCommittedEntryIndex();
+}
+
+CurrentHistoryCleaner::~CurrentHistoryCleaner() {
 }
 
 void CurrentHistoryCleaner::DidStopLoading(
     content::RenderViewHost* render_view_host) {
-  content::NavigationController& nc = web_contents()->GetController();
+  content::NavigationController* nc = &web_contents()->GetController();
   // Have to wait until something else gets added to history before removal.
-  if (history_index_to_remove_ < nc.GetLastCommittedEntryIndex()) {
-    nc.RemoveEntryAtIndex(history_index_to_remove_);
-    delete this;  /* success */
+  if (history_index_to_remove_ < nc->GetLastCommittedEntryIndex()) {
+    nc->RemoveEntryAtIndex(history_index_to_remove_);
+    delete this;  // Success.
   }
 }
 
 void CurrentHistoryCleaner::WebContentsDestroyed(
     content::WebContents* contents) {
-  delete this;  /* failure */
+  delete this;  // Failure.
 }
 
 }  // namespace
@@ -502,11 +508,11 @@
 
 // OneClickSigninHelper -------------------------------------------------------
 
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(OneClickSigninHelper);
+
 // static
 const int OneClickSigninHelper::kMaxNavigationsSince = 10;
 
-DEFINE_WEB_CONTENTS_USER_DATA_KEY(OneClickSigninHelper);
-
 OneClickSigninHelper::OneClickSigninHelper(content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
       showing_signin_(false),
@@ -876,9 +882,11 @@
 }
 
 // static
-void OneClickSigninHelper::RemoveCurrentHistoryItem(
+void OneClickSigninHelper::RemoveSigninRedirectURLHistoryItem(
     content::WebContents* web_contents) {
-  new CurrentHistoryCleaner(web_contents);  // will self-destruct when finished
+  // Only actually remove the item if it's the blank.html continue url.
+  if (SyncPromoUI::IsContinueUrlForWebBasedSigninFlow(web_contents->GetURL()))
+    new CurrentHistoryCleaner(web_contents);  // will self-destruct when done
 }
 
 void OneClickSigninHelper::ShowSigninErrorBubble(Browser* browser,
@@ -1023,7 +1031,7 @@
   // TODO(rogerta): Could we move this code back up to ShowInfoBarUIThread()?
   if (!error_message_.empty() && auto_accept_ == AUTO_ACCEPT_EXPLICIT) {
     VLOG(1) << "OneClickSigninHelper::DidStopLoading: error=" << error_message_;
-    RemoveCurrentHistoryItem(contents);
+    RemoveSigninRedirectURLHistoryItem(contents);
     // After we redirect to NTP, our browser pointer gets corrupted because the
     // WebContents have changed, so grab the browser pointer
     // before the navigation.
@@ -1057,7 +1065,7 @@
         continue_url_.ReplaceComponents(replacements));
 
   if (continue_url_match)
-    RemoveCurrentHistoryItem(contents);
+    RemoveSigninRedirectURLHistoryItem(contents);
 
   // If there is no valid email yet, there is nothing to do.  As of M26, the
   // password is allowed to be empty, since its no longer required to setup
diff --git a/chrome/browser/ui/sync/one_click_signin_helper.h b/chrome/browser/ui/sync/one_click_signin_helper.h
index 20c9954..1a876fd 100644
--- a/chrome/browser/ui/sync/one_click_signin_helper.h
+++ b/chrome/browser/ui/sync/one_click_signin_helper.h
@@ -112,10 +112,11 @@
                                     int child_id,
                                     int route_id);
 
-  // Remove the item currently at the top of the history list.  Due to
-  // limitations of the NavigationController, this cannot be done until
-  // a new page becomes "current".
-  static void RemoveCurrentHistoryItem(content::WebContents* web_contents);
+  // Remove the item currently at the top of the history list if it's
+  // the Gaia redirect URL. Due to limitations of the NavigationController
+  // this cannot be done until a new page becomes "current".
+  static void RemoveSigninRedirectURLHistoryItem(
+      content::WebContents* web_contents);
 
   static void LogConfirmHistogramValue(int action);
 
diff --git a/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc b/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc
index 3f32a3d..a962faa 100644
--- a/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc
+++ b/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/sync/test_profile_sync_service.h"
 #include "chrome/browser/ui/sync/one_click_signin_helper.h"
 #include "chrome/common/pref_names.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_pref_service_syncable.h"
 #include "chrome/test/base/testing_profile.h"
@@ -30,7 +31,6 @@
 #include "content/public/common/password_form.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/mock_render_process_host.h"
-#include "content/public/test/test_renderer_host.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -195,7 +195,7 @@
 
 }  // namespace
 
-class OneClickSigninHelperTest : public content::RenderViewHostTestHarness {
+class OneClickSigninHelperTest : public ChromeRenderViewHostTestHarness {
  public:
   OneClickSigninHelperTest();
 
@@ -223,7 +223,7 @@
   SigninManagerMock* signin_manager_;
 
  protected:
-  TestingProfile* profile_;
+  GoogleServiceAuthError no_error_;
 
  private:
   // The ID of the signin process the test will assume to be trusted.
@@ -235,14 +235,12 @@
 };
 
 OneClickSigninHelperTest::OneClickSigninHelperTest()
-    : profile_(NULL),
+    : no_error_(GoogleServiceAuthError::NONE),
       trusted_signin_process_id_(-1) {
 }
 
 void OneClickSigninHelperTest::SetUp() {
   SyncPromoUI::ForceWebBasedSigninFlowForTesting(true);
-  profile_ = new TestingProfile();
-  browser_context_.reset(profile_);
   content::RenderViewHostTestHarness::SetUp();
   SetTrustedSigninProcessID(process()->GetID());
 }
@@ -259,10 +257,10 @@
 void OneClickSigninHelperTest::CreateSigninManager(
     bool use_incognito,
     const std::string& username) {
-  profile_->set_incognito(use_incognito);
+  profile()->set_incognito(use_incognito);
   signin_manager_ = static_cast<SigninManagerMock*>(
       SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse(
-          profile_, BuildSigninManagerMock));
+          profile(), BuildSigninManagerMock));
   if (signin_manager_)
     signin_manager_->SetSigninProcess(trusted_signin_process_id_);
 
@@ -273,23 +271,21 @@
 }
 
 void OneClickSigninHelperTest::EnableOneClick(bool enable) {
-  PrefService* pref_service = Profile::FromBrowserContext(
-      browser_context_.get())->GetPrefs();
+  PrefService* pref_service = profile()->GetPrefs();
   pref_service->SetBoolean(prefs::kReverseAutologinEnabled, enable);
 }
 
 void OneClickSigninHelperTest::AddEmailToOneClickRejectedList(
     const std::string& email) {
-  PrefService* pref_service = Profile::FromBrowserContext(
-      browser_context_.get())->GetPrefs();
+  PrefService* pref_service = profile()->GetPrefs();
   ListPrefUpdate updater(pref_service,
                          prefs::kReverseAutologinRejectedEmailList);
   updater->AppendIfNotPresent(new base::StringValue(email));
 }
 
 void OneClickSigninHelperTest::AllowSigninCookies(bool enable) {
-  CookieSettings* cookie_settings = CookieSettings::Factory::GetForProfile(
-      Profile::FromBrowserContext(browser_context_.get())).get();
+  CookieSettings* cookie_settings =
+      CookieSettings::Factory::GetForProfile(profile()).get();
   cookie_settings->SetDefaultCookieSetting(enable ? CONTENT_SETTING_ALLOW
                                                   : CONTENT_SETTING_BLOCK);
 }
@@ -304,15 +300,19 @@
 OneClickSigninHelperTest::CreateProfileSyncServiceMock() {
   ProfileSyncServiceMock* sync_service = static_cast<ProfileSyncServiceMock*>(
       ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
-          profile_,
+          profile(),
           ProfileSyncServiceMock::BuildMockProfileSyncService));
-  sync_service->Initialize();
   EXPECT_CALL(*sync_service, SetSetupInProgress(true));
   EXPECT_CALL(*sync_service, AddObserver(_)).Times(AtLeast(1));
   EXPECT_CALL(*sync_service, FirstSetupInProgress()).WillRepeatedly(
       Return(false));
   EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(true));
   EXPECT_CALL(*sync_service, RemoveObserver(_)).Times(AtLeast(1));
+  EXPECT_CALL(*sync_service, GetAuthError()).
+      WillRepeatedly(::testing::ReturnRef(no_error_));
+  EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(false));
+  sync_service->Initialize();
+  EXPECT_CALL(*sync_service, sync_initialized()).WillRepeatedly(Return(true));
   return sync_service;
 }
 
@@ -355,10 +355,10 @@
 
 TestProfileIOData* OneClickSigninHelperIOTest::CreateTestProfileIOData(
     bool is_incognito) {
-  PrefService* pref_service = profile_->GetPrefs();
+  PrefService* pref_service = profile()->GetPrefs();
   PrefService* local_state = g_browser_process->local_state();
   CookieSettings* cookie_settings =
-      CookieSettings::Factory::GetForProfile(profile_).get();
+      CookieSettings::Factory::GetForProfile(profile()).get();
   TestProfileIOData* io_data = new TestProfileIOData(
       is_incognito, pref_service, local_state, cookie_settings);
   io_data->set_reverse_autologin_pending_email("user@gmail.com");
@@ -600,7 +600,7 @@
       "user@gmail.com", NULL));
 
   // Simulate a policy disabling signin by writing kSigninAllowed directly.
-  profile_->GetTestingPrefService()->SetManagedPref(
+  profile()->GetTestingPrefService()->SetManagedPref(
       prefs::kSigninAllowed, base::Value::CreateBooleanValue(false));
 
   EXPECT_FALSE(OneClickSigninHelper::CanOffer(
@@ -608,11 +608,11 @@
       "user@gmail.com", NULL));
 
   // Reset the preference value to true.
-  profile_->GetTestingPrefService()->SetManagedPref(
+  profile()->GetTestingPrefService()->SetManagedPref(
       prefs::kSigninAllowed, base::Value::CreateBooleanValue(true));
 
   // Simulate a policy disabling sync by writing kSyncManaged directly.
-  profile_->GetTestingPrefService()->SetManagedPref(
+  profile()->GetTestingPrefService()->SetManagedPref(
       prefs::kSyncManaged, base::Value::CreateBooleanValue(true));
 
   // Should still offer even if sync is disabled by policy.
@@ -753,7 +753,7 @@
 }
 
 TEST_F(OneClickSigninHelperIOTest, CanOfferOnIOThreadSignedIn) {
-  PrefService* pref_service = profile_->GetPrefs();
+  PrefService* pref_service = profile()->GetPrefs();
   pref_service->SetString(prefs::kGoogleServicesUsername, "user@gmail.com");
 
   scoped_ptr<TestProfileIOData> io_data(CreateTestProfileIOData(false));
@@ -807,19 +807,19 @@
 
   // Simulate a policy disabling signin by writing kSigninAllowed directly.
   // We should not offer to sign in the browser.
-  profile_->GetTestingPrefService()->SetManagedPref(
+  profile()->GetTestingPrefService()->SetManagedPref(
       prefs::kSigninAllowed, base::Value::CreateBooleanValue(false));
   EXPECT_EQ(OneClickSigninHelper::DONT_OFFER,
             OneClickSigninHelper::CanOfferOnIOThreadImpl(
                 valid_gaia_url_, std::string(), &request_, io_data.get()));
 
   // Reset the preference.
-  profile_->GetTestingPrefService()->SetManagedPref(
+  profile()->GetTestingPrefService()->SetManagedPref(
       prefs::kSigninAllowed, base::Value::CreateBooleanValue(true));
 
   // Simulate a policy disabling sync by writing kSyncManaged directly.
   // We should still offer to sign in the browser.
-  profile_->GetTestingPrefService()->SetManagedPref(
+  profile()->GetTestingPrefService()->SetManagedPref(
       prefs::kSyncManaged, base::Value::CreateBooleanValue(true));
   EXPECT_EQ(OneClickSigninHelper::CAN_OFFER,
             OneClickSigninHelper::CanOfferOnIOThreadImpl(
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
index 37001a4..6b5c947 100644
--- a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
+++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
@@ -313,7 +313,6 @@
 void OneClickSigninSyncStarter::UntrustedSigninConfirmed(
     StartSyncMode response) {
   if (response == UNDO_SYNC) {
-    CancelSigninAndDelete();
     // If this was not an interstitial signin, (i.e. it was a SAML signin)
     // then the browser page is now blank and should redirect to the NTP.
     if (source_ != SyncPromoUI::SOURCE_UNKNOWN) {
@@ -324,6 +323,7 @@
       params.window_action = chrome::NavigateParams::SHOW_WINDOW;
       chrome::Navigate(&params);
     }
+    CancelSigninAndDelete();  // This statement frees this object.
   } else {
     // If the user clicked the "Advanced" link in the confirmation dialog, then
     // override the current start_mode_ to bring up the advanced sync settings.
diff --git a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
index ad97ad9..a612888 100644
--- a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
+++ b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
@@ -34,7 +34,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/user_prefs/pref_registry_syncable.h"
-#include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -116,8 +116,7 @@
 class ProfileSigninConfirmationHelperTest : public testing::Test {
  public:
   ProfileSigninConfirmationHelperTest()
-      : ui_thread_(content::BrowserThread::UI, &message_loop_),
-        user_prefs_(NULL),
+      : user_prefs_(NULL),
         model_(NULL) {
   }
 
@@ -131,7 +130,7 @@
         new TestingPrefStore(),
         new user_prefs::PrefRegistrySyncable(),
         new PrefNotifierImpl());
-    chrome::RegisterUserPrefs(pref_service->registry());
+    chrome::RegisterUserProfilePrefs(pref_service->registry());
     builder.SetPrefService(make_scoped_ptr<PrefServiceSyncable>(pref_service));
     profile_ = builder.Build();
 
@@ -153,12 +152,11 @@
     // TestExtensionSystem uses DeleteSoon, so we need to delete the profile
     // and then run the message queue to clean up.
     profile_.reset();
-    base::MessageLoop::current()->RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 
  protected:
-  base::MessageLoopForUI message_loop_;
-  content::TestBrowserThread ui_thread_;
+  content::TestBrowserThreadBundle thread_bundle_;
   scoped_ptr<TestingProfile> profile_;
   TestingPrefStoreWithCustomReadError* user_prefs_;
   BookmarkModel* model_;
diff --git a/chrome/browser/ui/sync/sync_promo_ui.cc b/chrome/browser/ui/sync/sync_promo_ui.cc
index 83585b6..8698f14 100644
--- a/chrome/browser/ui/sync/sync_promo_ui.cc
+++ b/chrome/browser/ui/sync/sync_promo_ui.cc
@@ -114,7 +114,7 @@
 }
 
 // static
-void SyncPromoUI::RegisterUserPrefs(
+void SyncPromoUI::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       prefs::kSyncPromoStartupCount,
diff --git a/chrome/browser/ui/sync/sync_promo_ui.h b/chrome/browser/ui/sync/sync_promo_ui.h
index 48d2f1b..12b04b5 100644
--- a/chrome/browser/ui/sync/sync_promo_ui.h
+++ b/chrome/browser/ui/sync/sync_promo_ui.h
@@ -54,7 +54,7 @@
   static void SetUserSkippedSyncPromo(Profile* profile);
 
   // Registers the preferences the Sync Promo UI needs.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Gets the sync landing page URL.
   static std::string GetSyncLandingURL(const char* option, int value);
diff --git a/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.cc b/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.cc
index ab71b2e..327df0e 100644
--- a/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.cc
+++ b/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.cc
@@ -25,7 +25,7 @@
 
 TabContentsSyncedTabDelegate::TabContentsSyncedTabDelegate(
     content::WebContents* web_contents)
-        : web_contents_(web_contents) {}
+    : web_contents_(web_contents), sync_session_id_(0) {}
 
 TabContentsSyncedTabDelegate::~TabContentsSyncedTabDelegate() {}
 
@@ -105,3 +105,11 @@
 }
 
 bool TabContentsSyncedTabDelegate::HasWebContents() const { return true; }
+
+int64 TabContentsSyncedTabDelegate::GetSyncId() const {
+  return sync_session_id_;
+}
+
+void TabContentsSyncedTabDelegate::SetSyncId(int64 sync_id) {
+  sync_session_id_ = sync_id;
+}
diff --git a/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h b/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h
index d58b130..68486a5 100644
--- a/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h
+++ b/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h
@@ -37,12 +37,15 @@
       GetBlockedNavigations() const OVERRIDE;
   virtual bool IsPinned() const OVERRIDE;
   virtual bool HasWebContents() const OVERRIDE;
+  virtual int64 GetSyncId() const OVERRIDE;
+  virtual void SetSyncId(int64 sync_id) OVERRIDE;
 
  private:
   explicit TabContentsSyncedTabDelegate(content::WebContents* web_contents);
   friend class content::WebContentsUserData<TabContentsSyncedTabDelegate>;
 
   content::WebContents* web_contents_;
+  int64 sync_session_id_;
 
   DISALLOW_COPY_AND_ASSIGN(TabContentsSyncedTabDelegate);
 };
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc b/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc
index 903fed1..c8d87ea 100644
--- a/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc
+++ b/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
 
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/tabs/pinned_tab_codec.cc b/chrome/browser/ui/tabs/pinned_tab_codec.cc
index b917135..66985b6 100644
--- a/chrome/browser/ui/tabs/pinned_tab_codec.cc
+++ b/chrome/browser/ui/tabs/pinned_tab_codec.cc
@@ -101,7 +101,7 @@
 }
 
 // static
-void PinnedTabCodec::RegisterUserPrefs(
+void PinnedTabCodec::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(prefs::kPinnedTabs,
                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
diff --git a/chrome/browser/ui/tabs/pinned_tab_codec.h b/chrome/browser/ui/tabs/pinned_tab_codec.h
index a17078c..690aa90 100644
--- a/chrome/browser/ui/tabs/pinned_tab_codec.h
+++ b/chrome/browser/ui/tabs/pinned_tab_codec.h
@@ -8,7 +8,7 @@
 #include <vector>
 
 #include "chrome/browser/ui/startup/startup_tab.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Profile;
 
@@ -30,7 +30,7 @@
 class PinnedTabCodec {
  public:
   // Registers the preference used by this class.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Resets the preferences state.
   static void WritePinnedTabs(Profile* profile);
diff --git a/chrome/browser/ui/tabs/pinned_tab_service.cc b/chrome/browser/ui/tabs/pinned_tab_service.cc
index f1277f8..0762dcd 100644
--- a/chrome/browser/ui/tabs/pinned_tab_service.cc
+++ b/chrome/browser/ui/tabs/pinned_tab_service.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/ui/tabs/pinned_tab_service.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/tabs/pinned_tab_codec.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 
 namespace {
diff --git a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
index 4eaf291..8aac04f 100644
--- a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
@@ -24,7 +25,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model_order_controller.h"
 #include "chrome/browser/ui/tabs/test_tab_strip_model_delegate.h"
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
diff --git a/chrome/browser/ui/toolbar/action_box_button_controller.cc b/chrome/browser/ui/toolbar/action_box_button_controller.cc
index 351d3a6..c8b302a 100644
--- a/chrome/browser/ui/toolbar/action_box_button_controller.cc
+++ b/chrome/browser/ui/toolbar/action_box_button_controller.cc
@@ -8,6 +8,7 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chrome_to_mobile_service.h"
 #include "chrome/browser/extensions/api/page_launcher/page_launcher_api.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -18,7 +19,6 @@
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/toolbar/action_box_menu_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_set.h"
diff --git a/chrome/browser/ui/toolbar/action_box_context_menu_controller.cc b/chrome/browser/ui/toolbar/action_box_context_menu_controller.cc
index f2880d9..4978c3a 100644
--- a/chrome/browser/ui/toolbar/action_box_context_menu_controller.cc
+++ b/chrome/browser/ui/toolbar/action_box_context_menu_controller.cc
@@ -21,11 +21,11 @@
 #include "content/public/browser/page_navigator.h"
 #include "content/public/common/page_transition_types.h"
 #include "content/public/common/referrer.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "ui/base/models/menu_separator_types.h"
 #include "ui/base/window_open_disposition.h"
+#include "url/gurl.h"
 
 using extensions::Extension;
 
diff --git a/chrome/browser/ui/toolbar/toolbar_model.h b/chrome/browser/ui/toolbar/toolbar_model.h
index 77ddac0..9ef715d 100644
--- a/chrome/browser/ui/toolbar/toolbar_model.h
+++ b/chrome/browser/ui/toolbar/toolbar_model.h
@@ -9,7 +9,7 @@
 
 #include "base/basictypes.h"
 #include "base/strings/string16.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 namespace net {
 class X509Certificate;
diff --git a/chrome/browser/ui/toolbar/toolbar_model_impl.h b/chrome/browser/ui/toolbar/toolbar_model_impl.h
index d84c3e1..39b5707 100644
--- a/chrome/browser/ui/toolbar/toolbar_model_impl.h
+++ b/chrome/browser/ui/toolbar/toolbar_model_impl.h
@@ -11,7 +11,7 @@
 #include "base/compiler_specific.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/ui/toolbar/toolbar_model.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class Profile;
 class ToolbarModelDelegate;
diff --git a/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc b/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc
index d2bb889..d4c94a8 100644
--- a/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/toolbar/wrench_menu_model.h"
 
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/global_error/global_error.h"
 #include "chrome/browser/ui/global_error/global_error_service.h"
@@ -159,8 +160,10 @@
 
 // Tests global error menu items in the wrench menu.
 TEST_F(WrenchMenuModelTest, GlobalError) {
+  // Make sure services required for tests are initialized.
   GlobalErrorService* service =
       GlobalErrorServiceFactory::GetForProfile(browser()->profile());
+  ProfileOAuth2TokenServiceFactory::GetForProfile(browser()->profile());
   const int command1 = 1234567;
   // AddGlobalError takes ownership of error1.
   MenuError* error1 = new MenuError(command1);
diff --git a/chrome/browser/ui/uma_browsing_activity_observer.cc b/chrome/browser/ui/uma_browsing_activity_observer.cc
index eaae467..1db2777 100644
--- a/chrome/browser/ui/uma_browsing_activity_observer.cc
+++ b/chrome/browser/ui/uma_browsing_activity_observer.cc
@@ -5,12 +5,12 @@
 #include "chrome/browser/ui/uma_browsing_activity_observer.h"
 
 #include "base/metrics/histogram.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
diff --git a/chrome/browser/ui/unload_controller.cc b/chrome/browser/ui/unload_controller.cc
index da61646..875ef47 100644
--- a/chrome/browser/ui/unload_controller.cc
+++ b/chrome/browser/ui/unload_controller.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/ui/unload_controller.h"
 
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/notification_types.h"
diff --git a/chrome/browser/ui/view_ids.h b/chrome/browser/ui/view_ids.h
index 35dda47..5d792c9 100644
--- a/chrome/browser/ui/view_ids.h
+++ b/chrome/browser/ui/view_ids.h
@@ -76,7 +76,10 @@
   VIEW_ID_ZOOM_BUTTON,
 #endif
 
-  // Used in chrome/browser/ui/gtk/view_id_util_browsertests.cc
+  // The omnibox icon to do voice-based search.
+  VIEW_ID_MIC_SEARCH_BUTTON,
+
+  // Used in chrome/browser/ui/gtk/view_id_util_browsertest.cc
   // If you add new ids, make sure the above test passes.
   VIEW_ID_PREDEFINED_COUNT,
 
diff --git a/chrome/browser/ui/views/accessibility/accessibility_event_router_views.cc b/chrome/browser/ui/views/accessibility/accessibility_event_router_views.cc
index 88b7800..4ffe477 100644
--- a/chrome/browser/ui/views/accessibility/accessibility_event_router_views.cc
+++ b/chrome/browser/ui/views/accessibility/accessibility_event_router_views.cc
@@ -11,9 +11,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/accessibility/accessibility_extension_api.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
 #include "ui/base/accessibility/accessible_view_state.h"
diff --git a/chrome/browser/ui/views/accessibility/accessibility_event_router_views.h b/chrome/browser/ui/views/accessibility/accessibility_event_router_views.h
index 29c1aab..9bb3a25 100644
--- a/chrome/browser/ui/views/accessibility/accessibility_event_router_views.h
+++ b/chrome/browser/ui/views/accessibility/accessibility_event_router_views.h
@@ -11,7 +11,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/accessibility/accessibility_events.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "ui/base/accessibility/accessibility_types.h"
diff --git a/chrome/browser/ui/views/accessibility/accessibility_event_router_views_unittest.cc b/chrome/browser/ui/views/accessibility/accessibility_event_router_views_unittest.cc
index 42dcc6f..0edd5ea 100644
--- a/chrome/browser/ui/views/accessibility/accessibility_event_router_views_unittest.cc
+++ b/chrome/browser/ui/views/accessibility/accessibility_event_router_views_unittest.cc
@@ -8,8 +8,8 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/accessibility/accessibility_extension_api.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/views/accessibility/accessibility_event_router_views.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/views/accessibility/browser_views_accessibility_browsertest.cc b/chrome/browser/ui/views/accessibility/browser_views_accessibility_browsertest.cc
index 1094b7e..ca7270c 100644
--- a/chrome/browser/ui/views/accessibility/browser_views_accessibility_browsertest.cc
+++ b/chrome/browser/ui/views/accessibility/browser_views_accessibility_browsertest.cc
@@ -136,35 +136,34 @@
 
 // Retrieve accessibility object for non client view and verify accessibility
 // info.
-// http://crbug.com/104132
+// TODO(pkasting): Disabled pending resolution of whether this should be
+// ROLE_SYSTEM_CLIENT or ROLE_SYSTEM_WINDOW.
 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                        DISABLED_TestNonClientViewAccObj) {
-  views::View* non_client_view =
-  GetBrowserView()->GetWidget()->non_client_view();
-
-  TestViewAccessibilityObject(non_client_view,
+  TestViewAccessibilityObject(
+      GetBrowserView()->GetWidget()->non_client_view(),
       UTF16ToWide(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)),
       ROLE_SYSTEM_WINDOW);
 }
 
-// Retrieve accessibility object for browser root view and verify
-// accessibility info.
-// http://crbug.com/104132
+// Retrieve accessibility object for browser root view and verify accessibility
+// info.
+// TODO(pkasting): Disabled pending resolution of whether this should be
+// ROLE_SYSTEM_WINDOW or ROLE_SYSTEM_APPLICATION, as well as what the name
+// should be.
 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                        DISABLED_TestBrowserRootViewAccObj) {
-  views::View* browser_root_view = GetBrowserView()->frame()->GetRootView();
-
   TestViewAccessibilityObject(
-      browser_root_view,
+      GetBrowserView()->frame()->GetRootView(),
       UTF16ToWide(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)),
       ROLE_SYSTEM_APPLICATION);
 }
 
 // Retrieve accessibility object for browser view and verify accessibility info.
-// http://crbug.com/104132
+// TODO(pkasting): Disabled pending resolution of whether this object should
+// have an accessible name.
 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                        DISABLED_TestBrowserViewAccObj) {
-  // Verify root view MSAA name and role.
   TestViewAccessibilityObject(
       GetBrowserView(),
       UTF16ToWide(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)),
@@ -172,10 +171,7 @@
 }
 
 // Retrieve accessibility object for toolbar view and verify accessibility info.
-// http://crbug.com/104132
-IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
-                       DISABLED_TestToolbarViewAccObj) {
-  // Verify toolbar MSAA name and role.
+IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestToolbarViewAccObj) {
   TestViewAccessibilityObject(
       GetToolbarView(),
       UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_TOOLBAR)),
@@ -183,10 +179,7 @@
 }
 
 // Retrieve accessibility object for Back button and verify accessibility info.
-// http://crbug.com/104132
-IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
-                       DISABLED_TestBackButtonAccObj) {
-  // Verify Back button MSAA name and role.
+IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBackButtonAccObj) {
   TestViewAccessibilityObject(
       GetToolbarView()->GetViewByID(VIEW_ID_BACK_BUTTON),
       UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_BACK)),
@@ -195,10 +188,7 @@
 
 // Retrieve accessibility object for Forward button and verify accessibility
 // info.
-// http://crbug.com/104132
-IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
-                       DISABLED_TestForwardButtonAccObj) {
-  // Verify Forward button MSAA name and role.
+IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestForwardButtonAccObj) {
   TestViewAccessibilityObject(
       GetToolbarView()->GetViewByID(VIEW_ID_FORWARD_BUTTON),
       UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_FORWARD)),
@@ -207,10 +197,7 @@
 
 // Retrieve accessibility object for Reload button and verify accessibility
 // info.
-// http://crbug.com/104132
-IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
-                       DISABLED_TestReloadButtonAccObj) {
-  // Verify Reload button MSAA name and role.
+IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestReloadButtonAccObj) {
   TestViewAccessibilityObject(
       GetToolbarView()->GetViewByID(VIEW_ID_RELOAD_BUTTON),
       UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_RELOAD)),
@@ -218,10 +205,7 @@
 }
 
 // Retrieve accessibility object for Home button and verify accessibility info.
-// http://crbug.com/104132
-IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
-                       DISABLED_TestHomeButtonAccObj) {
-  // Verify Home button MSAA name and role.
+IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestHomeButtonAccObj) {
   TestViewAccessibilityObject(
       GetToolbarView()->GetViewByID(VIEW_ID_HOME_BUTTON),
       UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_HOME)),
@@ -229,31 +213,35 @@
 }
 
 // Retrieve accessibility object for Star button and verify accessibility info.
-// http://crbug.com/104132
-IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
-                       DISABLED_TestStarButtonAccObj) {
-  // Verify Star button MSAA name and role.
+IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestStarButtonAccObj) {
   TestViewAccessibilityObject(
       GetToolbarView()->GetViewByID(VIEW_ID_STAR_BUTTON),
-      UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_STAR)),
+      UTF16ToWide(l10n_util::GetStringUTF16(IDS_TOOLTIP_STAR)),
+      ROLE_SYSTEM_PUSHBUTTON);
+}
+
+// Retrieve accessibility object for Mic search button and verify accessibility
+// info.
+IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
+                       TestMicSearchButtonViewAccObj) {
+  TestViewAccessibilityObject(
+      GetToolbarView()->GetViewByID(VIEW_ID_MIC_SEARCH_BUTTON),
+      UTF16ToWide(l10n_util::GetStringUTF16(IDS_TOOLTIP_MIC_SEARCH)),
       ROLE_SYSTEM_PUSHBUTTON);
 }
 
 // Retrieve accessibility object for App menu button and verify accessibility
 // info.
-// http://crbug.com/104132
-IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
-                       DISABLED_TestAppMenuAccObj) {
-  // Verify App menu button MSAA name and role.
+IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestAppMenuAccObj) {
   TestViewAccessibilityObject(
       GetToolbarView()->GetViewByID(VIEW_ID_APP_MENU),
       UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_APP)),
       ROLE_SYSTEM_BUTTONMENU);
 }
 
-// http://crbug.com/104132
+// Retrieve accessibility object for bookmark bar and verify accessibility info.
 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
-                       DISABLED_TestBookmarkBarViewAccObj) {
+                       TestBookmarkBarViewAccObj) {
   TestViewAccessibilityObject(
       GetBookmarkBarView(),
       UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_BOOKMARKS)),
diff --git a/chrome/browser/ui/views/app_list/app_list_controller_win.cc b/chrome/browser/ui/views/app_list/app_list_controller_win.cc
index d459a01..20cc64f 100644
--- a/chrome/browser/ui/views/app_list/app_list_controller_win.cc
+++ b/chrome/browser/ui/views/app_list/app_list_controller_win.cc
@@ -224,7 +224,7 @@
     base::FilePath shortcut_file =
         shortcut_paths[i].Append(app_list_shortcut_name).
             AddExtension(installer::kLnkExt);
-    if (!file_util::PathExists(shortcut_file.DirName()) &&
+    if (!base::PathExists(shortcut_file.DirName()) &&
         !file_util::CreateDirectory(shortcut_file.DirName())) {
       NOTREACHED();
       return;
@@ -310,7 +310,7 @@
   virtual void ShowAppList(Profile* requested_profile) OVERRIDE;
   virtual void DismissAppList() OVERRIDE;
   virtual bool IsAppListVisible() const OVERRIDE;
-  virtual void EnableAppList() OVERRIDE;
+  virtual void EnableAppList(Profile* initial_profile) OVERRIDE;
   virtual gfx::NativeWindow GetAppListWindow() OVERRIDE;
   virtual AppListControllerDelegate* CreateControllerDelegate() OVERRIDE;
 
@@ -883,7 +883,7 @@
       chrome_launcher_support::UninstallLegacyAppLauncher(
           chrome_launcher_support::USER_LEVEL_INSTALLATION);
     }
-    EnableAppList();
+    EnableAppList(initial_profile);
   }
 #endif
 
@@ -895,7 +895,7 @@
   MigrateAppLauncherEnabledPref();
 
   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAppList))
-    EnableAppList();
+    EnableAppList(initial_profile);
 
   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableAppList))
     DisableAppList();
@@ -905,7 +905,8 @@
   return current_view_ && current_view_->GetWidget()->IsVisible();
 }
 
-void AppListController::EnableAppList() {
+void AppListController::EnableAppList(Profile* initial_profile) {
+  SaveProfilePathToLocalState(initial_profile->GetPath());
   // Check if the app launcher shortcuts have ever been created before.
   // Shortcuts should only be created once. If the user unpins the taskbar
   // shortcut, they can restore it by pinning the start menu or desktop
diff --git a/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc
index 877817c..50eba0c 100644
--- a/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc
+++ b/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc
@@ -9,7 +9,6 @@
 #include "base/command_line.h"
 #include "base/lazy_instance.h"
 #include "chrome/browser/chrome_browser_main.h"
-#include "chrome/browser/toolkit_extra_parts.h"
 #include "chrome/browser/ui/ash/ash_init.h"
 #include "chrome/browser/ui/ash/ash_util.h"
 #include "chrome/browser/ui/views/ash/tab_scrubber.h"
@@ -100,11 +99,3 @@
 void ChromeBrowserMainExtraPartsAsh::PostMainMessageLoopRun() {
   chrome::CloseAsh();
 }
-
-namespace chrome {
-
-void AddAshToolkitExtraParts(ChromeBrowserMainParts* main_parts) {
-  main_parts->AddParts(new ChromeBrowserMainExtraPartsAsh());
-}
-
-}  // namespace chrome
diff --git a/chrome/browser/ui/views/ash/tab_scrubber.cc b/chrome/browser/ui/views/ash/tab_scrubber.cc
index 9b3e540..5b106d2 100644
--- a/chrome/browser/ui/views/ash/tab_scrubber.cc
+++ b/chrome/browser/ui/views/ash/tab_scrubber.cc
@@ -7,13 +7,13 @@
 #include "ash/shell.h"
 #include "ash/wm/window_util.h"
 #include "base/metrics/histogram.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/tabs/tab.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/ui/views/autofill/autofill_credit_card_bubble_views.cc b/chrome/browser/ui/views/autofill/autofill_credit_card_bubble_views.cc
new file mode 100644
index 0000000..13f5ae5
--- /dev/null
+++ b/chrome/browser/ui/views/autofill/autofill_credit_card_bubble_views.cc
@@ -0,0 +1,106 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/autofill/autofill_credit_card_bubble_views.h"
+
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
+#include "ui/gfx/font.h"
+#include "ui/gfx/insets.h"
+#include "ui/gfx/size.h"
+#include "ui/views/bubble/bubble_frame_view.h"
+#include "ui/views/controls/link.h"
+#include "ui/views/controls/styled_label.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/layout_constants.h"
+#include "ui/views/view.h"
+#include "ui/views/widget/widget.h"
+
+namespace autofill {
+
+AutofillCreditCardBubbleViews::~AutofillCreditCardBubbleViews() {}
+
+void AutofillCreditCardBubbleViews::Show() {
+  views::BubbleDelegateView::CreateBubble(this);
+  // TODO(dbeam): investigate why this steals focus from the web contents.
+
+  views::BubbleFrameView* frame_view = GetBubbleFrameView();
+  frame_view->SetTitle(controller_->BubbleTitle());
+
+  views::Widget* widget = GetWidget();
+  widget->SetSize(frame_view->GetPreferredSize());
+  // Calls |frame_view_->Layout()| if necessary.
+  frame_view->SetBoundsRect(frame_view->bounds());
+
+  widget->Show();
+}
+
+void AutofillCreditCardBubbleViews::Hide() {
+  GetWidget()->Close();
+}
+
+bool AutofillCreditCardBubbleViews::IsHiding() const {
+  return GetWidget() && GetWidget()->IsClosed();
+}
+
+void AutofillCreditCardBubbleViews::Init() {
+  SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0,
+                                        views::kRelatedControlVerticalSpacing));
+
+  views::StyledLabel::RangeStyleInfo bold;
+  bold.font_style = gfx::Font::BOLD;
+  const std::vector<ui::Range>& ranges = controller_->BubbleTextRanges();
+
+  views::StyledLabel* contents =
+      new views::StyledLabel(controller_->BubbleText(), NULL);
+  for (size_t i = 0; i < ranges.size(); ++i) {
+    contents->AddStyleRange(ranges[i], bold);
+  }
+  AddChildView(contents);
+
+  views::Link* link = new views::Link();
+  link->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  link->SetText(controller_->LinkText());
+  link->set_listener(this);
+  AddChildView(link);
+}
+
+gfx::Size AutofillCreditCardBubbleViews::GetPreferredSize() {
+  return gfx::Size(
+      AutofillCreditCardBubbleViews::kContentWidth,
+      GetHeightForWidth(AutofillCreditCardBubble::kContentWidth));
+}
+
+void AutofillCreditCardBubbleViews::LinkClicked(views::Link* source,
+                                                int event_flags) {
+  if (controller_)
+    controller_->OnLinkClicked();
+}
+
+// static
+base::WeakPtr<AutofillCreditCardBubble> AutofillCreditCardBubble::Create(
+    const base::WeakPtr<AutofillCreditCardBubbleController>& controller) {
+  AutofillCreditCardBubbleViews* bubble =
+      new AutofillCreditCardBubbleViews(controller);
+  return bubble->weak_ptr_factory_.GetWeakPtr();
+}
+
+AutofillCreditCardBubbleViews::AutofillCreditCardBubbleViews(
+    const base::WeakPtr<AutofillCreditCardBubbleController>& controller)
+    : BubbleDelegateView(BrowserView::GetBrowserViewForBrowser(
+          chrome::FindBrowserWithWebContents(controller->web_contents()))->
+              GetLocationBarView()->autofill_credit_card_view(),
+        views::BubbleBorder::TOP_RIGHT),
+      controller_(controller),
+      weak_ptr_factory_(this) {
+  // Match bookmarks bubble view's anchor view insets and margins.
+  set_anchor_view_insets(gfx::Insets(7, 0, 7, 0));
+  set_margins(gfx::Insets(0, 19, 18, 18));
+  set_move_with_anchor(true);
+}
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/autofill_credit_card_bubble_views.h b/chrome/browser/ui/views/autofill/autofill_credit_card_bubble_views.h
new file mode 100644
index 0000000..c5d0fb6
--- /dev/null
+++ b/chrome/browser/ui/views/autofill/autofill_credit_card_bubble_views.h
@@ -0,0 +1,57 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_AUTOFILL_CREDIT_CARD_BUBBLE_VIEWS_H_
+#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_AUTOFILL_CREDIT_CARD_BUBBLE_VIEWS_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble.h"
+#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/controls/link_listener.h"
+
+namespace autofill {
+
+class AutofillCreditCardBubbleController;
+
+// Views toolkit implementation of AutofillCreditCard bubble (an educational
+// bubble shown after a successful submission of the Autofill dialog).
+class AutofillCreditCardBubbleViews : public AutofillCreditCardBubble,
+                                      public views::BubbleDelegateView,
+                                      public views::LinkListener {
+ public:
+  virtual ~AutofillCreditCardBubbleViews();
+
+  // AutofillCreditCardBubble:
+  virtual void Show() OVERRIDE;
+  virtual void Hide() OVERRIDE;
+  virtual bool IsHiding() const OVERRIDE;
+
+  // views::BubbleDelegateView:
+  virtual void Init() OVERRIDE;
+  virtual gfx::Size GetPreferredSize() OVERRIDE;
+
+  // views::LinkListener:
+  virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
+
+ private:
+  friend base::WeakPtr<AutofillCreditCardBubble>
+      AutofillCreditCardBubble::Create(
+          const base::WeakPtr<AutofillCreditCardBubbleController>& controller);
+
+  explicit AutofillCreditCardBubbleViews(
+     const base::WeakPtr<AutofillCreditCardBubbleController>& controller);
+
+  // Controller that drives this bubble. Invalid when hiding.
+  base::WeakPtr<AutofillCreditCardBubbleController> controller_;
+
+  base::WeakPtrFactory<AutofillCreditCardBubble> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(AutofillCreditCardBubbleViews);
+};
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_VIEWS_AUTOFILL_AUTOFILL_CREDIT_CARD_BUBBLE_VIEWS_H_
diff --git a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
index 0bd2fd0..a3523a6 100644
--- a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
+++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
@@ -23,7 +23,6 @@
 #include "grit/theme_resources.h"
 #include "grit/ui_resources.h"
 #include "third_party/skia/include/core/SkColor.h"
-#include "ui/base/animation/animation_delegate.h"
 #include "ui/base/animation/multi_animation.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/combobox_model.h"
@@ -68,29 +67,29 @@
 const int kAroundTextPadding = 4;
 
 // Padding around icons inside DecoratedTextfields.
-const size_t kTextfieldIconPadding = 3;
+const int kTextfieldIconPadding = 3;
 
 // Size of the triangular mark that indicates an invalid textfield (in pixels).
-const size_t kDogEarSize = 10;
+const int kDogEarSize = 10;
 
 // The space between the edges of a notification bar and the text within (in
 // pixels).
-const size_t kNotificationPadding = 14;
+const int kNotificationPadding = 14;
 
 // Vertical padding above and below each detail section (in pixels).
-const size_t kDetailSectionInset = 10;
+const int kDetailSectionInset = 10;
 
-const size_t kAutocheckoutStepsAreaPadding = 28;
-const size_t kAutocheckoutStepInset = 20;
+const int kAutocheckoutStepsAreaPadding = 28;
+const int kAutocheckoutStepInset = 20;
 
-const size_t kAutocheckoutProgressBarWidth = 375;
-const size_t kAutocheckoutProgressBarHeight = 15;
+const int kAutocheckoutProgressBarWidth = 375;
+const int kAutocheckoutProgressBarHeight = 15;
 
-const size_t kArrowHeight = 7;
-const size_t kArrowWidth = 2 * kArrowHeight;
+const int kArrowHeight = 7;
+const int kArrowWidth = 2 * kArrowHeight;
 
 // The padding around the edges of the legal documents text, in pixels.
-const size_t kLegalDocPadding = 20;
+const int kLegalDocPadding = 20;
 
 // Slight shading for mouse hover and legal document background.
 SkColor kShadingColor = SkColorSetARGB(7, 0, 0, 0);
@@ -99,13 +98,23 @@
 SkColor kSubtleBorderColor = SkColorSetARGB(10, 0, 0, 0);
 
 // The top padding, in pixels, for the suggestions menu dropdown arrows.
-const size_t kMenuButtonTopOffset = 5;
+const int kMenuButtonTopOffset = 5;
 
 // The side padding, in pixels, for the suggestions menu dropdown arrows.
-const size_t kMenuButtonHorizontalPadding = 20;
+const int kMenuButtonHorizontalPadding = 20;
+
+// The padding around text in the overlay view.
+const int kOverlayTextPadding = 20;
+
+// Spacing between lines of text in the overlay view.
+const int kOverlayTextInterlineSpacing = 10;
 
 const char kDecoratedTextfieldClassName[] = "autofill/DecoratedTextfield";
 const char kNotificationAreaClassName[] = "autofill/NotificationArea";
+const char kOverlayViewClassName[] = "autofill/OverlayView";
+
+typedef ui::MultiAnimation::Part Part;
+typedef ui::MultiAnimation::Parts Parts;
 
 views::Border* CreateLabelAlignmentBorder() {
   // TODO(estade): this should be made to match the native textfield top
@@ -125,99 +134,17 @@
 // Draws an arrow at the top of |canvas| pointing to |tip_x|.
 void DrawArrow(gfx::Canvas* canvas, int tip_x, const SkColor& color) {
   const int arrow_half_width = kArrowWidth / 2.0f;
-  const int arrow_middle = tip_x - arrow_half_width;
 
   SkPath arrow;
-  arrow.moveTo(arrow_middle - arrow_half_width, kArrowHeight);
-  arrow.lineTo(arrow_middle + arrow_half_width, kArrowHeight);
-  arrow.lineTo(arrow_middle, 0);
+  arrow.moveTo(tip_x, 0);
+  arrow.rLineTo(arrow_half_width, kArrowHeight);
+  arrow.rLineTo(-kArrowWidth, 0);
   arrow.close();
-  canvas->ClipPath(arrow);
-  canvas->DrawColor(color);
+  SkPaint paint;
+  paint.setColor(color);
+  canvas->DrawPath(arrow, paint);
 }
 
-typedef ui::MultiAnimation::Part Part;
-typedef ui::MultiAnimation::Parts Parts;
-
-class OverlayView : public views::View,
-                    public ui::AnimationDelegate {
- public:
-  OverlayView() {
-    SetLayoutManager(new views::FillLayout());
-
-    set_background(views::Background::CreateSolidBackground(GetNativeTheme()->
-        GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)));
-
-    Parts parts;
-    // For this part of the animation, simply show the splash image.
-    parts.push_back(Part(kSplashDisplayDurationMs, ui::Tween::ZERO));
-    // For this part of the animation, fade out the splash image.
-    parts.push_back(Part(kSplashFadeOutDurationMs, ui::Tween::EASE_IN));
-    // For this part of the animation, fade out |this| (fade in the dialog).
-    parts.push_back(Part(kSplashFadeInDialogDurationMs, ui::Tween::EASE_OUT));
-    fade_out_.reset(
-        new ui::MultiAnimation(parts,
-                               ui::MultiAnimation::GetDefaultTimerInterval()));
-    fade_out_->set_delegate(this);
-    fade_out_->set_continuous(false);
-    fade_out_->Start();
-  }
-
-  virtual ~OverlayView() {}
-
-  // ui::AnimationDelegate implementation:
-  virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE {
-    DCHECK_EQ(animation, fade_out_.get());
-    if (fade_out_->current_part_index() != 0)
-      SchedulePaint();
-  }
-
-  virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE {
-    DCHECK_EQ(animation, fade_out_.get());
-    SetVisible(false);
-  }
-
-  // views::View implementation:
-  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
-    // BubbleFrameView doesn't mask the window, it just draws the border via
-    // image assets. Match that rounding here.
-    static const SkScalar kCornerRadius = SkIntToScalar(2);
-    gfx::Rect rect =
-        GetWidget()->non_client_view()->frame_view()->GetLocalBounds();
-    rect.Inset(12, 12, 12, 12);
-    gfx::Path window_mask;
-    window_mask.addRoundRect(gfx::RectToSkRect(rect),
-                             kCornerRadius, kCornerRadius);
-    canvas->ClipPath(window_mask);
-
-    if (fade_out_->current_part_index() == 2) {
-      canvas->SaveLayerAlpha((1 - fade_out_->GetCurrentValue()) * 255);
-      views::View::OnPaint(canvas);
-      canvas->Restore();
-    } else {
-      views::View::OnPaint(canvas);
-    }
-  }
-
-  virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE {
-    if (fade_out_->current_part_index() == 0) {
-      views::View::PaintChildren(canvas);
-    } else if (fade_out_->current_part_index() == 1) {
-      canvas->SaveLayerAlpha((1 - fade_out_->GetCurrentValue()) * 255);
-      views::View::PaintChildren(canvas);
-      canvas->Restore();
-    }
-  }
-
- private:
-  // This MultiAnimation is used to first fade out the contents of the overlay,
-  // then fade out the background of the overlay (revealing the dialog behind
-  // the overlay). This avoids cross-fade.
-  scoped_ptr<ui::MultiAnimation> fade_out_;
-
-  DISALLOW_COPY_AND_ASSIGN(OverlayView);
-};
-
 // This class handles layout for the first row of a SuggestionView.
 // It exists to circumvent shortcomings of GridLayout and BoxLayout (namely that
 // the former doesn't fully respect child visibility, and that the latter won't
@@ -349,14 +276,14 @@
     const int kColumnSetId = 0;
     views::ColumnSet* columns = layout->AddColumnSet(kColumnSetId);
     columns->AddColumn(views::GridLayout::LEADING,
-                       views::GridLayout::LEADING,
+                       views::GridLayout::CENTER,
                        0,
                        views::GridLayout::USE_PREF,
                        0,
                        0);
     columns->AddPaddingColumn(0, 8);
     columns->AddColumn(views::GridLayout::LEADING,
-                       views::GridLayout::LEADING,
+                       views::GridLayout::CENTER,
                        0,
                        views::GridLayout::USE_PREF,
                        0,
@@ -609,6 +536,186 @@
   controller_->SignInLinkClicked();
 }
 
+// AutofillDialogViews::OverlayView --------------------------------------------
+
+AutofillDialogViews::OverlayView::OverlayView(views::ButtonListener* listener)
+    : image_view_(new views::ImageView()),
+      message_stack_(new views::View()),
+      button_(new views::LabelButton(listener, string16())) {
+  set_border(views::Border::CreateEmptyBorder(12, 12, 12, 12));
+  set_background(views::Background::CreateSolidBackground(GetNativeTheme()->
+      GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)));
+
+  AddChildView(image_view_);
+
+  AddChildView(message_stack_);
+  message_stack_->SetLayoutManager(
+      new views::BoxLayout(views::BoxLayout::kVertical, 0, 0,
+                           kOverlayTextInterlineSpacing));
+  message_stack_->set_border(views::Border::CreateEmptyBorder(
+      kOverlayTextPadding, kOverlayTextPadding, 0, kOverlayTextPadding));
+
+  AddChildView(button_);
+  button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
+  button_->set_focusable(true);
+}
+
+AutofillDialogViews::OverlayView::~OverlayView() {}
+
+void AutofillDialogViews::OverlayView::SetState(
+    const DialogOverlayState& state,
+    views::ButtonListener* listener) {
+  // Don't update anything if we're still fading out the old state.
+  if (fade_out_)
+    return;
+
+  if (state.image.IsEmpty()) {
+    SetVisible(false);
+    return;
+  }
+
+  image_view_->SetImage(state.image.ToImageSkia());
+
+  message_stack_->RemoveAllChildViews(true);
+  for (size_t i = 0; i < state.strings.size(); ++i) {
+    views::Label* label = new views::Label();
+    label->SetAutoColorReadabilityEnabled(false);
+    label->SetMultiLine(true);
+    label->SetText(state.strings[i].text);
+    label->SetFont(state.strings[i].font);
+    label->SetEnabledColor(state.strings[i].text_color);
+    label->SetHorizontalAlignment(state.strings[i].alignment);
+    message_stack_->AddChildView(label);
+  }
+  message_stack_->SetVisible(message_stack_->child_count() > 0);
+
+  button_->SetVisible(!state.button_text.empty());
+  if (!state.button_text.empty())
+    button_->SetText(state.button_text);
+
+  SetVisible(true);
+  if (parent())
+    parent()->Layout();
+}
+
+void AutofillDialogViews::OverlayView::BeginFadeOut() {
+  Parts parts;
+  // For this part of the animation, simply show the splash image.
+  parts.push_back(Part(kSplashDisplayDurationMs, ui::Tween::ZERO));
+  // For this part of the animation, fade out the splash image.
+  parts.push_back(Part(kSplashFadeOutDurationMs, ui::Tween::EASE_IN));
+  // For this part of the animation, fade out |this| (fade in the dialog).
+  parts.push_back(Part(kSplashFadeInDialogDurationMs, ui::Tween::EASE_OUT));
+  fade_out_.reset(
+      new ui::MultiAnimation(parts,
+                             ui::MultiAnimation::GetDefaultTimerInterval()));
+  fade_out_->set_delegate(this);
+  fade_out_->set_continuous(false);
+  fade_out_->Start();
+}
+
+void AutofillDialogViews::OverlayView::AnimationProgressed(
+    const ui::Animation* animation) {
+  DCHECK_EQ(animation, fade_out_.get());
+  if (fade_out_->current_part_index() != 0)
+    SchedulePaint();
+}
+
+void AutofillDialogViews::OverlayView::AnimationEnded(
+    const ui::Animation* animation) {
+  DCHECK_EQ(animation, fade_out_.get());
+  SetVisible(false);
+  fade_out_.reset();
+}
+
+void AutofillDialogViews::OverlayView::Layout() {
+  gfx::Rect bounds = GetContentsBounds();
+  if (!message_stack_->visible()) {
+    image_view_->SetBoundsRect(bounds);
+    return;
+  }
+
+  int y = bounds.bottom() - views::kButtonVEdgeMarginNew;
+  if (button_->visible()) {
+    button_->SizeToPreferredSize();
+    y -= button_->height();
+    button_->SetPosition(gfx::Point(
+        bounds.width() - button_->width() -
+            views::kButtonHEdgeMarginNew,
+        y));
+    y -= views::kButtonVEdgeMarginNew;
+  }
+
+  int message_height = message_stack_->GetHeightForWidth(bounds.width());
+  y -= message_height;
+  message_stack_->SetBounds(bounds.x(), y, bounds.width(), message_height);
+
+  gfx::Size image_size = image_view_->GetPreferredSize();
+  const int kImageBottomMargin = 50;
+  y -= image_size.height() + kImageBottomMargin;
+  image_view_->SetBounds(bounds.x(), y, bounds.width(), image_size.height());
+}
+
+const char* AutofillDialogViews::OverlayView::GetClassName() const {
+  return kOverlayViewClassName;
+}
+
+void AutofillDialogViews::OverlayView::OnPaint(gfx::Canvas* canvas) {
+  // BubbleFrameView doesn't mask the window, it just draws the border via
+  // image assets. Match that rounding here.
+  static const SkScalar kCornerRadius = SkIntToScalar(2);
+  gfx::Rect rect = GetContentsBounds();
+  gfx::Path window_mask;
+  window_mask.addRoundRect(gfx::RectToSkRect(rect),
+                           kCornerRadius, kCornerRadius);
+  canvas->ClipPath(window_mask);
+
+  // Fade out background (i.e. fade in what's behind |this|).
+  if (fade_out_ && fade_out_->current_part_index() == 2)
+    canvas->SaveLayerAlpha((1 - fade_out_->GetCurrentValue()) * 255);
+
+  OnPaintBackground(canvas);
+
+  // Draw the arrow, border, and fill for the bottom area.
+  if (message_stack_->visible()) {
+    const int arrow_half_width = kArrowWidth / 2.0f;
+    SkPath arrow;
+    int y = message_stack_->y() - 1;
+    // Note that we purposely draw slightly outside of |rect| so that the
+    // stroke is hidden on the sides.
+    arrow.moveTo(rect.x() - 1, y);
+    arrow.rLineTo(rect.width() / 2 - arrow_half_width, 0);
+    arrow.rLineTo(arrow_half_width, -kArrowHeight);
+    arrow.rLineTo(arrow_half_width, kArrowHeight);
+    arrow.lineTo(rect.right() + 1, y);
+    arrow.lineTo(rect.right() + 1, rect.bottom() + 1);
+    arrow.lineTo(rect.x() - 1, rect.bottom() + 1);
+    arrow.close();
+
+    SkPaint paint;
+    paint.setColor(kShadingColor);
+    paint.setStyle(SkPaint::kFill_Style);
+    canvas->DrawPath(arrow, paint);
+    paint.setColor(kSubtleBorderColor);
+    paint.setStyle(SkPaint::kStroke_Style);
+    canvas->DrawPath(arrow, paint);
+  }
+
+  PaintChildren(canvas);
+}
+
+void AutofillDialogViews::OverlayView::PaintChildren(gfx::Canvas* canvas) {
+  // Don't draw children.
+  if (fade_out_ && fade_out_->current_part_index() == 2)
+    return;
+
+  // Fade out children.
+  if (fade_out_ && fade_out_->current_part_index() == 1)
+    canvas->SaveLayerAlpha((1 - fade_out_->GetCurrentValue()) * 255);
+
+  views::View::PaintChildren(canvas);
+}
+
 // AutofillDialogViews::NotificationArea ---------------------------------------
 
 AutofillDialogViews::NotificationArea::NotificationArea(
@@ -1003,21 +1110,19 @@
   focus_manager_ = window_->GetFocusManager();
   focus_manager_->AddFocusChangeListener(this);
 
-#if defined(OS_WIN) && !defined(USE_AURA)
-  // On non-Aura Windows a standard accelerator gets registered that will
-  // navigate on a backspace. Override that here.
-  // TODO(abodenha): Remove this when no longer needed. See
-  // http://crbug.com/242584.
-  ui::Accelerator backspace(ui::VKEY_BACK, ui::EF_NONE);
-  focus_manager_->RegisterAccelerator(
-      backspace, ui::AcceleratorManager::kNormalPriority, this);
-#endif
-
   // Listen for size changes on the browser.
   views::Widget* browser_widget =
       views::Widget::GetTopLevelWidgetForNativeView(
           controller_->web_contents()->GetView()->GetNativeView());
   observer_.Add(browser_widget);
+
+  gfx::Image splash_image = controller_->SplashPageImage();
+  if (!splash_image.IsEmpty()) {
+    DialogOverlayState state;
+    state.image = splash_image;
+    overlay_view_->SetState(state, NULL);
+    overlay_view_->BeginFadeOut();
+  }
 }
 
 void AutofillDialogViews::Hide() {
@@ -1069,6 +1174,9 @@
   autocheckout_progress_bar_view_->SetVisible(
       controller_->ShouldShowProgressBar());
   GetDialogClientView()->UpdateDialogButtons();
+
+  overlay_view_->SetState(controller_->GetDialogOverlay(), this);
+
   ContentsPreferredSizeChanged();
 }
 
@@ -1149,6 +1257,7 @@
   sign_in_webview_->LoadInitialURL(wallet::GetSignInUrl());
 
   sign_in_webview_->SetVisible(true);
+  sign_in_webview_->RequestFocus();
   UpdateButtonStrip();
   ContentsPreferredSizeChanged();
   return &sign_in_webview_->web_contents()->GetController();
@@ -1187,8 +1296,7 @@
 }
 
 void AutofillDialogViews::CancelForTesting() {
-  if (Cancel())
-    Hide();
+  GetDialogClientView()->CancelWindow();
 }
 
 string16 AutofillDialogViews::GetTextContentsOfInput(const DetailInput& input) {
@@ -1243,18 +1351,6 @@
   return GetWidget() ? GetWidget()->GetRootView()->size() : gfx::Size();
 }
 
-bool AutofillDialogViews::AcceleratorPressed(
-    const ui::Accelerator& accelerator) {
-  ui::KeyboardCode key = accelerator.key_code();
-  if (key == ui::VKEY_BACK)
-    return true;
-  return false;
-}
-
-bool AutofillDialogViews::CanHandleAccelerators() const {
-  return true;
-}
-
 gfx::Size AutofillDialogViews::GetPreferredSize() {
   gfx::Insets insets = GetInsets();
   gfx::Size scroll_size = scrollable_area_->contents()->GetPreferredSize();
@@ -1394,6 +1490,8 @@
       views::Background::CreateSolidBackground(kShadingColor));
 
   legal_document_view_ = new views::StyledLabel(string16(), this);
+  legal_document_view_->SetDisplayedOnBackgroundColor(kShadingColor);
+
   footnote_view_->AddChildView(legal_document_view_);
   footnote_view_->SetVisible(false);
 
@@ -1401,15 +1499,6 @@
 }
 
 views::View* AutofillDialogViews::CreateOverlayView() {
-  gfx::Image splash_image = controller_->SplashPageImage();
-  if (splash_image.IsEmpty())
-    return NULL;
-
-  overlay_view_ = new OverlayView();
-  views::ImageView* image = new views::ImageView();
-  image->SetImage(splash_image.ToImageSkia());
-  overlay_view_->AddChildView(image);
-
   return overlay_view_;
 }
 
@@ -1439,6 +1528,11 @@
 
 void AutofillDialogViews::ButtonPressed(views::Button* sender,
                                         const ui::Event& event) {
+  if (sender->GetAncestorWithClassName(kOverlayViewClassName)) {
+    controller_->OverlayButtonPressed();
+    return;
+  }
+
   // TODO(estade): Should the menu be shown on mouse down?
   DetailsGroup* group = NULL;
   for (DetailGroupMap::iterator iter = detail_groups_.begin();
@@ -1544,11 +1638,21 @@
   button_strip_extra_view_->AddChildView(save_in_chrome_checkbox_);
 
   autocheckout_progress_bar_view_ = new views::View();
-  autocheckout_progress_bar_view_->SetLayoutManager(
-      new views::BoxLayout(views::BoxLayout::kVertical, 0, 15, 0));
+  views::GridLayout* progress_bar_layout =
+      new views::GridLayout(autocheckout_progress_bar_view_);
+  autocheckout_progress_bar_view_->SetLayoutManager(progress_bar_layout);
+  const int kColumnSetId = 0;
+  views::ColumnSet* columns = progress_bar_layout->AddColumnSet(kColumnSetId);
+  columns->AddColumn(views::GridLayout::LEADING,
+                     views::GridLayout::CENTER,
+                     0,
+                     views::GridLayout::USE_PREF,
+                     0,
+                     0);
+  progress_bar_layout->StartRow(1.0, kColumnSetId);
 
   autocheckout_progress_bar_ = new AutocheckoutProgressBar();
-  autocheckout_progress_bar_view_->AddChildView(autocheckout_progress_bar_);
+  progress_bar_layout->AddView(autocheckout_progress_bar_);
 
   button_strip_extra_view_->AddChildView(autocheckout_progress_bar_view_);
   autocheckout_progress_bar_view_->SetVisible(false);
@@ -1581,6 +1685,9 @@
   sign_in_delegate_.reset(
       new AutofillDialogSignInDelegate(this,
                                        sign_in_webview_->GetWebContents()));
+
+  overlay_view_ = new OverlayView(this);
+  overlay_view_->SetVisible(false);
 }
 
 views::View* AutofillDialogViews::CreateDetailsContainer() {
diff --git a/chrome/browser/ui/views/autofill/autofill_dialog_views.h b/chrome/browser/ui/views/autofill/autofill_dialog_views.h
index ef7d115..626d21a 100644
--- a/chrome/browser/ui/views/autofill/autofill_dialog_views.h
+++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.h
@@ -12,7 +12,7 @@
 #include "chrome/browser/ui/autofill/autofill_dialog_controller.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_view.h"
 #include "chrome/browser/ui/autofill/testable_autofill_dialog_view.h"
-#include "ui/base/accelerators/accelerator.h"
+#include "ui/base/animation/animation_delegate.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/button/menu_button_listener.h"
 #include "ui/views/controls/combobox/combobox_listener.h"
@@ -42,6 +42,7 @@
 class ImageButton;
 class ImageView;
 class Label;
+class LabelButton;
 class Link;
 class MenuRunner;
 class StyledLabel;
@@ -52,6 +53,7 @@
 namespace ui {
 class ComboboxModel;
 class KeyEvent;
+class MultiAnimation;
 }
 
 namespace autofill {
@@ -109,10 +111,6 @@
   virtual void ActivateInput(const DetailInput& input) OVERRIDE;
   virtual gfx::Size GetSize() const OVERRIDE;
 
-  // ui::AcceleratorTarget implementation:
-  virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
-  virtual bool CanHandleAccelerators() const OVERRIDE;
-
   // views::View implementation.
   virtual gfx::Size GetPreferredSize() OVERRIDE;
   virtual void Layout() OVERRIDE;
@@ -272,6 +270,48 @@
     DISALLOW_COPY_AND_ASSIGN(AccountChooser);
   };
 
+  // A view which displays an image, optionally some messages and a button. Used
+  // for the splash page as well as the Wallet interstitial.
+  class OverlayView : public views::View,
+                      public ui::AnimationDelegate {
+   public:
+    // The listener is informed when |button_| is pressed.
+    explicit OverlayView(views::ButtonListener* listener);
+    virtual ~OverlayView();
+
+    // Sets properties that should be displayed.
+    void SetState(const DialogOverlayState& state,
+                  views::ButtonListener* listener);
+
+    // Fades the view out after a delay.
+    void BeginFadeOut();
+
+    // ui::AnimationDelegate implementation:
+    virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
+    virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE;
+
+    // views::View implementation:
+    virtual void Layout() OVERRIDE;
+    virtual const char* GetClassName() const OVERRIDE;
+    virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
+    virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE;
+
+   private:
+    // Child View. Front and center.
+    views::ImageView* image_view_;
+    // Child View. When visible, below |image_view_|.
+    views::View* message_stack_;
+    // Child View. When visible, below |message_stack_|.
+    views::LabelButton* button_;
+
+    // This MultiAnimation is used to first fade out the contents of the
+    // overlay, then fade out the background of the overlay (revealing the
+    // dialog behind the overlay). This avoids cross-fade.
+    scoped_ptr<ui::MultiAnimation> fade_out_;
+
+    DISALLOW_COPY_AND_ASSIGN(OverlayView);
+  };
+
   // An area for notifications. Some notifications point at the account chooser.
   class NotificationArea : public views::View,
                            public views::ButtonListener {
@@ -565,7 +605,7 @@
   views::Label* loading_shield_;
 
   // The view that completely overlays the dialog (used for the splash page).
-  views::View* overlay_view_;
+  OverlayView* overlay_view_;
 
   // The "Extra view" is on the same row as the dialog buttons.
   views::View* button_strip_extra_view_;
diff --git a/chrome/browser/ui/views/avatar_label.cc b/chrome/browser/ui/views/avatar_label.cc
index 11a7056..1b4bf9f 100644
--- a/chrome/browser/ui/views/avatar_label.cc
+++ b/chrome/browser/ui/views/avatar_label.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/ui/views/avatar_menu_bubble_view.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
 #include "ui/base/events/event.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -27,32 +28,33 @@
   virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE;
 
  private:
-  scoped_ptr<views::Painter> hot_painter_;
   scoped_ptr<views::Painter> painter_;
 
   DISALLOW_COPY_AND_ASSIGN(AvatarLabelBorder);
 };
 
 AvatarLabelBorder::AvatarLabelBorder(ui::ThemeProvider* theme_provider) {
-  const int kHorizontalInset = 10;
-  const int kVerticalInset = 2;
-  SetInsets(gfx::Insets(
-      kVerticalInset, kHorizontalInset, kVerticalInset, kHorizontalInset));
-  SkColor color = theme_provider->GetColor(
-      ThemeProperties::COLOR_MANAGED_USER_LABEL_BACKGROUND);
-  SkColor color2 = color_utils::BlendTowardOppositeLuminance(color, 0x20);
-  painter_.reset(views::Painter::CreateVerticalGradient(color, color2));
-  hot_painter_.reset(views::Painter::CreateVerticalGradient(color2, color));
+  const int kHorizontalInsetRight = 10;
+  const int kHorizontalInsetLeft = 43;
+  const int kVerticalInsetTop = 3;
+  const int kVerticalInsetBottom = 3;
+  // We want to align with the top of the tab. This works if the BaseFont size
+  // is 13. If it is smaller, we need to increase the TopInset accordingly.
+  gfx::Font font = ui::ResourceBundle::GetSharedInstance().GetFont(
+      ui::ResourceBundle::BaseFont);
+  int difference = (font.GetFontSize() < 13) ? 13 - font.GetFontSize() : 0;
+  int addToTop = difference / 2;
+  int addToBottom = difference - addToTop;
+  SetInsets(gfx::Insets(kVerticalInsetTop + addToTop,
+                        kHorizontalInsetLeft,
+                        kVerticalInsetBottom + addToBottom,
+                        kHorizontalInsetRight));
+  const int kImages[] = IMAGE_GRID(IDR_MANAGED_USER_LABEL);
+  painter_.reset(views::Painter::CreateImageGridPainter(kImages));
 }
 
 void AvatarLabelBorder::Paint(const views::View& view, gfx::Canvas* canvas) {
-  const views::TextButton* button =
-      static_cast<const views::TextButton*>(&view);
-  if (button->state() == views::TextButton::STATE_HOVERED ||
-      button->state() == views::TextButton::STATE_PRESSED)
-    hot_painter_->Paint(canvas, view.size());
-  else
-    painter_->Paint(canvas, view.size());
+  painter_->Paint(canvas, view.size());
 }
 
 }  // namespace
@@ -64,7 +66,7 @@
       browser_view_(browser_view),
       theme_provider_(theme_provider) {
   SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
-      ui::ResourceBundle::SmallFont));
+      ui::ResourceBundle::BaseFont));
   ClearMaxTextSize();
   set_border(new AvatarLabelBorder(theme_provider));
   UpdateLabelStyle();
diff --git a/chrome/browser/ui/views/avatar_menu_button.cc b/chrome/browser/ui/views/avatar_menu_button.cc
index a638186..323d2e1 100644
--- a/chrome/browser/ui/views/avatar_menu_button.cc
+++ b/chrome/browser/ui/views/avatar_menu_button.cc
@@ -7,16 +7,15 @@
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/command_updater.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/avatar_menu_model.h"
 #include "chrome/browser/profiles/profile_info_util.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profile_metrics.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/views/avatar_menu_bubble_view.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/profile_chooser_view.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
 #include "ui/gfx/canvas.h"
@@ -97,8 +96,7 @@
   gfx::Point origin;
   views::View::ConvertPointToScreen(this, &origin);
   gfx::Rect bounds(origin, size());
-  if (CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kNewProfileManagement)) {
+  if (ProfileManager::IsNewProfileManagementEnabled()) {
     ProfileChooserView::ShowBubble(
         this, views::BubbleBorder::TOP_LEFT,
         views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR, bounds, browser_);
diff --git a/chrome/browser/ui/views/avatar_menu_button_browsertest.cc b/chrome/browser/ui/views/avatar_menu_button_browsertest.cc
index 611995e..9628c1d 100644
--- a/chrome/browser/ui/views/avatar_menu_button_browsertest.cc
+++ b/chrome/browser/ui/views/avatar_menu_button_browsertest.cc
@@ -7,13 +7,13 @@
 #include "base/command_line.h"
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/avatar_menu_model.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/views/avatar_menu_bubble_view.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/profile_chooser_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -74,7 +74,7 @@
   base::FilePath path;
   PathService::Get(chrome::DIR_USER_DATA, &path);
   path = path.AppendASCII("test_profile");
-  if (!file_util::PathExists(path))
+  if (!base::PathExists(path))
     ASSERT_TRUE(file_util::CreateDirectory(path));
   Profile* profile =
       Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
index 81b4a3b..f65154e 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/bookmarks/bookmark_utils.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
@@ -34,6 +35,8 @@
 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
+#include "chrome/browser/ui/omnibox/omnibox_view.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/view_ids.h"
 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_instructions_view.h"
@@ -43,7 +46,6 @@
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
@@ -669,6 +671,19 @@
   return LayoutItems(true);
 }
 
+bool BookmarkBarView::HitTestRect(const gfx::Rect& rect) const {
+  // If bookmark bar is attached and omnibox popup is open (on top of the bar),
+  // force hit-testing to fail.  This prevents hovers/clicks just above the
+  // omnibox popup from activating the top few pixels of items on the bookmark
+  // bar.
+  if (!IsDetached() && browser_view_ &&
+      browser_view_->GetLocationBar()->GetLocationEntry()->model()->
+          popup_model()->IsOpen()) {
+    return false;
+  }
+  return DetachableToolbarView::HitTestRect(rect);
+}
+
 gfx::Size BookmarkBarView::GetMinimumSize() {
   // The minimum width of the bookmark bar should at least contain the overflow
   // button, by which one can access all the Bookmark Bar items, and the "Other
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
index 72b0e2c..afea414 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
@@ -165,6 +165,7 @@
   // View methods:
   virtual gfx::Size GetPreferredSize() OVERRIDE;
   virtual gfx::Size GetMinimumSize() OVERRIDE;
+  virtual bool HitTestRect(const gfx::Rect& rect) const OVERRIDE;
   virtual void Layout() OVERRIDE;
   virtual void ViewHierarchyChanged(
       const ViewHierarchyChangedDetails& details) OVERRIDE;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
index d0b2ba8..c1f7053 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -11,6 +11,7 @@
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
 #include "chrome/browser/ui/browser.h"
@@ -19,7 +20,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
 #include "chrome/browser/ui/views/chrome_views_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
index 83923ec..da03710 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
@@ -9,10 +9,10 @@
 #include "base/compiler_specific.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h"
-#include "googleurl/src/gurl.h"
 #include "ui/views/bubble/bubble_delegate.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/combobox/combobox_listener.h"
+#include "url/gurl.h"
 
 class BookmarkBubbleViewObserver;
 class Profile;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc b/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc
index ca4a844..62aa8ca 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_context_menu.cc
@@ -8,7 +8,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
index 42c7d12..77819fe 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
@@ -20,7 +20,6 @@
 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
 #include "chrome/browser/ui/views/constrained_window_views.h"
 #include "components/user_prefs/user_prefs.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/locale_settings.h"
@@ -37,6 +36,7 @@
 #include "ui/views/layout/layout_constants.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/window/dialog_client_view.h"
+#include "url/gurl.h"
 
 using views::GridLayout;
 
diff --git a/chrome/browser/ui/views/browser_action_view.cc b/chrome/browser/ui/views/browser_action_view.cc
index 3f43bb9..14058e5 100644
--- a/chrome/browser/ui/views/browser_action_view.cc
+++ b/chrome/browser/ui/views/browser_action_view.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/views/browser_action_view.h"
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/commands/command_service.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
@@ -13,7 +14,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/views/browser_actions_container.h"
 #include "chrome/browser/ui/views/toolbar_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "grit/generated_resources.h"
@@ -22,6 +22,7 @@
 #include "ui/base/events/event.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/base/theme_provider.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_operations.h"
 #include "ui/gfx/image/image_skia_source.h"
@@ -51,7 +52,6 @@
   button_->set_drag_controller(delegate_);
   button_->set_owned_by_client();
   AddChildView(button_);
-  button_->UpdateState();
 }
 
 BrowserActionView::~BrowserActionView() {
@@ -71,6 +71,10 @@
   return action->GetIconWithBadge(icon, tab_id, spacing);
 }
 
+void BrowserActionView::UpdateState() {
+  button_->UpdateState();
+}
+
 void BrowserActionView::Layout() {
   // We can't rely on button_->GetPreferredSize() here because that's not set
   // correctly until the first call to
@@ -225,15 +229,15 @@
     if (!browser_action()->GetIsVisible(tab_id))
       icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25);
 
-    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+    ui::ThemeProvider* provider = GetThemeProvider();
 
-    gfx::ImageSkia bg = *rb.GetImageSkiaNamed(IDR_BROWSER_ACTION);
+    gfx::ImageSkia bg = *provider->GetImageSkiaNamed(IDR_BROWSER_ACTION);
     SetIcon(gfx::ImageSkiaOperations::CreateSuperimposedImage(bg, icon));
 
-    gfx::ImageSkia bg_h = *rb.GetImageSkiaNamed(IDR_BROWSER_ACTION_H);
+    gfx::ImageSkia bg_h = *provider->GetImageSkiaNamed(IDR_BROWSER_ACTION_H);
     SetHoverIcon(gfx::ImageSkiaOperations::CreateSuperimposedImage(bg_h, icon));
 
-    gfx::ImageSkia bg_p = *rb.GetImageSkiaNamed(IDR_BROWSER_ACTION_P);
+    gfx::ImageSkia bg_p = *provider->GetImageSkiaNamed(IDR_BROWSER_ACTION_P);
     SetPushedIcon(
         gfx::ImageSkiaOperations::CreateSuperimposedImage(bg_p, icon));
   }
diff --git a/chrome/browser/ui/views/browser_action_view.h b/chrome/browser/ui/views/browser_action_view.h
index 1b4e8e2..555267b 100644
--- a/chrome/browser/ui/views/browser_action_view.h
+++ b/chrome/browser/ui/views/browser_action_view.h
@@ -74,6 +74,9 @@
   // Gets browser action button icon with the badge.
   gfx::ImageSkia GetIconWithBadge();
 
+  // Updates the internal images used to draw this button.
+  void UpdateState();
+
   // Overridden from views::View:
   virtual void Layout() OVERRIDE;
   virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
diff --git a/chrome/browser/ui/views/browser_actions_container.cc b/chrome/browser/ui/views/browser_actions_container.cc
index 3a7c275..e82cfe5 100644
--- a/chrome/browser/ui/views/browser_actions_container.cc
+++ b/chrome/browser/ui/views/browser_actions_container.cc
@@ -158,6 +158,7 @@
     BrowserActionView* view = new BrowserActionView(i->get(), browser_, this);
     browser_action_views_.push_back(view);
     AddChildView(view);
+    view->UpdateState();
   }
 }
 
@@ -615,6 +616,7 @@
   BrowserActionView* view = new BrowserActionView(extension, browser_, this);
   browser_action_views_.insert(browser_action_views_.begin() + index, view);
   AddChildViewAt(view, index);
+  view->UpdateState();
 
   // If we are still initializing the container, don't bother animating.
   if (!model_->extensions_initialized())
diff --git a/chrome/browser/ui/views/browser_actions_container_browsertest.cc b/chrome/browser/ui/views/browser_actions_container_browsertest.cc
index 937c717..5f2b486 100644
--- a/chrome/browser/ui/views/browser_actions_container_browsertest.cc
+++ b/chrome/browser/ui/views/browser_actions_container_browsertest.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/ui/views/browser_actions_container.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
 #include "chrome/browser/extensions/browser_action_test_util.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/test/test_utils.h"
 
 using extensions::Extension;
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
index 5bdb592..3bf186f 100644
--- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
+++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h"
 
 #include "chrome/browser/chrome_browser_main.h"
-#include "chrome/browser/toolkit_extra_parts.h"
 #include "chrome/browser/ui/views/chrome_views_delegate.h"
 #include "chrome/common/chrome_switches.h"
 #include "ui/base/ui_base_switches.h"
@@ -19,11 +18,3 @@
   if (!views::ViewsDelegate::views_delegate)
     views::ViewsDelegate::views_delegate = new ChromeViewsDelegate;
 }
-
-namespace chrome {
-
-void AddViewsToolkitExtraParts(ChromeBrowserMainParts* main_parts) {
-  main_parts->AddParts(new ChromeBrowserMainExtraPartsViews());
-}
-
-}  // namespace chrome
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc
index 4f26860..4024245 100644
--- a/chrome/browser/ui/views/collected_cookies_views.cc
+++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_server_bound_cert_helper.h"
 #include "chrome/browser/browsing_data/cookies_tree_model.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/cookie_settings.h"
 #include "chrome/browser/content_settings/local_shared_objects_container.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
 #include "chrome/browser/ui/views/constrained_window_views.h"
 #include "chrome/browser/ui/views/cookie_info_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
@@ -522,7 +522,7 @@
   Profile* profile =
       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
   host_node->CreateContentException(
-      CookieSettings::Factory::GetForProfile(profile), setting);
+      CookieSettings::Factory::GetForProfile(profile).get(), setting);
   infobar_->UpdateVisibility(true, setting, host_node->GetTitle());
   status_changed_ = true;
 }
diff --git a/chrome/browser/ui/views/color_chooser_aura.cc b/chrome/browser/ui/views/color_chooser_aura.cc
index 4e9780c..637b367 100644
--- a/chrome/browser/ui/views/color_chooser_aura.cc
+++ b/chrome/browser/ui/views/color_chooser_aura.cc
@@ -101,7 +101,7 @@
     content::WebContents* web_contents, SkColor initial_color) {
   if (current_color_chooser_)
     current_color_chooser_->End();
-  DCHECK(current_color_chooser_);
+  DCHECK(!current_color_chooser_);
   current_color_chooser_ = new ColorChooserAura(web_contents, initial_color);
   return current_color_chooser_;
 }
diff --git a/chrome/browser/ui/views/conflicting_module_view_win.cc b/chrome/browser/ui/views/conflicting_module_view_win.cc
index f45b876..6c963a2 100644
--- a/chrome/browser/ui/views/conflicting_module_view_win.cc
+++ b/chrome/browser/ui/views/conflicting_module_view_win.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/ui/views/conflicting_module_view_win.h"

 

 #include "base/metrics/histogram.h"

+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/enumerate_modules_model_win.h"

 #include "chrome/browser/profiles/profile.h"

 #include "chrome/browser/ui/browser.h"

-#include "chrome/common/chrome_notification_types.h"

 #include "chrome/common/pref_names.h"

 #include "content/public/browser/notification_service.h"

 #include "content/public/browser/user_metrics.h"

diff --git a/chrome/browser/ui/views/conflicting_module_view_win.h b/chrome/browser/ui/views/conflicting_module_view_win.h
index f525307..118010f 100644
--- a/chrome/browser/ui/views/conflicting_module_view_win.h
+++ b/chrome/browser/ui/views/conflicting_module_view_win.h
@@ -7,9 +7,9 @@
 

 #include "content/public/browser/notification_observer.h"

 #include "content/public/browser/notification_registrar.h"

-#include "googleurl/src/gurl.h"

 #include "ui/views/bubble/bubble_delegate.h"

 #include "ui/views/controls/button/button.h"

+#include "url/gurl.h"

 

 class Browser;

 

diff --git a/chrome/browser/ui/views/create_application_shortcut_view.cc b/chrome/browser/ui/views/create_application_shortcut_view.cc
index 80e346f..58a8d09 100644
--- a/chrome/browser/ui/views/create_application_shortcut_view.cc
+++ b/chrome/browser/ui/views/create_application_shortcut_view.cc
@@ -27,7 +27,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/locale_settings.h"
@@ -52,6 +51,7 @@
 #include "ui/views/layout/layout_constants.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/window/dialog_client_view.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/views/edit_search_engine_dialog.cc b/chrome/browser/ui/views/edit_search_engine_dialog.cc
index 785f063..93cb343 100644
--- a/chrome/browser/ui/views/edit_search_engine_dialog.cc
+++ b/chrome/browser/ui/views/edit_search_engine_dialog.cc
@@ -10,7 +10,6 @@
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/ui/search_engines/edit_search_engine_controller.h"
 #include "chrome/browser/ui/views/constrained_window_views.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "grit/ui_resources.h"
@@ -24,6 +23,7 @@
 #include "ui/views/layout/layout_constants.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/window/dialog_client_view.h"
+#include "url/gurl.h"
 
 using views::GridLayout;
 using views::Textfield;
diff --git a/chrome/browser/ui/views/extensions/browser_action_drag_data_unittest.cc b/chrome/browser/ui/views/extensions/browser_action_drag_data_unittest.cc
index d324c4f..b808c37 100644
--- a/chrome/browser/ui/views/extensions/browser_action_drag_data_unittest.cc
+++ b/chrome/browser/ui/views/extensions/browser_action_drag_data_unittest.cc
@@ -5,10 +5,10 @@
 #include "base/pickle.h"
 #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h"
 #include "chrome/test/base/testing_profile.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/dragdrop/os_exchange_data.h"
 #include "ui/base/dragdrop/os_exchange_data_provider_win.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/views/extensions/extension_dialog.cc b/chrome/browser/ui/views/extensions/extension_dialog.cc
index f4c3c20..10fa001 100644
--- a/chrome/browser/ui/views/extensions/extension_dialog.cc
+++ b/chrome/browser/ui/views/extensions/extension_dialog.cc
@@ -4,24 +4,24 @@
 
 #include "chrome/browser/ui/views/extensions/extension_dialog.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/views/constrained_window_views.h"
 #include "chrome/browser/ui/views/extensions/extension_dialog_observer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_view.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/base_window.h"
 #include "ui/gfx/screen.h"
 #include "ui/views/background.h"
 #include "ui/views/widget/widget.h"
+#include "url/gurl.h"
 
 using content::WebContents;
 
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
index cbc70c1..b71fb28 100644
--- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
+++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
@@ -29,6 +29,7 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/transform.h"
 #include "ui/views/border.h"
+#include "ui/views/controls/button/image_button.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/link.h"
@@ -51,6 +52,13 @@
 // Size of extension icon in top left of dialog.
 const int kIconSize = 69;
 
+// The dialog width.
+const int kDialogWidth = 385;
+
+// The dialog will resize based on its content, but this sets a maximum height
+// before overflowing a scrollbar.
+const int kDialogMaxHeight = 300;
+
 // Width of the left column of the dialog when the extension requests
 // permissions.
 const int kPermissionsLeftColumnWidth = 250;
@@ -70,6 +78,8 @@
 // Maximum height of the retained files view.
 const int kMaxRetainedFilesHeight = 100;
 
+typedef std::vector<string16> PermissionDetails;
+
 void AddResourceIcon(const gfx::ImageSkia* skia_image, void* data) {
   views::View* parent = static_cast<views::View*>(data);
   views::ImageView* image_view = new views::ImageView();
@@ -94,9 +104,8 @@
                              const ExtensionInstallPrompt::Prompt& prompt);
   virtual ~ExtensionInstallDialogView();
 
-  // Changes the size of the containing widget to match the preferred size
-  // of this dialog.
-  void SizeToContents();
+  // Called when one of the child elements has expanded/collapsed.
+  void ContentsChanged();
 
  private:
   // views::DialogDelegateView:
@@ -105,10 +114,10 @@
   virtual int GetDefaultDialogButton() const OVERRIDE;
   virtual bool Cancel() OVERRIDE;
   virtual bool Accept() OVERRIDE;
-
-  // views::WidgetDelegate:
   virtual ui::ModalType GetModalType() const OVERRIDE;
   virtual string16 GetWindowTitle() const OVERRIDE;
+  virtual void Layout() OVERRIDE;
+  virtual gfx::Size GetPreferredSize() OVERRIDE;
 
   // views::LinkListener:
   virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
@@ -129,34 +138,54 @@
   ExtensionInstallPrompt::Delegate* delegate_;
   ExtensionInstallPrompt::Prompt prompt_;
 
+  // The scroll view containing all the details for the dialog (including all
+  // collapsible/expandable sections).
+  views::ScrollView* scroll_view_;
+
+  // The container view for the scroll view.
+  views::View* scrollable_;
+
+  // The preferred size of the dialog.
+  gfx::Size dialog_size_;
+
   DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogView);
 };
 
-// A view to display a single IssueAdviceInfoEntry.
-class IssueAdviceView : public views::View,
-                        public ui::AnimationDelegate {
+// A view to display text with an expandable details section.
+class ExpandableContainerView : public views::View,
+                                public views::ButtonListener,
+                                public views::LinkListener,
+                                public ui::AnimationDelegate {
  public:
-  IssueAdviceView(ExtensionInstallDialogView* owner,
-                  const IssueAdviceInfoEntry& issue_advice,
-                  int horizontal_space);
-  virtual ~IssueAdviceView() {}
+  ExpandableContainerView(ExtensionInstallDialogView* owner,
+                          const string16& description,
+                          const PermissionDetails& details,
+                          int horizontal_space,
+                          bool show_bullets);
+  virtual ~ExpandableContainerView();
 
-  // Implementation of views::View:
-  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
-  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
+  // views::View:
   virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE;
 
-  // Implementation of ui::AnimationDelegate:
+  // views::ButtonListener:
+  virtual void ButtonPressed(views::Button* sender,
+                             const ui::Event& event) OVERRIDE;
+
+  // views::LinkListener:
+  virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
+
+  // ui::AnimationDelegate:
   virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
+  virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE;
 
  private:
   // A view which displays all the details of an IssueAdviceInfoEntry.
   class DetailsView : public views::View {
    public:
-    explicit DetailsView(int horizontal_space);
+    explicit DetailsView(int horizontal_space, bool show_bullets);
     virtual ~DetailsView() {}
 
-    // Implementation of views::View:
+    // views::View:
     virtual gfx::Size GetPreferredSize() OVERRIDE;
 
     void AddDetail(const string16& detail);
@@ -168,9 +197,15 @@
     views::GridLayout* layout_;
     double state_;
 
+    // Whether to show bullets in front of each item in the details.
+    bool show_bullets_;
+
     DISALLOW_COPY_AND_ASSIGN(DetailsView);
   };
 
+  // Expand/Collapse the detail section for this ExpandableContainerView.
+  void ToggleDetailLevel();
+
   // The dialog that owns |this|. It's also an ancestor in the View hierarchy.
   ExtensionInstallDialogView* owner_;
 
@@ -182,7 +217,18 @@
 
   ui::SlideAnimation slide_animation_;
 
-  DISALLOW_COPY_AND_ASSIGN(IssueAdviceView);
+  // The 'more details' link shown under the heading (changes to 'hide details'
+  // when the details section is expanded).
+  views::Link* more_details_;
+
+  // The up/down arrow next to the 'more detail' link (points up/down depending
+  // on whether the details section is expanded).
+  views::ImageButton* arrow_toggle_;
+
+  // Whether the details section is expanded.
+  bool expanded_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExpandableContainerView);
 };
 
 void ShowExtensionInstallDialogImpl(
@@ -288,8 +334,13 @@
   // | oauth issue 2             |
   // +---------------------------+
 
-  views::GridLayout* layout = views::GridLayout::CreatePanel(this);
-  SetLayoutManager(layout);
+  scroll_view_ = new views::ScrollView();
+  AddChildView(scroll_view_);
+  scrollable_ = new views::View();
+  scroll_view_->SetContents(scrollable_);
+
+  views::GridLayout* layout = views::GridLayout::CreatePanel(scrollable_);
+  scrollable_->SetLayoutManager(layout);
 
   int column_set_id = 0;
   views::ColumnSet* column_set = layout->AddColumnSet(column_set_id);
@@ -360,9 +411,8 @@
       // have a padding row above it).
       icon_row_span = 3 + prompt.GetOAuthIssueCount() * 2;
     } else if (prompt.GetRetainedFileCount()) {
-      // Also span the permission header and each of the permission rows (all
-      // have a padding row above it).
-      icon_row_span = 3 + prompt.GetRetainedFileCount() * 2;
+      // Also span the permission header and the retained files container.
+      icon_row_span = 4;
     }
     layout->AddView(icon, 1, icon_row_span);
   }
@@ -397,7 +447,7 @@
   }
 
   if (is_bundle_install()) {
-    BundleInstaller::ItemList items = prompt_.bundle()->GetItemsWithState(
+    BundleInstaller::ItemList items = prompt.bundle()->GetItemsWithState(
         BundleInstaller::Item::STATE_PENDING);
     for (size_t i = 0; i < items.size(); ++i) {
       string16 extension_name = UTF8ToUTF16(items[i].localized_name);
@@ -450,6 +500,18 @@
         permission_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
         permission_label->SizeToFit(left_column_width);
         layout->AddView(permission_label);
+
+        // If we have more details to provide, show them in collapsed form.
+        if (!prompt.GetPermissionsDetails(i).empty()) {
+          layout->StartRow(0, column_set_id);
+          PermissionDetails details;
+          details.push_back(
+              PrepareForDisplay(prompt.GetPermissionsDetails(i), false));
+          ExpandableContainerView* details_container =
+              new ExpandableContainerView(
+                  this, string16(), details, left_column_width, false);
+          layout->AddView(details_container);
+        }
       }
     } else {
       layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
@@ -493,8 +555,13 @@
           0, column_set_id,
           0, views::kRelatedControlVerticalSpacing);
 
-      IssueAdviceView* issue_advice_view =
-          new IssueAdviceView(this, prompt.GetOAuthIssue(i), space_for_oauth);
+      PermissionDetails details;
+      const IssueAdviceInfoEntry& entry = prompt.GetOAuthIssue(i);
+      for (size_t x = 0; x < entry.details.size(); ++x)
+        details.push_back(entry.details[x]);
+      ExpandableContainerView* issue_advice_view =
+          new ExpandableContainerView(
+              this, entry.description, details, space_for_oauth, false);
       layout->AddView(issue_advice_view);
     }
   }
@@ -519,37 +586,34 @@
 
     layout->StartRow(0, column_set_id);
     views::Label* retained_files_header = NULL;
-    retained_files_header = new views::Label(prompt.GetRetainedFilesHeading());
+    retained_files_header =
+        new views::Label(prompt.GetRetainedFilesHeadingWithCount());
     retained_files_header->SetMultiLine(true);
     retained_files_header->SetHorizontalAlignment(gfx::ALIGN_LEFT);
     retained_files_header->SizeToFit(space_for_files);
     layout->AddView(retained_files_header);
 
-    layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
     layout->StartRow(0, column_set_id);
-    views::View* files_view = new views::View();
-    files_view->SetLayoutManager(new views::BoxLayout(
-        views::BoxLayout::kVertical,
-        views::kRelatedControlHorizontalSpacing,
-        0,
-        0));
-    for (size_t i = 0; i < prompt.GetRetainedFileCount(); ++i) {
-      views::Label* retained_file_label = new views::Label(PrepareForDisplay(
-          prompt.GetRetainedFile(i), true));
-      retained_file_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-      files_view->AddChildView(retained_file_label);
-    }
-    views::ScrollView* scroll_view =
-        new MaxSizeScrollView(kMaxRetainedFilesHeight, space_for_files);
-    scroll_view->SetContents(files_view);
-    layout->AddView(scroll_view);
+    PermissionDetails details;
+    for (size_t i = 0; i < prompt.GetRetainedFileCount(); ++i)
+      details.push_back(prompt.GetRetainedFile(i));
+    ExpandableContainerView* issue_advice_view =
+        new ExpandableContainerView(
+            this, string16(), details, space_for_files, false);
+    layout->AddView(issue_advice_view);
   }
+
+  gfx::Size scrollable_size = scrollable_->GetPreferredSize();
+  scrollable_->SetBoundsRect(gfx::Rect(scrollable_size));
+  dialog_size_ = gfx::Size(
+      kDialogWidth,
+      std::min(scrollable_size.height(), kDialogMaxHeight));
 }
 
 ExtensionInstallDialogView::~ExtensionInstallDialogView() {}
 
-void ExtensionInstallDialogView::SizeToContents() {
-  GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize());
+void ExtensionInstallDialogView::ContentsChanged() {
+  Layout();
 }
 
 int ExtensionInstallDialogView::GetDialogButtons() const {
@@ -608,19 +672,40 @@
   GetWidget()->Close();
 }
 
+void ExtensionInstallDialogView::Layout() {
+  views::View* contents_view = scroll_view_->contents();
+  int content_width = width();
+  int content_height = contents_view->GetHeightForWidth(content_width);
+  if (content_height > height()) {
+    content_width -= scroll_view_->GetScrollBarWidth();
+    content_height = contents_view->GetHeightForWidth(content_width);
+  }
+  contents_view->SetBounds(0, 0, content_width, content_height);
+  scroll_view_->SetBounds(0, 0, width(), height());
+
+  DialogDelegateView::Layout();
+}
+
+gfx::Size ExtensionInstallDialogView::GetPreferredSize() {
+  return dialog_size_;
+}
+
 // static
 ExtensionInstallPrompt::ShowDialogCallback
 ExtensionInstallPrompt::GetDefaultShowDialogCallback() {
   return base::Bind(&ShowExtensionInstallDialogImpl);
 }
 
-// IssueAdviceView::DetailsView ------------------------------------------------
+// ExpandableContainerView::DetailsView ----------------------------------------
 
-IssueAdviceView::DetailsView::DetailsView(int horizontal_space)
+ExpandableContainerView::DetailsView::DetailsView(int horizontal_space,
+                                                  bool show_bullets)
     : layout_(new views::GridLayout(this)),
-      state_(0) {
+      state_(0),
+      show_bullets_(show_bullets) {
   SetLayoutManager(layout_);
   views::ColumnSet* column_set = layout_->AddColumnSet(0);
+  column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
   column_set->AddColumn(views::GridLayout::LEADING,
                         views::GridLayout::LEADING,
                         0,
@@ -629,120 +714,158 @@
                         0);
 }
 
-void IssueAdviceView::DetailsView::AddDetail(const string16& detail) {
+void ExpandableContainerView::DetailsView::AddDetail(const string16& detail) {
   layout_->StartRowWithPadding(0, 0,
                                0, views::kRelatedControlSmallVerticalSpacing);
   views::Label* detail_label =
-      new views::Label(PrepareForDisplay(detail, true));
+      new views::Label(PrepareForDisplay(detail, show_bullets_));
   detail_label->SetMultiLine(true);
   detail_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   layout_->AddView(detail_label);
 }
 
-gfx::Size IssueAdviceView::DetailsView::GetPreferredSize() {
+gfx::Size ExpandableContainerView::DetailsView::GetPreferredSize() {
   gfx::Size size = views::View::GetPreferredSize();
   return gfx::Size(size.width(), size.height() * state_);
 }
 
-void IssueAdviceView::DetailsView::AnimateToState(double state) {
+void ExpandableContainerView::DetailsView::AnimateToState(double state) {
   state_ = state;
   PreferredSizeChanged();
   SchedulePaint();
 }
 
-// IssueAdviceView -------------------------------------------------------------
+// ExpandableContainerView -----------------------------------------------------
 
-IssueAdviceView::IssueAdviceView(ExtensionInstallDialogView* owner,
-                                 const IssueAdviceInfoEntry& issue_advice,
-                                 int horizontal_space)
+ExpandableContainerView::ExpandableContainerView(
+    ExtensionInstallDialogView* owner,
+    const string16& description,
+    const PermissionDetails& details,
+    int horizontal_space,
+    bool show_bullets)
     : owner_(owner),
       details_view_(NULL),
       arrow_view_(NULL),
-      slide_animation_(this) {
-  // TODO(estade): replace this with a more appropriate image.
-  const gfx::ImageSkia& image = *ui::ResourceBundle::GetSharedInstance().
-      GetImageSkiaNamed(IDR_OMNIBOX_TTS);
-
+      slide_animation_(this),
+      expanded_(false) {
   views::GridLayout* layout = new views::GridLayout(this);
   SetLayoutManager(layout);
   int column_set_id = 0;
   views::ColumnSet* column_set = layout->AddColumnSet(column_set_id);
-  if (!issue_advice.details.empty()) {
-    column_set->AddColumn(views::GridLayout::LEADING,
-                          views::GridLayout::LEADING,
-                          0,
-                          views::GridLayout::FIXED,
-                          image.width(),
-                          0);
-    horizontal_space -= image.width();
-    details_view_ = new DetailsView(horizontal_space);
-  }
   column_set->AddColumn(views::GridLayout::LEADING,
-                        views::GridLayout::FILL,
+                        views::GridLayout::LEADING,
                         0,
-                        views::GridLayout::FIXED,
-                        horizontal_space,
+                        views::GridLayout::USE_PREF,
+                        0,
                         0);
-  layout->StartRow(0, column_set_id);
+  if (!description.empty()) {
+    layout->StartRow(0, column_set_id);
 
-  if (details_view_) {
-    arrow_view_ = new views::ImageView();
-    arrow_view_->SetImage(image);
-    arrow_view_->SetVerticalAlignment(views::ImageView::CENTER);
-    layout->AddView(arrow_view_);
+    views::Label* description_label =
+        new views::Label(PrepareForDisplay(description, true));
+    description_label->SetMultiLine(true);
+    description_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+    description_label->SizeToFit(horizontal_space);
+    layout->AddView(description_label);
   }
 
-  views::Label* description_label =
-      new views::Label(PrepareForDisplay(issue_advice.description,
-                                         !details_view_));
-  description_label->SetMultiLine(true);
-  description_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  description_label->SizeToFit(horizontal_space);
-  layout->AddView(description_label);
-
-  if (!details_view_)
+  if (details.empty())
     return;
 
+  details_view_ = new DetailsView(horizontal_space, show_bullets);
+
   layout->StartRow(0, column_set_id);
-  layout->SkipColumns(1);
   layout->AddView(details_view_);
 
-  for (size_t i = 0; i < issue_advice.details.size(); ++i)
-    details_view_->AddDetail(issue_advice.details[i]);
+  for (size_t i = 0; i < details.size(); ++i)
+    details_view_->AddDetail(details[i]);
+
+  // Prepare the columns for the More Details row.
+  column_set = layout->AddColumnSet(++column_set_id);
+  column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
+  column_set->AddColumn(views::GridLayout::LEADING,
+                        views::GridLayout::LEADING,
+                        0,
+                        views::GridLayout::USE_PREF,
+                        0,
+                        0);
+  column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
+  column_set->AddColumn(views::GridLayout::LEADING,
+                       views::GridLayout::LEADING,
+                       0,
+                       views::GridLayout::USE_PREF,
+                       0,
+                       0);
+  column_set->AddColumn(views::GridLayout::LEADING,
+                        views::GridLayout::LEADING,
+                        0,
+                        views::GridLayout::USE_PREF,
+                        0,
+                        0);
+
+  // Add the More Details link.
+  layout->StartRow(0, column_set_id);
+  more_details_ = new views::Link(
+      l10n_util::GetStringUTF16(IDS_EXTENSIONS_SHOW_DETAILS));
+  more_details_->set_listener(this);
+  more_details_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  layout->AddView(more_details_);
+
+  // Add the arrow after the More Details link.
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  arrow_toggle_ = new views::ImageButton(this);
+  arrow_toggle_->SetImage(views::Button::STATE_NORMAL,
+                          rb.GetImageSkiaNamed(IDR_DOWN_ARROW));
+  layout->AddView(arrow_toggle_);
 }
 
-bool IssueAdviceView::OnMousePressed(const ui::MouseEvent& event) {
-  return details_view_ && event.IsLeftMouseButton();
+ExpandableContainerView::~ExpandableContainerView() {
 }
 
-void IssueAdviceView::OnMouseReleased(const ui::MouseEvent& event) {
+void ExpandableContainerView::ButtonPressed(
+    views::Button* sender, const ui::Event& event) {
+  ToggleDetailLevel();
+}
+
+void ExpandableContainerView::LinkClicked(
+    views::Link* source, int event_flags) {
+  ToggleDetailLevel();
+}
+
+void ExpandableContainerView::AnimationProgressed(
+    const ui::Animation* animation) {
+  DCHECK_EQ(&slide_animation_, animation);
+  if (details_view_)
+    details_view_->AnimateToState(animation->GetCurrentValue());
+}
+
+void ExpandableContainerView::AnimationEnded(const ui::Animation* animation) {
+  if (animation->GetCurrentValue() != 0.0) {
+    arrow_toggle_->SetImage(
+        views::Button::STATE_NORMAL,
+        ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
+            IDR_UP_ARROW));
+  } else {
+    arrow_toggle_->SetImage(
+        views::Button::STATE_NORMAL,
+        ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
+            IDR_DOWN_ARROW));
+  }
+
+  more_details_->SetText(expanded_ ?
+      l10n_util::GetStringUTF16(IDS_EXTENSIONS_HIDE_DETAILS) :
+      l10n_util::GetStringUTF16(IDS_EXTENSIONS_SHOW_DETAILS));
+}
+
+void ExpandableContainerView::ChildPreferredSizeChanged(views::View* child) {
+  owner_->ContentsChanged();
+}
+
+void ExpandableContainerView::ToggleDetailLevel() {
+  expanded_ = !expanded_;
+
   if (slide_animation_.IsShowing())
     slide_animation_.Hide();
   else
     slide_animation_.Show();
 }
-
-void IssueAdviceView::AnimationProgressed(const ui::Animation* animation) {
-  DCHECK_EQ(animation, &slide_animation_);
-
-  if (details_view_)
-    details_view_->AnimateToState(animation->GetCurrentValue());
-
-  if (arrow_view_) {
-    gfx::Transform rotate;
-    if (animation->GetCurrentValue() != 0.0) {
-      rotate.Translate(arrow_view_->width() / 2.0,
-                       arrow_view_->height() / 2.0);
-      // TODO(estade): for some reason there are rendering errors at 90 degrees.
-      // Figure out why.
-      rotate.Rotate(animation->GetCurrentValue() * 89);
-      rotate.Translate(-arrow_view_->width() / 2.0,
-                       -arrow_view_->height() / 2.0);
-    }
-    arrow_view_->SetTransform(rotate);
-  }
-}
-
-void IssueAdviceView::ChildPreferredSizeChanged(views::View* child) {
-  owner_->SizeToContents();
-}
diff --git a/chrome/browser/ui/views/extensions/extension_installed_bubble.cc b/chrome/browser/ui/views/extensions/extension_installed_bubble.cc
index 7d43187..bc59dc9 100644
--- a/chrome/browser/ui/views/extensions/extension_installed_bubble.cc
+++ b/chrome/browser/ui/views/extensions/extension_installed_bubble.cc
@@ -11,6 +11,7 @@
 #include "base/i18n/rtl.h"
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/commands/command_service.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
@@ -23,11 +24,9 @@
 #include "chrome/browser/ui/views/browser_action_view.h"
 #include "chrome/browser/ui/views/browser_actions_container.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "chrome/browser/ui/views/toolbar_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
 #include "chrome/common/extensions/api/omnibox/omnibox_handler.h"
 #include "chrome/common/extensions/extension.h"
@@ -655,14 +654,6 @@
   AddChildView(
       new InstalledBubbleContent(browser_, extension_, type_, &icon_, this));
 
-  // If we are in immersive fullscreen, reveal the top-of-window views
-  // (omnibox, toolbar) so that the view the bubble is anchored to is visible.
-  // We do not need to hold onto the lock because ImmersiveModeController will
-  // keep the top-of-window views revealed as long as the popup is active.
-  // TODO(pkotwicz): Move logic to ImmersiveModeController.
-  scoped_ptr<ImmersiveRevealedLock> immersive_reveal_lock(
-      browser_view->immersive_mode_controller()->GetRevealedLock(
-          ImmersiveModeController::ANIMATE_REVEAL_NO));
   views::BubbleDelegateView::CreateBubble(this);
 
   // The bubble widget is now the parent and owner of |this| and takes care of
diff --git a/chrome/browser/ui/views/extensions/extension_popup.cc b/chrome/browser/ui/views/extensions/extension_popup.cc
index 0c36f22..728a0bd 100644
--- a/chrome/browser/ui/views/extensions/extension_popup.cc
+++ b/chrome/browser/ui/views/extensions/extension_popup.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/extension_process_manager.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -14,9 +15,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
-#include "chrome/browser/ui/views/frame/top_container_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/devtools_manager.h"
 #include "content/public/browser/notification_details.h"
@@ -64,13 +62,11 @@
 const int ExtensionPopup::kMaxWidth = 800;
 const int ExtensionPopup::kMaxHeight = 600;
 
-ExtensionPopup::ExtensionPopup(Browser* browser,
-                               extensions::ExtensionHost* host,
+ExtensionPopup::ExtensionPopup(extensions::ExtensionHost* host,
                                views::View* anchor_view,
                                views::BubbleBorder::Arrow arrow,
                                ShowAction show_action)
     : BubbleDelegateView(anchor_view, arrow),
-      browser_(browser),
       extension_host_(host),
       devtools_callback_(base::Bind(
           &ExtensionPopup::OnDevToolsStateChanged, base::Unretained(this))) {
@@ -174,8 +170,8 @@
   ExtensionProcessManager* manager =
       extensions::ExtensionSystem::Get(browser->profile())->process_manager();
   extensions::ExtensionHost* host = manager->CreatePopupHost(url, browser);
-  ExtensionPopup* popup = new ExtensionPopup(browser, host, anchor_view,
-      arrow, show_action);
+  ExtensionPopup* popup = new ExtensionPopup(host, anchor_view, arrow,
+      show_action);
   views::BubbleDelegateView::CreateBubble(popup);
 
 #if defined(USE_AURA)
@@ -197,21 +193,6 @@
 }
 
 void ExtensionPopup::ShowBubble() {
-  BrowserView* browser_view = browser_ ?
-      BrowserView::GetBrowserViewForBrowser(browser_) : NULL;
-  scoped_ptr<ImmersiveRevealedLock> immersive_reveal_lock;
-  if (browser_view &&
-      browser_view->top_container()->Contains(anchor_view())) {
-    // If we are in immersive fullscreen and we are anchored to a view in the
-    // top-of-window views (eg omnibox, toolbar), trigger an immersive reveal.
-    // We do not need to hold onto the lock because ImmersiveModeController will
-    // keep the top-of-window views revealed as long as the popup is active.
-    // TODO(pkotwicz): Move logic to ImmersiveModeController.
-    immersive_reveal_lock.reset(
-        browser_view->immersive_mode_controller()->GetRevealedLock(
-            ImmersiveModeController::ANIMATE_REVEAL_NO));
-    SizeToContents();
-  }
   GetWidget()->Show();
 
   // Focus on the host contents when the bubble is first shown.
diff --git a/chrome/browser/ui/views/extensions/extension_popup.h b/chrome/browser/ui/views/extensions/extension_popup.h
index b3b031a..638153e 100644
--- a/chrome/browser/ui/views/extensions/extension_popup.h
+++ b/chrome/browser/ui/views/extensions/extension_popup.h
@@ -10,9 +10,9 @@
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/ui/views/extensions/extension_view_views.h"
 #include "content/public/browser/notification_observer.h"
-#include "googleurl/src/gurl.h"
 #include "ui/views/bubble/bubble_delegate.h"
 #include "ui/views/focus/widget_focus_manager.h"
+#include "url/gurl.h"
 
 class Browser;
 namespace views {
@@ -73,8 +73,7 @@
   static const int kMaxHeight;
 
  private:
-  ExtensionPopup(Browser* browser,
-                 extensions::ExtensionHost* host,
+  ExtensionPopup(extensions::ExtensionHost* host,
                  views::View* anchor_view,
                  views::BubbleBorder::Arrow arrow,
                  ShowAction show_action);
@@ -84,9 +83,6 @@
 
   void OnDevToolsStateChanged(content::DevToolsAgentHost*, bool attached);
 
-  // The browser to which the popup is anchored. Not owned.
-  Browser* browser_;
-
   // The contained host for the view.
   scoped_ptr<extensions::ExtensionHost> extension_host_;
 
diff --git a/chrome/browser/ui/views/extensions/native_app_window_views.cc b/chrome/browser/ui/views/extensions/native_app_window_views.cc
index 8d5433a..a7cc935 100644
--- a/chrome/browser/ui/views/extensions/native_app_window_views.cc
+++ b/chrome/browser/ui/views/extensions/native_app_window_views.cc
@@ -106,7 +106,7 @@
   ui::win::SetRelaunchDetailsForWindow(command_line.GetCommandLineString(),
       shortcut_info.title, hwnd);
 
-  if (!file_util::PathExists(web_app_path) &&
+  if (!base::PathExists(web_app_path) &&
       !file_util::CreateDirectory(web_app_path)) {
     return;
   }
diff --git a/chrome/browser/ui/views/external_protocol_dialog.h b/chrome/browser/ui/views/external_protocol_dialog.h
index 2f79103..6573d09 100644
--- a/chrome/browser/ui/views/external_protocol_dialog.h
+++ b/chrome/browser/ui/views/external_protocol_dialog.h
@@ -8,8 +8,8 @@
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "base/time/time.h"
-#include "googleurl/src/gurl.h"
 #include "ui/views/window/dialog_delegate.h"
+#include "url/gurl.h"
 
 namespace content {
 class WebContents;
diff --git a/chrome/browser/ui/views/external_tab_container_win.cc b/chrome/browser/ui/views/external_tab_container_win.cc
index 92c5834..63e2688 100644
--- a/chrome/browser/ui/views/external_tab_container_win.cc
+++ b/chrome/browser/ui/views/external_tab_container_win.cc
@@ -24,6 +24,7 @@
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/app/chrome_dll_resource.h"
 #include "chrome/browser/automation/automation_provider.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_toggle_action.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/file_select_helper.h"
@@ -46,7 +47,6 @@
 #include "chrome/browser/ui/views/tab_contents/render_view_context_menu_win.h"
 #include "chrome/common/automation_messages.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/load_notification_details.h"
@@ -69,7 +69,6 @@
 #include "third_party/WebKit/public/platform/WebCString.h"
 #include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
 #include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
 #include "ui/base/events/event_utils.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/menu_model.h"
@@ -96,7 +95,6 @@
 using content::WebContents;
 using WebKit::WebCString;
 using WebKit::WebReferrerPolicy;
-using WebKit::WebSecurityPolicy;
 using WebKit::WebString;
 
 namespace {
@@ -158,6 +156,43 @@
   return new_model;
 }
 
+// Generates a referrer header used by the AutomationProvider on navigation.
+// Based on code from
+// http://src.chromium.org/viewvc/blink/trunk/Source/weborigin/SecurityPolicy.cpp?revision=151498
+bool ShouldHideReferrer(const GURL& url, const GURL& referrer) {
+  bool referrer_is_secure = referrer.SchemeIsSecure();
+  bool referrer_is_web_url = referrer_is_secure || referrer.SchemeIs("http");
+
+  if (!referrer_is_web_url)
+    return true;
+
+  if (!referrer_is_secure)
+    return false;
+
+  return !url.SchemeIsSecure();
+}
+
+GURL GenerateReferrer(WebKit::WebReferrerPolicy policy,
+                      const GURL& url,
+                      const GURL& referrer) {
+  if (referrer.is_empty())
+    return GURL();
+
+  switch (policy) {
+    case WebKit::WebReferrerPolicyNever:
+      return GURL();
+    case WebKit::WebReferrerPolicyAlways:
+      return referrer;
+    case WebKit::WebReferrerPolicyOrigin:
+      return referrer.GetOrigin();
+    default:
+      break;
+  }
+
+  return ShouldHideReferrer(url, referrer) ? GURL() : referrer;
+}
+
+
 }  // namespace
 
 #if defined(USE_AURA)
@@ -383,9 +418,8 @@
   web_contents_.reset(existing_contents);
 
   if (!infobars_enabled) {
-    InfoBarService* infobar_service =
-        InfoBarService::FromWebContents(existing_contents);
-    infobar_service->set_infobars_enabled(false);
+    InfoBarService::FromWebContents(existing_contents)->set_infobars_enabled(
+        false);
   }
 
   // Start loading initial URL
@@ -606,10 +640,9 @@
     case NEW_WINDOW:
     case SAVE_TO_DISK:
       if (automation_) {
-        GURL referrer = GURL(WebSecurityPolicy::generateReferrerHeader(
-            params.referrer.policy,
-            params.url,
-            WebString::fromUTF8(params.referrer.url.spec())).utf8());
+        GURL referrer = GenerateReferrer(params.referrer.policy,
+                                         params.url,
+                                         params.referrer.url);
         automation_->Send(new AutomationMsg_OpenURL(tab_handle_,
                                                     params.url,
                                                     referrer,
@@ -1375,11 +1408,9 @@
   // widget is torn down.
   external_tab_view_ = new views::View();
 
-  InfoBarContainerView* info_bar_container =
-      new InfoBarContainerView(this, NULL);
-  InfoBarService* infobar_service =
-      InfoBarService::FromWebContents(web_contents_.get());
-  info_bar_container->ChangeInfoBarService(infobar_service);
+  InfoBarContainerView* infobar_container = new InfoBarContainerView(this);
+  infobar_container->ChangeInfoBarService(
+      InfoBarService::FromWebContents(web_contents_.get()));
 
   views::GridLayout* layout = new views::GridLayout(external_tab_view_);
   // Give this column an identifier of 0.
@@ -1394,7 +1425,7 @@
   external_tab_view_->SetLayoutManager(layout);
 
   layout->StartRow(0, 0);
-  layout->AddView(info_bar_container);
+  layout->AddView(infobar_container);
   layout->StartRow(1, 0);
   layout->AddView(tab_contents_container_);
   widget_->SetContentsView(external_tab_view_);
diff --git a/chrome/browser/ui/views/find_bar_controller_interactive_uitest.cc b/chrome/browser/ui/views/find_bar_controller_interactive_uitest.cc
index a4171d7..bc57b79 100644
--- a/chrome/browser/ui/views/find_bar_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/find_bar_controller_interactive_uitest.cc
@@ -11,10 +11,10 @@
 #include "chrome/browser/ui/find_bar/find_bar_host_unittest_util.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/views/focus/focus_manager.h"
 #include "ui/views/widget/widget.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc b/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc
index ffac97d..09951a3 100644
--- a/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc
+++ b/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc
@@ -5,6 +5,7 @@
 #include "base/process_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
@@ -14,7 +15,6 @@
 #include "chrome/browser/ui/view_ids.h"
 #include "chrome/browser/ui/views/find_bar_host.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/ui/views/frame/app_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/app_non_client_frame_view_ash_browsertest.cc
index 7374050..dcf54e8 100644
--- a/chrome/browser/ui/views/frame/app_non_client_frame_view_ash_browsertest.cc
+++ b/chrome/browser/ui/views/frame/app_non_client_frame_view_ash_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_list.h"
@@ -10,7 +11,6 @@
 #include "chrome/browser/ui/views/frame/app_non_client_frame_view_ash.h"
 #include "chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/test/test_utils.h"
 #include "ui/aura/client/aura_constants.h"
diff --git a/chrome/browser/ui/views/frame/browser_frame_win.cc b/chrome/browser/ui/views/frame/browser_frame_win.cc
index 7234942..9f14148 100644
--- a/chrome/browser/ui/views/frame/browser_frame_win.cc
+++ b/chrome/browser/ui/views/frame/browser_frame_win.cc
@@ -28,7 +28,6 @@
 #include "content/public/browser/page_navigator.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/page_transition_types.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -44,6 +43,7 @@
 #include "ui/views/widget/native_widget_win.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/window/non_client_view.h"
+#include "url/gurl.h"
 #include "win8/util/win8_util.h"
 
 #pragma comment(lib, "dwmapi.lib")
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
index d7e2f76..ccf676d 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
@@ -56,9 +56,6 @@
 void BrowserNonClientFrameView::UpdateAvatarInfo() {
   if (browser_view_->ShouldShowAvatar()) {
     if (!avatar_button_) {
-      avatar_button_ = new AvatarMenuButton(browser_view_->browser(),
-                                            browser_view_->IsOffTheRecord());
-      AddChildView(avatar_button_);
 #if defined(ENABLE_MANAGED_USERS)
       Profile* profile = browser_view_->browser()->profile();
       ManagedUserService* service =
@@ -69,6 +66,9 @@
         AddChildView(avatar_label_);
       }
 #endif
+      avatar_button_ = new AvatarMenuButton(browser_view_->browser(),
+                                            browser_view_->IsOffTheRecord());
+      AddChildView(avatar_button_);
       frame_->GetRootView()->Layout();
     }
   } else if (avatar_button_) {
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
index 523a456..98f40fc 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/ui/ash/chrome_shell_delegate.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/immersive_fullscreen_configuration.h"
-#include "chrome/browser/ui/views/avatar_label.h"
 #include "chrome/browser/ui/views/avatar_menu_button.h"
 #include "chrome/browser/ui/views/frame/browser_frame.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -135,10 +134,6 @@
   int left = avatar_button() ? kAvatarSideSpacing +
       browser_view()->GetOTRAvatarIcon().width() + kAvatarSideSpacing :
       kTabstripLeftSpacing;
-  if (avatar_label()) {
-    left += avatar_label()->GetPreferredSize().width() +
-            views::kRelatedControlHorizontalSpacing;
-  }
   int right = frame_painter_->GetRightInset() + kTabstripRightSpacing;
   return TabStripInsets(NonClientTopBorderHeight(force_restored), left, right);
 }
@@ -217,7 +212,7 @@
 
 void BrowserNonClientFrameViewAsh::UpdateWindowTitle() {
   if (!frame()->IsFullscreen())
-    frame_painter_->SchedulePaintForTitle(this, BrowserFrame::GetTitleFont());
+    frame_painter_->SchedulePaintForTitle(BrowserFrame::GetTitleFont());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -420,8 +415,6 @@
     if (immersive_controller->IsEnabled() &&
         !immersive_controller->IsRevealed()) {
       avatar_button()->SetBoundsRect(gfx::Rect());
-      if (avatar_label())
-        avatar_label()->SetBoundsRect(gfx::Rect());
       return;
     }
   }
@@ -437,16 +430,6 @@
                           incognito_icon.width(),
                           avatar_bottom - avatar_y);
   avatar_button()->SetBoundsRect(avatar_bounds);
-  if (avatar_label()) {
-    gfx::Size size = avatar_label()->GetPreferredSize();
-    int label_height = std::min(avatar_bounds.height(), size.height());
-    gfx::Rect label_bounds(
-        avatar_bounds.right() + views::kRelatedControlHorizontalSpacing,
-        avatar_y + (avatar_bounds.height() - label_height) / 2,
-        size.width(),
-        size.height());
-    avatar_label()->SetBoundsRect(label_bounds);
-  }
 }
 
 bool BrowserNonClientFrameViewAsh::ShouldPaint() const {
diff --git a/chrome/browser/ui/views/frame/browser_root_view.cc b/chrome/browser/ui/views/frame/browser_root_view.cc
index 88aea53..20f6b30 100644
--- a/chrome/browser/ui/views/frame/browser_root_view.cc
+++ b/chrome/browser/ui/views/frame/browser_root_view.cc
@@ -9,13 +9,13 @@
 #include "chrome/browser/autocomplete/autocomplete_classifier.h"
 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/omnibox/location_bar.h"
 #include "chrome/browser/ui/views/frame/browser_frame.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "chrome/browser/ui/views/touch_uma/touch_uma.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "grit/chromium_strings.h"
 #include "ui/base/accessibility/accessible_view_state.h"
 #include "ui/base/dragdrop/drag_drop_types.h"
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index e6fbbda..06081f1 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/app_mode/app_mode_utils.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/native_window_notification_source.h"
@@ -82,7 +83,6 @@
 #include "chrome/browser/ui/views/update_recommended_message_box.h"
 #include "chrome/browser/ui/views/website_settings/website_settings_popup_view.h"
 #include "chrome/browser/ui/window_sizer/window_sizer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -290,6 +290,10 @@
     return browser_view_->IsBookmarkBarVisible();
   }
 
+  virtual FullscreenExitBubbleViews* GetFullscreenExitBubble() const OVERRIDE {
+    return browser_view_->fullscreen_exit_bubble();
+  }
+
  private:
   BrowserView* browser_view_;
 
@@ -1050,6 +1054,8 @@
   // the window now so that we are deleted immediately and aren't left holding
   // references to deleted objects.
   GetWidget()->RemoveObserver(this);
+  GetLocationBar()->GetLocationEntry()->model()->popup_model()->RemoveObserver(
+      this);
   frame_->CloseNow();
 }
 
@@ -1109,15 +1115,6 @@
 }
 
 void BrowserView::ShowBookmarkBubble(const GURL& url, bool already_bookmarked) {
-  // Reveal the top-of-window views immediately (if they are not already
-  // revealed) because it looks weird to show the bookmark bubble while the
-  // top-of-window views are still animating. If the bookmark bubble gains
-  // focus, |immersive_mode_controller_| will keep the top-of-window views
-  // revealed.
-  scoped_ptr<ImmersiveRevealedLock> focus_reveal_lock(
-      immersive_mode_controller_->GetRevealedLock(
-          ImmersiveModeController::ANIMATE_REVEAL_NO));
-
   chrome::ShowBookmarkBubbleView(GetToolbarView()->GetBookmarkBubbleAnchor(),
                                  bookmark_bar_view_.get(), browser_->profile(),
                                  url, !already_bookmarked);
@@ -1206,8 +1203,7 @@
 void BrowserView::ShowWebsiteSettings(Profile* profile,
                                       content::WebContents* web_contents,
                                       const GURL& url,
-                                      const content::SSLStatus& ssl,
-                                      bool show_history) {
+                                      const content::SSLStatus& ssl) {
   WebsiteSettingsPopupView::ShowPopup(
       GetLocationBarView()->location_icon_view(), profile,
       web_contents, url, ssl, browser_.get());
@@ -1885,6 +1881,12 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// BrowserView, OmniboxPopupModelObserver overrides:
+void BrowserView::OnOmniboxPopupShownOrHidden() {
+  infobar_container_->SetMaxTopArrowHeight(GetMaxTopInfoBarArrowHeight());
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // BrowserView, ImmersiveModeController::Delegate overrides:
 
 BookmarkBarView* BrowserView::GetBookmarkBar() {
@@ -1971,8 +1973,7 @@
 
   LoadAccelerators();
 
-  infobar_container_ = new InfoBarContainerView(this,
-                                                browser()->search_model());
+  infobar_container_ = new InfoBarContainerView(this);
   AddChildView(infobar_container_);
 
   contents_web_view_ = new views::WebView(browser_->profile());
@@ -2060,6 +2061,9 @@
   }
 #endif
 
+  GetLocationBar()->GetLocationEntry()->model()->popup_model()->AddObserver(
+      this);
+
   // We're now initialized and ready to process Layout requests.
   ignore_layout_ = false;
 }
@@ -2728,8 +2732,10 @@
 
 int BrowserView::GetMaxTopInfoBarArrowHeight() {
   int top_arrow_height = 0;
-  // Only show the arrows when not in fullscreen and when there's no overlay.
-  if (!IsFullscreen() && !overlay_container_->visible()) {
+  // Only show the arrows when not in fullscreen and when there's no overlay
+  // and no omnibox popup.
+  if (!IsFullscreen() && !overlay_container_->visible() &&
+      !GetLocationBar()->GetLocationEntry()->model()->popup_model()->IsOpen()) {
     const LocationIconView* location_icon_view =
         toolbar_->location_bar()->location_icon_view();
     // The +1 in the next line creates a 1-px gap between icon and arrow tip.
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 6141f1a..c8599b1 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -17,6 +17,7 @@
 #include "chrome/browser/infobars/infobar_container.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/omnibox/omnibox_popup_model_observer.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 #include "chrome/browser/ui/views/frame/browser_frame.h"
 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
@@ -100,7 +101,8 @@
                     public InfoBarContainer::Delegate,
                     public views::SingleSplitViewListener,
                     public gfx::SysColorChangeListener,
-                    public LoadCompleteListener::Delegate {
+                    public LoadCompleteListener::Delegate,
+                    public OmniboxPopupModelObserver {
  public:
   // The browser view's class name.
   static const char kViewClassName[];
@@ -183,6 +185,11 @@
   // Accessor for the InfobarContainer.
   InfoBarContainerView* infobar_container() { return infobar_container_; }
 
+  // Accessor for the FullscreenExitBubbleViews.
+  FullscreenExitBubbleViews* fullscreen_exit_bubble() {
+    return fullscreen_bubble_.get();
+  }
+
   // Returns true if various window components are visible.
   bool IsTabStripVisible() const;
 
@@ -350,8 +357,7 @@
   virtual void ShowWebsiteSettings(Profile* profile,
                                    content::WebContents* web_contents,
                                    const GURL& url,
-                                   const content::SSLStatus& ssl,
-                                   bool show_history) OVERRIDE;
+                                   const content::SSLStatus& ssl) OVERRIDE;
   virtual void ShowAppMenu() OVERRIDE;
   virtual bool PreHandleKeyboardEvent(
       const content::NativeWebKeyboardEvent& event,
@@ -461,6 +467,9 @@
   // Overridden from ui::AcceleratorTarget:
   virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
 
+  // OmniboxPopupModelObserver overrides
+  virtual void OnOmniboxPopupShownOrHidden() OVERRIDE;
+
   // Testing interface:
   views::SingleSplitView* GetContentsSplitForTest() { return contents_split_; }
   ContentsContainer* GetContentsContainerForTest() {
@@ -607,7 +616,7 @@
   // |contents_container_|.
   void MakeOverlayContentsActiveContents();
 
-  // Return the max top arrow height for infobar.
+  // Returns the max top arrow height for infobar.
   int GetMaxTopInfoBarArrowHeight();
 
   // Last focused view that issued a tab traversal.
diff --git a/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc
new file mode 100644
index 0000000..b9b3e9f
--- /dev/null
+++ b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc
@@ -0,0 +1,95 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/frame/browser_view.h"
+
+#include "build/build_config.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/browser_tabstrip.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/view_ids.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/interactive_test_utils.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "ui/views/focus/focus_manager.h"
+#include "ui/views/view.h"
+#include "url/gurl.h"
+
+const char kSimplePage[] = "/focus/page_with_focus.html";
+
+class BrowserViewFocusTest : public InProcessBrowserTest {
+ public:
+  bool IsViewFocused(ViewID vid) {
+    return ui_test_utils::IsViewFocused(browser(), vid);
+  }
+};
+
+// Flaky, http://crbug.com/69034.
+IN_PROC_BROWSER_TEST_F(BrowserViewFocusTest, DISABLED_BrowsersRememberFocus) {
+  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+  // First we navigate to our test page.
+  GURL url = embedded_test_server()->GetURL(kSimplePage);
+  ui_test_utils::NavigateToURL(browser(), url);
+
+  gfx::NativeWindow window = browser()->window()->GetNativeWindow();
+
+  // The focus should be on the Tab contents.
+  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
+  // Now hide the window, show it again, the focus should not have changed.
+  ui_test_utils::HideNativeWindow(window);
+  ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(window));
+  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
+
+  chrome::FocusLocationBar(browser());
+  ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX));
+  // Hide the window, show it again, the focus should not have changed.
+  ui_test_utils::HideNativeWindow(window);
+  ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(window));
+  ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX));
+
+  // The rest of this test does not make sense on Linux because the behavior
+  // of Activate() is not well defined and can vary by window manager.
+#if defined(OS_WIN)
+  // Open a new browser window.
+  Browser* browser2 =
+      new Browser(Browser::CreateParams(browser()->profile(),
+                                        browser()->host_desktop_type()));
+  ASSERT_TRUE(browser2);
+  chrome::AddBlankTabAt(browser2, -1, true);
+  browser2->window()->Show();
+  ui_test_utils::NavigateToURL(browser2, url);
+
+  gfx::NativeWindow window2 = browser2->window()->GetNativeWindow();
+  BrowserView* browser_view2 = BrowserView::GetBrowserViewForBrowser(browser2);
+  ASSERT_TRUE(browser_view2);
+  const views::Widget* widget2 =
+      views::Widget::GetWidgetForNativeWindow(window2);
+  ASSERT_TRUE(widget2);
+  const views::FocusManager* focus_manager2 = widget2->GetFocusManager();
+  ASSERT_TRUE(focus_manager2);
+  EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
+            focus_manager2->GetFocusedView());
+
+  // Switch to the 1st browser window, focus should still be on the location
+  // bar and the second browser should have nothing focused.
+  browser()->window()->Activate();
+  ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX));
+  EXPECT_EQ(NULL, focus_manager2->GetFocusedView());
+
+  // Switch back to the second browser, focus should still be on the page.
+  browser2->window()->Activate();
+  views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
+  ASSERT_TRUE(widget);
+  EXPECT_EQ(NULL, widget->GetFocusManager()->GetFocusedView());
+  EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
+            focus_manager2->GetFocusedView());
+
+  // Close the 2nd browser to avoid a DCHECK().
+  browser_view2->Close();
+#endif
+}
diff --git a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
index 832637a..4440fcf 100644
--- a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
@@ -29,7 +29,7 @@
 #include "ui/views/window/non_client_view.h"
 
 #if defined(OS_CHROMEOS)
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
@@ -267,17 +267,6 @@
   // Type in the omnibox, which should generate suggestions in the main page
   // contents.
   SetOmniboxText("claus");
-  // The autocomplete controller isn't done until all the providers are done.
-  // Though we don't care about the SearchProvider when we send autocomplete
-  // results to the page, we do need to cause it to be "done" to make this test
-  // work. Setting the suggestion calls SearchProvider::FinalizeInstantQuery(),
-  // thus causing it to be done.
-  omnibox()->model()->SetInstantSuggestion(
-      InstantSuggestion(ASCIIToUTF16("query"),
-                        INSTANT_COMPLETE_NOW,
-                        INSTANT_SUGGESTION_SEARCH,
-                        ASCIIToUTF16("query"),
-                        kNoMatchIndex));
   while (!omnibox()->model()->autocomplete_controller()->done()) {
     content::WindowedNotificationObserver autocomplete_observer(
         chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc
index 1262a3d..a015739 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout.cc
+++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
 #include "chrome/browser/ui/views/frame/overlay_container.h"
 #include "chrome/browser/ui/views/frame/top_container_view.h"
+#include "chrome/browser/ui/views/fullscreen_exit_bubble_views.h"
 #include "chrome/browser/ui/views/infobars/infobar_container_view.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "components/web_modal/web_contents_modal_dialog_host.h"
@@ -374,6 +375,14 @@
         gfx::Rect(), true);
   }
 
+  // Adjust the fullscreen exit bubble bounds for |top_container_|'s new bounds.
+  // This makes the fullscreen exit bubble look like it animates with
+  // |top_container_| in immersive fullscreen.
+  FullscreenExitBubbleViews* fullscreen_exit_bubble =
+      delegate_->GetFullscreenExitBubble();
+  if (fullscreen_exit_bubble)
+    fullscreen_exit_bubble->RepositionIfVisible();
+
   // Adjust any web contents modal dialogs.
   dialog_host_->NotifyPositionRequiresUpdate();
 }
diff --git a/chrome/browser/ui/views/frame/browser_view_layout_delegate.h b/chrome/browser/ui/views/frame/browser_view_layout_delegate.h
index 0b1a6b4..f81d62bd 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout_delegate.h
+++ b/chrome/browser/ui/views/frame/browser_view_layout_delegate.h
@@ -5,6 +5,15 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_DELEGATE_H_
 #define CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_DELEGATE_H_
 
+class FullscreenExitBubbleViews;
+
+namespace gfx {
+class Rect;
+}
+namespace views {
+class View;
+}
+
 // Delegate class to allow BrowserViewLayout to be decoupled from BrowserView
 // for testing.
 class BrowserViewLayoutDelegate {
@@ -17,6 +26,7 @@
   virtual bool IsToolbarVisible() const = 0;
   virtual bool IsBookmarkBarVisible() const = 0;
   virtual bool DownloadShelfNeedsLayout() const = 0;
+  virtual FullscreenExitBubbleViews* GetFullscreenExitBubble() const = 0;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_DELEGATE_H_
diff --git a/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc b/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc
index 7449032..104c403 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc
@@ -60,6 +60,10 @@
     return download_shelf_needs_layout_;
   }
 
+  virtual FullscreenExitBubbleViews* GetFullscreenExitBubble() const OVERRIDE {
+    return NULL;
+  }
+
  private:
   bool tab_strip_visible_;
   bool toolbar_visible_;
@@ -111,10 +115,6 @@
       const gfx::Size& top_container_size) const OVERRIDE { return 0; }
   virtual ImmersiveRevealedLock* GetRevealedLock(
       AnimateReveal animate_reveal) OVERRIDE WARN_UNUSED_RESULT { return NULL; }
-  virtual void AnchorWidgetToTopContainer(views::Widget* widget,
-                                          int y_offset) OVERRIDE {}
-  virtual void UnanchorWidgetFromTopContainer(views::Widget* widget) OVERRIDE {}
-  virtual void OnTopContainerBoundsChanged() OVERRIDE {}
   virtual void OnFindBarVisibleBoundsChanged(
       const gfx::Rect& new_visible_bounds) OVERRIDE {}
 
@@ -167,7 +167,7 @@
         new OverlayContainer(NULL, immersive_mode_controller_.get());
     root_view_->AddChildView(overlay_container_);
 
-    infobar_container_ = new InfoBarContainerView(NULL, NULL);
+    infobar_container_ = new InfoBarContainerView(NULL);
     root_view_->AddChildView(infobar_container_);
 
     contents_split_ = new MockView(gfx::Size(800, 600));
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
index f1d8ba5..678eaa8 100644
--- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
@@ -9,6 +9,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/views/avatar_label.h"
@@ -16,7 +17,6 @@
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/tabs/tab.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
@@ -105,10 +105,6 @@
   int tabstrip_x = browser_view()->ShouldShowAvatar() ?
       (avatar_bounds_.right() + kAvatarRightSpacing) :
       NonClientBorderThickness() + kTabStripIndent;
-  if (avatar_label()) {
-    tabstrip_x += avatar_label()->bounds().width() +
-                  views::kRelatedControlHorizontalSpacing;
-  }
   // In RTL languages, we have moved an avatar icon left by the size of window
   // controls to prevent it from being rendered over them. So, we use its x
   // position to move this tab strip left when maximized. Also, we can render
@@ -209,9 +205,7 @@
 
   // See if the point is within the avatar menu button or within the avatar
   // label.
-  if ((avatar_button() &&
-       avatar_button()->GetMirroredBounds().Contains(point)) ||
-      (avatar_label() && avatar_label()->GetMirroredBounds().Contains(point)))
+  if (avatar_button() && avatar_button()->GetMirroredBounds().Contains(point))
     return HTCLIENT;
 
   int frame_component = frame()->client_view()->NonClientHitTest(point);
@@ -428,17 +422,6 @@
       browser_view()->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0);
   if (avatar_button())
     avatar_button()->SetBoundsRect(avatar_bounds_);
-
-  if (avatar_label()) {
-    gfx::Size size = avatar_label()->GetPreferredSize();
-    int label_height = std::min(avatar_bounds_.height(), size.height());
-    gfx::Rect label_bounds(
-        avatar_bounds_.right() + views::kRelatedControlHorizontalSpacing,
-        avatar_y + (avatar_bounds_.height() - label_height) / 2,
-        size.width(),
-        browser_view()->ShouldShowAvatar() ? size.height() : 0);
-    avatar_label()->SetBoundsRect(label_bounds);
-  }
 }
 
 void GlassBrowserFrameView::LayoutClientView() {
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller.h b/chrome/browser/ui/views/frame/immersive_mode_controller.h
index 81da8d8..f8f23de 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller.h
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller.h
@@ -115,27 +115,6 @@
   virtual ImmersiveRevealedLock* GetRevealedLock(
       AnimateReveal animate_reveal) WARN_UNUSED_RESULT = 0;
 
-  // Anchor |widget| to the top-of-window views. This repositions |widget| such
-  // that it stays |y_offset| below the top-of-window views when the
-  // top-of-window views are animating (top-of-window views reveal / unreveal)
-  // or the top container's bounds change (eg the bookmark bar is shown).
-  // If the top-of-window views are revealed (or become revealed), |widget|
-  // will keep the top-of-window views revealed till either |widget| is hidden
-  // or UnanchorWidgetFromTopContainer() is called.
-  // It is legal for a widget to be anchored when immersive fullscreen is
-  // disabled, however it will have no effect till immersive fullscreen is
-  // enabled.
-  virtual void AnchorWidgetToTopContainer(views::Widget* widget,
-                                          int y_offset) = 0;
-
-  // Stops managing |widget|'s y position.
-  // Closes the top-of-window views if no locks or other anchored widgets are
-  // keeping the top-of-window views revealed.
-  virtual void UnanchorWidgetFromTopContainer(views::Widget* widget) = 0;
-
-  // Called by the TopContainerView to indicate that its bounds have changed.
-  virtual void OnTopContainerBoundsChanged() = 0;
-
   // Called by the find bar to indicate that its visible bounds have changed.
   // |new_visible_bounds_in_screen| should be empty if the find bar is not
   // visible.
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
index a931f44..8b1b5f7 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -4,15 +4,17 @@
 
 #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
 
+#include <set>
+
 #include "ash/ash_switches.h"
 #include "ash/shell.h"
 #include "ash/wm/window_properties.h"
 #include "base/command_line.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
 #include "chrome/browser/ui/immersive_fullscreen_configuration.h"
 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
 #include "chrome/browser/ui/views/frame/top_container_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "ui/aura/client/activation_client.h"
 #include "ui/aura/client/aura_constants.h"
@@ -23,7 +25,7 @@
 #include "ui/aura/root_window.h"
 #include "ui/aura/window.h"
 #include "ui/base/animation/slide_animation.h"
-#include "ui/gfx/transform.h"
+#include "ui/views/bubble/bubble_delegate.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/window/non_client_view.h"
@@ -66,19 +68,24 @@
   aura::Env::GetInstance()->set_last_mouse_location(cursor_pos);
 }
 
-// Returns true if the currently active window is a transient child of
-// |toplevel|.
-bool IsActiveWindowTransientChildOf(aura::Window* toplevel) {
-  if (!toplevel)
+// Returns the BubbleDelegateView corresponding to |maybe_bubble| if
+// |maybe_bubble| is a bubble.
+views::BubbleDelegateView* AsBubbleDelegate(aura::Window* maybe_bubble) {
+  if (!maybe_bubble)
+    return NULL;
+  views::Widget* widget = views::Widget::GetWidgetForNativeView(maybe_bubble);
+  if (!widget)
+    return NULL;
+  return widget->widget_delegate()->AsBubbleDelegate();
+}
+
+// Returns true if |maybe_transient| is a transient child of |toplevel|.
+bool IsWindowTransientChildOf(aura::Window* maybe_transient,
+                              aura::Window* toplevel) {
+  if (!maybe_transient || !toplevel)
     return false;
 
-  aura::Window* active_window = aura::client::GetActivationClient(
-      toplevel->GetRootWindow())->GetActiveWindow();
-
-  if (!active_window)
-    return false;
-
-  for (aura::Window* window = active_window; window;
+  for (aura::Window* window = maybe_transient; window;
        window = window->transient_parent()) {
     if (window == toplevel)
       return true;
@@ -122,168 +129,116 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-// Manages widgets which should move in sync with the top-of-window views.
-class ImmersiveModeControllerAsh::AnchoredWidgetManager
-    : public views::WidgetObserver {
+// Class which keeps the top-of-window views revealed as long as one of the
+// bubbles it is observing is visible. The logic to keep the top-of-window
+// views revealed based on the visibility of bubbles anchored to
+// children of |ImmersiveModeController::top_container_| is separate from
+// the logic related to |ImmersiveModeControllerAsh::focus_revealed_lock_|
+// so that bubbles which are not activatable and bubbles which do not close
+// upon deactivation also keep the top-of-window views revealed for the
+// duration of their visibility.
+class ImmersiveModeControllerAsh::BubbleManager : public aura::WindowObserver {
  public:
-  explicit AnchoredWidgetManager(ImmersiveModeControllerAsh* controller);
-  virtual ~AnchoredWidgetManager();
+  explicit BubbleManager(ImmersiveModeControllerAsh* controller);
+  virtual ~BubbleManager();
 
-  // Anchors |widget| such that it stays |y_offset| below the top-of-window
-  // views. |widget| will be repositioned whenever the top-of-window views are
-  // animated (top-of-window views revealing / unrevealing) or the top-of-window
-  // bounds change (eg the bookmark bar is shown).
-  // If the top-of-window views are revealed (or become revealed), |widget| will
-  // keep the top-of-window views revealed till |widget| is hidden or
-  // RemoveAnchoredWidget() is called.
-  void AddAnchoredWidget(views::Widget* widget, int y_offset);
-
-  // Stops managing |widget|'s y position.
-  // Closes the top-of-window views if no locks or other anchored widgets are
-  // keeping the top-of-window views revealed.
-  void RemoveAnchoredWidget(views::Widget* widget);
-
-  // Repositions the anchored widgets for the current top container bounds if
-  // immersive mode is enabled.
-  void MaybeRepositionAnchoredWidgets();
-
-  // Called when immersive mode has been enabled.
-  void OnImmersiveModeEnabled();
+  // Start / stop observing changes to |bubble|'s visibility.
+  void StartObserving(aura::Window* bubble);
+  void StopObserving(aura::Window* bubble);
 
  private:
-  // Updates |revealed_lock_| based on the visible anchored widgets.
+  // Updates |revealed_lock_| based on whether any of |bubbles_| is visible.
   void UpdateRevealedLock();
 
-  // Updates the y position of |widget| given |y_offset| and the top
-  // container's target bounds.
-  void UpdateWidgetBounds(views::Widget* widget, int y_offset);
-
-  // views::WidgetObserver overrides:
-  virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
-  virtual void OnWidgetVisibilityChanged(views::Widget* widget,
+  // aura::WindowObserver overrides:
+  virtual void OnWindowVisibilityChanged(aura::Window* window,
                                          bool visible) OVERRIDE;
+  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
 
   ImmersiveModeControllerAsh* controller_;
 
-  // Mapping of anchored widgets to the y offset below the top-of-window views
-  // that they should be positioned at.
-  std::map<views::Widget*, int> widgets_;
+  std::set<aura::Window*> bubbles_;
 
-  // The subset of |widgets_| which are visible.
-  std::set<views::Widget*> visible_;
-
-  // Lock which keeps the top-of-window views revealed based on the visible
-  // anchored widgets.
+  // Lock which keeps the top-of-window views revealed based on whether any of
+  // |bubbles_| is visible.
   scoped_ptr<ImmersiveRevealedLock> revealed_lock_;
 
-  DISALLOW_COPY_AND_ASSIGN(AnchoredWidgetManager);
+  DISALLOW_COPY_AND_ASSIGN(BubbleManager);
 };
 
-ImmersiveModeControllerAsh::AnchoredWidgetManager::AnchoredWidgetManager(
+ImmersiveModeControllerAsh::BubbleManager::BubbleManager(
     ImmersiveModeControllerAsh* controller)
     : controller_(controller) {
 }
 
-ImmersiveModeControllerAsh::AnchoredWidgetManager::~AnchoredWidgetManager() {
-  while (!widgets_.empty())
-    RemoveAnchoredWidget(widgets_.begin()->first);
+ImmersiveModeControllerAsh::BubbleManager::~BubbleManager() {
+  for (std::set<aura::Window*>::const_iterator it = bubbles_.begin();
+       it != bubbles_.end(); ++it) {
+    (*it)->RemoveObserver(this);
+  }
 }
 
-void ImmersiveModeControllerAsh::AnchoredWidgetManager::AddAnchoredWidget(
-    views::Widget* widget,
-    int y_offset) {
-  DCHECK(widget);
-  bool already_added = widgets_.count(widget) > 0;
-  widgets_[widget] = y_offset;
-
-  if (already_added)
-    return;
-
-  widget->AddObserver(this);
-
-  if (widget->IsVisible())
-    visible_.insert(widget);
-
-  UpdateRevealedLock();
-  UpdateWidgetBounds(widget, y_offset);
+void ImmersiveModeControllerAsh::BubbleManager::StartObserving(
+    aura::Window* bubble) {
+  if (bubbles_.insert(bubble).second) {
+    bubble->AddObserver(this);
+    UpdateRevealedLock();
+  }
 }
 
-void ImmersiveModeControllerAsh::AnchoredWidgetManager::RemoveAnchoredWidget(
-    views::Widget* widget) {
-  if (!widgets_.count(widget))
-    return;
-
-  widget->RemoveObserver(this);
-  widgets_.erase(widget);
-  visible_.erase(widget);
-
-  UpdateRevealedLock();
+void ImmersiveModeControllerAsh::BubbleManager::StopObserving(
+    aura::Window* bubble) {
+  if (bubbles_.erase(bubble)) {
+    bubble->RemoveObserver(this);
+    UpdateRevealedLock();
+  }
 }
 
-void ImmersiveModeControllerAsh::AnchoredWidgetManager::
-    MaybeRepositionAnchoredWidgets() {
-  for (std::map<views::Widget*, int>::iterator it = widgets_.begin();
-       it != widgets_.end(); ++it) {
-    UpdateWidgetBounds(it->first, it->second);
+void ImmersiveModeControllerAsh::BubbleManager::UpdateRevealedLock() {
+  bool has_visible_bubble = false;
+  for (std::set<aura::Window*>::const_iterator it = bubbles_.begin();
+       it != bubbles_.end(); ++it) {
+    if ((*it)->IsVisible()) {
+      has_visible_bubble = true;
+      break;
+    }
   }
 
-  UpdateRevealedLock();
-}
-
-void ImmersiveModeControllerAsh::AnchoredWidgetManager::
-    OnImmersiveModeEnabled() {
-  UpdateRevealedLock();
-  // The top container bounds may have changed while immersive mode was
-  // disabled.
-  MaybeRepositionAnchoredWidgets();
-}
-
-void ImmersiveModeControllerAsh::AnchoredWidgetManager::UpdateRevealedLock() {
-  if (visible_.empty()) {
-    revealed_lock_.reset();
-  } else if (controller_->IsRevealed()) {
+  bool was_revealed = controller_->IsRevealed();
+  if (has_visible_bubble) {
     if (!revealed_lock_.get()) {
-      // CAUTION: Acquiring the lock results in a reentrant call to
-      // UpdateRevealedLock() when
-      // |ImmersiveModeControllerAsh::animations_disabled_for_test_| is true.
+      // Reveal the top-of-window views without animating because it looks
+      // weird for the top-of-window views to animate and the bubble not to
+      // animate along with the top-of-window views.
       revealed_lock_.reset(controller_->GetRevealedLock(
-          ImmersiveModeController::ANIMATE_REVEAL_YES));
+          ImmersiveModeController::ANIMATE_REVEAL_NO));
+    }
+  } else {
+    revealed_lock_.reset();
+  }
+
+  if (!was_revealed && revealed_lock_.get()) {
+    // Currently, there is no nice way for bubbles to reposition themselves
+    // whenever the anchor view moves. Tell the bubbles to reposition themselves
+    // explicitly instead. The hidden bubbles are also repositioned because
+    // BubbleDelegateView does not reposition its widget as a result of a
+    // visibility change.
+    for (std::set<aura::Window*>::const_iterator it = bubbles_.begin();
+         it != bubbles_.end(); ++it) {
+      AsBubbleDelegate(*it)->OnAnchorViewBoundsChanged();
     }
   }
 }
 
-void ImmersiveModeControllerAsh::AnchoredWidgetManager::UpdateWidgetBounds(
-    views::Widget* widget,
-    int y_offset) {
-  if (!controller_->IsEnabled() || !widget->IsVisible())
-    return;
-
-  gfx::Rect top_container_bounds =
-      controller_->top_container_->GetBoundsInScreen();
-  gfx::Rect bounds(widget->GetWindowBoundsInScreen());
-  bounds.set_y(top_container_bounds.bottom() + y_offset);
-  widget->SetBounds(bounds);
-}
-
-void ImmersiveModeControllerAsh::AnchoredWidgetManager::OnWidgetDestroying(
-    views::Widget* widget) {
-  RemoveAnchoredWidget(widget);
-}
-
-void ImmersiveModeControllerAsh::AnchoredWidgetManager::
-    OnWidgetVisibilityChanged(
-        views::Widget* widget,
-        bool visible) {
-  if (visible)
-    visible_.insert(widget);
-  else
-    visible_.erase(widget);
-
+void ImmersiveModeControllerAsh::BubbleManager::OnWindowVisibilityChanged(
+    aura::Window*,
+    bool visible) {
   UpdateRevealedLock();
+}
 
-  std::map<views::Widget*, int>::iterator it = widgets_.find(widget);
-  DCHECK(it != widgets_.end());
-  UpdateWidgetBounds(it->first, it->second);
+void ImmersiveModeControllerAsh::BubbleManager::OnWindowDestroying(
+    aura::Window* window) {
+  StopObserving(window);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -350,8 +305,6 @@
           HasSwitch(ash::switches::kAshImmersiveHideTabIndicators)) {
     tab_indicator_visibility_ = TAB_INDICATORS_FORCE_HIDE;
   }
-
-  anchored_widget_manager_.reset(new AnchoredWidgetManager(this));
 }
 
 void ImmersiveModeControllerAsh::SetEnabled(bool enabled) {
@@ -387,7 +340,6 @@
       UpdateLocatedEventRevealedLock(NULL);
       UpdateFocusRevealedLock();
     }
-    anchored_widget_manager_->OnImmersiveModeEnabled();
   } else {
     // Stop cursor-at-top tracking.
     top_edge_hover_timer_.Stop();
@@ -432,21 +384,6 @@
   return new RevealedLockAsh(weak_ptr_factory_.GetWeakPtr(), animate_reveal);
 }
 
-void ImmersiveModeControllerAsh::AnchorWidgetToTopContainer(
-    views::Widget* widget,
-    int y_offset) {
-  anchored_widget_manager_->AddAnchoredWidget(widget, y_offset);
-}
-
-void ImmersiveModeControllerAsh::UnanchorWidgetFromTopContainer(
-    views::Widget* widget) {
-  anchored_widget_manager_->RemoveAnchoredWidget(widget);
-}
-
-void ImmersiveModeControllerAsh::OnTopContainerBoundsChanged() {
-  anchored_widget_manager_->MaybeRepositionAnchoredWidgets();
-}
-
 void ImmersiveModeControllerAsh::OnFindBarVisibleBoundsChanged(
     const gfx::Rect& new_visible_bounds_in_screen) {
   find_bar_visible_bounds_in_screen_ = new_visible_bounds_in_screen;
@@ -539,6 +476,14 @@
 
 void ImmersiveModeControllerAsh::OnDidChangeFocus(views::View* focused_before,
                                                   views::View* focused_now) {
+  scoped_ptr<ImmersiveRevealedLock> lock;
+  if (reveal_state_ == REVEALED || reveal_state_ == SLIDING_OPEN) {
+    // Acquire a lock so that if UpdateLocatedEventRevealedLock() or
+    // UpdateFocusRevealedLock() ends the reveal, it occurs after the
+    // function terminates. This is useful in tests.
+    lock.reset(GetRevealedLock(ANIMATE_REVEAL_YES));
+  }
+
   UpdateLocatedEventRevealedLock(NULL);
   UpdateFocusRevealedLock();
 }
@@ -555,6 +500,14 @@
 void ImmersiveModeControllerAsh::OnWidgetActivationChanged(
     views::Widget* widget,
     bool active) {
+  scoped_ptr<ImmersiveRevealedLock> lock;
+  if (reveal_state_ == REVEALED || reveal_state_ == SLIDING_OPEN) {
+    // Acquire a lock so that if UpdateLocatedEventRevealedLock() or
+    // UpdateFocusRevealedLock() ends the reveal, it occurs after the
+    // function terminates. This is useful in tests.
+    lock.reset(GetRevealedLock(ANIMATE_REVEAL_YES));
+  }
+
   // Mouse hover should not initiate revealing the top-of-window views while
   // |native_window_| is inactive.
   top_edge_hover_timer_.Stop();
@@ -620,6 +573,25 @@
   }
 }
 
+void ImmersiveModeControllerAsh::OnAddTransientChild(aura::Window* window,
+                                                     aura::Window* transient) {
+  views::BubbleDelegateView* bubble_delegate = AsBubbleDelegate(transient);
+  if (bubble_delegate &&
+      bubble_delegate->anchor_view() &&
+      top_container_->Contains(bubble_delegate->anchor_view())) {
+    // Observe the aura::Window because the BubbleDelegateView may not be
+    // parented to the widget's root view yet so |bubble_delegate->GetWidget()|
+    // may still return NULL.
+    bubble_manager_->StartObserving(transient);
+  }
+}
+
+void ImmersiveModeControllerAsh::OnRemoveTransientChild(
+    aura::Window* window,
+    aura::Window* transient) {
+  bubble_manager_->StopObserving(transient);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Testing interface:
 
@@ -682,6 +654,16 @@
   }
 
   if (enable) {
+    RecreateBubbleManager();
+  } else {
+    // We have stopped observing whether transient children are added or removed
+    // to |native_window_|. The set of bubbles that BubbleManager is observing
+    // will become stale really quickly. Destroy BubbleManager and recreate it
+    // when we start observing |native_window_| again.
+    bubble_manager_.reset();
+  }
+
+  if (enable) {
     registrar_.Add(
         this,
         chrome::NOTIFICATION_FULLSCREEN_CHANGED,
@@ -823,16 +805,29 @@
     if (top_container_->Contains(focused_view))
       hold_lock = true;
   } else {
-    // If the currently active window is not |native_window_|, the top-of-window
-    // views should be revealed if:
-    // 1) The newly active window is a transient child of |native_window_|.
-    // 2) The top-of-window views are already revealed. This restriction
-    //    prevents a transient window opened by the web contents while the
-    //    top-of-window views are hidden from from initiating a reveal.
-    // The top-of-window views will stay revealed till |native_window_| is
-    // reactivated.
-    if (IsRevealed() && IsActiveWindowTransientChildOf(native_window_))
-      hold_lock = true;
+    aura::Window* active_window = aura::client::GetActivationClient(
+        native_window_->GetRootWindow())->GetActiveWindow();
+    views::BubbleDelegateView* bubble_delegate =
+        AsBubbleDelegate(active_window);
+    if (bubble_delegate && bubble_delegate->anchor_view()) {
+      // BubbleManager will already have locked the top-of-window views if the
+      // bubble is anchored to a child of |top_container_|. Don't acquire
+      // |focus_revealed_lock_| here for the sake of simplicity.
+    } else {
+      // The currently active window is not |native_window_| and it is not a
+      // bubble with an anchor view. The top-of-window views should be revealed
+      // if:
+      // 1) The active window is a transient child of |native_window_|.
+      // 2) The top-of-window views are already revealed. This restriction
+      //    prevents a transient window opened by the web contents while the
+      //    top-of-window views are hidden from from initiating a reveal.
+      // The top-of-window views will stay revealed till |native_window_| is
+      // reactivated.
+      if (IsRevealed() &&
+          IsWindowTransientChildOf(active_window, native_window_)) {
+        hold_lock = true;
+      }
+    }
   }
 
   if (hold_lock) {
@@ -1087,3 +1082,19 @@
        (location.x() >= near_bounds.x()) &&
        (location.x() < near_bounds.right()));
 }
+
+void ImmersiveModeControllerAsh::RecreateBubbleManager() {
+  bubble_manager_.reset(new BubbleManager(this));
+  const std::vector<aura::Window*> transient_children =
+      native_window_->transient_children();
+  for (size_t i = 0; i < transient_children.size(); ++i) {
+    aura::Window* transient_child = transient_children[i];
+    views::BubbleDelegateView* bubble_delegate =
+        AsBubbleDelegate(transient_child);
+    if (bubble_delegate &&
+        bubble_delegate->anchor_view() &&
+        top_container_->Contains(bubble_delegate->anchor_view())) {
+      bubble_manager_->StartObserving(transient_child);
+    }
+  }
+}
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h
index ae7417a..a1e909e 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h
@@ -72,10 +72,6 @@
       const gfx::Size& top_container_size) const OVERRIDE;
   virtual ImmersiveRevealedLock* GetRevealedLock(
       AnimateReveal animate_reveal) OVERRIDE WARN_UNUSED_RESULT;
-  virtual void AnchorWidgetToTopContainer(views::Widget* widget,
-                                          int y_offset) OVERRIDE;
-  virtual void UnanchorWidgetFromTopContainer(views::Widget* widget) OVERRIDE;
-  virtual void OnTopContainerBoundsChanged() OVERRIDE;
   virtual void OnFindBarVisibleBoundsChanged(
       const gfx::Rect& new_visible_bounds_in_screen) OVERRIDE;
 
@@ -108,6 +104,10 @@
   virtual void OnWindowPropertyChanged(aura::Window* window,
                                        const void* key,
                                        intptr_t old) OVERRIDE;
+  virtual void OnAddTransientChild(aura::Window* window,
+                                   aura::Window* transient) OVERRIDE;
+  virtual void OnRemoveTransientChild(aura::Window* window,
+                                      aura::Window* transient) OVERRIDE;
 
   // Testing interface.
   void SetForceHideTabIndicatorsForTest(bool force);
@@ -219,6 +219,10 @@
   // is a bezel sensor above the top container.
   bool ShouldHandleGestureEvent(const gfx::Point& location) const;
 
+  // Recreate |bubble_manager_| and start observing any bubbles anchored to a
+  // child of |top_container_|.
+  void RecreateBubbleManager();
+
   // Injected dependencies. Not owned.
   Delegate* delegate_;
   views::Widget* widget_;
@@ -274,9 +278,9 @@
   // Whether the animations are disabled for testing.
   bool animations_disabled_for_test_;
 
-  // Manages widgets which are anchored to the top-of-window views.
-  class AnchoredWidgetManager;
-  scoped_ptr<AnchoredWidgetManager> anchored_widget_manager_;
+  // Manages bubbles which are anchored to a child of |top_container_|.
+  class BubbleManager;
+  scoped_ptr<BubbleManager> bubble_manager_;
 
   content::NotificationRegistrar registrar_;
 
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
index d18fecb..644798b 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
@@ -13,23 +13,16 @@
 #include "ash/wm/window_util.h"
 #include "base/command_line.h"
 #include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
 #include "chrome/browser/ui/fullscreen/fullscreen_controller_test.h"
 #include "chrome/browser/ui/immersive_fullscreen_configuration.h"
-#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
-#include "chrome/browser/ui/views/browser_dialogs.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/top_container_view.h"
 #include "chrome/browser/ui/views/tabs/tab.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "content/public/browser/javascript_dialog_manager.h"
 #include "content/public/test/test_utils.h"
 #include "ui/aura/client/screen_position_client.h"
 #include "ui/aura/env.h"
@@ -63,13 +56,6 @@
   BrowserView* browser_view() { return browser_view_; }
   ImmersiveModeControllerAsh* controller() { return controller_; }
 
-  // Callback for when the onbeforeunload dialog closes for the sake of testing
-  // the dialog with immersive mode.
-  void OnBeforeUnloadJavaScriptDialogClosed(
-      bool success,
-      const string16& user_input) {
-  }
-
   // content::BrowserTestBase overrides:
   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     ImmersiveFullscreenConfiguration::EnableImmersiveFullscreenForTest();
@@ -232,102 +218,6 @@
   controller()->StartRevealForTest(true);
 }
 
-// Test how focus affects whether the top-of-window views are revealed.
-// Do not test under windows because focus testing is not reliable on
-// Windows, crbug.com/79493
-#if !defined(OS_WIN)
-IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshTest, Focus) {
-  chrome::ToggleFullscreenMode(browser());
-  ASSERT_TRUE(controller()->IsEnabled());
-
-  // 1) Test that focusing the location bar automatically reveals the
-  // top-of-window views.
-  //
-  // Move the mouse of the way.
-  controller()->SetMouseHoveredForTest(false);
-  browser_view()->SetFocusToLocationBar(false);
-  EXPECT_TRUE(controller()->IsRevealed());
-  browser_view()->GetFocusManager()->ClearFocus();
-  EXPECT_FALSE(controller()->IsRevealed());
-
-  // 2) Test that the top-of-window views stay revealed as long as either the
-  // location bar has focus or the mouse is hovered above the top-of-window
-  // views.
-  controller()->StartRevealForTest(true);
-  browser_view()->SetFocusToLocationBar(false);
-  browser_view()->GetFocusManager()->ClearFocus();
-  EXPECT_TRUE(controller()->IsRevealed());
-  browser_view()->SetFocusToLocationBar(false);
-  controller()->SetMouseHoveredForTest(false);
-  EXPECT_TRUE(controller()->IsRevealed());
-  browser_view()->GetFocusManager()->ClearFocus();
-  EXPECT_FALSE(controller()->IsRevealed());
-
-  // 3) Test that a bubble keeps the top-of-window views revealed for the
-  // duration of its visibity.
-  //
-  // Setup so that the bookmark bubble actually shows.
-  ui_test_utils::WaitForBookmarkModelToLoad(
-      BookmarkModelFactory::GetForProfile(browser()->profile()));
-  browser_view()->Activate();
-  EXPECT_TRUE(browser_view()->IsActive());
-
-  controller()->StartRevealForTest(false);
-  chrome::ExecuteCommand(browser(), IDC_BOOKMARK_PAGE_FROM_STAR);
-  EXPECT_TRUE(chrome::IsBookmarkBubbleViewShowing());
-  EXPECT_TRUE(controller()->IsRevealed());
-  chrome::HideBookmarkBubbleView();
-  EXPECT_FALSE(controller()->IsRevealed());
-
-  // 4) Test that focusing the web contents hides the top-of-window views.
-  browser_view()->SetFocusToLocationBar(false);
-  EXPECT_TRUE(controller()->IsRevealed());
-  browser_view()->GetTabContentsContainerView()->RequestFocus();
-  EXPECT_FALSE(controller()->IsRevealed());
-
-  // 5) Test that a loss of focus of the location bar to the web contents
-  // while immersive mode is disabled is properly registered.
-  browser_view()->SetFocusToLocationBar(false);
-  EXPECT_TRUE(controller()->IsRevealed());
-  chrome::ToggleFullscreenMode(browser());
-  EXPECT_FALSE(controller()->IsEnabled());
-  EXPECT_FALSE(controller()->IsRevealed());
-  browser_view()->GetTabContentsContainerView()->RequestFocus();
-  chrome::ToggleFullscreenMode(browser());
-  EXPECT_TRUE(controller()->IsEnabled());
-  EXPECT_FALSE(controller()->IsRevealed());
-
-  // Repeat test but with a revealed lock acquired when immersive mode is
-  // enabled because the code path is different.
-  browser_view()->SetFocusToLocationBar(false);
-  EXPECT_TRUE(controller()->IsRevealed());
-  chrome::ToggleFullscreenMode(browser());
-  scoped_ptr<ImmersiveRevealedLock> lock(controller()->GetRevealedLock(
-      ImmersiveModeController::ANIMATE_REVEAL_NO));
-  EXPECT_FALSE(controller()->IsRevealed());
-  browser_view()->GetTabContentsContainerView()->RequestFocus();
-  chrome::ToggleFullscreenMode(browser());
-  EXPECT_TRUE(controller()->IsRevealed());
-  lock.reset();
-  EXPECT_FALSE(controller()->IsRevealed());
-
-  // 6) Test that a dialog opened by the web contents does not initiate a
-  // reveal.
-  AppModalDialogQueue* queue = AppModalDialogQueue::GetInstance();
-  EXPECT_FALSE(queue->HasActiveDialog());
-  content::WebContents* web_contents = browser_view()->GetActiveWebContents();
-  GetJavaScriptDialogManagerInstance()->RunBeforeUnloadDialog(
-      web_contents,
-      string16(),
-      false,
-      base::Bind(
-          &ImmersiveModeControllerAshTest::OnBeforeUnloadJavaScriptDialogClosed,
-          base::Unretained(this)));
-  EXPECT_TRUE(queue->HasActiveDialog());
-  EXPECT_FALSE(controller()->IsRevealed());
-}
-#endif  // OS_WIN
-
 // Test behavior when the mouse becomes hovered without moving.
 IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshTest,
                        MouseHoveredWithoutMoving) {
@@ -438,126 +328,6 @@
   EXPECT_FALSE(controller()->IsRevealed());
 }
 
-// Test how changing the bounds of the top container repositions anchored
-// widgets and how the visibility of anchored widgets affects whether the
-// top-of-window views stay revealed.
-IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshTest, AnchoredWidgets) {
-  BookmarkBarView::DisableAnimationsForTesting(true);
-
-  chrome::ToggleFullscreenMode(browser());
-  ASSERT_TRUE(controller()->IsEnabled());
-
-  gfx::Rect kInitialBounds(100, 100, 100, 100);
-  views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
-  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
-  params.parent = browser_view()->GetNativeWindow();
-  params.bounds = kInitialBounds;
-  views::Widget anchored_widget;
-  anchored_widget.Init(params);
-
-  // 1) Test that an anchored widget does not cause the top-of-window views to
-  // reveal but instead prolongs the duration of the reveal till either the
-  // widget is unanchored or is hidden.
-  EXPECT_FALSE(controller()->IsRevealed());
-
-  anchored_widget.Show();
-  controller()->AnchorWidgetToTopContainer(&anchored_widget, 10);
-
-  // Anchoring a widget should not cause the top-of-window views to reveal.
-  EXPECT_FALSE(controller()->IsRevealed());
-
-  controller()->StartRevealForTest(true);
-  EXPECT_TRUE(controller()->IsRevealed());
-
-  // Once the top-of-window views are revealed, the top-of-window views should
-  // stay revealed as long as there is a visible anchored widget (or something
-  // else like the mouse hover is keeping the top-of-window views revealed).
-  controller()->SetMouseHoveredForTest(false);
-  EXPECT_TRUE(controller()->IsRevealed());
-  anchored_widget.Hide();
-  EXPECT_FALSE(controller()->IsRevealed());
-
-  anchored_widget.Show();
-  EXPECT_FALSE(controller()->IsRevealed());
-  controller()->StartRevealForTest(true);
-  EXPECT_TRUE(controller()->IsRevealed());
-
-  controller()->UnanchorWidgetFromTopContainer(&anchored_widget);
-  EXPECT_TRUE(controller()->IsRevealed());
-  controller()->SetMouseHoveredForTest(false);
-  EXPECT_FALSE(controller()->IsRevealed());
-
-  // 2) Test that the anchored widget is repositioned to |y_offset| below
-  // the bottom of the top container when the top container bounds are changed.
-  //
-  // Make sure that the bookmark bar is hidden.
-  ui_test_utils::WaitForBookmarkModelToLoad(
-      BookmarkModelFactory::GetForProfile(browser()->profile()));
-  if (browser_view()->IsBookmarkBarVisible())
-    chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR);
-  EXPECT_FALSE(browser_view()->IsBookmarkBarVisible());
-
-  anchored_widget.SetBounds(kInitialBounds);
-
-  // Anchoring the widget should adjust the top-of-window bounds.
-  controller()->AnchorWidgetToTopContainer(&anchored_widget, 10);
-  gfx::Rect bounds1 = anchored_widget.GetWindowBoundsInScreen();
-  EXPECT_EQ(bounds1.y(),
-            browser_view()->top_container()->GetBoundsInScreen().bottom() + 10);
-  EXPECT_EQ(kInitialBounds.x(), bounds1.x());
-  EXPECT_EQ(kInitialBounds.size(), bounds1.size());
-
-  controller()->StartRevealForTest(true);
-  gfx::Rect bounds2 = anchored_widget.GetWindowBoundsInScreen();
-
-  // The top-of-window bounds changed in the immersive reveal. |anchored_widget|
-  // should have been repositioned.
-  EXPECT_EQ(bounds2.y(),
-            browser_view()->top_container()->GetBoundsInScreen().bottom() + 10);
-  EXPECT_EQ(kInitialBounds.x(), bounds2.x());
-  EXPECT_EQ(kInitialBounds.size(), bounds2.size());
-
-  // Showing the bookmark bar changes the top container bounds and should
-  // reposition the anchored widget.
-  chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR);
-  EXPECT_TRUE(browser_view()->IsBookmarkBarVisible());
-  gfx::Rect bounds3 = anchored_widget.GetWindowBoundsInScreen();
-  EXPECT_EQ(bounds3.y(),
-            browser_view()->top_container()->GetBoundsInScreen().bottom() + 10);
-  EXPECT_GT(bounds3.y(), bounds2.y());
-  EXPECT_EQ(kInitialBounds.x(), bounds3.x());
-  EXPECT_EQ(kInitialBounds.size(), bounds3.size());
-
-  // 3) Test that the anchored widget is not repositioned when immersive mode
-  // is not enabled.
-  chrome::ToggleFullscreenMode(browser());
-  ASSERT_FALSE(controller()->IsEnabled());
-  chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR);
-  EXPECT_EQ(bounds3, anchored_widget.GetWindowBoundsInScreen());
-  EXPECT_NE(browser_view()->top_container()->GetBoundsInScreen().bottom() + 10,
-            bounds3.bottom());
-
-  // 4) Test that reenabling immersive fullscreen repositions any anchored
-  // widgets.
-  //
-  // Maximize the window so that a bounds change in the top container is not
-  // reported when entering immersive fullscreen. The top container has the
-  // same bounds when |browser_view| is maximized as when the top container is
-  // revealed when |browser_view_| is in immersive mode.
-  ash::wm::MaximizeWindow(browser_view()->GetNativeWindow());
-  chrome::ToggleFullscreenMode(browser());
-  ASSERT_TRUE(controller()->IsEnabled());
-
-  gfx::Rect bounds4 = anchored_widget.GetWindowBoundsInScreen();
-  EXPECT_NE(bounds3, bounds4);
-  EXPECT_EQ(bounds4.y(),
-            browser_view()->top_container()->GetBoundsInScreen().bottom() + 10);
-  EXPECT_EQ(kInitialBounds.x(), bounds4.x());
-  EXPECT_EQ(kInitialBounds.size(), bounds4.size());
-
-  BookmarkBarView::DisableAnimationsForTesting(false);
-}
-
 // Shelf-specific immersive mode tests.
 IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshTest, ImmersiveShelf) {
   // Shelf is visible when the test starts.
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
index f3125d7..b02982b 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
@@ -10,6 +10,7 @@
 #include "ui/aura/root_window.h"
 #include "ui/aura/test/event_generator.h"
 #include "ui/aura/window.h"
+#include "ui/views/bubble/bubble_delegate.h"
 
 // For now, immersive fullscreen is Chrome OS only.
 #if defined(OS_CHROMEOS)
@@ -111,6 +112,13 @@
     AttemptRevealStateChange(false, modality);
   }
 
+  // Sets whether the mouse is hovered above |top_container_|.
+  // SetHovered(true) moves the mouse over the |top_container_| but does not
+  // move it to the top of the screen so will not initiate a reveal.
+  void SetHovered(bool is_mouse_hovered) {
+    MoveMouse(0, is_mouse_hovered ? 1 : top_container_->height() + 100);
+  }
+
   // Move the mouse to the given coordinates. The coordinates should be in
   // |top_container_| coordinates.
   void MoveMouse(int x, int y) {
@@ -396,4 +404,234 @@
   EXPECT_FALSE(controller()->IsRevealed());
 }
 
+// Do not test under windows because focus testing is not reliable on
+// Windows. (crbug.com/79493)
+#if !defined(OS_WIN)
+
+// Test how focus and activation affects whether the top-of-window views are
+// revealed.
+TEST_F(ImmersiveModeControllerAshTest, Focus) {
+  // Add views to the view hierarchy which we will focus and unfocus during the
+  // test.
+  views::View* child_view = new views::View();
+  child_view->SetBounds(0, 0, 10, 10);
+  child_view->set_focusable(true);
+  top_container()->AddChildView(child_view);
+  views::View* unrelated_view = new views::View();
+  unrelated_view->SetBounds(0, 100, 10, 10);
+  unrelated_view->set_focusable(true);
+  top_container()->parent()->AddChildView(unrelated_view);
+  views::FocusManager* focus_manager =
+      top_container()->GetWidget()->GetFocusManager();
+
+  controller()->SetEnabled(true);
+
+  // 1) Test that the top-of-window views stay revealed as long as either a
+  // |child_view| has focus or the mouse is hovered above the top-of-window
+  // views.
+  AttemptReveal(MODALITY_MOUSE);
+  child_view->RequestFocus();
+  focus_manager->ClearFocus();
+  EXPECT_TRUE(controller()->IsRevealed());
+  child_view->RequestFocus();
+  SetHovered(false);
+  EXPECT_TRUE(controller()->IsRevealed());
+  focus_manager->ClearFocus();
+  EXPECT_FALSE(controller()->IsRevealed());
+
+  // 2) Test that focusing |unrelated_view| hides the top-of-window views.
+  // Note: In this test we can cheat and trigger a reveal via focus because
+  // the top container does not hide when the top-of-window views are not
+  // revealed.
+  child_view->RequestFocus();
+  EXPECT_TRUE(controller()->IsRevealed());
+  unrelated_view->RequestFocus();
+  EXPECT_FALSE(controller()->IsRevealed());
+
+  // 3) Test that a loss of focus of |child_view| to |unrelated_view|
+  // while immersive mode is disabled is properly registered.
+  child_view->RequestFocus();
+  EXPECT_TRUE(controller()->IsRevealed());
+  controller()->SetEnabled(false);
+  EXPECT_FALSE(controller()->IsRevealed());
+  unrelated_view->RequestFocus();
+  controller()->SetEnabled(true);
+  EXPECT_FALSE(controller()->IsRevealed());
+
+  // Repeat test but with a revealed lock acquired when immersive mode is
+  // disabled because the code path is different.
+  child_view->RequestFocus();
+  EXPECT_TRUE(controller()->IsRevealed());
+  controller()->SetEnabled(false);
+  scoped_ptr<ImmersiveRevealedLock> lock(controller()->GetRevealedLock(
+      ImmersiveModeController::ANIMATE_REVEAL_NO));
+  EXPECT_FALSE(controller()->IsRevealed());
+  unrelated_view->RequestFocus();
+  controller()->SetEnabled(true);
+  EXPECT_TRUE(controller()->IsRevealed());
+  lock.reset();
+  EXPECT_FALSE(controller()->IsRevealed());
+}
+
+// Test how activation affects whether the top-of-window views are revealed.
+// The behavior when a bubble is activated is tested in
+// ImmersiveModeControllerAshTest.Bubbles.
+TEST_F(ImmersiveModeControllerAshTest, Activation) {
+  views::Widget* top_container_widget = top_container()->GetWidget();
+
+  controller()->SetEnabled(true);
+  ASSERT_FALSE(controller()->IsRevealed());
+
+  // 1) Test that a transient window which is not a bubble does not trigger a
+  // reveal but does keep the top-of-window views revealed if they are already
+  // revealed.
+  views::Widget::InitParams transient_params;
+  transient_params.ownership =
+      views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  transient_params.parent = top_container_widget->GetNativeView();
+  transient_params.bounds = gfx::Rect(0, 0, 100, 100);
+  scoped_ptr<views::Widget> transient_widget(new views::Widget());
+  transient_widget->Init(transient_params);
+  transient_widget->Show();
+
+  EXPECT_FALSE(controller()->IsRevealed());
+  top_container_widget->Activate();
+  AttemptReveal(MODALITY_MOUSE);
+  EXPECT_TRUE(controller()->IsRevealed());
+  transient_widget->Activate();
+  SetHovered(false);
+  EXPECT_TRUE(controller()->IsRevealed());
+  transient_widget.reset();
+  EXPECT_FALSE(controller()->IsRevealed());
+
+  // 2) Test that activating a non-transient window ends the reveal if any.
+  views::Widget::InitParams non_transient_params;
+  non_transient_params.ownership =
+      views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  non_transient_params.context = top_container_widget->GetNativeView();
+  non_transient_params.bounds = gfx::Rect(0, 0, 100, 100);
+  scoped_ptr<views::Widget> non_transient_widget(new views::Widget());
+  non_transient_widget->Init(non_transient_params);
+  non_transient_widget->Show();
+
+  EXPECT_FALSE(controller()->IsRevealed());
+  top_container_widget->Activate();
+  AttemptReveal(MODALITY_MOUSE);
+  EXPECT_TRUE(controller()->IsRevealed());
+  non_transient_widget->Activate();
+  EXPECT_FALSE(controller()->IsRevealed());
+}
+
+// Test how bubbles affect whether the top-of-window views are revealed.
+TEST_F(ImmersiveModeControllerAshTest, Bubbles) {
+  scoped_ptr<ImmersiveRevealedLock> revealed_lock;
+  views::Widget* top_container_widget = top_container()->GetWidget();
+
+  // Add views to the view hierarchy to which we will anchor bubbles.
+  views::View* child_view = new views::View();
+  child_view->SetBounds(0, 0, 10, 10);
+  top_container()->AddChildView(child_view);
+  views::View* unrelated_view = new views::View();
+  unrelated_view->SetBounds(0, 100, 10, 10);
+  top_container()->parent()->AddChildView(unrelated_view);
+
+  controller()->SetEnabled(true);
+  ASSERT_FALSE(controller()->IsRevealed());
+
+  // 1) Test that a bubble anchored to a child of the top container triggers
+  // a reveal and keeps the top-of-window views revealed for the duration of
+  // its visibility.
+  views::Widget* bubble_widget1(views::BubbleDelegateView::CreateBubble(
+      new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE)));
+  bubble_widget1->Show();
+  EXPECT_TRUE(controller()->IsRevealed());
+
+  // Activating |top_container_widget| will close |bubble_widget1|.
+  top_container_widget->Activate();
+  AttemptReveal(MODALITY_MOUSE);
+  revealed_lock.reset(controller()->GetRevealedLock(
+      ImmersiveModeController::ANIMATE_REVEAL_NO));
+  EXPECT_TRUE(controller()->IsRevealed());
+
+  views::Widget* bubble_widget2 = views::BubbleDelegateView::CreateBubble(
+      new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE));
+  bubble_widget2->Show();
+  EXPECT_TRUE(controller()->IsRevealed());
+  revealed_lock.reset();
+  SetHovered(false);
+  EXPECT_TRUE(controller()->IsRevealed());
+  bubble_widget2->Close();
+  EXPECT_FALSE(controller()->IsRevealed());
+
+  // 2) Test that the top-of-window views stay revealed as long as at least one
+  // bubble anchored to a child of the top container is visible.
+  views::BubbleDelegateView* bubble_delegate3(new views::BubbleDelegateView(
+      child_view, views::BubbleBorder::NONE));
+  bubble_delegate3->set_use_focusless(true);
+  views::Widget* bubble_widget3(views::BubbleDelegateView::CreateBubble(
+      bubble_delegate3));
+  bubble_widget3->Show();
+
+  views::BubbleDelegateView* bubble_delegate4(new views::BubbleDelegateView(
+      child_view, views::BubbleBorder::NONE));
+  bubble_delegate4->set_use_focusless(true);
+  views::Widget* bubble_widget4(views::BubbleDelegateView::CreateBubble(
+      bubble_delegate4));
+  bubble_widget4->Show();
+
+  EXPECT_TRUE(controller()->IsRevealed());
+  bubble_widget3->Hide();
+  EXPECT_TRUE(controller()->IsRevealed());
+  bubble_widget4->Hide();
+  EXPECT_FALSE(controller()->IsRevealed());
+  bubble_widget4->Show();
+  EXPECT_TRUE(controller()->IsRevealed());
+
+  // 3) Test that visibility changes which occur while immersive fullscreen is
+  // disabled are handled upon reenabling immersive fullscreen.
+  controller()->SetEnabled(false);
+  bubble_widget4->Hide();
+  controller()->SetEnabled(true);
+  EXPECT_FALSE(controller()->IsRevealed());
+
+  // We do not need |bubble_widget3| or |bubble_widget4| anymore, close them.
+  bubble_widget3->Close();
+  bubble_widget4->Close();
+
+  // 4) Test that a bubble added while immersive fullscreen is disabled is
+  // handled upon reenabling immersive fullscreen.
+  controller()->SetEnabled(false);
+
+  views::Widget* bubble_widget5 = views::BubbleDelegateView::CreateBubble(
+      new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE));
+  bubble_widget5->Show();
+
+  controller()->SetEnabled(true);
+  EXPECT_TRUE(controller()->IsRevealed());
+
+  bubble_widget5->Close();
+
+  // 5) Test that a bubble which is not anchored to a child of the
+  // TopContainerView does not trigger a reveal or keep the
+  // top-of-window views revealed if they are already revealed.
+  views::Widget* bubble_widget6 = views::BubbleDelegateView::CreateBubble(
+      new views::BubbleDelegateView(unrelated_view, views::BubbleBorder::NONE));
+  bubble_widget6->Show();
+  EXPECT_FALSE(controller()->IsRevealed());
+
+  // Activating |top_container_widget| will close |bubble_widget6|.
+  top_container_widget->Activate();
+  AttemptReveal(MODALITY_MOUSE);
+  EXPECT_TRUE(controller()->IsRevealed());
+
+  views::Widget* bubble_widget7 = views::BubbleDelegateView::CreateBubble(
+      new views::BubbleDelegateView(unrelated_view, views::BubbleBorder::NONE));
+  bubble_widget7->Show();
+  SetHovered(false);
+  EXPECT_FALSE(controller()->IsRevealed());
+  bubble_widget7->Close();
+}
+
+#endif  // defined(OS_WIN)
+
 #endif  // defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_stub.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_stub.cc
index 5b11ec2..fdcedd5 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_stub.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_stub.cc
@@ -48,18 +48,6 @@
   return NULL;
 }
 
-void ImmersiveModeControllerStub::AnchorWidgetToTopContainer(
-    views::Widget* widget,
-    int y_offset) {
-}
-
-void ImmersiveModeControllerStub::UnanchorWidgetFromTopContainer(
-    views::Widget* widget) {
-}
-
-void ImmersiveModeControllerStub::OnTopContainerBoundsChanged() {
-}
-
 void ImmersiveModeControllerStub::OnFindBarVisibleBoundsChanged(
     const gfx::Rect& new_visible_bounds_in_screen) {
 }
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_stub.h b/chrome/browser/ui/views/frame/immersive_mode_controller_stub.h
index 2d03832..27bfba0 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_stub.h
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_stub.h
@@ -30,10 +30,6 @@
       const gfx::Size& top_container_size) const OVERRIDE;
   virtual ImmersiveRevealedLock* GetRevealedLock(
       AnimateReveal animate_reveal) OVERRIDE WARN_UNUSED_RESULT;
-  virtual void AnchorWidgetToTopContainer(views::Widget* widget,
-                                          int y_offset) OVERRIDE;
-  virtual void UnanchorWidgetFromTopContainer(views::Widget* widget) OVERRIDE;
-  virtual void OnTopContainerBoundsChanged() OVERRIDE;
   virtual void OnFindBarVisibleBoundsChanged(
       const gfx::Rect& new_visible_bounds_in_screen) OVERRIDE;
 
diff --git a/chrome/browser/ui/views/frame/minimize_button_metrics_win.cc b/chrome/browser/ui/views/frame/minimize_button_metrics_win.cc
index 1855b35..827aeda 100644
--- a/chrome/browser/ui/views/frame/minimize_button_metrics_win.cc
+++ b/chrome/browser/ui/views/frame/minimize_button_metrics_win.cc
@@ -24,7 +24,7 @@
                                    ui::win::GetUndocumentedDPIScale(),
                                    0 };
   MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1);
-  return minimize_button_corner.x;
+  return minimize_button_corner.x / ui::win::GetDeviceScaleFactor();
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
index c4bbf28..3e0547b 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
@@ -11,6 +11,7 @@
 #include "base/compiler_specific.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/views/avatar_label.h"
 #include "chrome/browser/ui/views/avatar_menu_button.h"
@@ -19,7 +20,6 @@
 #include "chrome/browser/ui/views/tab_icon_view.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "chrome/browser/ui/views/toolbar_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
@@ -235,12 +235,17 @@
     return gfx::Rect();
 
   gfx::Rect bounds = GetBoundsForTabStripAndAvatarArea(tabstrip);
-  int space_left_of_tabstrip = browser_view()->ShouldShowAvatar() ?
-      (kAvatarLeftSpacing + avatar_bounds_.width() + kAvatarRightSpacing) :
-      kTabStripIndent;
-  if (avatar_label() && avatar_label()->bounds().width()) {
-    space_left_of_tabstrip += views::kRelatedControlHorizontalSpacing +
-                              avatar_label()->bounds().width();
+  int space_left_of_tabstrip = kTabStripIndent;
+  if (browser_view()->ShouldShowAvatar()) {
+    if (avatar_label() && avatar_label()->bounds().width()) {
+      // Space between the right edge of the avatar label and the tabstrip.
+      const int kAvatarLabelRightSpacing = -10;
+      space_left_of_tabstrip =
+          avatar_label()->bounds().right() + kAvatarLabelRightSpacing;
+    } else {
+      space_left_of_tabstrip =
+          kAvatarLeftSpacing + avatar_bounds_.width() + kAvatarRightSpacing;
+    }
   }
   bounds.Inset(space_left_of_tabstrip, 0, 0, 0);
   return bounds;
@@ -1030,13 +1035,17 @@
     avatar_button()->SetBoundsRect(avatar_bounds_);
 
   if (avatar_label()) {
-    gfx::Size size = avatar_label()->GetPreferredSize();
-    int label_height = std::min(avatar_bounds_.height(), size.height());
+    // Space between the bottom of the avatar and the bottom of the avatar
+    // label.
+    const int kAvatarLabelBottomSpacing = 3;
+    // Space between the frame border and the left edge of the avatar label.
+    const int kAvatarLabelLeftSpacing = -1;
+    gfx::Size label_size = avatar_label()->GetPreferredSize();
     gfx::Rect label_bounds(
-        avatar_bounds_.right() + views::kRelatedControlHorizontalSpacing,
-        avatar_y + (avatar_bounds_.height() - label_height) / 2,
-        size.width(),
-        browser_view()->ShouldShowAvatar() ? size.height() : 0);
+        FrameBorderThickness(false) + kAvatarLabelLeftSpacing,
+        avatar_bottom - kAvatarLabelBottomSpacing - label_size.height(),
+        label_size.width(),
+        browser_view()->ShouldShowAvatar() ? label_size.height() : 0);
     avatar_label()->SetBoundsRect(label_bounds);
   }
 }
diff --git a/chrome/browser/ui/views/frame/top_container_view.cc b/chrome/browser/ui/views/frame/top_container_view.cc
index 5563c6c..212c799 100644
--- a/chrome/browser/ui/views/frame/top_container_view.cc
+++ b/chrome/browser/ui/views/frame/top_container_view.cc
@@ -32,13 +32,6 @@
   return "TopContainerView";
 }
 
-void TopContainerView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
-  ImmersiveModeController* immersive_controller =
-      browser_view_->immersive_mode_controller();
-  if (immersive_controller->IsEnabled())
-    immersive_controller->OnTopContainerBoundsChanged();
-}
-
 void TopContainerView::PaintChildren(gfx::Canvas* canvas) {
   if (browser_view_->immersive_mode_controller()->IsRevealed()) {
     // Top-views depend on parts of the frame (themes, window buttons) being
diff --git a/chrome/browser/ui/views/frame/top_container_view.h b/chrome/browser/ui/views/frame/top_container_view.h
index 213db1c..7527f40 100644
--- a/chrome/browser/ui/views/frame/top_container_view.h
+++ b/chrome/browser/ui/views/frame/top_container_view.h
@@ -23,7 +23,6 @@
   // views::View overrides:
   virtual gfx::Size GetPreferredSize() OVERRIDE;
   virtual const char* GetClassName() const OVERRIDE;
-  virtual void OnBoundsChanged(const gfx::Rect& bounds) OVERRIDE;
   virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE;
 
  private:
diff --git a/chrome/browser/ui/views/fullscreen_exit_bubble_views.cc b/chrome/browser/ui/views/fullscreen_exit_bubble_views.cc
index 87bb1a3..030e4a4 100644
--- a/chrome/browser/ui/views/fullscreen_exit_bubble_views.cc
+++ b/chrome/browser/ui/views/fullscreen_exit_bubble_views.cc
@@ -7,13 +7,12 @@
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
 #include "chrome/browser/ui/views/frame/top_container_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "grit/ui_strings.h"
 #include "ui/base/animation/slide_animation.h"
@@ -30,6 +29,7 @@
 #include "ui/views/layout/grid_layout.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
+#include "url/gurl.h"
 
 #if defined(OS_WIN)
 #include "ui/base/l10n/l10n_util_win.h"
@@ -274,6 +274,8 @@
       this, accelerator.GetShortcutText(), url, bubble_type_);
 
   // TODO(yzshen): Change to use the new views bubble, BubbleDelegateView.
+  // TODO(pkotwicz): When this becomes a views bubble, make sure that this
+  // bubble is ignored by ImmersiveModeControllerAsh::BubbleManager.
   // Initialize the popup.
   popup_ = new views::Widget;
   views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
@@ -306,11 +308,6 @@
 
 FullscreenExitBubbleViews::~FullscreenExitBubbleViews() {
   popup_->RemoveObserver(this);
-  ImmersiveModeController* immersive_controller =
-      browser_view_->immersive_mode_controller();
-  // |immersive_controller| may already have been destroyed.
-  if (immersive_controller)
-    immersive_controller->UnanchorWidgetFromTopContainer(popup_);
 
   // This is tricky.  We may be in an ATL message handler stack, in which case
   // the popup cannot be deleted yet.  We also can't set the popup's ownership
@@ -349,6 +346,11 @@
   UpdateMouseWatcher();
 }
 
+void FullscreenExitBubbleViews::RepositionIfVisible() {
+  if (popup_->IsVisible())
+    UpdateBounds();
+}
+
 void FullscreenExitBubbleViews::UpdateMouseWatcher() {
   bool should_watch_mouse = false;
   if (popup_->IsVisible())
@@ -366,11 +368,8 @@
 }
 
 void FullscreenExitBubbleViews::UpdateForImmersiveState() {
-  ImmersiveModeController* immersive_controller =
-      browser_view_->immersive_mode_controller();
-
   AnimatedAttribute expected_animated_attribute =
-      immersive_controller->IsEnabled() ?
+      browser_view_->immersive_mode_controller()->IsEnabled() ?
           ANIMATED_ATTRIBUTE_OPACITY : ANIMATED_ATTRIBUTE_BOUNDS;
   if (animated_attribute_ != expected_animated_attribute) {
     // If an animation is currently in progress, skip to the end because
@@ -389,27 +388,14 @@
       UpdateBounds();
   }
 
-  if (immersive_controller->IsEnabled()) {
-    // In immersive mode, anchor |popup_| to the top container. This repositions
-    // the top container so that it stays |kPopupTopPx| below the top container
-    // when the top container animates its position (top container reveals /
-    // unreveals) or the top container bounds change (eg bookmark bar is shown).
-    immersive_controller->AnchorWidgetToTopContainer(popup_, kPopupTopPx);
-  } else {
-    immersive_controller->UnanchorWidgetFromTopContainer(popup_);
-  }
-
   UpdateMouseWatcher();
 }
 
 void FullscreenExitBubbleViews::UpdateBounds() {
   gfx::Rect popup_rect(GetPopupRect(false));
-  if (popup_rect.IsEmpty()) {
-    popup_->Hide();
-  } else {
+  if (!popup_rect.IsEmpty()) {
     popup_->SetBounds(popup_rect);
     view_->SetY(popup_rect.height() - view_->height());
-    popup_->Show();
   }
 }
 
@@ -428,7 +414,12 @@
       popup_->SetOpacity(opacity);
     }
   } else {
-    UpdateBounds();
+    if (GetPopupRect(false).IsEmpty()) {
+      popup_->Hide();
+    } else {
+      UpdateBounds();
+      popup_->Show();
+    }
   }
 }
 
diff --git a/chrome/browser/ui/views/fullscreen_exit_bubble_views.h b/chrome/browser/ui/views/fullscreen_exit_bubble_views.h
index 0d7e2d7..d98de0c 100644
--- a/chrome/browser/ui/views/fullscreen_exit_bubble_views.h
+++ b/chrome/browser/ui/views/fullscreen_exit_bubble_views.h
@@ -37,6 +37,9 @@
 
   void UpdateContent(const GURL& url, FullscreenExitBubbleType bubble_type);
 
+  // Repositions |popup_| if it is visible.
+  void RepositionIfVisible();
+
  private:
   class FullscreenExitView;
 
diff --git a/chrome/browser/ui/views/hung_renderer_view.cc b/chrome/browser/ui/views/hung_renderer_view.cc
index 5ff6306..665064b 100644
--- a/chrome/browser/ui/views/hung_renderer_view.cc
+++ b/chrome/browser/ui/views/hung_renderer_view.cc
@@ -158,7 +158,7 @@
       model_(model) {
 }
 
-void HungPagesTableModel::WebContentsObserverImpl::RenderViewGone(
+void HungPagesTableModel::WebContentsObserverImpl::RenderProcessGone(
     base::TerminationStatus status) {
   model_->TabDestroyed(this);
 }
diff --git a/chrome/browser/ui/views/hung_renderer_view.h b/chrome/browser/ui/views/hung_renderer_view.h
index a657b44..0593f1f 100644
--- a/chrome/browser/ui/views/hung_renderer_view.h
+++ b/chrome/browser/ui/views/hung_renderer_view.h
@@ -74,7 +74,7 @@
     }
 
     // WebContentsObserver overrides:
-    virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+    virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
     virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE;
 
    private:
diff --git a/chrome/browser/ui/views/infobars/infobar_container_view.cc b/chrome/browser/ui/views/infobars/infobar_container_view.cc
index 8bc5752..50a5266 100644
--- a/chrome/browser/ui/views/infobars/infobar_container_view.cc
+++ b/chrome/browser/ui/views/infobars/infobar_container_view.cc
@@ -14,9 +14,8 @@
 // static
 const char InfoBarContainerView::kViewClassName[] = "InfoBarContainerView";
 
-InfoBarContainerView::InfoBarContainerView(Delegate* delegate,
-                                           SearchModel* search_model)
-    : InfoBarContainer(delegate, search_model) {
+InfoBarContainerView::InfoBarContainerView(Delegate* delegate)
+    : InfoBarContainer(delegate) {
   set_id(VIEW_ID_INFO_BAR_CONTAINER);
 }
 
diff --git a/chrome/browser/ui/views/infobars/infobar_container_view.h b/chrome/browser/ui/views/infobars/infobar_container_view.h
index 6efda9a..73cd321 100644
--- a/chrome/browser/ui/views/infobars/infobar_container_view.h
+++ b/chrome/browser/ui/views/infobars/infobar_container_view.h
@@ -14,8 +14,7 @@
  public:
   static const char kViewClassName[];
 
-  explicit InfoBarContainerView(Delegate* delegate,
-                                SearchModel* search_model);
+  explicit InfoBarContainerView(Delegate* delegate);
   virtual ~InfoBarContainerView();
 
  private:
diff --git a/chrome/browser/ui/views/keyboard_access_browsertest.cc b/chrome/browser/ui/views/keyboard_access_browsertest.cc
index 3e69624..23904d4 100644
--- a/chrome/browser/ui/views/keyboard_access_browsertest.cc
+++ b/chrome/browser/ui/views/keyboard_access_browsertest.cc
@@ -10,12 +10,12 @@
 #include "base/message_loop.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/toolbar_view.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/ui/views/location_bar/autofill_credit_card_view.cc b/chrome/browser/ui/views/location_bar/autofill_credit_card_view.cc
new file mode 100644
index 0000000..21e7208
--- /dev/null
+++ b/chrome/browser/ui/views/location_bar/autofill_credit_card_view.cc
@@ -0,0 +1,52 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/location_bar/autofill_credit_card_view.h"
+
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h"
+#include "chrome/browser/ui/toolbar/toolbar_model.h"
+#include "ui/gfx/image/image.h"
+
+AutofillCreditCardView::AutofillCreditCardView(
+    ToolbarModel* toolbar_model,
+    LocationBarView::Delegate* delegate)
+    : toolbar_model_(toolbar_model),
+      delegate_(delegate) {
+  Update();
+}
+
+AutofillCreditCardView::~AutofillCreditCardView() {}
+
+void AutofillCreditCardView::Update() {
+  autofill::AutofillCreditCardBubbleController* controller = GetController();
+  if (controller && !controller->AnchorIcon().IsEmpty()) {
+    SetVisible(true);
+    SetImage(controller->AnchorIcon().AsImageSkia());
+  } else {
+    SetVisible(false);
+    SetImage(NULL);
+  }
+}
+
+// TODO(dbeam): figure out what to do for a tooltip and accessibility.
+
+bool AutofillCreditCardView::CanHandleClick() const {
+  autofill::AutofillCreditCardBubbleController* controller = GetController();
+  return controller && !controller->IsHiding();
+}
+
+void AutofillCreditCardView::OnClick() {
+  autofill::AutofillCreditCardBubbleController* controller = GetController();
+  if (controller)
+    controller->OnAnchorClicked();
+}
+
+autofill::AutofillCreditCardBubbleController* AutofillCreditCardView::
+    GetController() const {
+  content::WebContents* wc = delegate_->GetWebContents();
+  if (!wc || toolbar_model_->GetInputInProgress())
+    return NULL;
+
+  return autofill::AutofillCreditCardBubbleController::FromWebContents(wc);
+}
diff --git a/chrome/browser/ui/views/location_bar/autofill_credit_card_view.h b/chrome/browser/ui/views/location_bar/autofill_credit_card_view.h
new file mode 100644
index 0000000..169c5f2
--- /dev/null
+++ b/chrome/browser/ui/views/location_bar/autofill_credit_card_view.h
@@ -0,0 +1,54 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_AUTOFILL_CREDIT_CARD_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_AUTOFILL_CREDIT_CARD_VIEW_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_decoration_view.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
+#include "ui/views/controls/image_view.h"
+
+class ToolbarModel;
+
+namespace autofill {
+class AutofillCreditCardBubbleController;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// AutofillCreditCardView
+//
+//  An icon that shows up in the omnibox after successfully submitting the
+//  Autofill dialog. Used as an anchor and click target to show the associated
+//  bubble with more details about the credit cards saved or used.
+//
+////////////////////////////////////////////////////////////////////////////////
+class AutofillCreditCardView : public LocationBarDecorationView {
+ public:
+  AutofillCreditCardView(ToolbarModel* toolbar_model,
+                         LocationBarView::Delegate* delegate);
+  virtual ~AutofillCreditCardView();
+
+  void Update();
+
+ protected:
+  // LocationBarDecorationView:
+  virtual bool CanHandleClick() const OVERRIDE;
+  virtual void OnClick() OVERRIDE;
+
+ private:
+  // Helper to get the AutofillCreditCardBubbleController associated with the
+  // current web contents.
+  autofill::AutofillCreditCardBubbleController* GetController() const;
+
+  ToolbarModel* toolbar_model_;  // weak; outlives us.
+  LocationBarView::Delegate* delegate_;  // weak; outlives us.
+
+  DISALLOW_COPY_AND_ASSIGN(AutofillCreditCardView);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_AUTOFILL_CREDIT_CARD_VIEW_H_
diff --git a/chrome/browser/ui/views/location_bar/location_bar_decoration_view.cc b/chrome/browser/ui/views/location_bar/location_bar_decoration_view.cc
new file mode 100644
index 0000000..443e368
--- /dev/null
+++ b/chrome/browser/ui/views/location_bar/location_bar_decoration_view.cc
@@ -0,0 +1,57 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/location_bar/location_bar_decoration_view.h"
+
+#include "ui/base/events/event.h"
+
+LocationBarDecorationView::LocationBarDecorationView()
+    : could_handle_click_(true) {
+  set_accessibility_focusable(true);
+  TouchableLocationBarView::Init(this);
+}
+
+LocationBarDecorationView::~LocationBarDecorationView() {}
+
+bool LocationBarDecorationView::OnMousePressed(const ui::MouseEvent& event) {
+  if (event.IsOnlyLeftMouseButton() && HitTestPoint(event.location())) {
+    // Do nothing until mouse is released.
+    could_handle_click_ = CanHandleClick();
+    return true;
+  }
+
+  return false;
+}
+
+void LocationBarDecorationView::OnMouseReleased(const ui::MouseEvent& event) {
+  if (event.IsOnlyLeftMouseButton() && HitTestPoint(event.location()) &&
+      could_handle_click_ && CanHandleClick()) {
+    OnClick();
+  }
+}
+
+bool LocationBarDecorationView::OnKeyPressed(const ui::KeyEvent& event) {
+  if (event.key_code() == ui::VKEY_SPACE ||
+      event.key_code() == ui::VKEY_RETURN) {
+    OnClick();
+    return true;
+  }
+
+  return false;
+}
+
+void LocationBarDecorationView::OnGestureEvent(ui::GestureEvent* event) {
+  if (event->type() == ui::ET_GESTURE_TAP) {
+    OnClick();
+    event->SetHandled();
+  }
+}
+
+int LocationBarDecorationView::GetBuiltInHorizontalPadding() const {
+  return GetBuiltInHorizontalPaddingImpl();
+}
+
+bool LocationBarDecorationView::CanHandleClick() const {
+  return true;
+}
diff --git a/chrome/browser/ui/views/location_bar/location_bar_decoration_view.h b/chrome/browser/ui/views/location_bar/location_bar_decoration_view.h
new file mode 100644
index 0000000..58e69db
--- /dev/null
+++ b/chrome/browser/ui/views/location_bar/location_bar_decoration_view.h
@@ -0,0 +1,53 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_DECORATION_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_DECORATION_VIEW_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "chrome/browser/ui/views/location_bar/touchable_location_bar_view.h"
+#include "ui/views/controls/image_view.h"
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// LocationBarDecorationView
+//
+//  An abstract class to provide common functionality to all icons that show up
+//  in the omnibox (like the bookmarks star or SSL lock).
+//
+////////////////////////////////////////////////////////////////////////////////
+class LocationBarDecorationView : public views::ImageView,
+                                  public TouchableLocationBarView {
+ public:
+  LocationBarDecorationView();
+  virtual ~LocationBarDecorationView();
+
+  // views::ImageView:
+  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
+  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
+  virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
+  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
+
+  // TouchableLocationBarView:
+  virtual int GetBuiltInHorizontalPadding() const OVERRIDE;
+
+ protected:
+  // Whether this icon should currently be able to process a mouse click. Called
+  // both on mouse up and mouse down; must return true both times to for
+  // |OnClick()| to be called.
+  virtual bool CanHandleClick() const;
+
+  // Called when a user mouses up, taps, or presses a key on this icon.
+  virtual void OnClick() = 0;
+
+ private:
+  // Set when the user's mouse goes down to determine whether |CanHandleClick()|
+  // was true at that point.
+  bool could_handle_click_;
+
+  DISALLOW_COPY_AND_ASSIGN(LocationBarDecorationView);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_DECORATION_VIEW_H_
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index cd2deb9..eaa8e7c 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -13,6 +13,7 @@
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/defaults.h"
 #include "chrome/browser/extensions/api/omnibox/omnibox_api.h"
@@ -38,11 +39,13 @@
 #include "chrome/browser/ui/views/browser_dialogs.h"
 #include "chrome/browser/ui/views/extensions/extension_popup.h"
 #include "chrome/browser/ui/views/location_bar/action_box_button_view.h"
+#include "chrome/browser/ui/views/location_bar/autofill_credit_card_view.h"
 #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h"
 #include "chrome/browser/ui/views/location_bar/ev_bubble_view.h"
 #include "chrome/browser/ui/views/location_bar/keyword_hint_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_layout.h"
 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
+#include "chrome/browser/ui/views/location_bar/mic_search_view.h"
 #include "chrome/browser/ui/views/location_bar/open_pdf_in_reader_view.h"
 #include "chrome/browser/ui/views/location_bar/page_action_image_view.h"
 #include "chrome/browser/ui/views/location_bar/page_action_with_badge_view.h"
@@ -54,7 +57,6 @@
 #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
 #include "chrome/browser/ui/views/omnibox/omnibox_views.h"
 #include "chrome/browser/ui/zoom/zoom_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/feature_switch.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
@@ -179,7 +181,9 @@
       selected_keyword_view_(NULL),
       suggested_text_view_(NULL),
       keyword_hint_view_(NULL),
+      mic_search_view_(NULL),
       zoom_view_(NULL),
+      autofill_credit_card_view_(NULL),
       open_pdf_in_reader_view_(NULL),
       script_bubble_icon_view_(NULL),
       star_view_(NULL),
@@ -210,11 +214,16 @@
       base::Bind(&LocationBarView::Update,
                  base::Unretained(this),
                  static_cast<content::WebContents*>(NULL)));
+
+  if (browser_)
+    browser_->search_model()->AddObserver(this);
 }
 
 LocationBarView::~LocationBarView() {
   if (template_url_service_)
     template_url_service_->RemoveObserver(this);
+  if (browser_)
+    browser_->search_model()->RemoveObserver(this);
 }
 
 void LocationBarView::Init() {
@@ -302,6 +311,10 @@
       background_color);
   AddChildView(keyword_hint_view_);
 
+  mic_search_view_ = new MicSearchView(this);
+  mic_search_view_->SetVisible(false);
+  AddChildView(mic_search_view_);
+
   for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
     ContentSettingImageView* content_blocked_view =
         new ContentSettingImageView(static_cast<ContentSettingsType>(i), this,
@@ -312,6 +325,9 @@
     AddChildView(content_blocked_view);
   }
 
+  autofill_credit_card_view_ = new AutofillCreditCardView(model_, delegate_);
+  AddChildView(autofill_credit_card_view_);
+
   zoom_view_ = new ZoomView(model_, delegate_);
   zoom_view_->set_id(VIEW_ID_ZOOM_BUTTON);
   AddChildView(zoom_view_);
@@ -323,17 +339,12 @@
   script_bubble_icon_view_->SetVisible(false);
   AddChildView(script_bubble_icon_view_);
 
-  // The star icon is hidden in popups.
-  if (browser_defaults::bookmarks_enabled && !is_popup_mode_) {
-    star_view_ = new StarView(command_updater_);
-    star_view_->SetVisible(true);
-    AddChildView(star_view_);
-  }
+  star_view_ = new StarView(command_updater_);
+  star_view_->SetVisible(false);
+  AddChildView(star_view_);
+
   if (extensions::FeatureSwitch::action_box()->IsEnabled() && !is_popup_mode_ &&
       browser_) {
-    if (star_view_)
-      star_view_->SetVisible(false);
-
     action_box_button_view_ = new ActionBoxButtonView(
         browser_,
         gfx::Point(GetHorizontalEdgeThickness(), vertical_edge_thickness()));
@@ -457,7 +468,11 @@
 }
 
 void LocationBarView::Update(const WebContents* tab_for_state_restoring) {
+  mic_search_view_->SetVisible(
+      !model_->GetInputInProgress() && browser_ &&
+      browser_->search_model()->voice_search_supported());
   RefreshContentSettingViews();
+  autofill_credit_card_view_->Update();
   ZoomBubbleView::CloseBubble();
   RefreshZoomView();
   RefreshPageActionViews();
@@ -465,8 +480,9 @@
   open_pdf_in_reader_view_->Update(
       model_->GetInputInProgress() ? NULL : GetWebContents());
 
-  bool star_enabled = star_view_ && !model_->GetInputInProgress() &&
-                      edit_bookmarks_enabled_.GetValue();
+  bool star_enabled =
+      browser_defaults::bookmarks_enabled && !is_popup_mode_ && star_view_ &&
+      !model_->GetInputInProgress() && edit_bookmarks_enabled_.GetValue();
 
   command_updater_->UpdateCommandEnabled(IDC_BOOKMARK_PAGE, star_enabled);
   command_updater_->UpdateCommandEnabled(IDC_BOOKMARK_PAGE_FROM_STAR,
@@ -522,6 +538,12 @@
   SchedulePaint();
 }
 
+void LocationBarView::UpdateAutofillCreditCardView() {
+  autofill_credit_card_view_->Update();
+  Layout();
+  SchedulePaint();
+}
+
 void LocationBarView::OnFocus() {
   // Focus the view widget first which implements accessibility for
   // Chrome OS.  It is noop on Win. This should be removed once
@@ -566,14 +588,12 @@
 }
 
 void LocationBarView::SetStarToggled(bool on) {
-  if (star_view_)
-    star_view_->SetToggled(on);
-
-  if (action_box_button_view_) {
-    if (star_view_ && (star_view_->visible() != on)) {
-      star_view_->SetVisible(on);
-      Layout();
-    }
+  if (!star_view_)
+    return;
+  star_view_->SetToggled(on);
+  if (action_box_button_view_ && (star_view_->visible() != on)) {
+    star_view_->SetVisible(on);
+    Layout();
   }
 }
 
@@ -629,7 +649,7 @@
   ime_inline_autocomplete_view_->SetVisible(!text.empty());
 }
 
-void LocationBarView::SetInstantSuggestion(const string16& text) {
+void LocationBarView::SetGrayTextAutocompletion(const string16& text) {
   if (suggested_text_view_->text() != text) {
     suggested_text_view_->SetText(text);
     suggested_text_view_->SetVisible(!text.empty());
@@ -638,7 +658,7 @@
   }
 }
 
-string16 LocationBarView::GetInstantSuggestion() const {
+string16 LocationBarView::GetGrayTextAutocompletion() const {
   return HasValidSuggestText() ? suggested_text_view_->text() : string16();
 }
 
@@ -663,9 +683,6 @@
   if (!location_entry_.get())
     return;
 
-  // TODO(jhawkins): Remove once crbug.com/101994 is fixed.
-  CHECK(location_icon_view_);
-
   selected_keyword_view_->SetVisible(false);
   location_icon_view_->SetVisible(false);
   ev_bubble_view_->SetVisible(false);
@@ -769,6 +786,15 @@
           item_padding, (*i)->GetBuiltInHorizontalPadding(), (*i));
     }
   }
+  if (autofill_credit_card_view_->visible()) {
+    trailing_decorations.AddDecoration(vertical_edge_thickness(),
+                                       location_height, 0,
+                                       autofill_credit_card_view_);
+  }
+  if (mic_search_view_->visible()) {
+    trailing_decorations.AddDecoration(vertical_edge_thickness(),
+                                       location_height, 0, mic_search_view_);
+  }
   // Because IMEs may eat the tab key, we don't show "press tab to search" while
   // IME composition is in progress.
   if (!keyword.empty() && is_keyword_hint &&
@@ -995,6 +1021,10 @@
 }
 #endif
 
+views::View* LocationBarView::autofill_credit_card_view() {
+  return autofill_credit_card_view_;
+}
+
 void LocationBarView::OnAutocompleteAccept(
     const GURL& url,
     WindowOpenDisposition disposition,
@@ -1307,6 +1337,12 @@
     popup->UpdatePopupAppearance();
 }
 
+void LocationBarView::ButtonPressed(views::Button* sender,
+                                    const ui::Event& event) {
+  DCHECK_EQ(mic_search_view_, sender);
+  command_updater_->ExecuteCommand(IDC_TOGGLE_SPEECH_INPUT);
+}
+
 void LocationBarView::WriteDragDataForView(views::View* sender,
                                            const gfx::Point& press_pt,
                                            OSExchangeData* data) {
@@ -1356,11 +1392,6 @@
   ShowFirstRunBubbleInternal();
 }
 
-void LocationBarView::SetInstantSuggestion(
-    const InstantSuggestion& suggestion) {
-  location_entry_->model()->SetInstantSuggestion(suggestion);
-}
-
 string16 LocationBarView::GetInputString() const {
   return location_input_;
 }
@@ -1496,6 +1527,16 @@
   }
 }
 
+void LocationBarView::ModelChanged(const SearchModel::State& old_state,
+                                   const SearchModel::State& new_state) {
+  const bool visible =
+      !model_->GetInputInProgress() && new_state.voice_search_supported;
+  if (mic_search_view_->visible() != visible) {
+    mic_search_view_->SetVisible(visible);
+    Layout();
+  }
+}
+
 int LocationBarView::GetInternalHeight(bool use_preferred_size) {
   int total_height =
       use_preferred_size ? GetPreferredSize().height() : height();
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h
index a3b20a2..2296e8c 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -14,6 +14,7 @@
 #include "chrome/browser/search_engines/template_url_service_observer.h"
 #include "chrome/browser/ui/omnibox/location_bar.h"
 #include "chrome/browser/ui/omnibox/omnibox_edit_controller.h"
+#include "chrome/browser/ui/search/search_model_observer.h"
 #include "chrome/browser/ui/toolbar/toolbar_model.h"
 #include "chrome/browser/ui/views/dropdown_bar_host.h"
 #include "chrome/browser/ui/views/dropdown_bar_host_delegate.h"
@@ -22,6 +23,7 @@
 #include "content/public/browser/notification_registrar.h"
 #include "ui/gfx/font.h"
 #include "ui/gfx/rect.h"
+#include "ui/views/controls/button/button.h"
 #include "ui/views/controls/native/native_view_host.h"
 #include "ui/views/drag_controller.h"
 
@@ -30,6 +32,7 @@
 #endif
 
 class ActionBoxButtonView;
+class AutofillCreditCardView;
 class CommandUpdater;
 class ContentSettingBubbleModelDelegate;
 class ContentSettingImageView;
@@ -39,6 +42,7 @@
 class InstantController;
 class KeywordHintView;
 class LocationIconView;
+class MicSearchView;
 class OpenPDFInReaderView;
 class PageActionWithBadgeView;
 class PageActionImageView;
@@ -66,11 +70,13 @@
 class LocationBarView : public LocationBar,
                         public LocationBarTesting,
                         public views::View,
+                        public views::ButtonListener,
                         public views::DragController,
                         public OmniboxEditController,
                         public DropdownBarHostDelegate,
                         public TemplateURLServiceObserver,
-                        public content::NotificationObserver {
+                        public content::NotificationObserver,
+                        public SearchModelObserver {
  public:
   // The location bar view's class name.
   static const char kViewClassName[];
@@ -106,8 +112,7 @@
     // Shows permissions and settings for the given web contents.
     virtual void ShowWebsiteSettings(content::WebContents* web_contents,
                                      const GURL& url,
-                                     const content::SSLStatus& ssl,
-                                     bool show_history) = 0;
+                                     const content::SSLStatus& ssl) = 0;
 
     // Called by the location bar view when the user starts typing in the edit.
     // This forces our security style to be UNKNOWN for the duration of the
@@ -196,11 +201,11 @@
   // comments on |ime_inline_autocomplete_view_|.
   void SetImeInlineAutocompletion(const string16& text);
 
-  // Invoked from OmniboxViewWin to show the instant suggestion.
-  void SetInstantSuggestion(const string16& text);
+  // Invoked from OmniboxViewWin to show gray text autocompletion.
+  void SetGrayTextAutocompletion(const string16& text);
 
-  // Returns the current instant suggestion text.
-  string16 GetInstantSuggestion() const;
+  // Returns the current gray text autocompletion.
+  string16 GetGrayTextAutocompletion() const;
 
   // Sets whether the location entry can accept focus.
   void SetLocationEntryFocusable(bool focusable);
@@ -243,6 +248,8 @@
 
   views::View* location_entry_view() const { return location_entry_view_; }
 
+  views::View* autofill_credit_card_view();
+
   // OmniboxEditController:
   virtual void OnAutocompleteAccept(const GURL& url,
                                     WindowOpenDisposition disposition,
@@ -267,6 +274,10 @@
   virtual bool HasFocus() const OVERRIDE;
   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
 
+  // views::ButtonListener:
+  virtual void ButtonPressed(views::Button* sender,
+                             const ui::Event& event) OVERRIDE;
+
   // views::DragController:
   virtual void WriteDragDataForView(View* sender,
                                     const gfx::Point& press_pt,
@@ -279,8 +290,6 @@
 
   // LocationBar:
   virtual void ShowFirstRunBubble() OVERRIDE;
-  virtual void SetInstantSuggestion(
-      const InstantSuggestion& suggestion) OVERRIDE;
   virtual string16 GetInputString() const OVERRIDE;
   virtual WindowOpenDisposition GetWindowOpenDisposition() const OVERRIDE;
   virtual content::PageTransition GetPageTransition() const OVERRIDE;
@@ -291,6 +300,7 @@
   virtual void UpdatePageActions() OVERRIDE;
   virtual void InvalidatePageActions() OVERRIDE;
   virtual void UpdateOpenPDFInReaderPrompt() OVERRIDE;
+  virtual void UpdateAutofillCreditCardView() OVERRIDE;
   virtual void SaveStateToContents(content::WebContents* contents) OVERRIDE;
   virtual void Revert() OVERRIDE;
   virtual const OmniboxView* GetLocationEntry() const OVERRIDE;
@@ -314,6 +324,10 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
+  // SearchModelObserver:
+  virtual void ModelChanged(const SearchModel::State& old_state,
+                            const SearchModel::State& new_state) OVERRIDE;
+
   // Returns the height of the control without the top and bottom
   // edges(i.e.  the height of the edit control inside).  If
   // |use_preferred_size| is true this will be the preferred height,
@@ -464,12 +478,18 @@
   // Shown if the selected url has a corresponding keyword.
   KeywordHintView* keyword_hint_view_;
 
+  // The voice search icon.
+  MicSearchView* mic_search_view_;
+
   // The content setting views.
   ContentSettingViews content_setting_views_;
 
   // The zoom icon.
   ZoomView* zoom_view_;
 
+  // A bubble that shows after successful submission of the Autofill dialog.
+  AutofillCreditCardView* autofill_credit_card_view_;
+
   // The icon to open a PDF in Reader.
   OpenPDFInReaderView* open_pdf_in_reader_view_;
 
diff --git a/chrome/browser/ui/views/location_bar/mic_search_view.cc b/chrome/browser/ui/views/location_bar/mic_search_view.cc
new file mode 100644
index 0000000..31f67d6
--- /dev/null
+++ b/chrome/browser/ui/views/location_bar/mic_search_view.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/location_bar/mic_search_view.h"
+
+#include "chrome/browser/ui/view_ids.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "ui/base/accessibility/accessible_view_state.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+
+MicSearchView::MicSearchView(views::ButtonListener* button_listener)
+    : views::ImageButton(button_listener) {
+  set_id(VIEW_ID_MIC_SEARCH_BUTTON);
+  set_accessibility_focusable(true);
+  SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_MIC_SEARCH));
+  SetImage(STATE_NORMAL,
+           ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
+               IDR_OMNIBOX_MIC_SEARCH));
+  SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
+  TouchableLocationBarView::Init(this);
+}
+
+MicSearchView::~MicSearchView() {
+}
+
+int MicSearchView::GetBuiltInHorizontalPadding() const {
+  return GetBuiltInHorizontalPaddingImpl();
+}
diff --git a/chrome/browser/ui/views/location_bar/mic_search_view.h b/chrome/browser/ui/views/location_bar/mic_search_view.h
new file mode 100644
index 0000000..30159a7
--- /dev/null
+++ b/chrome/browser/ui/views/location_bar/mic_search_view.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_MIC_SEARCH_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_MIC_SEARCH_VIEW_H_
+
+#include "chrome/browser/ui/views/location_bar/touchable_location_bar_view.h"
+#include "ui/views/controls/button/image_button.h"
+
+class CommandUpdater;
+
+class MicSearchView : public views::ImageButton,
+                      public TouchableLocationBarView {
+ public:
+  explicit MicSearchView(views::ButtonListener* button_listener);
+  virtual ~MicSearchView();
+
+  // TouchableLocationBarView:
+  virtual int GetBuiltInHorizontalPadding() const OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MicSearchView);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_MIC_SEARCH_VIEW_H_
diff --git a/chrome/browser/ui/views/location_bar/page_info_helper.cc b/chrome/browser/ui/views/location_bar/page_info_helper.cc
index 52bf7fc..7f27d50 100644
--- a/chrome/browser/ui/views/location_bar/page_info_helper.cc
+++ b/chrome/browser/ui/views/location_bar/page_info_helper.cc
@@ -41,5 +41,5 @@
   }
 
   location_bar_->delegate()->ShowWebsiteSettings(
-      tab, nav_entry->GetURL(), nav_entry->GetSSL(), true);
+      tab, nav_entry->GetURL(), nav_entry->GetSSL());
 }
diff --git a/chrome/browser/ui/views/location_bar/script_bubble_icon_view.cc b/chrome/browser/ui/views/location_bar/script_bubble_icon_view.cc
index 0420b9c..92a8411 100644
--- a/chrome/browser/ui/views/location_bar/script_bubble_icon_view.cc
+++ b/chrome/browser/ui/views/location_bar/script_bubble_icon_view.cc
@@ -61,7 +61,7 @@
 }
 
 void ScriptBubbleIconView::GetAccessibleState(ui::AccessibleViewState* state) {
-  state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_STAR);
+  ImageView::GetAccessibleState(state);
   state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
 }
 
diff --git a/chrome/browser/ui/views/location_bar/star_view.cc b/chrome/browser/ui/views/location_bar/star_view.cc
index d732432..d07328e 100644
--- a/chrome/browser/ui/views/location_bar/star_view.cc
+++ b/chrome/browser/ui/views/location_bar/star_view.cc
@@ -30,6 +30,10 @@
 StarView::~StarView() {
 }
 
+int StarView::GetBuiltInHorizontalPadding() const {
+  return GetBuiltInHorizontalPaddingImpl();
+}
+
 void StarView::SetToggled(bool on) {
   SetTooltipText(l10n_util::GetStringUTF16(
       on ? IDS_TOOLTIP_STARRED : IDS_TOOLTIP_STAR));
@@ -37,12 +41,8 @@
       on ? IDR_STAR_LIT : IDR_STAR));
 }
 
-int StarView::GetBuiltInHorizontalPadding() const {
-  return GetBuiltInHorizontalPaddingImpl();
-}
-
 void StarView::GetAccessibleState(ui::AccessibleViewState* state) {
-  state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_STAR);
+  ImageView::GetAccessibleState(state);
   state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
 }
 
diff --git a/chrome/browser/ui/views/location_bar/star_view.h b/chrome/browser/ui/views/location_bar/star_view.h
index 6035d4c..bac32f0 100644
--- a/chrome/browser/ui/views/location_bar/star_view.h
+++ b/chrome/browser/ui/views/location_bar/star_view.h
@@ -10,20 +10,19 @@
 
 class CommandUpdater;
 
-class StarView : public views::ImageView,
-                 public TouchableLocationBarView {
+class StarView : public views::ImageView, public TouchableLocationBarView {
  public:
   explicit StarView(CommandUpdater* command_updater);
   virtual ~StarView();
 
+  // TouchableLocationBarView:
+  virtual int GetBuiltInHorizontalPadding() const OVERRIDE;
+
   // Toggles the star on or off.
   void SetToggled(bool on);
 
-  // TouchableLocationBarView.
-  virtual int GetBuiltInHorizontalPadding() const OVERRIDE;
-
  private:
-  // views::ImageView overrides:
+  // views::ImageView:
   virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
   virtual bool GetTooltipText(const gfx::Point& p,
                               string16* tooltip) const OVERRIDE;
@@ -42,7 +41,7 @@
   // prevent the bubble from reshowing.
   bool suppress_mouse_released_action_;
 
-  DISALLOW_IMPLICIT_CONSTRUCTORS(StarView);
+  DISALLOW_COPY_AND_ASSIGN(StarView);
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_STAR_VIEW_H_
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
index 76f1c7a..f3d61a3 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h"
 
 #include "base/i18n/rtl.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chrome_page_zoom.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
@@ -13,7 +14,6 @@
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/views/location_bar/zoom_view.h"
 #include "chrome/browser/ui/zoom/zoom_controller.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
@@ -121,16 +121,6 @@
   set_use_focusless(auto_close);
   set_notify_enter_exit_on_child(true);
 
-  if (anchor_view) {
-    // If we are in immersive fullscreen and the top-of-window views are
-    // already revealed, lock the top-of-window views in the revealed state
-    // as long as the zoom bubble is visible. ImmersiveModeController does
-    // not do this for us automatically because the zoom bubble is not
-    // activatable.
-    immersive_reveal_lock_.reset(immersive_mode_controller_->GetRevealedLock(
-        ImmersiveModeController::ANIMATE_REVEAL_NO));
-  }
-
   // Add observers to close the bubble if the fullscreen state or immersive
   // fullscreen revealed state changes.
   registrar_.Add(this,
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
index 1b05401..cc54372 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
@@ -115,10 +115,6 @@
   // Not owned.
   ImmersiveModeController* immersive_mode_controller_;
 
-  // Keeps the top-of-window views revealed (but does not initiate a reveal)
-  // when the bubble is visible in immersive fullscreen.
-  scoped_ptr<ImmersiveRevealedLock> immersive_reveal_lock_;
-
   // Used to register for fullscreen change notifications.
   content::NotificationRegistrar registrar_;
 
diff --git a/chrome/browser/ui/views/menu_item_view_test.cc b/chrome/browser/ui/views/menu_item_view_test.cc
index 2b182d9..1b66352 100644
--- a/chrome/browser/ui/views/menu_item_view_test.cc
+++ b/chrome/browser/ui/views/menu_item_view_test.cc
@@ -217,6 +217,7 @@
     inserted_item_ = menu_->AddMenuItemAt(INSERT_INDEX,
                                           1000,
                                           ASCIIToUTF16("inserted item"),
+                                          string16(),
                                           gfx::ImageSkia(),
                                           views::MenuItemView::NORMAL,
                                           ui::NORMAL_SEPARATOR);
@@ -328,6 +329,7 @@
     inserted_item_ = menu_->AddMenuItemAt(INSERT_INDEX,
                                           1000,
                                           ASCIIToUTF16("inserted item"),
+                                          string16(),
                                           gfx::ImageSkia(),
                                           views::MenuItemView::NORMAL,
                                           ui::NORMAL_SEPARATOR);
diff --git a/chrome/browser/ui/views/message_center/message_center_frame_view.cc b/chrome/browser/ui/views/message_center/message_center_frame_view.cc
new file mode 100644
index 0000000..0efd863
--- /dev/null
+++ b/chrome/browser/ui/views/message_center/message_center_frame_view.cc
@@ -0,0 +1,78 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/message_center/message_center_frame_view.h"
+
+#include "ui/base/hit_test.h"
+#include "ui/message_center/message_center_style.h"
+#include "ui/views/shadow_border.h"
+#include "ui/views/widget/widget.h"
+
+namespace {
+
+const int kBorderWidth = 1;
+const int kShadowBlur = 8;
+
+}  // namepspace
+
+namespace message_center {
+
+MessageCenterFrameView::MessageCenterFrameView() {
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+  set_border(views::Border::CreateSolidBorder(
+      kBorderWidth, message_center::kMessageCenterBorderColor));
+#else
+  set_border(new views::ShadowBorder(kShadowBlur,
+                                     message_center::kMessageCenterShadowColor,
+                                     0,    // Vertical offset
+                                     0));  // Horizontal offset
+#endif
+}
+
+MessageCenterFrameView::~MessageCenterFrameView() {}
+
+gfx::Rect MessageCenterFrameView::GetBoundsForClientView() const {
+  gfx::Rect client_bounds = GetLocalBounds();
+  client_bounds.Inset(GetInsets());
+  return client_bounds;
+}
+
+gfx::Rect MessageCenterFrameView::GetWindowBoundsForClientBounds(
+    const gfx::Rect& client_bounds) const {
+  gfx::Rect window_bounds = client_bounds;
+  window_bounds.Inset(GetInsets());
+  return window_bounds;
+}
+
+int MessageCenterFrameView::NonClientHitTest(const gfx::Point& point) {
+  gfx::Rect frame_bounds = bounds();
+  frame_bounds.Inset(GetInsets());
+  if (!frame_bounds.Contains(point))
+    return HTNOWHERE;
+
+  return GetWidget()->client_view()->NonClientHitTest(point);
+}
+
+void MessageCenterFrameView::GetWindowMask(const gfx::Size& size,
+                                           gfx::Path* window_mask) {
+}
+
+void MessageCenterFrameView::ResetWindowControls() {
+}
+
+void MessageCenterFrameView::UpdateWindowIcon() {
+}
+
+void MessageCenterFrameView::UpdateWindowTitle() {
+}
+
+gfx::Insets MessageCenterFrameView::GetInsets() const {
+  return border()->GetInsets();
+}
+
+const char* MessageCenterFrameView::GetClassName() const {
+  return "MessageCenterFrameView";
+}
+
+}  // namespace message_center
diff --git a/chrome/browser/ui/views/message_center/message_center_frame_view.h b/chrome/browser/ui/views/message_center/message_center_frame_view.h
new file mode 100644
index 0000000..19adcd4
--- /dev/null
+++ b/chrome/browser/ui/views/message_center/message_center_frame_view.h
@@ -0,0 +1,45 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_MESSAGE_CENTER_MESSAGE_CENTER_FRAME_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_MESSAGE_CENTER_MESSAGE_CENTER_FRAME_VIEW_H_
+
+#include "ui/views/window/non_client_view.h"
+
+namespace views {
+class Label;
+class LabelButton;
+class BubbleBorder;
+}
+
+namespace message_center {
+
+// The non-client frame view of the message center widget.
+class MessageCenterFrameView : public views::NonClientFrameView {
+ public:
+  explicit MessageCenterFrameView();
+  virtual ~MessageCenterFrameView();
+
+  // NonClientFrameView overrides:
+  virtual gfx::Rect GetBoundsForClientView() const OVERRIDE;
+  virtual gfx::Rect GetWindowBoundsForClientBounds(
+      const gfx::Rect& client_bounds) const OVERRIDE;
+  virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE;
+  virtual void GetWindowMask(const gfx::Size& size,
+                             gfx::Path* window_mask) OVERRIDE;
+  virtual void ResetWindowControls() OVERRIDE;
+  virtual void UpdateWindowIcon() OVERRIDE;
+  virtual void UpdateWindowTitle() OVERRIDE;
+
+  // View overrides:
+  virtual gfx::Insets GetInsets() const OVERRIDE;
+  virtual const char* GetClassName() const OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MessageCenterFrameView);
+};
+
+}  // namespace message_center
+
+#endif  // CHROME_BROWSER_UI_VIEWS_MESSAGE_CENTER_MESSAGE_CENTER_FRAME_VIEW_H_
diff --git a/chrome/browser/ui/views/message_center/message_center_widget_delegate.cc b/chrome/browser/ui/views/message_center/message_center_widget_delegate.cc
new file mode 100644
index 0000000..d308601
--- /dev/null
+++ b/chrome/browser/ui/views/message_center/message_center_widget_delegate.cc
@@ -0,0 +1,235 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/message_center/message_center_widget_delegate.h"
+
+#include <complex>
+
+#include "chrome/browser/ui/views/message_center/message_center_frame_view.h"
+#include "content/public/browser/user_metrics.h"
+#include "ui/base/accessibility/accessible_view_state.h"
+#include "ui/gfx/screen.h"
+#include "ui/message_center/message_center_style.h"
+#include "ui/message_center/message_center_util.h"
+#include "ui/message_center/views/message_center_view.h"
+#include "ui/native_theme/native_theme.h"
+#include "ui/views/border.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/widget/widget.h"
+
+#if defined(OS_WIN)
+#include "ui/views/win/hwnd_util.h"
+#endif
+
+namespace message_center {
+
+MessageCenterWidgetDelegate::MessageCenterWidgetDelegate(
+    WebNotificationTray* tray,
+    MessageCenterTray* mc_tray,
+    bool initially_settings_visible,
+    const PositionInfo& pos_info)
+    : MessageCenterView(tray->message_center(),
+                        mc_tray,
+                        pos_info.max_height,
+                        initially_settings_visible,
+                        pos_info.message_center_alignment &
+                            ALIGNMENT_TOP),  // Show buttons on top if message
+                                             // center is top aligned
+      pos_info_(pos_info),
+      tray_(tray) {
+  // A WidgetDelegate should be deleted on DeleteDelegate.
+  set_owned_by_client();
+
+  views::BoxLayout* layout =
+      new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
+  layout->set_spread_blank_space(true);
+  SetLayoutManager(layout);
+
+  AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
+
+  if (get_use_acceleration_when_possible()) {
+    SetPaintToLayer(true);
+    SetFillsBoundsOpaquely(true);
+  }
+
+  InitWidget();
+}
+
+MessageCenterWidgetDelegate::~MessageCenterWidgetDelegate() {
+  views::Widget* widget = GetWidget();
+  if (widget) {
+    widget->RemoveObserver(this);
+  }
+}
+
+views::View* MessageCenterWidgetDelegate::GetContentsView() {
+  return this;
+}
+
+views::NonClientFrameView*
+MessageCenterWidgetDelegate::CreateNonClientFrameView(views::Widget* widget) {
+  MessageCenterFrameView* frame_view = new MessageCenterFrameView();
+  border_insets_ = frame_view->GetInsets();
+  return frame_view;
+}
+
+void MessageCenterWidgetDelegate::DeleteDelegate() {
+  delete this;
+}
+
+views::Widget* MessageCenterWidgetDelegate::GetWidget() {
+  return View::GetWidget();
+}
+
+const views::Widget* MessageCenterWidgetDelegate::GetWidget() const {
+  return View::GetWidget();
+}
+
+void MessageCenterWidgetDelegate::OnWidgetActivationChanged(
+    views::Widget* widget,
+    bool active) {
+  if (!active) {
+    tray_->SendHideMessageCenter();
+  }
+}
+
+void MessageCenterWidgetDelegate::OnWidgetClosing(views::Widget* widget) {
+  tray_->MarkMessageCenterHidden();
+}
+
+void MessageCenterWidgetDelegate::PreferredSizeChanged() {
+  GetWidget()->SetBounds(GetMessageCenterBounds());
+  views::View::PreferredSizeChanged();
+}
+
+gfx::Size MessageCenterWidgetDelegate::GetPreferredSize() {
+  int preferred_width = kNotificationWidth + 2 * kMarginBetweenItems;
+  return gfx::Size(preferred_width, GetHeightForWidth(preferred_width));
+}
+
+gfx::Size MessageCenterWidgetDelegate::GetMaximumSize() {
+  gfx::Size size = GetPreferredSize();
+  return size;
+}
+
+int MessageCenterWidgetDelegate::GetHeightForWidth(int width) {
+  int height = MessageCenterView::GetHeightForWidth(width);
+  return (pos_info_.max_height != 0) ? std::min(height, pos_info_.max_height)
+                                     : height;
+}
+
+bool MessageCenterWidgetDelegate::AcceleratorPressed(
+    const ui::Accelerator& accelerator) {
+  if (accelerator.key_code() != ui::VKEY_ESCAPE)
+    return false;
+  tray_->SendHideMessageCenter();
+  return true;
+}
+
+void MessageCenterWidgetDelegate::InitWidget() {
+  views::Widget* widget = new views::Widget();
+  views::Widget::InitParams params(views::Widget::InitParams::TYPE_BUBBLE);
+  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
+  params.delegate = this;
+  params.keep_on_top = true;
+  params.top_level = true;
+  widget->Init(params);
+
+#if defined(OS_WIN)
+  // Remove the Message Center from taskbar and alt-tab rotation.
+  HWND hwnd = views::HWNDForWidget(widget);
+  LONG_PTR ex_styles = ::GetWindowLongPtr(hwnd, GWL_EXSTYLE);
+  ex_styles |= WS_EX_TOOLWINDOW;
+  ::SetWindowLongPtr(hwnd, GWL_EXSTYLE, ex_styles);
+#endif
+
+  widget->AddObserver(this);
+  widget->StackAtTop();
+  widget->SetAlwaysOnTop(true);
+
+  const NotificationList::Notifications& notifications =
+      tray_->message_center()->GetNotifications();
+  SetNotifications(notifications);
+
+  widget->SetBounds(GetMessageCenterBounds());
+  widget->Show();
+  widget->Activate();
+}
+
+gfx::Point MessageCenterWidgetDelegate::GetCorrectedAnchor(
+    gfx::Size calculated_size) {
+  gfx::Point corrected_anchor = pos_info_.inital_anchor_point;
+
+  // Inset the width slightly so that the click point is not exactly on the edge
+  // of the message center but somewhere within the middle 60 %.
+  int insetted_width = (calculated_size.width() * 4) / 5;
+
+  if (pos_info_.taskbar_alignment == ALIGNMENT_TOP ||
+      pos_info_.taskbar_alignment == ALIGNMENT_BOTTOM) {
+    int click_point_x = tray_->mouse_click_point().x();
+
+    if (pos_info_.message_center_alignment & ALIGNMENT_RIGHT) {
+      int opposite_x_corner =
+          pos_info_.inital_anchor_point.x() - insetted_width;
+
+      // If the click point is outside the x axis length of the message center,
+      // push the message center towards the left to align with the click point.
+      if (opposite_x_corner > click_point_x)
+        corrected_anchor.set_x(pos_info_.inital_anchor_point.x() -
+                               (opposite_x_corner - click_point_x));
+    } else {
+      int opposite_x_corner =
+          pos_info_.inital_anchor_point.x() + insetted_width;
+
+      if (opposite_x_corner < click_point_x)
+        corrected_anchor.set_x(pos_info_.inital_anchor_point.x() +
+                               (click_point_x - opposite_x_corner));
+    }
+  } else if (pos_info_.taskbar_alignment == ALIGNMENT_LEFT ||
+             pos_info_.taskbar_alignment == ALIGNMENT_RIGHT) {
+    int click_point_y = tray_->mouse_click_point().y();
+
+    if (pos_info_.message_center_alignment & ALIGNMENT_BOTTOM) {
+      int opposite_y_corner =
+          pos_info_.inital_anchor_point.y() - insetted_width;
+
+      // If the click point is outside the y axis length of the message center,
+      // push the message center upwards to align with the click point.
+      if (opposite_y_corner > click_point_y)
+        corrected_anchor.set_y(pos_info_.inital_anchor_point.y() -
+                               (opposite_y_corner - click_point_y));
+    } else {
+      int opposite_y_corner =
+          pos_info_.inital_anchor_point.y() + insetted_width;
+
+      if (opposite_y_corner < click_point_y)
+        corrected_anchor.set_y(pos_info_.inital_anchor_point.y() +
+                               (click_point_y - opposite_y_corner));
+    }
+  }
+  return corrected_anchor;
+}
+
+gfx::Rect MessageCenterWidgetDelegate::GetMessageCenterBounds() {
+  gfx::Size size = GetPreferredSize();
+
+  // Make space for borders on sides.
+  size.Enlarge(border_insets_.width(), border_insets_.height());
+  gfx::Rect bounds(size);
+
+  gfx::Point corrected_anchor = GetCorrectedAnchor(size);
+
+  if (pos_info_.message_center_alignment & ALIGNMENT_TOP)
+    bounds.set_y(corrected_anchor.y());
+  if (pos_info_.message_center_alignment & ALIGNMENT_BOTTOM)
+    bounds.set_y(corrected_anchor.y() - size.height());
+  if (pos_info_.message_center_alignment & ALIGNMENT_LEFT)
+    bounds.set_x(corrected_anchor.x());
+  if (pos_info_.message_center_alignment & ALIGNMENT_RIGHT)
+    bounds.set_x(corrected_anchor.x() - size.width());
+
+  return bounds;
+}
+
+}  // namespace message_center
diff --git a/chrome/browser/ui/views/message_center/message_center_widget_delegate.h b/chrome/browser/ui/views/message_center/message_center_widget_delegate.h
new file mode 100644
index 0000000..f69d6f5
--- /dev/null
+++ b/chrome/browser/ui/views/message_center/message_center_widget_delegate.h
@@ -0,0 +1,113 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_MESSAGE_CENTER_MESSAGE_CENTER_WIDGET_DELEGATE_H_
+#define CHROME_BROWSER_UI_VIEWS_MESSAGE_CENTER_MESSAGE_CENTER_WIDGET_DELEGATE_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/views/message_center/web_notification_tray.h"
+#include "ui/base/animation/animation_delegate.h"
+#include "ui/base/animation/slide_animation.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/rect.h"
+#include "ui/message_center/message_center.h"
+#include "ui/message_center/message_center_tray.h"
+#include "ui/message_center/message_center_tray_delegate.h"
+#include "ui/message_center/views/message_center_view.h"
+#include "ui/views/widget/widget_delegate.h"
+#include "ui/views/widget/widget_observer.h"
+
+namespace ui {
+class SlideAnimation;
+class AnimationDelegate;
+}
+
+namespace message_center {
+
+enum Alignment {
+  ALIGNMENT_TOP = 1 << 0,
+  ALIGNMENT_LEFT = 1 << 1,
+  ALIGNMENT_BOTTOM = 1 << 2,
+  ALIGNMENT_RIGHT = 1 << 3,
+  ALIGNMENT_NONE = 1 << 4,
+};
+
+struct PositionInfo {
+  int max_height;
+
+  // Alignment of the message center relative to the center of the screen.
+  Alignment message_center_alignment;
+
+  // Alignment of the taskbar relative to the center of the screen.
+  Alignment taskbar_alignment;
+
+  // Point relative to which message center is positioned.
+  gfx::Point inital_anchor_point;
+};
+
+class WebNotificationTray;
+class MessageCenterFrameView;
+
+// MessageCenterWidgetDelegate is the message center's client view. It also
+// creates the message center widget and sets the notifications.
+//
+////////////////////////////////////////////////////////////////////////////////
+class MessageCenterWidgetDelegate : public views::WidgetDelegate,
+                                    public message_center::MessageCenterView,
+                                    public views::WidgetObserver {
+ public:
+  MessageCenterWidgetDelegate(WebNotificationTray* tray,
+                              MessageCenterTray* mc_tray,
+                              bool initially_settings_visible,
+                              const PositionInfo& pos_info);
+  virtual ~MessageCenterWidgetDelegate();
+
+  // WidgetDelegate overrides:
+  virtual View* GetContentsView() OVERRIDE;
+  virtual views::NonClientFrameView* CreateNonClientFrameView(
+      views::Widget* widget) OVERRIDE;
+  virtual void DeleteDelegate() OVERRIDE;
+  virtual views::Widget* GetWidget() OVERRIDE;
+  virtual const views::Widget* GetWidget() const OVERRIDE;
+
+  // WidgetObserver overrides:
+  virtual void OnWidgetActivationChanged(views::Widget* widget,
+                                         bool active) OVERRIDE;
+  virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
+
+  // View overrides:
+  virtual void PreferredSizeChanged() OVERRIDE;
+  virtual gfx::Size GetPreferredSize() OVERRIDE;
+  virtual gfx::Size GetMaximumSize() OVERRIDE;
+  virtual int GetHeightForWidth(int width) OVERRIDE;
+  virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
+
+ private:
+  // Creates and initializes the message center widget.
+  void InitWidget();
+
+  // Shifts the message center anchor point such that the mouse click point is
+  // along the middle 60% of the width of the message center if taskbar is
+  // horizontal aligned. If vertically aligned, ensures that mouse click point
+  // is along the height of the message center (at least at a corner).
+  gfx::Point GetCorrectedAnchor(gfx::Size calculated_size);
+
+  // Calculates the message center bounds using the position info and the
+  // corrected anchor.
+  gfx::Rect GetMessageCenterBounds();
+
+  // Insets of the message center border (set in MessageCenterFrameView).
+  gfx::Insets border_insets_;
+
+  // Info necessary to calculate the estimated position of the message center.
+  PositionInfo pos_info_;
+
+  WebNotificationTray* tray_;
+};
+
+}  // namespace message_center
+
+#endif  // CHROME_BROWSER_UI_VIEWS_MESSAGE_CENTER_MESSAGE_CENTER_WIDGET_DELEGATE_H_
diff --git a/chrome/browser/ui/views/message_center/notification_bubble_wrapper.cc b/chrome/browser/ui/views/message_center/notification_bubble_wrapper.cc
deleted file mode 100644
index 16fdefc..0000000
--- a/chrome/browser/ui/views/message_center/notification_bubble_wrapper.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/message_center/notification_bubble_wrapper.h"
-
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/ui/views/message_center/web_notification_tray.h"
-#include "grit/ui_strings.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/size.h"
-#include "ui/message_center/views/message_bubble_base.h"
-#include "ui/message_center/views/message_center_bubble.h"
-#include "ui/message_center/views/message_popup_bubble.h"
-#include "ui/views/bubble/bubble_delegate.h"
-#include "ui/views/bubble/tray_bubble_view.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_observer.h"
-
-#if defined(OS_WIN)
-#include "ui/views/win/hwnd_util.h"
-#endif
-
-namespace message_center {
-
-namespace internal {
-
-NotificationBubbleWrapper::NotificationBubbleWrapper(
-    WebNotificationTray* tray,
-    scoped_ptr<message_center::MessageBubbleBase> bubble,
-    BubbleType bubble_type)
-    : bubble_(bubble.Pass()),
-      bubble_type_(bubble_type),
-      bubble_view_(NULL),
-      bubble_widget_(NULL),
-      tray_(tray) {
-  // Windows-specific initialization.
-  views::TrayBubbleView::AnchorAlignment anchor_alignment =
-      tray_->GetAnchorAlignment();
-  views::TrayBubbleView::InitParams init_params =
-      bubble_->GetInitParams(anchor_alignment);
-  init_params.close_on_deactivate = false;
-  init_params.arrow_alignment = views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE;
-  init_params.arrow_paint_type = views::BubbleBorder::PAINT_NONE;
-  // TODO(dewittj): Show big shadow without blocking clicks.
-  init_params.shadow = views::BubbleBorder::NO_SHADOW;
-
-  bubble_view_ = views::TrayBubbleView::Create(
-      tray_->GetBubbleWindowContainer(), NULL, this, &init_params);
-
-  bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
-
-#if defined(OS_WIN)
-  // Remove the bubbles for Notifications and Notification Center from taskbar
-  // and alt-tab rotation.
-  HWND hwnd = views::HWNDForWidget(bubble_widget_);
-  LONG_PTR ex_styles = ::GetWindowLongPtr(hwnd, GWL_EXSTYLE);
-  ex_styles |= WS_EX_TOOLWINDOW;
-  ::SetWindowLongPtr(hwnd, GWL_EXSTYLE, ex_styles);
-#endif
-
-  bubble_widget_->AddObserver(this);
-  bubble_widget_->StackAtTop();
-  bubble_widget_->SetAlwaysOnTop(true);
-  // Popups should appear on top of everything, but not disturb the user's
-  // focus since they could appear at any time.  Message Center is always
-  // shown as a result of user action so it can be activated here.
-  if (bubble_type_ != BUBBLE_TYPE_POPUP)
-    bubble_widget_->Activate();
-  bubble_view_->InitializeAndShowBubble();
-
-  bubble_view_->set_close_on_deactivate(true);
-  bubble_->InitializeContents(bubble_view_);
-}
-
-NotificationBubbleWrapper::~NotificationBubbleWrapper() {
-  bubble_.reset();
-  if (bubble_widget_) {
-    bubble_widget_->RemoveObserver(this);
-    bubble_widget_->Close();
-  }
-}
-
-void NotificationBubbleWrapper::OnWidgetDestroying(views::Widget* widget) {
-  DCHECK_EQ(widget, bubble_widget_);
-  bubble_widget_->RemoveObserver(this);
-  bubble_widget_ = NULL;
-  tray_->HideBubbleWithView(bubble_view_);
-}
-
-void NotificationBubbleWrapper::BubbleViewDestroyed() {
-  bubble_->BubbleViewDestroyed();
-}
-
-void NotificationBubbleWrapper::OnMouseEnteredView() {
-  bubble_->OnMouseEnteredView();
-}
-
-void NotificationBubbleWrapper::OnMouseExitedView() {
-  bubble_->OnMouseExitedView();
-}
-
-string16 NotificationBubbleWrapper::GetAccessibleNameForBubble() {
-  return l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_ACCESSIBLE_NAME);
-}
-
-gfx::Rect NotificationBubbleWrapper::GetAnchorRect(
-    views::Widget* anchor_widget,
-    AnchorType anchor_type,
-    AnchorAlignment anchor_alignment) {
-  if (bubble_type_ == BUBBLE_TYPE_POPUP)
-    return tray_->GetPopupAnchor();
-  return tray_->GetMessageCenterAnchor();
-}
-
-void NotificationBubbleWrapper::HideBubble(
-    const views::TrayBubbleView* bubble_view) {
-  tray_->HideBubbleWithView(bubble_view);
-}
-
-}  // namespace internal
-
-}  // namespace message_center
diff --git a/chrome/browser/ui/views/message_center/notification_bubble_wrapper.h b/chrome/browser/ui/views/message_center/notification_bubble_wrapper.h
deleted file mode 100644
index 0156147..0000000
--- a/chrome/browser/ui/views/message_center/notification_bubble_wrapper.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_MESSAGE_CENTER_NOTIFICATION_BUBBLE_WRAPPER_H_
-#define CHROME_BROWSER_UI_VIEWS_MESSAGE_CENTER_NOTIFICATION_BUBBLE_WRAPPER_H_
-
-#include "chrome/browser/ui/views/message_center/web_notification_tray.h"
-#include "ui/views/bubble/tray_bubble_view.h"
-#include "ui/views/widget/widget.h"
-
-namespace message_center {
-
-namespace internal {
-
-// NotificationBubbleWrapper is a class that manages the views associated
-// with a MessageBubbleBase object and that notifies the WebNotificationTray
-// when the widget closes.  Delegates GetAnchorRect to the
-// WebNotificationTray.
-class NotificationBubbleWrapper : public views::WidgetObserver,
-                                  public views::TrayBubbleView::Delegate {
- public:
-  enum BubbleType {
-    BUBBLE_TYPE_POPUP,
-    BUBBLE_TYPE_MESSAGE_CENTER,
-  };
-
-  NotificationBubbleWrapper(
-      WebNotificationTray* tray,
-      scoped_ptr<message_center::MessageBubbleBase> bubble,
-      BubbleType bubble_type);
-  virtual ~NotificationBubbleWrapper();
-
-  // Overridden from views::WidgetObserver.
-  virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
-
-  // TrayBubbleView::Delegate implementation.
-  virtual void BubbleViewDestroyed() OVERRIDE;
-  virtual void OnMouseEnteredView() OVERRIDE;
-  virtual void OnMouseExitedView() OVERRIDE;
-  virtual string16 GetAccessibleNameForBubble() OVERRIDE;
-  // GetAnchorRect passes responsibility for BubbleDelegateView::GetAnchorRect
-  // to the delegate.
-  virtual gfx::Rect GetAnchorRect(views::Widget* anchor_widget,
-                                  AnchorType anchor_type,
-                                  AnchorAlignment anchor_alignment) OVERRIDE;
-  virtual void HideBubble(const views::TrayBubbleView* bubble_view) OVERRIDE;
-
-  // Convenience accessors.
-  views::TrayBubbleView* bubble_view() { return bubble_view_; }
-  views::Widget* bubble_widget() { return bubble_widget_; }
-  message_center::MessageBubbleBase* bubble() { return bubble_.get(); }
-
- private:
-  scoped_ptr<message_center::MessageBubbleBase> bubble_;
-  const BubbleType bubble_type_;
-  // |bubble_view_| is owned by its Widget.
-  views::TrayBubbleView* bubble_view_;
-  views::Widget* bubble_widget_;
-  WebNotificationTray* tray_;
-
-  DISALLOW_COPY_AND_ASSIGN(NotificationBubbleWrapper);
-};
-
-}  // namespace internal
-
-}  // namespace message_center
-
-#endif  // CHROME_BROWSER_UI_VIEWS_MESSAGE_CENTER_NOTIFICATION_BUBBLE_WRAPPER_H_
diff --git a/chrome/browser/ui/views/message_center/web_notification_tray.cc b/chrome/browser/ui/views/message_center/web_notification_tray.cc
index d8ae595..eb65227 100644
--- a/chrome/browser/ui/views/message_center/web_notification_tray.cc
+++ b/chrome/browser/ui/views/message_center/web_notification_tray.cc
@@ -10,13 +10,11 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/status_icons/status_icon.h"
 #include "chrome/browser/status_icons/status_tray.h"
-#include "chrome/browser/ui/views/message_center/notification_bubble_wrapper.h"
 #include "content/public/browser/user_metrics.h"
 #include "grit/chromium_strings.h"
 #include "grit/theme_resources.h"
 #include "grit/ui_strings.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "ui/base/models/simple_menu_model.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/image/image_skia_operations.h"
@@ -25,8 +23,6 @@
 #include "ui/gfx/size.h"
 #include "ui/message_center/message_center_tray.h"
 #include "ui/message_center/message_center_tray_delegate.h"
-#include "ui/message_center/views/message_bubble_base.h"
-#include "ui/message_center/views/message_center_bubble.h"
 #include "ui/message_center/views/message_popup_collection.h"
 #include "ui/views/widget/widget.h"
 
@@ -39,15 +35,50 @@
 const int kSystemTrayHeight = 16;
 const int kNumberOfSystemTraySprites = 10;
 
-gfx::Rect GetCornerAnchorRect() {
-  // TODO(dewittj): Use the preference to determine which corner to anchor from.
-  gfx::Screen* screen = gfx::Screen::GetNativeScreen();
-  gfx::Rect rect = screen->GetPrimaryDisplay().work_area();
-  rect.Inset(kScreenEdgePadding, kScreenEdgePadding);
-  return gfx::Rect(rect.bottom_right(), gfx::Size());
+gfx::ImageSkia GetIcon(int unread_count) {
+  bool has_unread = unread_count > 0;
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  if (!has_unread)
+    return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY);
+
+  return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_ATTENTION);
 }
 
-gfx::Point GetClosestCorner(gfx::Rect rect, gfx::Point query) {
+}  // namespace
+
+using content::UserMetricsAction;
+
+namespace message_center {
+
+namespace internal {
+
+// Gets the position of the taskbar from the work area bounds. Returns
+// ALIGNMENT_NONE if position cannot be found.
+Alignment GetTaskbarAlignment() {
+  gfx::Screen* screen = gfx::Screen::GetNativeScreen();
+  // TODO(dewittj): It's possible GetPrimaryDisplay is wrong.
+  gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds();
+  gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
+  work_area.Inset(kScreenEdgePadding, kScreenEdgePadding);
+
+  // Comparing the work area to the screen bounds gives us the location of the
+  // taskbar.  If the work area is exactly the same as the screen bounds,
+  // we are unable to locate the taskbar so we say we don't know it's alignment.
+  if (work_area.height() < screen_bounds.height()) {
+    if (work_area.y() > screen_bounds.y())
+      return ALIGNMENT_TOP;
+    return ALIGNMENT_BOTTOM;
+  }
+  if (work_area.width() < screen_bounds.width()) {
+    if (work_area.x() > screen_bounds.x())
+      return ALIGNMENT_LEFT;
+    return ALIGNMENT_RIGHT;
+  }
+
+  return ALIGNMENT_NONE;
+}
+
+gfx::Point GetClosestCorner(const gfx::Rect& rect, const gfx::Point& query) {
   gfx::Point center_point = rect.CenterPoint();
   gfx::Point rv;
 
@@ -64,64 +95,28 @@
   return rv;
 }
 
-// GetMouseAnchorRect returns a rectangle that has one corner where the mouse
-// clicked, and the opposite corner at the closest corner of the work area
-// (inset by an appropriate margin.)
-gfx::Rect GetMouseAnchorRect(gfx::Point cursor) {
-  // TODO(dewittj): GetNativeScreen could be wrong for Aura.
-  gfx::Screen* screen = gfx::Screen::GetNativeScreen();
-  gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
-  work_area.Inset(kScreenEdgePadding, kScreenEdgePadding);
-  gfx::Point corner = GetClosestCorner(work_area, cursor);
+// Gets the corner of the screen where the message center should pop up.
+Alignment GetAnchorAlignment(const gfx::Rect& work_area, gfx::Point corner) {
+  gfx::Point center = work_area.CenterPoint();
 
-  gfx::Rect mouse_anchor_rect(gfx::BoundingRect(cursor, corner));
-  return mouse_anchor_rect;
+  Alignment anchor_alignment =
+      center.y() > corner.y() ? ALIGNMENT_TOP : ALIGNMENT_BOTTOM;
+  anchor_alignment =
+      (Alignment)(anchor_alignment |
+                  (center.x() > corner.x() ? ALIGNMENT_LEFT : ALIGNMENT_RIGHT));
+
+  return anchor_alignment;
 }
 
-gfx::ImageSkia GetIcon(int unread_count) {
-  bool has_unread = unread_count > 0;
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  if (!has_unread)
-    return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY);
-
-  // TODO(dewittj): Use scale factors other than 100P.
-  scoped_ptr<gfx::Canvas> canvas(
-      new gfx::Canvas(gfx::Size(kSystemTrayWidth, kSystemTrayHeight),
-                      ui::SCALE_FACTOR_100P,
-                      false));
-
-  // Draw the attention-grabbing background image.
-  canvas->DrawImageInt(
-      *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_ATTENTION), 0, 0);
-
-  // |numbers| is a sprite map with the image of a number from 1-9 and 9+. They
-  // are arranged horizontally, and have a transparent background.
-  gfx::ImageSkia* numbers = rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_NUMBERS);
-
-  // Assume that the last sprite is the catch-all for higher numbers of
-  // notifications.
-  int effective_unread = std::min(unread_count, kNumberOfSystemTraySprites);
-  int x_offset = (effective_unread - 1) * kSystemTrayWidth;
-
-  canvas->DrawImageInt(*numbers,
-                       x_offset, 0, kSystemTrayWidth, kSystemTrayHeight,
-                       0, 0, kSystemTrayWidth, kSystemTrayHeight,
-                       false);
-  return gfx::ImageSkia(canvas->ExtractImageRep());
-}
-
-}  // namespace
-
-using content::UserMetricsAction;
-
-namespace message_center {
+}  // namespace internal
 
 MessageCenterTrayDelegate* CreateMessageCenterTray() {
   return new WebNotificationTray();
 }
 
 WebNotificationTray::WebNotificationTray()
-    : status_icon_(NULL),
+    : message_center_delegate_(NULL),
+      status_icon_(NULL),
       message_center_visible_(false),
       should_update_tray_content_(true) {
   message_center_tray_.reset(
@@ -151,67 +146,36 @@
 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) {
   content::RecordAction(UserMetricsAction("Notifications.ShowMessageCenter"));
 
-  // Using MessageBubbleBase instead of MessageCenterBubble to
-  // remove dependence on implicit type conversion
-  scoped_ptr<message_center::MessageCenterBubble> bubble(
-      new message_center::MessageCenterBubble(message_center(),
-                                              message_center_tray_.get()));
-
-  gfx::Screen* screen = gfx::Screen::GetNativeScreen();
-  gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
-  views::TrayBubbleView::AnchorAlignment alignment = GetAnchorAlignment();
-
-  int max_height = work_area.height();
-
-  // If the alignment is left- or right-oriented, the bubble can fill up the
-  // entire vertical height of the screen since the bubble is rendered to the
-  // side of the clicked icon.  Otherwise we have to adjust for the arrow's
-  // height.
-  if (alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM ||
-      alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_TOP) {
-    max_height -= 2 * kScreenEdgePadding;
-
-    // If the work area contains the click point, then we know that the icon is
-    // not in the taskbar.  Then we need to subtract the distance of the click
-    // point from the edge of the work area so we can see the whole bubble.
-    if (work_area.Contains(mouse_click_point_)) {
-      max_height -= std::min(mouse_click_point_.y() - work_area.y(),
-                             work_area.bottom() - mouse_click_point_.y());
-    }
-  }
-  bubble->SetMaxHeight(max_height);
-  if (show_settings)
-    bubble->SetSettingsVisible();
-
-  message_center_bubble_.reset(new internal::NotificationBubbleWrapper(
+  // Message center delegate will be set to NULL when the message center
+  // widget's Close method is called so we don't need to worry about
+  // use-after-free issues.
+  message_center_delegate_ = new MessageCenterWidgetDelegate(
       this,
-      bubble.PassAs<message_center::MessageBubbleBase>(),
-      internal::NotificationBubbleWrapper::BUBBLE_TYPE_MESSAGE_CENTER));
+      message_center_tray_.get(),
+      show_settings,  // settings initally invisible
+      GetPositionInfo());
+
   return true;
 }
 
 bool WebNotificationTray::ShowMessageCenter() {
-  return ShowMessageCenterInternal(false /* show_settings */);
+  return ShowMessageCenterInternal(/*show_settings =*/false);
 }
 
 void WebNotificationTray::HideMessageCenter() {
-  message_center_bubble_.reset();
+  if (message_center_delegate_) {
+    views::Widget* widget = message_center_delegate_->GetWidget();
+    if (widget)
+      widget->Close();
+  }
 }
 
-void WebNotificationTray::UpdatePopups() {
-  // |popup_collection_| receives notification add/remove events and updates
-  // itself, so this method doesn't need to do anything.
-  // TODO(mukai): remove this method (currently this is used by
-  // non-rich-notifications in ChromeOS).
-};
-
 bool WebNotificationTray::ShowNotifierSettings() {
-  if (message_center_bubble_) {
-    static_cast<MessageCenterBubble*>(
-        message_center_bubble_->bubble())->SetSettingsVisible();
+  if (message_center_delegate_) {
+    message_center_delegate_->SetSettingsVisible(true);
     return true;
   }
-  return ShowMessageCenterInternal(true /* show_settings */);
+  return ShowMessageCenterInternal(/*show_settings =*/true);
 }
 
 void WebNotificationTray::OnMessageCenterTrayChanged() {
@@ -223,36 +187,13 @@
       base::Bind(&WebNotificationTray::UpdateStatusIcon, AsWeakPtr()));
 }
 
-gfx::Rect WebNotificationTray::GetMessageCenterAnchor() {
-  return GetMouseAnchorRect(mouse_click_point_);
-}
-
-gfx::Rect WebNotificationTray::GetPopupAnchor() {
-  return GetCornerAnchorRect();
-}
-
-views::TrayBubbleView::AnchorAlignment
-WebNotificationTray::GetAnchorAlignment() {
+void WebNotificationTray::OnStatusIconClicked() {
+  // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura.
   gfx::Screen* screen = gfx::Screen::GetNativeScreen();
-  // TODO(dewittj): It's possible GetPrimaryDisplay is wrong.
-  gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds();
-  gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
-
-  // Comparing the work area to the screen bounds gives us the location of the
-  // taskbar.  If the work area is less tall than the screen, assume the taskbar
-  // is on the bottom, and cause the arrow to be displayed on the bottom of the
-  // bubble.  Otherwise, cause the arrow to be displayed on the side of the
-  // bubble that the taskbar is on.
-  if (work_area.width() < screen_bounds.width()) {
-    if (work_area.x() > screen_bounds.x())
-      return views::TrayBubbleView::ANCHOR_ALIGNMENT_LEFT;
-    return views::TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT;
-  }
-  return views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
+  mouse_click_point_ = screen->GetCursorScreenPoint();
+  message_center_tray_->ToggleMessageCenterBubble();
 }
 
-gfx::NativeView WebNotificationTray::GetBubbleWindowContainer() { return NULL; }
-
 void WebNotificationTray::UpdateStatusIcon() {
   if (!should_update_tray_content_)
     return;
@@ -282,21 +223,56 @@
   }
 }
 
-void WebNotificationTray::OnStatusIconClicked() {
-  // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura.
-  gfx::Screen* screen = gfx::Screen::GetNativeScreen();
-  mouse_click_point_ = screen->GetCursorScreenPoint();
-  message_center_tray_->ToggleMessageCenterBubble();
+void WebNotificationTray::SendHideMessageCenter() {
+  message_center_tray_->HideMessageCenterBubble();
 }
 
-void WebNotificationTray::HideBubbleWithView(
-    const views::TrayBubbleView* bubble_view) {
-  if (message_center_bubble_.get() &&
-      bubble_view == message_center_bubble_->bubble_view()) {
-    message_center_tray_->HideMessageCenterBubble();
+void WebNotificationTray::MarkMessageCenterHidden() {
+  if (message_center_delegate_) {
+    message_center_tray_->MarkMessageCenterHidden();
+    message_center_delegate_ = NULL;
   }
 }
 
+PositionInfo WebNotificationTray::GetPositionInfo() {
+  PositionInfo pos_info;
+
+  gfx::Screen* screen = gfx::Screen::GetNativeScreen();
+  gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
+  work_area.Inset(kScreenEdgePadding, kScreenEdgePadding);
+
+  gfx::Point corner = internal::GetClosestCorner(work_area, mouse_click_point_);
+
+  pos_info.taskbar_alignment = internal::GetTaskbarAlignment();
+
+  // We assume the taskbar is either at the top or at the bottom if we are not
+  // able to find it.
+  if (pos_info.taskbar_alignment == ALIGNMENT_NONE) {
+    if (mouse_click_point_.y() > corner.y())
+      pos_info.taskbar_alignment = ALIGNMENT_TOP;
+    else
+      pos_info.taskbar_alignment = ALIGNMENT_BOTTOM;
+  }
+
+  pos_info.message_center_alignment =
+      internal::GetAnchorAlignment(work_area, corner);
+
+  pos_info.inital_anchor_point = corner;
+  pos_info.max_height = work_area.height();
+
+  if (work_area.Contains(mouse_click_point_)) {
+    pos_info.max_height -= std::abs(mouse_click_point_.y() - corner.y());
+
+    // Message center is in the work area. So position it few pixels above the
+    // mouse click point if alignemnt is towards bottom and few pixels below if
+    // alignment is towards top.
+    pos_info.inital_anchor_point
+        .set_y(mouse_click_point_.y() +
+               (pos_info.message_center_alignment & ALIGNMENT_BOTTOM ? -5 : 5));
+  }
+  return pos_info;
+}
+
 StatusIcon* WebNotificationTray::GetStatusIcon() {
   if (status_icon_)
     return status_icon_;
@@ -332,12 +308,9 @@
   status_icon->SetContextMenu(message_center_tray_->CreateQuietModeMenu());
 }
 
-message_center::MessageCenterBubble*
-WebNotificationTray::GetMessageCenterBubbleForTest() {
-  if (!message_center_bubble_.get())
-    return NULL;
-  return static_cast<message_center::MessageCenterBubble*>(
-      message_center_bubble_->bubble());
+MessageCenterWidgetDelegate*
+WebNotificationTray::GetMessageCenterWidgetDelegateForTest() {
+  return message_center_delegate_;
 }
 
 }  // namespace message_center
diff --git a/chrome/browser/ui/views/message_center/web_notification_tray.h b/chrome/browser/ui/views/message_center/web_notification_tray.h
index 67e2d4f..8d4010d 100644
--- a/chrome/browser/ui/views/message_center/web_notification_tray.h
+++ b/chrome/browser/ui/views/message_center/web_notification_tray.h
@@ -7,16 +7,17 @@
 
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/status_icons/status_icon_observer.h"
+#include "chrome/browser/ui/views/message_center/message_center_widget_delegate.h"
 #include "ui/base/models/simple_menu_model.h"
+#include "ui/gfx/rect.h"
 #include "ui/message_center/message_center_tray.h"
 #include "ui/message_center/message_center_tray_delegate.h"
-#include "ui/views/bubble/tray_bubble_view.h"
+#include "ui/views/widget/widget_observer.h"
 
 class StatusIcon;
 
 namespace message_center {
 class MessageCenter;
-class MessageCenterBubble;
 class MessagePopupCollection;
 }
 
@@ -26,9 +27,9 @@
 
 namespace message_center {
 
-namespace internal {
-class NotificationBubbleWrapper;
-}
+struct PositionInfo;
+
+class MessageCenterWidgetDelegate;
 
 // A MessageCenterTrayDelegate implementation that exposes the MessageCenterTray
 // via a system tray icon.  The notification popups will be displayed in the
@@ -48,18 +49,9 @@
   virtual void HidePopups() OVERRIDE;
   virtual bool ShowMessageCenter() OVERRIDE;
   virtual void HideMessageCenter() OVERRIDE;
-  virtual void UpdatePopups() OVERRIDE;
   virtual void OnMessageCenterTrayChanged() OVERRIDE;
   virtual bool ShowNotifierSettings() OVERRIDE;
 
-  // These are forwarded to WebNotificationTray by
-  // NotificationBubbleWrapper classes since they don't have enough
-  // context to provide the required data for TrayBubbleView::Delegate.
-  gfx::Rect GetMessageCenterAnchor();
-  gfx::Rect GetPopupAnchor();
-  gfx::NativeView GetBubbleWindowContainer();
-  views::TrayBubbleView::AnchorAlignment GetAnchorAlignment();
-
   // StatusIconObserver implementation.
   virtual void OnStatusIconClicked() OVERRIDE;
 #if defined(OS_WIN)
@@ -72,7 +64,11 @@
 
   // Changes the icon and hovertext based on number of unread notifications.
   void UpdateStatusIcon();
-  void HideBubbleWithView(const views::TrayBubbleView* bubble_view);
+  void SendHideMessageCenter();
+  void MarkMessageCenterHidden();
+
+  // Gets the point where the status icon was clicked.
+  gfx::Point mouse_click_point() { return mouse_click_point_; }
 
  private:
   FRIEND_TEST_ALL_PREFIXES(WebNotificationTrayTest, WebNotifications);
@@ -85,12 +81,15 @@
   // if the message center should be initialized with the settings visible.
   // Returns true if the center is successfully created.
   bool ShowMessageCenterInternal(bool show_settings);
+
+  PositionInfo GetPositionInfo();
+
   StatusIcon* GetStatusIcon();
   void DestroyStatusIcon();
   void AddQuietModeMenu(StatusIcon* status_icon);
-  message_center::MessageCenterBubble* GetMessageCenterBubbleForTest();
+  MessageCenterWidgetDelegate* GetMessageCenterWidgetDelegateForTest();
 
-  scoped_ptr<internal::NotificationBubbleWrapper> message_center_bubble_;
+  MessageCenterWidgetDelegate* message_center_delegate_;
   scoped_ptr<message_center::MessagePopupCollection> popup_collection_;
 
   StatusIcon* status_icon_;
diff --git a/chrome/browser/ui/views/message_center/web_notification_tray_browsertest.cc b/chrome/browser/ui/views/message_center/web_notification_tray_browsertest.cc
index 8354633..ca491ef 100644
--- a/chrome/browser/ui/views/message_center/web_notification_tray_browsertest.cc
+++ b/chrome/browser/ui/views/message_center/web_notification_tray_browsertest.cc
@@ -173,10 +173,10 @@
   bool shown = tray->message_center_tray_->ShowMessageCenterBubble();
   EXPECT_TRUE(shown);
   content::RunAllPendingInMessageLoop();
-  EXPECT_TRUE(tray->message_center_bubble_.get() != NULL);
+  EXPECT_TRUE(tray->message_center_delegate_ != NULL);
   EXPECT_EQ(notifications_to_add, message_center->NotificationCount());
   EXPECT_EQ(kMaxVisibleMessageCenterNotifications,
-            tray->GetMessageCenterBubbleForTest()->NumMessageViewsForTest());
+            tray->message_center_delegate_->NumMessageViewsForTest());
 }
 
 IN_PROC_BROWSER_TEST_F(WebNotificationTrayTest, ManyPopupNotifications) {
diff --git a/chrome/browser/ui/views/notifications/balloon_view_views.cc b/chrome/browser/ui/views/notifications/balloon_view_views.cc
index 83884c7..ab91975 100644
--- a/chrome/browser/ui/views/notifications/balloon_view_views.cc
+++ b/chrome/browser/ui/views/notifications/balloon_view_views.cc
@@ -10,11 +10,11 @@
 #include "base/bind.h"
 #include "base/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/notifications/balloon_collection.h"
 #include "chrome/browser/notifications/desktop_notification_service.h"
 #include "chrome/browser/notifications/notification.h"
 #include "chrome/browser/notifications/notification_options_menu_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/notification_types.h"
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 3c39284..0c59dbc 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -23,7 +23,6 @@
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/gurl.h"
 #include "grit/app_locale_settings.h"
 #include "grit/generated_resources.h"
 #include "grit/ui_strings.h"
@@ -49,6 +48,7 @@
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/views_delegate.h"
 #include "ui/views/widget/widget.h"
+#include "url/gurl.h"
 
 #if defined(USE_AURA)
 #include "ui/aura/focus_manager.h"
@@ -517,16 +517,9 @@
 void OmniboxViewViews::OnRevertTemporaryText() {
   SelectRange(saved_temporary_selection_);
   // We got here because the user hit the Escape key. We explicitly don't call
-  // TextChanged(), since calling it breaks Instant-Extended, and isn't needed
-  // otherwise (in regular non-Instant or Instant-but-not-Extended modes).
-  //
-  // Why it breaks Instant-Extended: Instant handles the Escape key separately
-  // (cf: OmniboxEditModel::RevertTemporaryText). Calling TextChanged() makes
-  // the page think the user additionally typed some text, causing it to update
-  // its suggestions dropdown with new suggestions, which is wrong.
-  //
-  // Why it isn't needed: OmniboxPopupModel::ResetToDefaultMatch() has already
-  // been called by now; it would've called TextChanged() if it was warranted.
+  // TextChanged(), since OmniboxPopupModel::ResetToDefaultMatch() has already
+  // been called by now, and it would've called TextChanged() if it was
+  // warranted.
 }
 
 void OmniboxViewViews::OnBeforePossibleChange() {
@@ -581,15 +574,15 @@
   return GetWidget()->GetTopLevelWidget()->GetNativeView();
 }
 
-void OmniboxViewViews::SetInstantSuggestion(const string16& input) {
+void OmniboxViewViews::SetGrayTextAutocompletion(const string16& input) {
 #if defined(OS_WIN) || defined(USE_AURA)
-  location_bar_view_->SetInstantSuggestion(input);
+  location_bar_view_->SetGrayTextAutocompletion(input);
 #endif
 }
 
-string16 OmniboxViewViews::GetInstantSuggestion() const {
+string16 OmniboxViewViews::GetGrayTextAutocompletion() const {
 #if defined(OS_WIN) || defined(USE_AURA)
-  return location_bar_view_->GetInstantSuggestion();
+  return location_bar_view_->GetGrayTextAutocompletion();
 #else
   return string16();
 #endif
@@ -661,7 +654,7 @@
   }
 
   // Handle the right-arrow key for LTR text and the left-arrow key for RTL text
-  // if there is an Instant suggestion (gray text) that needs to be committed.
+  // if there is gray text that needs to be committed.
   if (GetCursorPosition() == text().length()) {
     base::i18n::TextDirection direction = GetTextDirection();
     if ((direction == base::i18n::LEFT_TO_RIGHT &&
@@ -853,7 +846,7 @@
 // OmniboxViewViews, private:
 
 int OmniboxViewViews::GetOmniboxTextLength() const {
-  // TODO(oshima): Support instant, IME.
+  // TODO(oshima): Support IME.
   return static_cast<int>(text().length());
 }
 
@@ -903,7 +896,7 @@
 }
 
 string16 OmniboxViewViews::GetSelectedText() const {
-  // TODO(oshima): Support instant, IME.
+  // TODO(oshima): Support IME.
   return views::Textfield::GetSelectedText();
 }
 
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
index 2ddf4fb..b757c69 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
@@ -100,8 +100,8 @@
   virtual bool OnAfterPossibleChange() OVERRIDE;
   virtual gfx::NativeView GetNativeView() const OVERRIDE;
   virtual gfx::NativeView GetRelativeWindowForPopup() const OVERRIDE;
-  virtual void SetInstantSuggestion(const string16& input) OVERRIDE;
-  virtual string16 GetInstantSuggestion() const OVERRIDE;
+  virtual void SetGrayTextAutocompletion(const string16& input) OVERRIDE;
+  virtual string16 GetGrayTextAutocompletion() const OVERRIDE;
   virtual int TextWidth() const OVERRIDE;
   virtual bool IsImeComposing() const OVERRIDE;
   virtual bool IsImeShowingPopup() const OVERRIDE;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_win.cc b/chrome/browser/ui/views/omnibox/omnibox_view_win.cc
index db535a3..bde208b 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_win.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_win.cc
@@ -29,6 +29,7 @@
 #include "chrome/browser/autocomplete/autocomplete_match.h"
 #include "chrome/browser/autocomplete/keyword_provider.h"
 #include "chrome/browser/bookmarks/bookmark_node_data.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/net/url_fixer_upper.h"
 #include "chrome/browser/profiles/profile.h"
@@ -39,11 +40,9 @@
 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/url_util.h"
 #include "grit/generated_resources.h"
 #include "net/base/escape.h"
 #include "skia/ext/skia_utils_win.h"
@@ -72,6 +71,7 @@
 #include "ui/views/controls/menu/menu_runner.h"
 #include "ui/views/controls/textfield/native_textfield_win.h"
 #include "ui/views/widget/widget.h"
+#include "url/url_util.h"
 #include "win8/util/win8_util.h"
 
 #pragma comment(lib, "oleacc.lib")  // Needed for accessibility support.
@@ -901,16 +901,9 @@
 void OmniboxViewWin::OnRevertTemporaryText() {
   SetSelectionRange(original_selection_);
   // We got here because the user hit the Escape key. We explicitly don't call
-  // TextChanged(), since calling it breaks Instant-Extended, and isn't needed
-  // otherwise (in regular non-Instant or Instant-but-not-Extended modes).
-  //
-  // Why it breaks Instant-Extended: Instant handles the Escape key separately
-  // (cf: OmniboxEditModel::RevertTemporaryText). Calling TextChanged() makes
-  // the page think the user additionally typed some text, causing it to update
-  // its suggestions dropdown with new suggestions, which is wrong.
-  //
-  // Why it isn't needed: OmniboxPopupModel::ResetToDefaultMatch() has already
-  // been called by now; it would've called TextChanged() if it was warranted.
+  // TextChanged(), since OmniboxPopupModel::ResetToDefaultMatch() has already
+  // been called by now, and it would've called TextChanged() if it was
+  // warranted.
 }
 
 void OmniboxViewWin::OnBeforePossibleChange() {
@@ -1028,16 +1021,16 @@
   return GetRelativeWindowForNativeView(GetNativeView());
 }
 
-void OmniboxViewWin::SetInstantSuggestion(const string16& suggestion) {
-  location_bar_->SetInstantSuggestion(suggestion);
+void OmniboxViewWin::SetGrayTextAutocompletion(const string16& suggestion) {
+  location_bar_->SetGrayTextAutocompletion(suggestion);
 }
 
 int OmniboxViewWin::TextWidth() const {
   return WidthNeededToDisplay(GetText());
 }
 
-string16 OmniboxViewWin::GetInstantSuggestion() const {
-  return location_bar_->GetInstantSuggestion();
+string16 OmniboxViewWin::GetGrayTextAutocompletion() const {
+  return location_bar_->GetGrayTextAutocompletion();
 }
 
 bool OmniboxViewWin::IsImeComposing() const {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_win.h b/chrome/browser/ui/views/omnibox/omnibox_view_win.h
index e61a007..7caecff 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_win.h
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_win.h
@@ -110,9 +110,9 @@
   virtual bool OnAfterPossibleChange() OVERRIDE;
   virtual gfx::NativeView GetNativeView() const OVERRIDE;
   virtual gfx::NativeView GetRelativeWindowForPopup() const OVERRIDE;
-  virtual void SetInstantSuggestion(const string16& suggestion) OVERRIDE;
+  virtual void SetGrayTextAutocompletion(const string16& suggestion) OVERRIDE;
   virtual int TextWidth() const OVERRIDE;
-  virtual string16 GetInstantSuggestion() const OVERRIDE;
+  virtual string16 GetGrayTextAutocompletion() const OVERRIDE;
   virtual bool IsImeComposing() const OVERRIDE;
   virtual int GetMaxEditWidth(int entry_width) const OVERRIDE;
   virtual views::View* AddToView(views::View* parent) OVERRIDE;
diff --git a/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc b/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc
index 77be5a4..28dc908 100644
--- a/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc
+++ b/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc
@@ -8,7 +8,6 @@
 #include "chrome/browser/upgrade_detector.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/browser/user_metrics.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
@@ -20,6 +19,7 @@
 #include "ui/views/layout/grid_layout.h"
 #include "ui/views/layout/layout_constants.h"
 #include "ui/views/widget/widget.h"
+#include "url/gurl.h"
 
 using views::GridLayout;
 
diff --git a/chrome/browser/ui/views/panels/panel_stack_view.cc b/chrome/browser/ui/views/panels/panel_stack_view.cc
index 25843ed..90dcf48 100644
--- a/chrome/browser/ui/views/panels/panel_stack_view.cc
+++ b/chrome/browser/ui/views/panels/panel_stack_view.cc
@@ -52,6 +52,9 @@
 }
 
 PanelStackView::~PanelStackView() {
+#if defined(OS_WIN)
+  ui::HWNDSubclass::RemoveFilterFromAllTargets(this);
+#endif
 }
 
 void PanelStackView::Close() {
@@ -460,6 +463,14 @@
       ShellIntegration::GetAppModelIdForProfile(UTF8ToWide(panel->app_name()),
                                                 panel->profile()->GetPath()),
       views::HWNDForWidget(window));
+
+  // Remove the filter for old window in case that we're recreating the window.
+  ui::HWNDSubclass::RemoveFilterFromAllTargets(this);
+
+  // Listen to WM_MOVING message in order to move all panels windows on top of
+  // the background window altogether when the background window is being moved
+  // by the user.
+  ui::HWNDSubclass::AddFilterToTarget(views::HWNDForWidget(window), this);
 #endif
 
   return window;
@@ -483,6 +494,23 @@
 }
 
 #if defined(OS_WIN)
+bool PanelStackView::FilterMessage(HWND hwnd,
+                                   UINT message,
+                                   WPARAM w_param,
+                                   LPARAM l_param,
+                                   LRESULT* l_result) {
+  switch (message) {
+    case WM_MOVING:
+      // When the background window is being moved by the user, all panels
+      // should also move.
+      gfx::Rect new_stack_bounds(*(reinterpret_cast<LPRECT>(l_param)));
+      MovePanelsBy(
+          new_stack_bounds.origin() - panels_.front()->GetBounds().origin());
+      break;
+  }
+  return false;
+}
+
 std::vector<HWND> PanelStackView::GetSnapshotWindowHandles() const {
   std::vector<HWND> native_panel_windows;
   for (Panels::const_iterator iter = panels_.begin();
diff --git a/chrome/browser/ui/views/panels/panel_stack_view.h b/chrome/browser/ui/views/panels/panel_stack_view.h
index a3fff3c..18cba8c 100644
--- a/chrome/browser/ui/views/panels/panel_stack_view.h
+++ b/chrome/browser/ui/views/panels/panel_stack_view.h
@@ -17,6 +17,7 @@
 
 #if defined(OS_WIN)
 #include "chrome/browser/ui/views/panels/taskbar_window_thumbnailer_win.h"
+#include "ui/base/win/hwnd_subclass.h"
 #endif
 
 namespace ui {
@@ -33,6 +34,7 @@
                        public views::WidgetDelegateView,
                        public views::WidgetFocusChangeListener,
 #if defined(OS_WIN)
+                       public ui::HWNDMessageFilter,
                        public TaskbarWindowThumbnailerDelegateWin,
 #endif
                        public ui::AnimationDelegate {
@@ -104,6 +106,13 @@
                                             PanelStackView* stack_window);
 
 #if defined(OS_WIN)
+  // Overridden from ui::HWNDMessageFilter:
+  virtual bool FilterMessage(HWND hwnd,
+                             UINT message,
+                             WPARAM w_param,
+                             LPARAM l_param,
+                             LRESULT* l_result) OVERRIDE;
+
   // Overridden from TaskbarWindowThumbnailerDelegateWin:
   virtual std::vector<HWND> GetSnapshotWindowHandles() const OVERRIDE;
 
diff --git a/chrome/browser/ui/views/panels/panel_view.cc b/chrome/browser/ui/views/panels/panel_view.cc
index bf81562..54f48dd 100644
--- a/chrome/browser/ui/views/panels/panel_view.cc
+++ b/chrome/browser/ui/views/panels/panel_view.cc
@@ -107,6 +107,7 @@
   virtual bool IsButtonVisible(
       panel::TitlebarButtonType button_type) const OVERRIDE;
   virtual panel::CornerStyle GetWindowCornerStyle() const OVERRIDE;
+  virtual bool EnsureApplicationRunOnForeground() OVERRIDE;
 
   PanelView* panel_view_;
 };
@@ -222,6 +223,11 @@
   return panel_view_->GetFrameView()->corner_style();
 }
 
+bool NativePanelTestingWin::EnsureApplicationRunOnForeground() {
+  // Not needed on views.
+  return true;
+}
+
 }  // namespace
 
 // static
@@ -952,12 +958,14 @@
   // bring up the panel with the above alternatives.
   // When the user clicks on the minimized panel, the panel expansion will be
   // done when we process the mouse button pressed message.
+#if defined(OS_WIN)
   if (focused_ && panel_->IsMinimized() &&
       panel_->collection()->type() == PanelCollection::DOCKED &&
       gfx::Screen::GetScreenFor(widget->GetNativeWindow())->
           GetWindowAtCursorScreenPoint() != widget->GetNativeWindow()) {
     panel_->Restore();
   }
+#endif
 
   panel()->OnActiveStateChanged(focused);
 }
diff --git a/chrome/browser/ui/views/password_generation_bubble_view.cc b/chrome/browser/ui/views/password_generation_bubble_view.cc
index cab4c79..8774f4e 100644
--- a/chrome/browser/ui/views/password_generation_bubble_view.cc
+++ b/chrome/browser/ui/views/password_generation_bubble_view.cc
@@ -14,7 +14,6 @@
 #include "components/autofill/core/common/password_generation_util.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/browser/render_view_host.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "third_party/skia/include/core/SkPaint.h"
@@ -29,6 +28,7 @@
 #include "ui/views/controls/link.h"
 #include "ui/views/controls/textfield/textfield.h"
 #include "ui/views/layout/layout_constants.h"
+#include "url/gurl.h"
 
 namespace {
 // Constants for PasswordGenerationBubbleView.
diff --git a/chrome/browser/ui/views/profile_chooser_view.cc b/chrome/browser/ui/views/profile_chooser_view.cc
index 0c16b40..280853f 100644
--- a/chrome/browser/ui/views/profile_chooser_view.cc
+++ b/chrome/browser/ui/views/profile_chooser_view.cc
@@ -66,7 +66,7 @@
     : BubbleDelegateView(anchor_view, arrow),
       browser_(browser),
       current_profile_view_(NULL),
-      option_buttons_view_(NULL),
+      guest_button_view_(NULL),
       other_profiles_view_(NULL),
       signout_current_profile_view_(NULL) {
   avatar_menu_model_.reset(new AvatarMenuModel(
@@ -105,13 +105,18 @@
 
 void ProfileChooserView::ButtonPressed(views::Button* sender,
                                        const ui::Event& event) {
-  DCHECK(sender == signout_current_profile_view_);
   // Disable button after clicking so that it doesn't get clicked twice and
-  // start a second sign-out procedure... which will crash Chrome.  But don't
-  // disable if it has no parent (like in tests) because that will also
-  // crash.
+  // start a second action... which can crash Chrome.  But don't disable if it
+  // has no parent (like in tests) because that will also crash.
   if (sender->parent())
     sender->SetEnabled(false);
+
+  if (sender == guest_button_view_) {
+    avatar_menu_model_->SwitchToGuestProfileWindow(browser_);
+    return;
+  }
+
+  DCHECK_EQ(sender, signout_current_profile_view_);
   avatar_menu_model_->BeginSignOut();
 }
 
@@ -120,8 +125,8 @@
   // Unset all our child view references and call RemoveAllChildViews() which
   // will actually delete them.
   current_profile_view_ = NULL;
+  guest_button_view_ = NULL;
   open_other_profile_indexes_map_.clear();
-  option_buttons_view_ = NULL;
   other_profiles_view_ = NULL;
   signout_current_profile_view_ = NULL;
   RemoveAllChildViews(true);
@@ -160,10 +165,10 @@
   layout->StartRow(0, 0);
   layout->AddView(new views::Separator(views::Separator::HORIZONTAL));
 
-  option_buttons_view_ = CreateOptionsView();
-  option_buttons_view_->SetSize(current_profile_view_->GetPreferredSize());
+  views::View* option_buttons_view = CreateOptionsView();
+  option_buttons_view->SetSize(current_profile_view_->GetPreferredSize());
   layout->StartRow(0, 0);
-  layout->AddView(option_buttons_view_);
+  layout->AddView(option_buttons_view);
 
   layout->StartRow(0, 0);
   layout->AddView(new views::Separator(views::Separator::HORIZONTAL));
@@ -301,6 +306,9 @@
   guest_button->SetHorizontalAlignment(gfx::ALIGN_CENTER);
   guest_button->set_tag(IDS_PROFILES_PROFILE_GUEST_BUTTON);
 
+  DCHECK(!guest_button_view_);
+  guest_button_view_ = guest_button;
+
   views::GridLayout* layout = new views::GridLayout(view);
   view->SetLayoutManager(layout);
 
diff --git a/chrome/browser/ui/views/profile_chooser_view.h b/chrome/browser/ui/views/profile_chooser_view.h
index fe8f1a1..e2de425 100644
--- a/chrome/browser/ui/views/profile_chooser_view.h
+++ b/chrome/browser/ui/views/profile_chooser_view.h
@@ -77,8 +77,8 @@
   scoped_ptr<AvatarMenuModel> avatar_menu_model_;
   Browser* browser_;
   views::View* current_profile_view_;
+  views::View* guest_button_view_;
   ViewIndexes open_other_profile_indexes_map_;
-  views::View* option_buttons_view_;
   views::View* other_profiles_view_;
   views::View* signout_current_profile_view_;
 
diff --git a/chrome/browser/ui/views/reload_button.cc b/chrome/browser/ui/views/reload_button.cc
index 470498f..11ef78e 100644
--- a/chrome/browser/ui/views/reload_button.cc
+++ b/chrome/browser/ui/views/reload_button.cc
@@ -19,8 +19,8 @@
 #include "ui/views/metrics.h"
 #include "ui/views/widget/widget.h"
 
-// static
-const char ReloadButton::kViewClassName[] = "ReloadButton";
+
+namespace {
 
 const int kReloadImages[] =
     { IDR_RELOAD, IDR_RELOAD_H, IDR_RELOAD_P, IDR_RELOAD_D };
@@ -34,8 +34,13 @@
   IDS_RELOAD_MENU_EMPTY_AND_HARD_RELOAD_ITEM,
 };
 
-////////////////////////////////////////////////////////////////////////////////
-// ReloadButton, public:
+}  // namespace
+
+
+// ReloadButton ---------------------------------------------------------------
+
+// static
+const char ReloadButton::kViewClassName[] = "ReloadButton";
 
 ReloadButton::ReloadButton(LocationBarView* location_bar,
                            CommandUpdater* command_updater)
@@ -104,8 +109,41 @@
   PreferredSizeChanged();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// ReloadButton, views::ButtonListener implementation:
+void ReloadButton::OnMouseExited(const ui::MouseEvent& event) {
+  ButtonDropDown::OnMouseExited(event);
+  if (!IsMenuShowing())
+    ChangeMode(intended_mode_, true);
+}
+
+bool ReloadButton::GetTooltipText(const gfx::Point& p,
+                                  string16* tooltip) const {
+  int reload_tooltip = menu_enabled_ ?
+      IDS_TOOLTIP_RELOAD_WITH_MENU : IDS_TOOLTIP_RELOAD;
+  int text_id = (visible_mode_ == MODE_RELOAD) ?
+      reload_tooltip : IDS_TOOLTIP_STOP;
+  tooltip->assign(l10n_util::GetStringUTF16(text_id));
+  return true;
+}
+
+const char* ReloadButton::GetClassName() const {
+  return kViewClassName;
+}
+
+void ReloadButton::GetAccessibleState(ui::AccessibleViewState* state) {
+  if (menu_enabled_)
+    ButtonDropDown::GetAccessibleState(state);
+  else
+    CustomButton::GetAccessibleState(state);
+}
+
+bool ReloadButton::ShouldShowMenu() {
+  return menu_enabled_ && (visible_mode_ == MODE_RELOAD);
+}
+
+void ReloadButton::ShowDropDownMenu(ui::MenuSourceType source_type) {
+  ButtonDropDown::ShowDropDownMenu(source_type);  // Blocks.
+  ChangeMode(intended_mode_, true);
+}
 
 void ReloadButton::ButtonPressed(views::Button* /* button */,
                                  const ui::Event& event) {
@@ -143,41 +181,6 @@
   }
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// ReloadButton, View overrides:
-
-void ReloadButton::OnMouseExited(const ui::MouseEvent& event) {
-  ButtonDropDown::OnMouseExited(event);
-  if (!IsMenuShowing())
-    ChangeMode(intended_mode_, true);
-}
-
-bool ReloadButton::GetTooltipText(const gfx::Point& p,
-                                  string16* tooltip) const {
-  int reload_tooltip = menu_enabled_ ?
-      IDS_TOOLTIP_RELOAD_WITH_MENU : IDS_TOOLTIP_RELOAD;
-  int text_id = (visible_mode_ == MODE_RELOAD) ?
-      reload_tooltip : IDS_TOOLTIP_STOP;
-  tooltip->assign(l10n_util::GetStringUTF16(text_id));
-  return true;
-}
-
-const char* ReloadButton::GetClassName() const {
-  return kViewClassName;
-}
-
-bool ReloadButton::ShouldShowMenu() {
-  return menu_enabled_ && (visible_mode_ == MODE_RELOAD);
-}
-
-void ReloadButton::ShowDropDownMenu(ui::MenuSourceType source_type) {
-  ButtonDropDown::ShowDropDownMenu(source_type);  // Blocks.
-  ChangeMode(intended_mode_, true);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ReloadButton, ui::SimpleMenuModel::Delegate overrides:
-
 bool ReloadButton::IsCommandIdChecked(int command_id) const {
   return false;
 }
@@ -221,9 +224,6 @@
   ExecuteBrowserCommand(browser_command, event_flags);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// ReloadButton, private:
-
 ui::SimpleMenuModel* ReloadButton::CreateMenuModel() {
   ui::SimpleMenuModel* menu_model = new ui::SimpleMenuModel(this);
   for (size_t i = 0; i < arraysize(kReloadMenuItems); ++i)
diff --git a/chrome/browser/ui/views/reload_button.h b/chrome/browser/ui/views/reload_button.h
index 2611aef..94b6017 100644
--- a/chrome/browser/ui/views/reload_button.h
+++ b/chrome/browser/ui/views/reload_button.h
@@ -47,20 +47,21 @@
 
   void LoadImages(ui::ThemeProvider* tp);
 
-  // Overridden from views::ButtonListener:
-  virtual void ButtonPressed(views::Button* /* button */,
-                             const ui::Event& event) OVERRIDE;
-
   // Overridden from views::View:
   virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
   virtual bool GetTooltipText(const gfx::Point& p,
                               string16* tooltip) const OVERRIDE;
   virtual const char* GetClassName() const OVERRIDE;
+  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
 
   // Overridden from views::ButtonDropDown:
   virtual bool ShouldShowMenu() OVERRIDE;
   virtual void ShowDropDownMenu(ui::MenuSourceType source_type) OVERRIDE;
 
+  // Overridden from views::ButtonListener:
+  virtual void ButtonPressed(views::Button* /* button */,
+                             const ui::Event& event) OVERRIDE;
+
   // Overridden from ui::SimpleMenuModel::Delegate:
   virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
   virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc
index 09e9ee5..c9430cd 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -231,7 +231,7 @@
 
 // static
 bool SelectFileDialogExtension::PendingExists(int32 tab_id) {
-  return PendingDialog::GetInstance()->Find(tab_id) != NULL;
+  return PendingDialog::GetInstance()->Find(tab_id).get() != NULL;
 }
 
 bool SelectFileDialogExtension::HasMultipleFileTypeChoicesImpl() {
diff --git a/chrome/browser/ui/views/status_bubble_views.cc b/chrome/browser/ui/views/status_bubble_views.cc
index 48ed6eb..d6418fb 100644
--- a/chrome/browser/ui/views/status_bubble_views.cc
+++ b/chrome/browser/ui/views/status_bubble_views.cc
@@ -12,7 +12,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/themes/theme_properties.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "net/base/net_util.h"
@@ -33,6 +32,7 @@
 #include "ui/views/controls/scrollbar/native_scroll_bar.h"
 #include "ui/views/widget/root_view.h"
 #include "ui/views/widget/widget.h"
+#include "url/gurl.h"
 
 #if defined(USE_ASH)
 #include "ash/wm/property_util.h"
@@ -699,8 +699,10 @@
 void StatusBubbleViews::MouseMoved(const gfx::Point& location,
                                    bool left_content) {
   contains_mouse_ = !left_content;
-  if (left_content)
+  if (left_content) {
+    Reposition();
     return;
+  }
   last_mouse_moved_location_ = location;
 
   if (view_) {
diff --git a/chrome/browser/ui/views/status_bubble_views.h b/chrome/browser/ui/views/status_bubble_views.h
index 7a2c5e9..c1bdc13 100644
--- a/chrome/browser/ui/views/status_bubble_views.h
+++ b/chrome/browser/ui/views/status_bubble_views.h
@@ -11,8 +11,8 @@
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/ui/status_bubble.h"
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/rect.h"
+#include "url/gurl.h"
 
 namespace gfx {
 class Point;
diff --git a/chrome/browser/ui/views/sync/one_click_signin_bubble_view.cc b/chrome/browser/ui/views/sync/one_click_signin_bubble_view.cc
index 35484b9..b7e8f25 100644
--- a/chrome/browser/ui/views/sync/one_click_signin_bubble_view.cc
+++ b/chrome/browser/ui/views/sync/one_click_signin_bubble_view.cc
@@ -207,8 +207,7 @@
   {
     layout->StartRow(0, COLUMN_SET_TITLE_BAR);
 
-    views::Label* label = new views::Label(email_.empty() ?
-        l10n_util::GetStringUTF16(IDS_ONE_CLICK_SIGNIN_DIALOG_TITLE) :
+    views::Label* label = new views::Label(
         l10n_util::GetStringFUTF16(IDS_ONE_CLICK_SIGNIN_DIALOG_TITLE_NEW,
                                    email_));
     label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
@@ -231,8 +230,7 @@
   {
     layout->StartRow(0, COLUMN_SET_FILL_ALIGN);
 
-    views::Label* label = new views::Label(email_.empty() ?
-        l10n_util::GetStringUTF16(IDS_ONE_CLICK_SIGNIN_DIALOG_MESSAGE) :
+    views::Label* label = new views::Label(
         l10n_util::GetStringFUTF16(IDS_ONE_CLICK_SIGNIN_DIALOG_MESSAGE_NEW,
                                    email_));
     label->SetMultiLine(true);
diff --git a/chrome/browser/ui/views/sync/one_click_signin_bubble_view.h b/chrome/browser/ui/views/sync/one_click_signin_bubble_view.h
index dafeb02..a04cb55 100644
--- a/chrome/browser/ui/views/sync/one_click_signin_bubble_view.h
+++ b/chrome/browser/ui/views/sync/one_click_signin_bubble_view.h
@@ -114,12 +114,13 @@
   // Creates advanced link to be used at the bottom of the bubble.
   void InitAdvancedLink();
 
-  // The bubble/dialog will always outlive the web_content, so this is ok
+  // The bubble/dialog will always outlive the web_content, so this is ok.
   content::WebContents* web_contents_;
 
-  // Alternate error message to be displayed
+  // Alternate error message to be displayed.
   const string16 error_message_;
 
+  // The user's email address to be used for sync.
   const string16 email_;
 
   // This callback is nulled once its called, so that it is called only once.
diff --git a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
index a585367..e9183af 100644
--- a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
+++ b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
@@ -153,6 +153,10 @@
   if (!details.is_add || details.child != this)
     return;
 
+  const SkColor kPromptBarBackgroundColor =
+      ui::GetSigninConfirmationPromptBarColor(
+          ui::kSigninConfirmationPromptBarBackgroundAlpha);
+
   // Create the prompt label.
   size_t offset;
   const string16 domain = ASCIIToUTF16(gaia::ExtractDomainName(username_));
@@ -162,6 +166,8 @@
           IDS_ENTERPRISE_SIGNIN_ALERT_NEW_STYLE,
           domain, &offset);
   views::StyledLabel* prompt_label = new views::StyledLabel(prompt_text, this);
+  prompt_label->SetDisplayedOnBackgroundColor(kPromptBarBackgroundColor);
+
   views::StyledLabel::RangeStyleInfo bold_style;
   bold_style.font_style = gfx::Font::BOLD;
   prompt_label->AddStyleRange(
@@ -174,11 +180,8 @@
           1, 0, 1, 0,
           ui::GetSigninConfirmationPromptBarColor(
               ui::kSigninConfirmationPromptBarBorderAlpha)));
-  // TODO(dconnelly): set the background color on the label (crbug.com/244630)
-  prompt_bar->set_background(
-      views::Background::CreateSolidBackground(
-          ui::GetSigninConfirmationPromptBarColor(
-              ui::kSigninConfirmationPromptBarBackgroundAlpha)));
+  prompt_bar->set_background(views::Background::CreateSolidBackground(
+      kPromptBarBackgroundColor));
 
   // Create the explanation label.
   std::vector<size_t> offsets;
diff --git a/chrome/browser/ui/views/tab_contents/render_view_context_menu_win.cc b/chrome/browser/ui/views/tab_contents/render_view_context_menu_win.cc
index 10e3ce1..72345c2 100644
--- a/chrome/browser/ui/views/tab_contents/render_view_context_menu_win.cc
+++ b/chrome/browser/ui/views/tab_contents/render_view_context_menu_win.cc
@@ -5,11 +5,11 @@
 #include "chrome/browser/ui/views/tab_contents/render_view_context_menu_win.h"
 
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/tab_contents/retargeting_details.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/web_contents.h"
 #include "win8/util/win8_util.h"
 
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
index c98da98..68fc48f 100644
--- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
+++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -8,6 +8,7 @@
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/favicon/favicon_tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/ui/views/tabs/tab.h"
 #include "chrome/browser/ui/views/tabs/tab_renderer_data.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc
index 3100357..f556be5 100644
--- a/chrome/browser/ui/views/tabs/tab.cc
+++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -1320,11 +1320,11 @@
   // rectangle. And again, don't draw over the toolbar.
   background_canvas.TileImageInt(*tab_bg,
      offset + tab_image->l_width,
-     bg_offset_y + drop_shadow_height() + tab_image->y_offset,
+     bg_offset_y + drop_shadow_height(),
      tab_image->l_width,
-     drop_shadow_height() + tab_image->y_offset,
+     drop_shadow_height(),
      width() - tab_image->l_width - tab_image->r_width,
-     height() - drop_shadow_height() - kToolbarOverlap - tab_image->y_offset);
+     height() - drop_shadow_height() - kToolbarOverlap);
 
   canvas->DrawImageInt(
       gfx::ImageSkia(background_canvas.ExtractImageRep()), 0, 0);
@@ -1373,11 +1373,11 @@
   // by incrementing by GetDropShadowHeight(), since it's a simple rectangle.
   canvas->TileImageInt(*tab_background,
      offset + tab_image->l_width,
-     drop_shadow_height() + tab_image->y_offset,
+     drop_shadow_height(),
      tab_image->l_width,
-     drop_shadow_height() + tab_image->y_offset,
+     drop_shadow_height(),
      width() - tab_image->l_width - tab_image->r_width,
-     height() - drop_shadow_height() - tab_image->y_offset);
+     height() - drop_shadow_height());
 
   // Now draw the highlights/shadows around the tab edge.
   canvas->DrawImageInt(*tab_image->image_l, 0, 0);
diff --git a/chrome/browser/ui/views/tabs/tab.h b/chrome/browser/ui/views/tabs/tab.h
index 534091f..9b697a4 100644
--- a/chrome/browser/ui/views/tabs/tab.h
+++ b/chrome/browser/ui/views/tabs/tab.h
@@ -345,7 +345,6 @@
     gfx::ImageSkia* image_r;
     int l_width;
     int r_width;
-    int y_offset;
   };
   static TabImage tab_active_;
   static TabImage tab_inactive_;
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
index 3b432ce..9ba163c 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -11,6 +11,7 @@
 #include "base/callback.h"
 #include "base/command_line.h"
 #include "base/i18n/rtl.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_function_dispatcher.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.h"
@@ -24,7 +25,6 @@
 #include "chrome/browser/ui/views/tabs/stacked_tab_strip_layout.h"
 #include "chrome/browser/ui/views/tabs/tab.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
@@ -201,15 +201,6 @@
 #endif
 }
 
-bool ShouldDetachIntoNewBrowser() {
-#if defined(USE_AURA)
-  return true;
-#else
-  return CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kTabBrowserDragging);
-#endif
-}
-
 // Returns true if |bounds| contains the y-coordinate |y|. The y-coordinate
 // of |bounds| is adjusted by |vertical_adjustment|.
 bool DoesRectContainVerticalPointExpanded(
@@ -479,6 +470,16 @@
   return instance_ && instance_->active();
 }
 
+// static
+bool TabDragController::ShouldDetachIntoNewBrowser() {
+#if defined(USE_AURA)
+  return true;
+#else
+  return CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kTabBrowserDragging);
+#endif
+}
+
 void TabDragController::SetMoveBehavior(MoveBehavior behavior) {
   if (started_drag())
     return;
@@ -1307,7 +1308,6 @@
 
   // Create a new browser to house the dragged tabs and have the OS run a move
   // loop.
-
   gfx::Point attached_point = GetAttachedDragPoint(point_in_screen);
 
   // Calculate the bounds for the tabs from the attached_tab_strip. We do this
@@ -1315,6 +1315,11 @@
   std::vector<gfx::Rect> drag_bounds =
       CalculateBoundsForDraggedTabs(attached_point.x());
 
+  // Stash the current window size and tab area width.
+  gfx::Size source_size =
+      attached_tabstrip_->GetWidget()->GetWindowBoundsInScreen().size();
+  int available_source_width = attached_tabstrip_->tab_area_width();
+
   gfx::Vector2d drag_offset;
   Browser* browser = CreateBrowserForDrag(
       attached_tabstrip_, point_in_screen, &drag_offset, &drag_bounds);
@@ -1324,7 +1329,50 @@
   dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled(
       false);
   Attach(dragged_browser_view->tabstrip(), gfx::Point());
-  // TODO: come up with a cleaner way to do this.
+
+  // If the window size has changed, the tab positioning will be quite off.
+  if (source_size !=
+          attached_tabstrip_->GetWidget()->GetWindowBoundsInScreen().size()) {
+    // First, scale the drag bounds such that they fit within the new window
+    // while maintaining the same relative positions. This scales the tabs
+    // down so that they occupy the same relative width on the new tab strip,
+    // clamping to minimum tab width.
+      int available_attached_width = attached_tabstrip_->tab_area_width();
+    float x_scale =
+        static_cast<float>(available_attached_width) / available_source_width;
+    int x_offset = std::ceil((1.0 - x_scale) * drag_bounds[0].x());
+    int accumulated_width_offset = 0;
+    for (size_t i = 0; i < drag_bounds.size(); ++i) {
+      gfx::Rect& tab_bounds = drag_bounds[i];
+      tab_bounds.Offset(-(x_offset + accumulated_width_offset), 0);
+      int old_width = tab_bounds.width();
+      int min_width = (i == source_tab_index_) ?
+          drag_data_[i].attached_tab->GetMinimumSelectedSize().width() :
+          drag_data_[i].attached_tab->GetMinimumUnselectedSize().width();
+      int new_width =
+          std::max(min_width, static_cast<int>(std::ceil(old_width * x_scale)));
+      tab_bounds.set_width(new_width);
+      accumulated_width_offset += (old_width - tab_bounds.width());
+    }
+
+    // Next, re-position the restored window such that the tab that was dragged
+    // remains centered under the mouse cursor. The two offsets needed here are
+    // the offset of the dragged tab in widget coordinates, and half the dragged
+    // tab width. The sum of these is the horizontal distance from the mouse
+    // cursor to the window edge.
+    gfx::Point offset(drag_bounds[source_tab_index_].origin());
+    views::View::ConvertPointToWidget(attached_tabstrip_, &offset);
+    int half_tab_width = drag_bounds[source_tab_index_].width() / 2;
+    gfx::Rect new_bounds = browser->window()->GetBounds();
+    new_bounds.set_x(point_in_screen.x() - offset.x() - half_tab_width);
+
+    // To account for the extra vertical on restored windows that is absent
+    // on maximized windows, add an additional vertical offset extracted from
+    // the tab strip.
+    new_bounds.Offset(0, -attached_tabstrip_->button_v_offset());
+    browser->window()->SetBounds(new_bounds);
+  }
+
   attached_tabstrip_->SetTabBoundsForDrag(drag_bounds);
 
   WindowPositionManagedUpdater updater;
@@ -2003,14 +2051,13 @@
     std::vector<gfx::Rect>* drag_bounds) {
   gfx::Point center(0, source->height() / 2);
   views::View::ConvertPointToWidget(source, &center);
-  gfx::Rect new_bounds(source->GetWidget()->GetWindowBoundsInScreen());
+  gfx::Rect new_bounds(source->GetWidget()->GetRestoredBounds());
   new_bounds.set_y(point_in_screen.y() - center.y());
   switch (GetDetachPosition(point_in_screen)) {
     case DETACH_BEFORE:
       new_bounds.set_x(point_in_screen.x() - center.x());
       new_bounds.Offset(-mouse_offset_.x(), 0);
       break;
-
     case DETACH_AFTER: {
       gfx::Point right_edge(source->width(), 0);
       views::View::ConvertPointToWidget(source, &right_edge);
@@ -2021,7 +2068,6 @@
         (*drag_bounds)[i].Offset(-delta, 0);
       break;
     }
-
     default:
       break; // Nothing to do for DETACH_ABOVE_OR_BELOW.
   }
@@ -2041,9 +2087,6 @@
   // We need to reset them again so they are honored.
   browser->window()->SetBounds(new_bounds);
 
-  // If source window was maximized - maximize the new window as well.
-  if (source->GetWidget()->IsMaximized() || source->GetWidget()->IsFullscreen())
-    browser->window()->Maximize();
   return browser;
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.h b/chrome/browser/ui/views/tabs/tab_drag_controller.h
index 7323976..2f5a37a 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.h
@@ -113,6 +113,10 @@
   // Returns true if there is a drag underway.
   static bool IsActive();
 
+  // Used to determine whether the tab drag controller detaches dragged tabs
+  // into new browser windows while the drag is in process.
+  static bool ShouldDetachIntoNewBrowser();
+
   // Sets the move behavior. Has no effect if started_drag() is true.
   void SetMoveBehavior(MoveBehavior behavior);
   MoveBehavior move_behavior() const { return move_behavior_; }
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index f1e896a..fc9c3e2 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -10,6 +10,7 @@
 #include "base/command_line.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_iterator.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/ui/views/tabs/tab.h"
 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/interactive_test_utils.h"
@@ -518,6 +518,63 @@
   EXPECT_FALSE(new_browser->window()->IsMaximized());
 }
 
+// Drags from browser to separate window and releases mouse.
+IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
+                       DetachToOwnWindowFromMaximizedWindow) {
+  if (!TabDragController::ShouldDetachIntoNewBrowser()) {
+    VLOG(1)
+        << "Skipping DetachToOwnWindowFromMaximizedWindow on this platform.";
+    return;
+  }
+
+  // Maximize the initial browser window.
+  browser()->window()->Maximize();
+  ASSERT_TRUE(browser()->window()->IsMaximized());
+
+  // Add another tab.
+  AddTabAndResetBrowser(browser());
+  TabStrip* tab_strip = GetTabStripForBrowser(browser());
+
+  // Move to the first tab and drag it enough so that it detaches.
+  gfx::Point tab_0_center(
+      GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
+  ASSERT_TRUE(PressInput(tab_0_center));
+  ASSERT_TRUE(DragInputToNotifyWhenDone(
+                  tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
+                  base::Bind(&DetachToOwnWindowStep2, this)));
+  if (input_source() == INPUT_SOURCE_MOUSE) {
+    ASSERT_TRUE(ReleaseMouseAsync());
+    QuitWhenNotDragging();
+  }
+
+  // Should no longer be dragging.
+  ASSERT_FALSE(tab_strip->IsDragSessionActive());
+  ASSERT_FALSE(TabDragController::IsActive());
+
+  // There should now be another browser.
+  ASSERT_EQ(2u, native_browser_list->size());
+  Browser* new_browser = native_browser_list->get(1);
+  ASSERT_TRUE(new_browser->window()->IsActive());
+  TabStrip* tab_strip2 = GetTabStripForBrowser(new_browser);
+  ASSERT_FALSE(tab_strip2->IsDragSessionActive());
+
+  EXPECT_EQ("0", IDString(new_browser->tab_strip_model()));
+  EXPECT_EQ("1", IDString(browser()->tab_strip_model()));
+
+  // The bounds of the initial window should not have changed.
+  EXPECT_TRUE(browser()->window()->IsMaximized());
+
+  EXPECT_TRUE(GetTrackedByWorkspace(browser()));
+  EXPECT_TRUE(GetTrackedByWorkspace(new_browser));
+  // After this both windows should still be managable.
+  EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow()));
+  EXPECT_TRUE(IsWindowPositionManaged(
+      new_browser->window()->GetNativeWindow()));
+
+  // The new window should not be maximized.
+  EXPECT_FALSE(new_browser->window()->IsMaximized());
+}
+
 // Deletes a tab being dragged before the user moved enough to start a drag.
 IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
                        DeleteBeforeStartedDragging) {
@@ -1079,9 +1136,10 @@
   EXPECT_TRUE(GetTrackedByWorkspace(browser()));
   EXPECT_TRUE(GetTrackedByWorkspace(new_browser));
 
-  // Both windows should be maximized
+  // The source window should be maximized, but the new window should now
+  // be restored.
   EXPECT_TRUE(browser()->window()->IsMaximized());
-  EXPECT_TRUE(new_browser->window()->IsMaximized());
+  EXPECT_FALSE(new_browser->window()->IsMaximized());
 }
 
 // Subclass of DetachToBrowserInSeparateDisplayTabDragControllerTest that
@@ -1459,7 +1517,7 @@
   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     DetachToBrowserTabDragControllerTest::SetUpCommandLine(command_line);
     command_line->AppendSwitchASCII("ash-host-window-bounds",
-                                    "400x400,800x800*2");
+                                    "400x400,0+400-800x800*2");
   }
 
   float GetCursorDeviceScaleFactor() const {
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest_win.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest_win.cc
index bf9dda0..5263b7d 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest_win.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest_win.cc
@@ -9,6 +9,7 @@
 #include "base/command_line.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/win/windows_version.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/ui/views/tabs/tab.h"
 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/interactive_test_utils.h"
diff --git a/chrome/browser/ui/views/tabs/tab_renderer_data.h b/chrome/browser/ui/views/tabs/tab_renderer_data.h
index 27348c7..ddfe4dd 100644
--- a/chrome/browser/ui/views/tabs/tab_renderer_data.h
+++ b/chrome/browser/ui/views/tabs/tab_renderer_data.h
@@ -8,8 +8,8 @@
 #include "base/process_util.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/ui/views/chrome_views_export.h"
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/image/image_skia.h"
+#include "url/gurl.h"
 
 // Wraps the state needed by the renderers.
 struct CHROME_VIEWS_EXPORT TabRendererData {
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index e0356c8..a99257d 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -2505,10 +2505,20 @@
   return next_x;
 }
 
-int TabStrip::new_tab_button_width() const {
+// static
+int TabStrip::new_tab_button_width() {
   return newtab_button_asset_width() + newtab_button_h_offset();
 }
 
+// static
+int TabStrip::button_v_offset() {
+  return newtab_button_v_offset();
+}
+
+int TabStrip::tab_area_width() const {
+  return width() - new_tab_button_width();
+}
+
 void TabStrip::StartResizeLayoutAnimation() {
   PrepareForAnimation();
   GenerateIdealBounds();
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h
index a78cff7..9ace500 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.h
+++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -475,7 +475,15 @@
   int GenerateIdealBoundsForMiniTabs(int* first_non_mini_index);
 
   // Returns the width needed for the new tab button (and padding).
-  int new_tab_button_width() const;
+  static int new_tab_button_width();
+
+  // Returns the vertical offset of the tab strip button. This offset applies
+  // only to restored windows.
+  static int button_v_offset();
+
+  // Returns the width of the area that contains tabs. This does not include
+  // the width of the new tab button.
+  int tab_area_width() const;
 
   // Starts various types of TabStrip animations.
   void StartResizeLayoutAnimation();
diff --git a/chrome/browser/ui/views/toolbar_view.cc b/chrome/browser/ui/views/toolbar_view.cc
index 0b3cc79..98f7381 100644
--- a/chrome/browser/ui/views/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar_view.cc
@@ -9,6 +9,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_service.h"
@@ -34,7 +35,6 @@
 #include "chrome/browser/ui/views/wrench_menu.h"
 #include "chrome/browser/ui/views/wrench_toolbar_button.h"
 #include "chrome/browser/upgrade_detector.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_accessibility_state.h"
 #include "content/public/browser/notification_service.h"
@@ -360,9 +360,8 @@
 
 void ToolbarView::ShowWebsiteSettings(content::WebContents* web_contents,
                                       const GURL& url,
-                                      const content::SSLStatus& ssl,
-                                      bool show_history) {
-  chrome::ShowWebsiteSettings(browser_, web_contents, url, ssl, show_history);
+                                      const content::SSLStatus& ssl) {
+  chrome::ShowWebsiteSettings(browser_, web_contents, url, ssl);
 }
 
 views::Widget* ToolbarView::CreateViewsBubble(
diff --git a/chrome/browser/ui/views/toolbar_view.h b/chrome/browser/ui/views/toolbar_view.h
index 6af7c97..7f72778 100644
--- a/chrome/browser/ui/views/toolbar_view.h
+++ b/chrome/browser/ui/views/toolbar_view.h
@@ -103,8 +103,7 @@
       GetContentSettingBubbleModelDelegate() OVERRIDE;
   virtual void ShowWebsiteSettings(content::WebContents* web_contents,
                                    const GURL& url,
-                                   const content::SSLStatus& ssl,
-                                   bool show_history) OVERRIDE;
+                                   const content::SSLStatus& ssl) OVERRIDE;
   virtual void OnInputInProgress(bool in_progress) OVERRIDE;
 
   // Overridden from CommandObserver:
diff --git a/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc b/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc
index b2cc59f..e5419ba 100644
--- a/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc
+++ b/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc
@@ -18,7 +18,6 @@
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/cert_store.h"
 #include "content/public/browser/user_metrics.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
@@ -45,6 +44,7 @@
 #include "ui/views/layout/layout_manager.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
+#include "url/gurl.h"
 
 namespace {
 
@@ -261,11 +261,12 @@
                                          const GURL& url,
                                          const content::SSLStatus& ssl,
                                          Browser* browser) {
-  if (InternalChromePage(url))
+  if (InternalChromePage(url)) {
     new InternalPageInfoPopupView(anchor_view);
-  else
+  } else {
     new WebsiteSettingsPopupView(anchor_view, profile, web_contents, url, ssl,
                                  browser);
+  }
 }
 
 WebsiteSettingsPopupView::WebsiteSettingsPopupView(
@@ -336,16 +337,11 @@
   views::BubbleDelegateView::CreateBubble(this)->Show();
   SizeToContents();
 
-  TabSpecificContentSettings* content_settings =
-      TabSpecificContentSettings::FromWebContents(web_contents);
-  InfoBarService* infobar_service =
-      InfoBarService::FromWebContents(web_contents);
-  presenter_.reset(new WebsiteSettings(this, profile,
-                                       content_settings,
-                                       infobar_service,
-                                       url,
-                                       ssl,
-                                       content::CertStore::GetInstance()));
+  presenter_.reset(new WebsiteSettings(
+      this, profile,
+      TabSpecificContentSettings::FromWebContents(web_contents),
+      InfoBarService::FromWebContents(web_contents), url, ssl,
+      content::CertStore::GetInstance()));
 }
 
 void WebsiteSettingsPopupView::OnPermissionChanged(
diff --git a/chrome/browser/ui/views/wrench_menu.cc b/chrome/browser/ui/views/wrench_menu.cc
index a20b978..53daa47 100644
--- a/chrome/browser/ui/views/wrench_menu.cc
+++ b/chrome/browser/ui/views/wrench_menu.cc
@@ -13,13 +13,13 @@
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/host_zoom_map.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
diff --git a/chrome/browser/ui/web_applications/web_app_ui.cc b/chrome/browser/ui/web_applications/web_app_ui.cc
index b83cbd5..47cfe9a 100644
--- a/chrome/browser/ui/web_applications/web_app_ui.cc
+++ b/chrome/browser/ui/web_applications/web_app_ui.cc
@@ -11,13 +11,13 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/image_loader.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/favicon/favicon_tab_helper.h"
 #include "chrome/browser/favicon/favicon_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
@@ -27,7 +27,6 @@
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents.h"
-#include "googleurl/src/gurl.h"
 #include "grit/theme_resources.h"
 #include "skia/ext/image_operations.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -35,6 +34,7 @@
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_family.h"
 #include "ui/gfx/image/image_skia.h"
+#include "url/gurl.h"
 
 #if defined(OS_POSIX) && !defined(OS_MACOSX)
 #include "base/environment.h"
@@ -260,7 +260,7 @@
 
     base::FilePath shortcut_file = path.Append(file_name_).
         ReplaceExtension(FILE_PATH_LITERAL(".lnk"));
-    if (file_util::PathExists(shortcut_file)) {
+    if (base::PathExists(shortcut_file)) {
       shortcut_files_.push_back(shortcut_file);
     }
   }
@@ -280,7 +280,7 @@
 
   // Ensure web_app_path exists. web_app_path could be missing for a legacy
   // shortcut created by Gears.
-  if (!file_util::PathExists(web_app_path) &&
+  if (!base::PathExists(web_app_path) &&
       !file_util::CreateDirectory(web_app_path)) {
     NOTREACHED();
     return;
diff --git a/chrome/browser/ui/website_settings/permission_menu_model.h b/chrome/browser/ui/website_settings/permission_menu_model.h
index cb6537e..9500aa1 100644
--- a/chrome/browser/ui/website_settings/permission_menu_model.h
+++ b/chrome/browser/ui/website_settings/permission_menu_model.h
@@ -5,10 +5,10 @@
 #ifndef CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_MENU_MODEL_H_
 #define CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_MENU_MODEL_H_
 
-#include "ui/base/models/simple_menu_model.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/content_settings_types.h"
-#include "googleurl/src/gurl.h"
+#include "ui/base/models/simple_menu_model.h"
+#include "url/gurl.h"
 
 class PermissionMenuModel : public ui::SimpleMenuModel,
                             public ui::SimpleMenuModel::Delegate {
diff --git a/chrome/browser/ui/website_settings/website_settings.cc b/chrome/browser/ui/website_settings/website_settings.cc
index 6c3db3f..c0c175c 100644
--- a/chrome/browser/ui/website_settings/website_settings.cc
+++ b/chrome/browser/ui/website_settings/website_settings.cc
@@ -62,6 +62,7 @@
   CONTENT_SETTINGS_TYPE_FULLSCREEN,
   CONTENT_SETTINGS_TYPE_MOUSELOCK,
   CONTENT_SETTINGS_TYPE_MEDIASTREAM,
+  CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
 };
 
 }  // namespace
@@ -229,7 +230,7 @@
 
 void WebsiteSettings::OnUIClosing() {
   if (show_info_bar_)
-    WebsiteSettingsInfobarDelegate::Create(infobar_service_);
+    WebsiteSettingsInfoBarDelegate::Create(infobar_service_);
 }
 
 void WebsiteSettings::Init(Profile* profile,
diff --git a/chrome/browser/ui/website_settings/website_settings.h b/chrome/browser/ui/website_settings/website_settings.h
index 89712b4..e27d857 100644
--- a/chrome/browser/ui/website_settings/website_settings.h
+++ b/chrome/browser/ui/website_settings/website_settings.h
@@ -13,8 +13,8 @@
 #include "chrome/browser/history/history_service.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/content_settings_types.h"
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/native_widget_types.h"
+#include "url/gurl.h"
 
 namespace content {
 class CertStore;
@@ -144,7 +144,7 @@
   WebsiteSettingsUI* ui_;
 
   // The infobar service of the active tab.
-  InfoBarService* infobar_service_;  // Owned by the active tab contents.
+  InfoBarService* infobar_service_;
 
   // The flag that controls whether an infobar is displayed after the website
   // settings UI is closed or not.
diff --git a/chrome/browser/ui/website_settings/website_settings_infobar_delegate.cc b/chrome/browser/ui/website_settings/website_settings_infobar_delegate.cc
index 9ed9009..9c2ba16 100644
--- a/chrome/browser/ui/website_settings/website_settings_infobar_delegate.cc
+++ b/chrome/browser/ui/website_settings/website_settings_infobar_delegate.cc
@@ -13,39 +13,42 @@
 #include "ui/base/l10n/l10n_util.h"
 
 // static
-void WebsiteSettingsInfobarDelegate::Create(InfoBarService* infobar_service) {
+void WebsiteSettingsInfoBarDelegate::Create(InfoBarService* infobar_service) {
   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
-      new WebsiteSettingsInfobarDelegate(infobar_service)));
+      new WebsiteSettingsInfoBarDelegate(infobar_service)));
 }
 
-WebsiteSettingsInfobarDelegate::WebsiteSettingsInfobarDelegate(
+WebsiteSettingsInfoBarDelegate::WebsiteSettingsInfoBarDelegate(
     InfoBarService* infobar_service)
     : ConfirmInfoBarDelegate(infobar_service) {
 }
 
-int WebsiteSettingsInfobarDelegate::GetIconID() const {
+WebsiteSettingsInfoBarDelegate::~WebsiteSettingsInfoBarDelegate() {
+}
+
+int WebsiteSettingsInfoBarDelegate::GetIconID() const {
   return IDR_INFOBAR_ALT_NAV_URL;
 }
 
-InfoBarDelegate::Type WebsiteSettingsInfobarDelegate::GetInfoBarType() const {
+InfoBarDelegate::Type WebsiteSettingsInfoBarDelegate::GetInfoBarType() const {
   return PAGE_ACTION_TYPE;
 }
 
-string16 WebsiteSettingsInfobarDelegate::GetMessageText() const {
+string16 WebsiteSettingsInfoBarDelegate::GetMessageText() const {
   return l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_INFOBAR_TEXT);
 }
 
-int WebsiteSettingsInfobarDelegate::GetButtons() const {
+int WebsiteSettingsInfoBarDelegate::GetButtons() const {
   return BUTTON_OK;
 }
 
-string16 WebsiteSettingsInfobarDelegate::GetButtonLabel(
+string16 WebsiteSettingsInfoBarDelegate::GetButtonLabel(
     InfoBarButton button) const {
   DCHECK_EQ(BUTTON_OK, button);
   return l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_INFOBAR_BUTTON);
 }
 
-bool WebsiteSettingsInfobarDelegate::Accept() {
+bool WebsiteSettingsInfoBarDelegate::Accept() {
   web_contents()->GetController().Reload(true);
   return true;
 }
diff --git a/chrome/browser/ui/website_settings/website_settings_infobar_delegate.h b/chrome/browser/ui/website_settings/website_settings_infobar_delegate.h
index b824053..6f6b3d9 100644
--- a/chrome/browser/ui/website_settings/website_settings_infobar_delegate.h
+++ b/chrome/browser/ui/website_settings/website_settings_infobar_delegate.h
@@ -14,13 +14,14 @@
 // changed. The user is shown a message indicating that a reload of the page is
 // required for the changes to take effect, and presented a button to perform
 // the reload right from the infobar.
-class WebsiteSettingsInfobarDelegate : public ConfirmInfoBarDelegate {
+class WebsiteSettingsInfoBarDelegate : public ConfirmInfoBarDelegate {
  public:
   // Creates a website settings delegate and adds it to |infobar_service|.
   static void Create(InfoBarService* infobar_service);
 
  private:
-  explicit WebsiteSettingsInfobarDelegate(InfoBarService* infobar_service);
+  explicit WebsiteSettingsInfoBarDelegate(InfoBarService* infobar_service);
+  virtual ~WebsiteSettingsInfoBarDelegate();
 
   // ConfirmInfoBarDelegate:
   virtual int GetIconID() const OVERRIDE;
@@ -30,7 +31,7 @@
   virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
   virtual bool Accept() OVERRIDE;
 
-  DISALLOW_COPY_AND_ASSIGN(WebsiteSettingsInfobarDelegate);
+  DISALLOW_COPY_AND_ASSIGN(WebsiteSettingsInfoBarDelegate);
 };
 
 #endif  // CHROME_BROWSER_UI_WEBSITE_SETTINGS_WEBSITE_SETTINGS_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/ui/website_settings/website_settings_ui.cc b/chrome/browser/ui/website_settings/website_settings_ui.cc
index fa352fa..7d7e4d3 100644
--- a/chrome/browser/ui/website_settings/website_settings_ui.cc
+++ b/chrome/browser/ui/website_settings/website_settings_ui.cc
@@ -124,6 +124,8 @@
       return l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TYPE_MOUSELOCK);
     case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
       return l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TYPE_MEDIASTREAM);
+    case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
+      return l10n_util::GetStringUTF16(IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL);
     default:
       NOTREACHED();
       return string16();
@@ -218,6 +220,10 @@
     case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
       resource_id = use_blocked ? IDR_BLOCKED_MEDIA : IDR_ASK_MEDIA;
       break;
+    case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
+      resource_id = use_blocked ? IDR_BLOCKED_DOWNLOADS
+                                : IDR_ALLOWED_DOWNLOADS;
+      break;
     default:
       NOTREACHED();
       break;
diff --git a/chrome/browser/ui/website_settings/website_settings_utils.cc b/chrome/browser/ui/website_settings/website_settings_utils.cc
index a2b7a02..f2c633b 100644
--- a/chrome/browser/ui/website_settings/website_settings_utils.cc
+++ b/chrome/browser/ui/website_settings/website_settings_utils.cc
@@ -6,7 +6,7 @@
 
 #include "chrome/common/url_constants.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 // Returns true if the passed |url| refers to an internal chrome page.
 bool InternalChromePage(const GURL& url) {
diff --git a/chrome/browser/ui/webui/OWNERS b/chrome/browser/ui/webui/OWNERS
index a989230..6df6124 100644
--- a/chrome/browser/ui/webui/OWNERS
+++ b/chrome/browser/ui/webui/OWNERS
@@ -7,5 +7,6 @@
 pam@chromium.org
 xiyuan@chromium.org
 
+per-file inspect_ui*=pfeldman@chromium.org
 per-file sync_setup_handler*=atwilson@chromium.org
 per-file sync_setup_handler*=rogerta@chromium.org
diff --git a/chrome/browser/ui/webui/about_ui.cc b/chrome/browser/ui/webui/about_ui.cc
index 6c1765f..864eb3f 100644
--- a/chrome/browser/ui/webui/about_ui.cc
+++ b/chrome/browser/ui/webui/about_ui.cc
@@ -48,7 +48,6 @@
 #include "content/public/common/content_client.h"
 #include "content/public/common/process_type.h"
 #include "google_apis/gaia/google_service_auth_error.h"
-#include "googleurl/src/gurl.h"
 #include "grit/browser_resources.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
@@ -63,6 +62,7 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/webui/jstemplate_builder.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/gurl.h"
 
 #if defined(ENABLE_THEMES)
 #include "chrome/browser/ui/webui/theme_source.h"
diff --git a/chrome/browser/ui/webui/app_launcher_page_ui.cc b/chrome/browser/ui/webui/app_launcher_page_ui.cc
index 1a2b32e..09281cf 100644
--- a/chrome/browser/ui/webui/app_launcher_page_ui.cc
+++ b/chrome/browser/ui/webui/app_launcher_page_ui.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ui/webui/app_launcher_page_ui.h"
 
-#include "apps/app_launcher.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/metrics/histogram.h"
 #include "chrome/browser/profiles/profile.h"
@@ -111,16 +110,6 @@
   scoped_refptr<base::RefCountedMemory> html_bytes(
       resource->GetNewTabHTML(is_incognito));
 
-  if (!is_incognito) {
-    if (apps::IsAppLauncherEnabled()) {
-      AppLauncherHandler::RecordAppLauncherPromoHistogram(
-          apps::APP_LAUNCHER_PROMO_ALREADY_INSTALLED);
-    } else if (apps::ShouldShowAppLauncherPromo()){
-      AppLauncherHandler::RecordAppLauncherPromoHistogram(
-          apps::APP_LAUNCHER_PROMO_SHOWN);
-    }
-  }
-
   callback.Run(html_bytes.get());
 }
 
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 4bcecf7..e918829 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -60,9 +60,9 @@
 #include "content/public/common/content_client.h"
 #include "content/public/common/url_utils.h"
 #include "extensions/common/constants.h"
-#include "googleurl/src/gurl.h"
 #include "ui/gfx/favicon_size.h"
 #include "ui/web_dialogs/web_dialog_ui.h"
+#include "url/gurl.h"
 
 #if !defined(DISABLE_NACL)
 #include "chrome/browser/ui/webui/nacl_ui.h"
diff --git a/chrome/browser/ui/webui/chromeos/OWNERS b/chrome/browser/ui/webui/chromeos/OWNERS
index f8ba7a2..53311ba 100644
--- a/chrome/browser/ui/webui/chromeos/OWNERS
+++ b/chrome/browser/ui/webui/chromeos/OWNERS
@@ -5,3 +5,4 @@
 satorux@chromium.org
 
 per-file about_network.*=stevenjb@chromium.org
+per-file sim_unlock_ui.*=stevenjb@chromium.org
diff --git a/chrome/browser/ui/webui/chromeos/about_network.cc b/chrome/browser/ui/webui/chromeos/about_network.cc
index bd0b510..b377709 100644
--- a/chrome/browser/ui/webui/chromeos/about_network.cc
+++ b/chrome/browser/ui/webui/chromeos/about_network.cc
@@ -10,6 +10,7 @@
 #include "base/strings/string_tokenizer.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/webui/about_ui.h"
+#include "chromeos/network/favorite_state.h"
 #include "chromeos/network/network_event_log.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
@@ -83,6 +84,7 @@
       WrapWithTH("Type") +
       WrapWithTH("State") +
       WrapWithTH("Path") +
+      WrapWithTH("Profile") +
       WrapWithTH("Connect") +
       WrapWithTH("Error") +
       WrapWithTH("IP Addr") +
@@ -104,6 +106,7 @@
       WrapWithTD(network->type()) +
       WrapWithTD(network->connection_state()) +
       WrapWithTD(network->path()) +
+      WrapWithTD(network->profile_path()) +
       WrapWithTD(base::IntToString(network->connectable())) +
       WrapWithTD(network->error()) +
       WrapWithTD(network->ip_address()) +
@@ -119,6 +122,24 @@
   return WrapWithTR(str);
 }
 
+std::string FavoriteStateToHtmlTableHeader() {
+  std::string str =
+      WrapWithTH("Name") +
+      WrapWithTH("Type") +
+      WrapWithTH("Path") +
+      WrapWithTH("Profile");
+  return WrapWithTR(str);
+}
+
+std::string FavoriteStateToHtmlTableRow(const FavoriteState* favorite) {
+  std::string str =
+      WrapWithTD(favorite->name()) +
+      WrapWithTD(favorite->type()) +
+      WrapWithTD(favorite->path()) +
+      WrapWithTD(favorite->profile_path());
+  return WrapWithTR(str);
+}
+
 std::string GetNetworkStateHtmlInfo() {
   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
   NetworkStateHandler::NetworkStateList network_list;
@@ -138,6 +159,25 @@
   return output;
 }
 
+std::string GetFavoriteStateHtmlInfo() {
+  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
+  NetworkStateHandler::FavoriteStateList favorite_list;
+  handler->GetFavoriteList(&favorite_list);
+
+  std::string output;
+  output.append(WrapWithH3(
+      l10n_util::GetStringUTF8(IDS_ABOUT_NETWORK_FAVORITES)));
+  output.append("<table border=1>");
+  output.append(FavoriteStateToHtmlTableHeader());
+  for (NetworkStateHandler::FavoriteStateList::iterator iter =
+           favorite_list.begin(); iter != favorite_list.end(); ++iter) {
+    const FavoriteState* favorite = *iter;
+    output.append(FavoriteStateToHtmlTableRow(favorite));
+  }
+  output.append("</table>");
+  return output;
+}
+
 }  // namespace
 
 namespace about_ui {
@@ -157,6 +197,7 @@
   if (network_event_log::IsInitialized())
     output += GetEventLogSection(debug);
   output += GetNetworkStateHtmlInfo();
+  output += GetFavoriteStateHtmlInfo();
   return output;
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/choose_mobile_network_ui.cc b/chrome/browser/ui/webui/chromeos/choose_mobile_network_ui.cc
index d207f42..ab318e1 100644
--- a/chrome/browser/ui/webui/chromeos/choose_mobile_network_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/choose_mobile_network_ui.cc
@@ -13,7 +13,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/url_constants.h"
@@ -101,7 +100,7 @@
 
 ChooseMobileNetworkHandler::ChooseMobileNetworkHandler()
     : is_page_ready_(false), has_pending_results_(false) {
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   if (const NetworkDevice* cellular = cros->FindCellularDevice()) {
     device_path_ = cellular->device_path();
     cros->AddNetworkDeviceObserver(device_path_, this);
@@ -111,7 +110,7 @@
 
 ChooseMobileNetworkHandler::~ChooseMobileNetworkHandler() {
   if (!device_path_.empty()) {
-    NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+    NetworkLibrary* cros = NetworkLibrary::Get();
     cros->RemoveNetworkDeviceObserver(device_path_, this);
   }
 }
@@ -174,7 +173,7 @@
   }
 
   // Switch to automatic mode.
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   cros->RequestCellularRegister(std::string());
 }
 
@@ -187,7 +186,7 @@
     return;
   }
 
-  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* cros = NetworkLibrary::Get();
   cros->RequestCellularRegister(network_id);
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/imageburner/imageburner_ui.cc b/chrome/browser/ui/webui/chromeos/imageburner/imageburner_ui.cc
index e7eeda5..834a9d0 100644
--- a/chrome/browser/ui/webui/chromeos/imageburner/imageburner_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/imageburner/imageburner_ui.cc
@@ -17,11 +17,11 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "content/public/browser/web_ui_message_handler.h"
-#include "googleurl/src/gurl.h"
 #include "grit/browser_resources.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/text/bytes_formatting.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 namespace imageburner {
diff --git a/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc b/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc
index a768034..3854377 100644
--- a/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc
@@ -222,6 +222,8 @@
     IDS_KEYBOARD_OVERLAY_TOGGLE_SPEECH_INPUT },
   { "keyboardOverlayToggleSpokenFeedback",
     IDS_KEYBOARD_OVERLAY_TOGGLE_SPOKEN_FEEDBACK },
+  { "keyboardOverlayToggleTouchHudProjection",
+    IDS_KEYBOARD_OVERLAY_TOGGLE_TOUCH_HUD_PROJECTION },
   { "keyboardOverlayUndo", IDS_KEYBOARD_OVERLAY_UNDO },
   { "keyboardOverlayViewKeyboardOverlay",
     IDS_KEYBOARD_OVERLAY_VIEW_KEYBOARD_OVERLAY },
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
index 259cdf6..f41bbc8 100644
--- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -7,6 +7,7 @@
 #include "ash/magnifier/magnifier_constants.h"
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
@@ -15,7 +16,6 @@
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chromeos/chromeos_constants.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc
index cee9ea1..341c8a2 100644
--- a/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc
@@ -7,11 +7,11 @@
 #include "base/logging.h"
 #include "base/message_loop.h"
 #include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/captive_portal_window_proxy.h"
 #include "chrome/browser/chromeos/net/network_portal_detector.h"
 #include "chrome/browser/ui/webui/chromeos/login/native_window_delegate.h"
 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "grit/generated_resources.h"
 
 namespace chromeos {
diff --git a/chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.cc b/chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.cc
index 1fdc155..7cfea29 100644
--- a/chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.cc
@@ -8,11 +8,11 @@
 #include "base/command_line.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_launcher.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chromeos/chromeos_switches.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
@@ -35,10 +35,6 @@
 
 void KioskAppMenuHandler::GetLocalizedStrings(
     base::DictionaryValue* localized_strings) {
-  localized_strings->SetBoolean(
-      "enableAppMode",
-      !CommandLine::ForCurrentProcess()->HasSwitch(
-          chromeos::switches::kDisableAppMode));
   localized_strings->SetString(
       "showApps",
       l10n_util::GetStringUTF16(IDS_KIOSK_APPS_BUTTON));
diff --git a/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc
index f38c744..edf9af6 100644
--- a/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc
@@ -10,8 +10,8 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_switches.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc
index 1c6c1eb..523038c 100644
--- a/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc
@@ -7,7 +7,7 @@
 #include <string>
 
 #include "chrome/browser/browser_process.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
index 8d96641..6a13f8a 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
@@ -8,7 +8,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/input_method/input_method_util.h"
 #include "chrome/browser/chromeos/login/language_switch_menu.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc b/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc
index 3f78058..9f48f45 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc
+++ b/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc
@@ -7,10 +7,10 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/message_loop.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/net/proxy_config_handler.h"
 #include "chrome/browser/prefs/proxy_config_dictionary.h"
 #include "chrome/browser/prefs/proxy_prefs.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
 #include "net/proxy/proxy_config.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 2388a61..f679ad7 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -6,6 +6,7 @@
 
 #include "base/callback.h"
 #include "base/command_line.h"
+#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/metrics/histogram.h"
@@ -17,6 +18,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part_chromeos.h"
 #include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
 #include "chrome/browser/chromeos/login/hwid_checker.h"
@@ -35,7 +37,6 @@
 #include "chrome/browser/ui/webui/chromeos/login/native_window_delegate.h"
 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -445,6 +446,7 @@
 }
 
 void SigninScreenHandler::Show(bool oobe_ui) {
+  TRACE_EVENT_ASYNC_BEGIN0("ui", "ShowLoginWebUI", this);
   CHECK(delegate_);
   oobe_ui_ = oobe_ui;
   if (!page_is_ready()) {
@@ -1434,6 +1436,7 @@
 }
 
 void SigninScreenHandler::HandleLoginVisible(const std::string& source) {
+  TRACE_EVENT_ASYNC_END0("ui", "ShowLoginWebUI", this);
   LOG(INFO) << "Login WebUI >> LoginVisible, source: " << source << ", "
             << "webui_visible_: " << webui_visible_;
   if (!webui_visible_) {
diff --git a/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc
index 43b770b..7eb604a 100644
--- a/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc
@@ -14,10 +14,10 @@
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "net/base/data_url.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
diff --git a/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc b/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc
index a6c5c9d..2322c11 100644
--- a/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc
@@ -19,7 +19,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/mobile/mobile_activator.h"
 #include "chrome/browser/profiles/profile.h"
@@ -33,7 +32,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_message_handler.h"
-#include "googleurl/src/gurl.h"
 #include "grit/browser_resources.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
@@ -42,9 +40,9 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/webui/jstemplate_builder.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/gurl.h"
 
 using chromeos::CellularNetwork;
-using chromeos::CrosLibrary;
 using chromeos::MobileActivator;
 using chromeos::NetworkLibrary;
 using content::BrowserThread;
@@ -228,8 +226,7 @@
     const content::URLDataSource::GotDataCallback& callback) {
   CellularNetwork* network = NULL;
   if (!path.empty()) {
-    network = CrosLibrary::Get()->GetNetworkLibrary()->
-        FindCellularNetworkByPath(path);
+    network = NetworkLibrary::Get()-> FindCellularNetworkByPath(path);
   }
 
   if (!network || (!network->SupportsActivation() && !network->activated())) {
@@ -302,7 +299,7 @@
     MobileActivator::GetInstance()->RemoveObserver(this);
     MobileActivator::GetInstance()->TerminateActivation();
   } else if (type_ == TYPE_PORTAL_LTE) {
-    CrosLibrary::Get()->GetNetworkLibrary()->RemoveNetworkManagerObserver(this);
+    NetworkLibrary::Get()->RemoveNetworkManagerObserver(this);
   }
 }
 
@@ -399,7 +396,7 @@
   if (path.empty())
     return;
 
-  NetworkLibrary* network_lib = CrosLibrary::Get()->GetNetworkLibrary();
+  NetworkLibrary* network_lib = NetworkLibrary::Get();
   CellularNetwork* network =
       network_lib->FindCellularNetworkByPath(path.substr(1));
   if (!network) {
@@ -477,7 +474,7 @@
                                        DictionaryValue* value) {
   DCHECK(network);
   chromeos::NetworkLibrary* cros =
-      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+      chromeos::NetworkLibrary::Get();
   if (!cros)
     return;
   value->SetBoolean("activate_over_non_cellular_network",
diff --git a/chrome/browser/ui/webui/chromeos/sim_unlock_ui.cc b/chrome/browser/ui/webui/chromeos/sim_unlock_ui.cc
index 6aef30c..ea4d4af 100644
--- a/chrome/browser/ui/webui/chromeos/sim_unlock_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/sim_unlock_ui.cc
@@ -6,20 +6,25 @@
 
 #include <string>
 
+#include "base/basictypes.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop.h"
 #include "base/strings/string_piece.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
-#include "chrome/browser/chromeos/cros/network_library.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
+#include "chromeos/network/device_state.h"
+#include "chromeos/network/network_device_handler.h"
+#include "chromeos/network/network_event_log.h"
+#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/network_state_handler_observer.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/url_data_source.h"
@@ -28,6 +33,7 @@
 #include "content/public/browser/web_ui_message_handler.h"
 #include "grit/browser_resources.h"
 #include "grit/generated_resources.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/webui/jstemplate_builder.h"
@@ -60,11 +66,12 @@
 const char kErrorPuk[] = "incorrectPuk";
 const char kErrorOk[] = "ok";
 
-const chromeos::NetworkDevice* GetCellularDevice() {
-  chromeos::NetworkLibrary* lib = chromeos::CrosLibrary::Get()->
-      GetNetworkLibrary();
-  CHECK(lib);
-  return lib->FindCellularDevice();
+chromeos::NetworkDeviceHandler* GetNetworkDeviceHandler() {
+  return chromeos::NetworkHandler::Get()->network_device_handler();
+}
+
+chromeos::NetworkStateHandler* GetNetworkStateHandler() {
+  return chromeos::NetworkHandler::Get()->network_state_handler();
 }
 
 }  // namespace
@@ -99,8 +106,7 @@
 // The handler for Javascript messages related to the "sim-unlock" view.
 class SimUnlockHandler : public WebUIMessageHandler,
                          public base::SupportsWeakPtr<SimUnlockHandler>,
-                         public NetworkLibrary::NetworkDeviceObserver,
-                         public NetworkLibrary::PinOperationObserver {
+                         public NetworkStateHandlerObserver {
  public:
   SimUnlockHandler();
   virtual ~SimUnlockHandler();
@@ -108,13 +114,8 @@
   // WebUIMessageHandler implementation.
   virtual void RegisterMessages() OVERRIDE;
 
-  // NetworkLibrary::NetworkDeviceObserver implementation.
-  virtual void OnNetworkDeviceSimLockChanged(
-      NetworkLibrary* cros, const NetworkDevice* device) OVERRIDE;
-
-  // NetworkLibrary::PinOperationObserver implementation.
-  virtual void OnPinOperationCompleted(NetworkLibrary* cros,
-                                       PinOperationError error) OVERRIDE;
+  // NetworkStateHandlerObserver implementation.
+  virtual void DeviceListChanged() OVERRIDE;
 
  private:
   // Should keep this state enum in sync with similar one in JS code.
@@ -135,10 +136,17 @@
   } SimUnlockState;
 
   // Type of the SIM unlock code.
-  typedef enum SimUnlockCode {
+  enum SimUnlockCode {
     CODE_PIN,
-    CODE_PUK,
-  } SimUnlockCode;
+    CODE_PUK
+  };
+
+  enum PinOperationError {
+    PIN_ERROR_NONE = 0,
+    PIN_ERROR_UNKNOWN = 1,
+    PIN_ERROR_INCORRECT_CODE = 2,
+    PIN_ERROR_BLOCKED = 3
+  };
 
   class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> {
    public:
@@ -190,12 +198,28 @@
     DISALLOW_COPY_AND_ASSIGN(TaskProxy);
   };
 
+  // Returns the cellular device that this dialog currently corresponds to.
+  const DeviceState* GetCellularDevice();
+
   // Processing for the cases when dialog was cancelled.
   void CancelDialog();
 
   // Pass PIN/PUK code to shill and check status.
   void EnterCode(const std::string& code, SimUnlockCode code_type);
 
+  // Methods to invoke shill PIN/PUK D-Bus operations.
+  void ChangeRequirePin(bool require_pin, const std::string& pin);
+  void EnterPin(const std::string& pin);
+  void ChangePin(const std::string& old_pin, const std::string& new_pin);
+  void UnblockPin(const std::string& puk, const std::string& new_pin);
+  void PinOperationSuccessCallback(const std::string& operation_name);
+  void PinOperationErrorCallback(const std::string& operation_name,
+                                 const std::string& error_name,
+                                 scoped_ptr<base::DictionaryValue> error_data);
+
+  // Called when an asynchronous PIN operation has completed.
+  void OnPinOperationCompleted(PinOperationError error);
+
   // Single handler for PIN/PUK code operations.
   void HandleEnterCode(SimUnlockCode code_type, const std::string& code);
 
@@ -222,11 +246,10 @@
   void ProceedToPukInput();
 
   // Processes current SIM card state and update internal state/page.
-  void ProcessSimCardState(const chromeos::NetworkDevice* cellular);
+  void ProcessSimCardState(const DeviceState* cellular);
 
   // Updates page with the current state/SIM card info/error.
-  void UpdatePage(const chromeos::NetworkDevice* cellular,
-                  const std::string& error_msg);
+  void UpdatePage(const DeviceState* cellular, const std::string& error_msg);
 
   // Dialog internal state.
   SimUnlockState state_;
@@ -240,12 +263,17 @@
   // New PIN value for the case when we unblock SIM card or change PIN.
   std::string new_pin_;
 
+  // The initial lock type value, used to observe changes to lock status;
+  std::string sim_lock_type_;
+
   // True if there's a pending PIN operation.
   // That means that SIM lock state change will be received 2 times:
   // OnNetworkDeviceSimLockChanged and OnPinOperationCompleted.
   // First one should be ignored.
   bool pending_pin_operation_;
 
+  base::WeakPtrFactory<SimUnlockHandler> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(SimUnlockHandler);
 };
 
@@ -332,23 +360,15 @@
 SimUnlockHandler::SimUnlockHandler()
     : state_(SIM_UNLOCK_LOADING),
       dialog_mode_(SimDialogDelegate::SIM_DIALOG_UNLOCK),
-      pending_pin_operation_(false) {
-  const chromeos::NetworkDevice* cellular = GetCellularDevice();
-  // One could just call us directly via chrome://sim-unlock.
-  if (cellular) {
-    cellular_device_path_ = cellular->device_path();
-    CrosLibrary::Get()->GetNetworkLibrary()->AddNetworkDeviceObserver(
-        cellular_device_path_, this);
-    CrosLibrary::Get()->GetNetworkLibrary()->AddPinOperationObserver(this);
-  }
+      pending_pin_operation_(false),
+      weak_ptr_factory_(this) {
+  if (GetNetworkStateHandler()->GetTechnologyState(flimflam::kTypeCellular)
+      != NetworkStateHandler::TECHNOLOGY_UNAVAILABLE)
+    GetNetworkStateHandler()->AddObserver(this, FROM_HERE);
 }
 
 SimUnlockHandler::~SimUnlockHandler() {
-  if (!cellular_device_path_.empty()) {
-    CrosLibrary::Get()->GetNetworkLibrary()->RemoveNetworkDeviceObserver(
-        cellular_device_path_, this);
-    CrosLibrary::Get()->GetNetworkLibrary()->RemovePinOperationObserver(this);
-  }
+  GetNetworkStateHandler()->RemoveObserver(this, FROM_HERE);
 }
 
 void SimUnlockHandler::RegisterMessages() {
@@ -372,25 +392,38 @@
                  base::Unretained(this)));
 }
 
-void SimUnlockHandler::OnNetworkDeviceSimLockChanged(
-    NetworkLibrary* cros, const NetworkDevice* device) {
-  chromeos::SimLockState lock_state = device->sim_lock_state();
-  int retries_left = device->sim_retries_left();
-  VLOG(1) << "OnNetworkDeviceSimLockChanged, lock: " << lock_state
+void SimUnlockHandler::DeviceListChanged() {
+  const DeviceState* cellular_device = GetCellularDevice();
+  if (!cellular_device) {
+    LOG(WARNING) << "Cellular device with path '" << cellular_device_path_
+                 << "' disappeared.";
+    ProcessSimCardState(NULL);
+    return;
+  }
+
+  // Process the SIM card state only if the lock state changed.
+  if (cellular_device->sim_lock_type() == sim_lock_type_)
+    return;
+
+  sim_lock_type_ = cellular_device->sim_lock_type();
+  uint32 retries_left = cellular_device->sim_retries_left();
+  VLOG(1) << "OnNetworkDeviceSimLockChanged, lock: " << sim_lock_type_
           << ", retries: " << retries_left;
   // There's a pending PIN operation.
   // Wait for it to finish and refresh state then.
   if (!pending_pin_operation_)
-    ProcessSimCardState(GetCellularDevice());
+    ProcessSimCardState(cellular_device);
 }
 
-void SimUnlockHandler::OnPinOperationCompleted(NetworkLibrary* cros,
-                                               PinOperationError error) {
+void SimUnlockHandler::OnPinOperationCompleted(PinOperationError error) {
   pending_pin_operation_ = false;
-  DCHECK(cros);
-  const NetworkDevice* cellular = cros->FindCellularDevice();
-  DCHECK(cellular);
   VLOG(1) << "OnPinOperationCompleted, error: " << error;
+  const DeviceState* cellular = GetCellularDevice();
+  if (!cellular) {
+    VLOG(1) << "Cellular device disappeared. Dismissing dialog.";
+    ProcessSimCardState(NULL);
+    return;
+  }
   if (state_ == SIM_NOT_LOCKED_ASK_PIN && error == PIN_ERROR_NONE) {
     CHECK(dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON ||
           dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF);
@@ -414,6 +447,10 @@
     NotifyOnEnterPinEnded(false);
 }
 
+const DeviceState* SimUnlockHandler::GetCellularDevice() {
+  return GetNetworkStateHandler()->GetDeviceState(cellular_device_path_);
+}
+
 void SimUnlockHandler::CancelDialog() {
   if (dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON ||
       dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF) {
@@ -431,42 +468,142 @@
 void SimUnlockHandler::EnterCode(const std::string& code,
                                  SimUnlockCode code_type) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  NetworkLibrary* lib = chromeos::CrosLibrary::Get()->GetNetworkLibrary();
-  CHECK(lib);
 
-  const NetworkDevice* cellular = GetCellularDevice();
-  chromeos::SimLockState lock_state = cellular->sim_lock_state();
   pending_pin_operation_ = true;
 
   switch (code_type) {
     case CODE_PIN:
       if (dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON ||
           dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF) {
-        if (lock_state != chromeos::SIM_UNLOCKED) {
+        if (!sim_lock_type_.empty()) {
           // If SIM is locked/absent, change RequirePin UI is not accessible.
           NOTREACHED() <<
               "Changing RequirePin pref on locked / uninitialized SIM.";
         }
-        lib->ChangeRequirePin(
+        ChangeRequirePin(
             dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON,
             code);
       } else if (dialog_mode_ == SimDialogDelegate::SIM_DIALOG_CHANGE_PIN) {
-        if (lock_state != chromeos::SIM_UNLOCKED) {
+        if (!sim_lock_type_.empty()) {
           // If SIM is locked/absent, changing PIN UI is not accessible.
           NOTREACHED() << "Changing PIN on locked / uninitialized SIM.";
         }
-        lib->ChangePin(code, new_pin_);
+        ChangePin(code, new_pin_);
       } else {
-        lib->EnterPin(code);
+        EnterPin(code);
       }
       break;
     case CODE_PUK:
       DCHECK(!new_pin_.empty());
-      lib->UnblockPin(code, new_pin_);
+      UnblockPin(code, new_pin_);
       break;
   }
 }
 
+void SimUnlockHandler::ChangeRequirePin(bool require_pin,
+                                        const std::string& pin) {
+  const DeviceState* cellular = GetCellularDevice();
+  if (!cellular) {
+    NOTREACHED() << "Calling RequirePin method w/o cellular device.";
+    return;
+  }
+  std::string operation_name = "ChangeRequirePin";
+  NET_LOG_USER(operation_name, cellular->path());
+  GetNetworkDeviceHandler()->RequirePin(
+      cellular->path(),
+      require_pin,
+      pin,
+      base::Bind(&SimUnlockHandler::PinOperationSuccessCallback,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 operation_name),
+      base::Bind(&SimUnlockHandler::PinOperationErrorCallback,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 operation_name));
+}
+
+void SimUnlockHandler::EnterPin(const std::string& pin) {
+  const DeviceState* cellular = GetCellularDevice();
+  if (!cellular) {
+    NOTREACHED() << "Calling RequirePin method w/o cellular device.";
+    return;
+  }
+  std::string operation_name = "EnterPin";
+  NET_LOG_USER(operation_name, cellular->path());
+  GetNetworkDeviceHandler()->EnterPin(
+      cellular->path(),
+      pin,
+      base::Bind(&SimUnlockHandler::PinOperationSuccessCallback,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 operation_name),
+      base::Bind(&SimUnlockHandler::PinOperationErrorCallback,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 operation_name));
+}
+
+void SimUnlockHandler::ChangePin(const std::string& old_pin,
+                                 const std::string& new_pin) {
+  const DeviceState* cellular = GetCellularDevice();
+  if (!cellular) {
+    NOTREACHED() << "Calling RequirePin method w/o cellular device.";
+    return;
+  }
+  std::string operation_name = "ChangePin";
+  NET_LOG_USER(operation_name, cellular->path());
+  GetNetworkDeviceHandler()->ChangePin(
+      cellular->path(),
+      old_pin,
+      new_pin,
+      base::Bind(&SimUnlockHandler::PinOperationSuccessCallback,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 operation_name),
+      base::Bind(&SimUnlockHandler::PinOperationErrorCallback,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 operation_name));
+}
+
+void SimUnlockHandler::UnblockPin(const std::string& puk,
+                                  const std::string& new_pin) {
+  const DeviceState* cellular = GetCellularDevice();
+  if (!cellular) {
+    NOTREACHED() << "Calling RequirePin method w/o cellular device.";
+    return;
+  }
+  std::string operation_name = "UnblockPin";
+  NET_LOG_USER(operation_name, cellular->path());
+  GetNetworkDeviceHandler()->UnblockPin(
+      cellular->path(),
+      puk,
+      new_pin,
+      base::Bind(&SimUnlockHandler::PinOperationSuccessCallback,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 operation_name),
+      base::Bind(&SimUnlockHandler::PinOperationErrorCallback,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 operation_name));
+}
+
+void SimUnlockHandler::PinOperationSuccessCallback(
+    const std::string& operation_name) {
+  NET_LOG_DEBUG("Pin operation successful.", operation_name);
+  OnPinOperationCompleted(PIN_ERROR_NONE);
+}
+
+void SimUnlockHandler::PinOperationErrorCallback(
+    const std::string& operation_name,
+    const std::string& error_name,
+    scoped_ptr<base::DictionaryValue> error_data) {
+  NET_LOG_ERROR("Pin operation failed: " + error_name, operation_name);
+  PinOperationError pin_error;
+  if (error_name == NetworkDeviceHandler::kErrorIncorrectPin ||
+      error_name == NetworkDeviceHandler::kErrorPinRequired)
+    pin_error = PIN_ERROR_INCORRECT_CODE;
+  else if (error_name == NetworkDeviceHandler::kErrorPinBlocked)
+    pin_error = PIN_ERROR_BLOCKED;
+  else
+    pin_error = PIN_ERROR_UNKNOWN;
+  OnPinOperationCompleted(pin_error);
+}
+
 void SimUnlockHandler::NotifyOnEnterPinEnded(bool cancelled) {
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_ENTER_PIN_ENDED,
@@ -565,7 +702,16 @@
 
 void SimUnlockHandler::InitializeSimStatus() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  ProcessSimCardState(GetCellularDevice());
+  // TODO(armansito): For now, we're initializing the device path to the first
+  // available cellular device. We should try to obtain a specific device here,
+  // as there can be multiple cellular devices present.
+  const DeviceState* cellular_device = GetNetworkStateHandler()->
+      GetDeviceStateByType(flimflam::kTypeCellular);
+  if (cellular_device) {
+    cellular_device_path_ = cellular_device->path();
+    sim_lock_type_ = cellular_device->sim_lock_type();
+  }
+  ProcessSimCardState(cellular_device);
 }
 
 void SimUnlockHandler::ProceedToPukInput() {
@@ -574,23 +720,22 @@
 }
 
 void SimUnlockHandler::ProcessSimCardState(
-    const chromeos::NetworkDevice* cellular) {
+    const DeviceState* cellular) {
   std::string error_msg;
   if (cellular) {
-    chromeos::SimLockState lock_state = cellular->sim_lock_state();
-    int retries_left = cellular->sim_retries_left();
-    VLOG(1) << "Current state: " << state_ << " lock_state: " << lock_state
+    uint32 retries_left = cellular->sim_retries_left();
+    VLOG(1) << "Current state: " << state_ << " lock_type: " << sim_lock_type_
             << " retries: " << retries_left;
     switch (state_) {
       case SIM_UNLOCK_LOADING:
-        if (lock_state == chromeos::SIM_LOCKED_PIN) {
+        if (sim_lock_type_ == flimflam::kSIMLockPin) {
           state_ = SIM_LOCKED_PIN;
-        } else if (lock_state == chromeos::SIM_LOCKED_PUK) {
+        } else if (sim_lock_type_ == flimflam::kSIMLockPuk) {
           if (retries_left > 0)
             state_ = SIM_LOCKED_PUK;
           else
             state_ = SIM_DISABLED;
-        } else if (lock_state == chromeos::SIM_UNLOCKED) {
+        } else if (sim_lock_type_.empty()) {
           if (dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON ||
               dialog_mode_ == SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF) {
             state_ = SIM_NOT_LOCKED_ASK_PIN;
@@ -614,9 +759,9 @@
         // We always start in these states when SIM is unlocked.
         // So if we get here while still being UNLOCKED,
         // that means entered PIN was incorrect.
-        if (lock_state == chromeos::SIM_UNLOCKED) {
+        if (sim_lock_type_.empty()) {
           error_msg = kErrorPin;
-        } else if (lock_state == chromeos::SIM_LOCKED_PUK) {
+        } else if (sim_lock_type_ == flimflam::kSIMLockPuk) {
           state_ = SIM_LOCKED_NO_PIN_TRIES_LEFT;
         } else {
           NOTREACHED()
@@ -625,14 +770,13 @@
         }
         break;
       case SIM_LOCKED_PIN:
-        if (lock_state == chromeos::SIM_UNLOCKED ||
-            lock_state == chromeos::SIM_UNKNOWN) {
-          state_ = SIM_ABSENT_NOT_LOCKED;
-        } else if (lock_state == chromeos::SIM_LOCKED_PUK) {
+        if (sim_lock_type_ == flimflam::kSIMLockPuk) {
           state_ = SIM_LOCKED_NO_PIN_TRIES_LEFT;
-        } else {
-          // Still blocked with PIN.
+        } else if (sim_lock_type_ == flimflam::kSIMLockPin) {
+          // Still locked with PIN.
           error_msg = kErrorPin;
+        } else {
+          state_ = SIM_ABSENT_NOT_LOCKED;
         }
         break;
       case SIM_LOCKED_NO_PIN_TRIES_LEFT:
@@ -640,8 +784,8 @@
         state_ = SIM_LOCKED_PUK;
         break;
       case SIM_LOCKED_PUK:
-        if (lock_state == chromeos::SIM_UNLOCKED ||
-            lock_state == chromeos::SIM_UNKNOWN) {
+        if (sim_lock_type_ != flimflam::kSIMLockPin &&
+            sim_lock_type_ != flimflam::kSIMLockPuk) {
           state_ = SIM_ABSENT_NOT_LOCKED;
         } else if (retries_left == 0) {
           state_ = SIM_LOCKED_NO_PUK_TRIES_LEFT;
@@ -663,7 +807,7 @@
   UpdatePage(cellular, error_msg);
 }
 
-void SimUnlockHandler::UpdatePage(const chromeos::NetworkDevice* cellular,
+void SimUnlockHandler::UpdatePage(const DeviceState* cellular,
                                   const std::string& error_msg) {
   DictionaryValue sim_dict;
   if (cellular)
diff --git a/chrome/browser/ui/webui/chromeos/system_info_ui.cc b/chrome/browser/ui/webui/chromeos/system_info_ui.cc
index e60ca63..8dc187a 100644
--- a/chrome/browser/ui/webui/chromeos/system_info_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/system_info_ui.cc
@@ -18,7 +18,6 @@
 #include "base/threading/thread.h"
 #include "base/time/time.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/system_logs/system_logs_fetcher.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_paths.h"
diff --git a/chrome/browser/ui/webui/conflicts_ui.cc b/chrome/browser/ui/webui/conflicts_ui.cc
index 5c5b98d..c5f0a19 100644
--- a/chrome/browser/ui/webui/conflicts_ui.cc
+++ b/chrome/browser/ui/webui/conflicts_ui.cc
@@ -14,9 +14,9 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/enumerate_modules_model_win.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
diff --git a/chrome/browser/ui/webui/downloads_dom_handler_browsertest.cc b/chrome/browser/ui/webui/downloads_dom_handler_browsertest.cc
index 01133a2..9c445dc 100644
--- a/chrome/browser/ui/webui/downloads_dom_handler_browsertest.cc
+++ b/chrome/browser/ui/webui/downloads_dom_handler_browsertest.cc
@@ -139,6 +139,7 @@
     url_chain.push_back(url);
     base::Time current(base::Time::Now());
     download_manager()->CreateDownloadItem(
+        1, // id
         base::FilePath(FILE_PATH_LITERAL("/path/to/file")),
         base::FilePath(FILE_PATH_LITERAL("/path/to/file")),
         url_chain,
@@ -158,7 +159,7 @@
         mock_handler_->downloads_list(),
         "[{\"file_externally_removed\": false,"
         "  \"file_name\": \"file\","
-        "  \"id\": 0,"
+        "  \"id\": 1,"
         "  \"otr\": false,"
         "  \"since_string\": \"Today\","
         "  \"state\": \"COMPLETE\","
@@ -197,7 +198,7 @@
 IN_PROC_BROWSER_TEST_F(DownloadsDOMHandlerTest, RemoveOneItem) {
   DownloadAnItem();
   base::ListValue item;
-  item.AppendInteger(0);
+  item.AppendInteger(1);
 
   mock_handler_->reset_downloads_list();
   browser()->profile()->GetPrefs()->SetBoolean(
@@ -228,7 +229,7 @@
   EXPECT_TRUE(ListMatches(
       mock_handler_->download_updated(),
       "[{\"file_externally_removed\": true,"
-      "  \"id\": 0}]"));
+      "  \"id\": 1}]"));
 
   mock_handler_->reset_downloads_list();
   browser()->profile()->GetPrefs()->SetBoolean(
diff --git a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc b/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc
index cebe5b9..d7ee7f7 100644
--- a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc
+++ b/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc
@@ -21,11 +21,11 @@
 #include "chromeos/chromeos_switches.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/gurl.h"
 
 namespace chromeos {
 
@@ -197,11 +197,9 @@
     chromeos::KioskAppManager::ConsumerKioskModeStatus status) {
   initialized_ = true;
   is_kiosk_enabled_ =
-     !CommandLine::ForCurrentProcess()->HasSwitch(
-         chromeos::switches::kDisableAppMode) &&
-     (((status == KioskAppManager::CONSUMER_KIOSK_MODE_ENABLED) &&
-         chromeos::UserManager::Get()->IsCurrentUserOwner()) ||
-         !base::chromeos::IsRunningOnChromeOS());
+      ((status == KioskAppManager::CONSUMER_KIOSK_MODE_ENABLED) &&
+          chromeos::UserManager::Get()->IsCurrentUserOwner()) ||
+      !base::chromeos::IsRunningOnChromeOS();
 
   if (is_kiosk_enabled_) {
     base::FundamentalValue enabled(is_kiosk_enabled_);
diff --git a/chrome/browser/ui/webui/extensions/command_handler.cc b/chrome/browser/ui/webui/extensions/command_handler.cc
index b9f1273..d99e9f9 100644
--- a/chrome/browser/ui/webui/extensions/command_handler.cc
+++ b/chrome/browser/ui/webui/extensions/command_handler.cc
@@ -6,12 +6,12 @@
 
 #include "base/bind.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/commands/command_service.h"
 #include "chrome/browser/extensions/extension_keybinding_registry.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "chrome/common/extensions/extension_set.h"
 #include "content/public/browser/web_ui.h"
diff --git a/chrome/browser/ui/webui/extensions/extension_icon_source.cc b/chrome/browser/ui/webui/extensions/extension_icon_source.cc
index c9de20f..5cd6ed6 100644
--- a/chrome/browser/ui/webui/extensions/extension_icon_source.cc
+++ b/chrome/browser/ui/webui/extensions/extension_icon_source.cc
@@ -24,9 +24,7 @@
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
 #include "chrome/common/url_constants.h"
-#include "content/public/child/image_decoder_utils.h"
 #include "extensions/common/extension_resource.h"
-#include "googleurl/src/gurl.h"
 #include "grit/component_extension_resources_map.h"
 #include "grit/theme_resources.h"
 #include "skia/ext/image_operations.h"
@@ -37,6 +35,7 @@
 #include "ui/gfx/favicon_size.h"
 #include "ui/gfx/size.h"
 #include "ui/gfx/skbitmap_operations.h"
+#include "url/gurl.h"
 
 namespace {
 
@@ -53,7 +52,8 @@
 
 SkBitmap* ToBitmap(const unsigned char* data, size_t size) {
   SkBitmap* decoded = new SkBitmap();
-  *decoded = content::DecodeImage(data, gfx::Size(), size);
+  bool success = gfx::PNGCodec::Decode(data, size, decoded);
+  DCHECK(success);
   return decoded;
 }
 
diff --git a/chrome/browser/ui/webui/extensions/extension_info_ui.h b/chrome/browser/ui/webui/extensions/extension_info_ui.h
index fd54e31..37843c5 100644
--- a/chrome/browser/ui/webui/extensions/extension_info_ui.h
+++ b/chrome/browser/ui/webui/extensions/extension_info_ui.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_EXTENSIONS_EXTENSION_INFO_UI_H_
 
 #include "content/public/browser/web_ui_controller.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 
 namespace base {
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
index 240cbca..74063d8 100644
--- a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
+++ b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
@@ -20,6 +20,7 @@
 #include "base/values.h"
 #include "base/version.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
 #include "chrome/browser/extensions/crx_installer.h"
@@ -46,7 +47,6 @@
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/webui/extensions/extension_basic_info.h"
 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/background_info.h"
 #include "chrome/common/extensions/extension.h"
@@ -126,7 +126,7 @@
 }
 
 // static
-void ExtensionSettingsHandler::RegisterUserPrefs(
+void ExtensionSettingsHandler::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kExtensionsUIDeveloperMode,
@@ -160,8 +160,9 @@
       extension_service_->terminated_extensions()->Contains(extension->id()));
   extension_data->SetBoolean("enabledIncognito",
       extension_service_->IsIncognitoEnabled(extension->id()));
-  extension_data->SetBoolean("incognitoCanBeEnabled",
-                             extension->can_be_incognito_enabled());
+  extension_data->SetBoolean("incognitoCanBeToggled",
+                             extension->can_be_incognito_enabled() &&
+                             !extension->force_incognito_enabled());
   extension_data->SetBoolean("wantsFileAccess", extension->wants_file_access());
   extension_data->SetBoolean("allowFileAccess",
                              extension_service_->AllowFileAccess(extension));
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_handler.h b/chrome/browser/ui/webui/extensions/extension_settings_handler.h
index 0324406..55e2c30 100644
--- a/chrome/browser/ui/webui/extensions/extension_settings_handler.h
+++ b/chrome/browser/ui/webui/extensions/extension_settings_handler.h
@@ -23,8 +23,8 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_ui_message_handler.h"
-#include "googleurl/src/gurl.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
+#include "url/gurl.h"
 
 class ExtensionService;
 
@@ -77,7 +77,7 @@
   ExtensionSettingsHandler();
   virtual ~ExtensionSettingsHandler();
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Extension Detail JSON Struct for page. |pages| is injected for unit
   // testing.
diff --git a/chrome/browser/ui/webui/extensions/install_extension_handler.cc b/chrome/browser/ui/webui/extensions/install_extension_handler.cc
index 6ccf455..4904820 100644
--- a/chrome/browser/ui/webui/extensions/install_extension_handler.cc
+++ b/chrome/browser/ui/webui/extensions/install_extension_handler.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/extensions/extension_install_prompt.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/extensions/unpacked_installer.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/extensions/feature_switch.h"
 #include "content/public/browser/web_contents.h"
@@ -51,6 +52,10 @@
       "installDroppedFile",
       base::Bind(&InstallExtensionHandler::HandleInstallMessage,
                  base::Unretained(this)));
+  web_ui()->RegisterMessageCallback(
+      "installDroppedDirectory",
+      base::Bind(&InstallExtensionHandler::HandleInstallDirectoryMessage,
+                 base::Unretained(this)));
 }
 
 void InstallExtensionHandler::HandleStartDragMessage(const ListValue* args) {
@@ -115,3 +120,12 @@
   file_to_install_.clear();
   file_display_name_.clear();
 }
+
+void InstallExtensionHandler::HandleInstallDirectoryMessage(
+    const ListValue* args) {
+  Profile* profile = Profile::FromBrowserContext(
+      web_ui()->GetWebContents()->GetBrowserContext());
+  extensions::UnpackedInstaller::Create(
+      extensions::ExtensionSystem::Get(profile)->
+          extension_service())->Load(file_to_install_);
+}
diff --git a/chrome/browser/ui/webui/extensions/install_extension_handler.h b/chrome/browser/ui/webui/extensions/install_extension_handler.h
index dc3761b..81afefd 100644
--- a/chrome/browser/ui/webui/extensions/install_extension_handler.h
+++ b/chrome/browser/ui/webui/extensions/install_extension_handler.h
@@ -43,6 +43,10 @@
   // getting XSS'd.
   void HandleInstallMessage(const ListValue* args);
 
+  // Handles a notification from the JavaScript to install the directory
+  // currently being dragged.
+  void HandleInstallDirectoryMessage(const ListValue* args);
+
   // The path to the file that will be installed when HandleInstallMessage() is
   // called.
   base::FilePath file_to_install_;
diff --git a/chrome/browser/ui/webui/extensions/pack_extension_handler.cc b/chrome/browser/ui/webui/extensions/pack_extension_handler.cc
index 38b854e..59c8884 100644
--- a/chrome/browser/ui/webui/extensions/pack_extension_handler.cc
+++ b/chrome/browser/ui/webui/extensions/pack_extension_handler.cc
@@ -122,6 +122,8 @@
       base::FilePath::FromWStringHack(UTF8ToWide(extension_path_));
   base::FilePath key_file =
       base::FilePath::FromWStringHack(UTF8ToWide(private_key_path_));
+  last_used_path_ =
+      base::FilePath::FromWStringHack(UTF8ToWide(extension_path_));
 
   if (root_directory.empty()) {
     if (extension_path_.empty()) {
@@ -161,8 +163,11 @@
   ui::SelectFileDialog::Type type = ui::SelectFileDialog::SELECT_FOLDER;
   ui::SelectFileDialog::FileTypeInfo info;
   int file_type_index = 0;
-  if (select_type == "file")
+  base::FilePath path_to_use = last_used_path_;
+  if (select_type == "file") {
     type = ui::SelectFileDialog::SELECT_OPEN_FILE;
+    path_to_use = base::FilePath();
+  }
 
   string16 select_title;
   if (operation == "load") {
@@ -186,7 +191,7 @@
   load_extension_dialog_->SelectFile(
       type,
       select_title,
-      base::FilePath(),
+      path_to_use,
       &info,
       file_type_index,
       base::FilePath::StringType(),
diff --git a/chrome/browser/ui/webui/extensions/pack_extension_handler.h b/chrome/browser/ui/webui/extensions/pack_extension_handler.h
index 183a766..84ffbcd 100644
--- a/chrome/browser/ui/webui/extensions/pack_extension_handler.h
+++ b/chrome/browser/ui/webui/extensions/pack_extension_handler.h
@@ -71,6 +71,9 @@
   // Path to private key file, or null if none specified
   std::string private_key_path_;
 
+  // Path to the last used folder to load an extension.
+  base::FilePath last_used_path_;
+
   DISALLOW_COPY_AND_ASSIGN(PackExtensionHandler);
 };
 
diff --git a/chrome/browser/ui/webui/feedback_ui.cc b/chrome/browser/ui/webui/feedback_ui.cc
index 3da8d3a..5a7cdd0 100644
--- a/chrome/browser/ui/webui/feedback_ui.cc
+++ b/chrome/browser/ui/webui/feedback_ui.cc
@@ -60,7 +60,6 @@
 #include "ash/shell_delegate.h"
 #include "base/file_util.h"
 #include "base/path_service.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/drive/drive.pb.h"
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
 #include "chrome/browser/chromeos/drive/file_system_interface.h"
@@ -145,7 +144,7 @@
     saved_screenshots->push_back(
         std::string(ScreenshotSource::kScreenshotUrlRoot) +
         std::string(ScreenshotSource::kScreenshotSaved) +
-        entry.resource_id());
+        entry.base_name());
   }
   callback.Run();
 }
diff --git a/chrome/browser/ui/webui/fileicon_source.cc b/chrome/browser/ui/webui/fileicon_source.cc
index 9d7cdab..9e056d0 100644
--- a/chrome/browser/ui/webui/fileicon_source.cc
+++ b/chrome/browser/ui/webui/fileicon_source.cc
@@ -14,7 +14,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/common/time_format.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "net/base/escape.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -22,6 +21,7 @@
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/gurl.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/webui/flags_ui.cc b/chrome/browser/ui/webui/flags_ui.cc
index b02441ee..ed4fe78 100644
--- a/chrome/browser/ui/webui/flags_ui.cc
+++ b/chrome/browser/ui/webui/flags_ui.cc
@@ -237,7 +237,7 @@
 
 #if defined(OS_CHROMEOS)
 // static
-void FlagsUI::RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+void FlagsUI::RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(prefs::kEnabledLabsExperiments,
                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 }
diff --git a/chrome/browser/ui/webui/flags_ui.h b/chrome/browser/ui/webui/flags_ui.h
index 4b26836..0e2f3fe 100644
--- a/chrome/browser/ui/webui/flags_ui.h
+++ b/chrome/browser/ui/webui/flags_ui.h
@@ -33,7 +33,7 @@
       ui::ScaleFactor scale_factor);
   static void RegisterPrefs(PrefRegistrySimple* registry);
 #if defined(OS_CHROMEOS)
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 #endif
 
  private:
diff --git a/chrome/browser/ui/webui/gesture_config_ui.cc b/chrome/browser/ui/webui/gesture_config_ui.cc
index 2446e37..adde2bd 100644
--- a/chrome/browser/ui/webui/gesture_config_ui.cc
+++ b/chrome/browser/ui/webui/gesture_config_ui.cc
@@ -27,8 +27,8 @@
 
   // Register callback handlers.
   web_ui->RegisterMessageCallback(
-      "getPreferenceValue",
-      base::Bind(&GestureConfigUI::GetPreferenceValue,
+      "updatePreferenceValue",
+      base::Bind(&GestureConfigUI::UpdatePreferenceValue,
                  base::Unretained(this)));
   web_ui->RegisterMessageCallback(
       "resetPreferenceValue",
@@ -51,21 +51,24 @@
 GestureConfigUI::~GestureConfigUI() {
 }
 
-void GestureConfigUI::GetPreferenceValue(const base::ListValue* args) {
+void GestureConfigUI::UpdatePreferenceValue(const base::ListValue* args) {
   std::string pref_name;
 
   if (!args->GetString(0, &pref_name)) return;
 
-  Profile* profile = Profile::FromWebUI(web_ui());
-  PrefService* prefs = profile->GetPrefs();
+  PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
+  const PrefService::Preference* pref =
+      prefs->FindPreference(pref_name.c_str());
 
   base::StringValue js_pref_name(pref_name);
   base::FundamentalValue js_pref_value(prefs->GetDouble(pref_name.c_str()));
+  base::FundamentalValue js_pref_default(pref->IsDefaultValue());
 
   web_ui()->CallJavascriptFunction(
-      "gesture_config.getPreferenceValueResult",
+      "gesture_config.updatePreferenceValueResult",
       js_pref_name,
-      js_pref_value);
+      js_pref_value,
+      js_pref_default);
 }
 
 void GestureConfigUI::ResetPreferenceValue(const base::ListValue* args) {
@@ -73,30 +76,10 @@
 
   if (!args->GetString(0, &pref_name)) return;
 
-  Profile* profile = Profile::FromWebUI(web_ui());
-  PrefService* prefs = profile->GetPrefs();
+  PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
 
-  base::StringValue js_pref_name(pref_name);
-  double d;
-  if (prefs->GetDefaultPrefValue(pref_name.c_str())->GetAsDouble(&d)) {
-    base::FundamentalValue js_pref_value(d);
-    const PrefService::Preference* pref =
-        prefs->FindPreference(pref_name.c_str());
-    switch (pref->GetType()) {
-      case base::Value::TYPE_INTEGER:
-        prefs->SetInteger(pref_name.c_str(), static_cast<int>(d));
-        break;
-      case base::Value::TYPE_DOUBLE:
-        prefs->SetDouble(pref_name.c_str(), d);
-        break;
-      default:
-        NOTREACHED();
-    }
-    web_ui()->CallJavascriptFunction(
-        "gesture_config.getPreferenceValueResult",
-        js_pref_name,
-        js_pref_value);
-  }
+  prefs->ClearPref(pref_name.c_str());
+  UpdatePreferenceValue(args);
 }
 
 void GestureConfigUI::SetPreferenceValue(const base::ListValue* args) {
@@ -105,8 +88,7 @@
 
   if (!args->GetString(0, &pref_name) || !args->GetDouble(1, &value)) return;
 
-  Profile* profile = Profile::FromWebUI(web_ui());
-  PrefService* prefs = profile->GetPrefs();
+  PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
 
   const PrefService::Preference* pref =
       prefs->FindPreference(pref_name.c_str());
diff --git a/chrome/browser/ui/webui/gesture_config_ui.h b/chrome/browser/ui/webui/gesture_config_ui.h
index 4378ad9..3ef29cd 100644
--- a/chrome/browser/ui/webui/gesture_config_ui.h
+++ b/chrome/browser/ui/webui/gesture_config_ui.h
@@ -22,14 +22,14 @@
   /**
    * Request a preference setting's value.
    * This method is asynchronous; the result is provided by a call to
-   * the JS method 'gesture_config.getPreferenceValueResult'.
+   * the JS method 'gesture_config.updatePreferenceValueResult'.
    */
-  void GetPreferenceValue(const base::ListValue* args);
+  void UpdatePreferenceValue(const base::ListValue* args);
 
   /**
    * Reset a preference to its default value and return this value
    * via asynchronous callback to the JS method
-   * 'gesture_config.getPreferenceValueResult'.
+   * 'gesture_config.updatePreferenceValueResult'.
    */
   void ResetPreferenceValue(const base::ListValue* args);
 
diff --git a/chrome/browser/ui/webui/help/help_handler.cc b/chrome/browser/ui/webui/help/help_handler.cc
index 3ca356a..c8fe9cd 100644
--- a/chrome/browser/ui/webui/help/help_handler.cc
+++ b/chrome/browser/ui/webui/help/help_handler.cc
@@ -14,6 +14,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/ui/browser.h"
@@ -21,7 +22,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/send_feedback_experiment.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -347,7 +347,7 @@
     // If |g_build_date_string| is |NULL|, the date has not yet been assigned.
     // Get the date of the last lsb-release file modification.
     base::FileUtilProxy::GetFileInfo(
-        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
+        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(),
         base::SysInfo::GetLsbReleaseFilePath(),
         base::Bind(&HelpHandler::ProcessLsbFileInfo,
                    weak_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/history_ui.cc b/chrome/browser/ui/webui/history_ui.cc
index ddcc5bb..0312080 100644
--- a/chrome/browser/ui/webui/history_ui.cc
+++ b/chrome/browser/ui/webui/history_ui.cc
@@ -23,6 +23,7 @@
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/history/history_types.h"
@@ -41,7 +42,6 @@
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/webui/favicon_source.h"
 #include "chrome/browser/ui/webui/metrics_handler.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/time_format.h"
diff --git a/chrome/browser/ui/webui/inspect_ui.cc b/chrome/browser/ui/webui/inspect_ui.cc
index b7fb6fa..248d19d 100644
--- a/chrome/browser/ui/webui/inspect_ui.cc
+++ b/chrome/browser/ui/webui/inspect_ui.cc
@@ -304,8 +304,13 @@
     : public WorkerServiceObserver,
       public base::RefCountedThreadSafe<WorkerCreationDestructionListener> {
  public:
-  explicit WorkerCreationDestructionListener(InspectUI* workers_ui)
-      : discovery_ui_(workers_ui) {
+  WorkerCreationDestructionListener()
+      : discovery_ui_(NULL) {}
+
+  void Init(InspectUI* workers_ui) {
+    DCHECK(workers_ui);
+    DCHECK(!discovery_ui_);
+    discovery_ui_ = workers_ui;
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
         base::Bind(&WorkerCreationDestructionListener::RegisterObserver,
@@ -313,6 +318,7 @@
   }
 
   void InspectUIDestroyed() {
+    DCHECK(discovery_ui_);
     discovery_ui_ = NULL;
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
@@ -360,11 +366,12 @@
 
 InspectUI::InspectUI(content::WebUI* web_ui)
     : WebUIController(web_ui),
-      observer_(new WorkerCreationDestructionListener(this)),
+      observer_(new WorkerCreationDestructionListener()),
       weak_factory_(this) {
+  observer_->Init(this);
   Profile* profile = Profile::FromWebUI(web_ui);
-  adb_bridge_.reset(new DevToolsAdbBridge(profile));
-  web_ui->AddMessageHandler(new InspectMessageHandler(adb_bridge_.get()));
+  adb_bridge_ = DevToolsAdbBridge::Factory::GetForProfile(profile);
+  web_ui->AddMessageHandler(new InspectMessageHandler(adb_bridge_));
   content::WebUIDataSource::Add(profile, CreateInspectUIHTMLSource());
 
   registrar_.Add(this,
@@ -409,7 +416,7 @@
 {
   if (!observer_.get())
     return;
-  adb_bridge_.reset();
+  adb_bridge_ = NULL;
   observer_->InspectUIDestroyed();
   observer_ = NULL;
   registrar_.RemoveAll();
diff --git a/chrome/browser/ui/webui/inspect_ui.h b/chrome/browser/ui/webui/inspect_ui.h
index 90500c2..3b13086 100644
--- a/chrome/browser/ui/webui/inspect_ui.h
+++ b/chrome/browser/ui/webui/inspect_ui.h
@@ -57,7 +57,7 @@
   // A scoped container for notification registries.
   content::NotificationRegistrar registrar_;
 
-  scoped_ptr<DevToolsAdbBridge> adb_bridge_;
+  DevToolsAdbBridge* adb_bridge_;
   base::WeakPtrFactory<InspectUI> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(InspectUI);
diff --git a/chrome/browser/ui/webui/instant_ui.cc b/chrome/browser/ui/webui/instant_ui.cc
index d399753..cc67fb4 100644
--- a/chrome/browser/ui/webui/instant_ui.cc
+++ b/chrome/browser/ui/webui/instant_ui.cc
@@ -168,7 +168,8 @@
 }
 
 // static
-void InstantUI::RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+void InstantUI::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterStringPref(
       prefs::kInstantUIZeroSuggestUrlPrefix,
       std::string(),
diff --git a/chrome/browser/ui/webui/instant_ui.h b/chrome/browser/ui/webui/instant_ui.h
index 3aac9a9..0a0bd0b 100644
--- a/chrome/browser/ui/webui/instant_ui.h
+++ b/chrome/browser/ui/webui/instant_ui.h
@@ -23,7 +23,7 @@
   // handlers.
   explicit InstantUI(content::WebUI* web_ui);
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(InstantUI);
diff --git a/chrome/browser/ui/webui/memory_internals/memory_internals_handler.cc b/chrome/browser/ui/webui/memory_internals/memory_internals_handler.cc
index ac6c51a..1cba471 100644
--- a/chrome/browser/ui/webui/memory_internals/memory_internals_handler.cc
+++ b/chrome/browser/ui/webui/memory_internals/memory_internals_handler.cc
@@ -35,7 +35,7 @@
 }
 
 void MemoryInternalsHandler::OnJSUpdate(const base::ListValue* list) {
-  proxy_->GetInfo(list);
+  proxy_->StartFetch(list);
 }
 
 void MemoryInternalsHandler::OnUpdate(const string16& update) {
diff --git a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc
index accb3a5..509ccad 100644
--- a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc
+++ b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc
@@ -13,11 +13,15 @@
 #include "base/sys_info.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/memory_details.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
+#include "chrome/browser/ui/android/tab_model/tab_model.h"
+#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
 #include "chrome/browser/ui/webui/memory_internals/memory_internals_handler.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/render_messages.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -70,17 +74,21 @@
          iter != web_contents_.end(); ++iter)
       (*iter)->GetRenderViewHost()->Send(new ChromeViewMsg_GetV8HeapStats);
   }
+
   void AddWebContents(content::WebContents* content) {
     web_contents_.insert(content);
   }
+
   void Clear() {
     web_contents_.clear();
   }
-  void RemoveWebContents() {
+
+  void RemoveWebContents(base::ProcessId) {
     // We don't have to detect which content is the caller of this method.
     if (!web_contents_.empty())
       web_contents_.erase(web_contents_.begin());
   }
+
   int IsClean() {
     return web_contents_.empty();
   }
@@ -110,8 +118,7 @@
 MemoryInternalsProxy::MemoryInternalsProxy()
     : information_(new base::DictionaryValue()),
       renderer_details_(new RendererDetails(
-          base::Bind(&MemoryInternalsProxy::OnV8MemoryUpdate, this))) {
-}
+          base::Bind(&MemoryInternalsProxy::OnRendererAvailable, this))) {}
 
 void MemoryInternalsProxy::Attach(MemoryInternalsHandler* handler) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -123,27 +130,73 @@
   handler_ = NULL;
 }
 
-void MemoryInternalsProxy::GetInfo(const base::ListValue* list) {
+void MemoryInternalsProxy::StartFetch(const base::ListValue* list) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  scoped_refptr<ProcessDetails> browsers(new ProcessDetails(
-      base::Bind(&MemoryInternalsProxy::OnDetailsAvailable, this)));
-  browsers->StartFetch(MemoryDetails::SKIP_USER_METRICS);
+  // Clear previous information before fetching new information.
+  information_->Clear();
+  scoped_refptr<ProcessDetails> process(new ProcessDetails(
+      base::Bind(&MemoryInternalsProxy::OnProcessAvailable, this)));
+  process->StartFetch(MemoryDetails::SKIP_USER_METRICS);
 }
 
 MemoryInternalsProxy::~MemoryInternalsProxy() {}
 
-void MemoryInternalsProxy::UpdateUIOnUIThread(const string16& update) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+void MemoryInternalsProxy::RequestRendererDetails() {
+  renderer_details_->Clear();
 
-  // Don't forward updates to a destructed UI.
-  if (handler_)
-    handler_->OnUpdate(update);
+#if defined(OS_ANDROID)
+  for (TabModelList::const_iterator iter = TabModelList::begin();
+       iter != TabModelList::end(); ++iter) {
+    TabModel* model = *iter;
+    for (int i = 0; i < model->GetTabCount(); ++i)
+      renderer_details_->AddWebContents(model->GetWebContentsAt(i));
+  }
+#else
+  for (TabContentsIterator iter; !iter.done(); iter.Next())
+    renderer_details_->AddWebContents(*iter);
+#endif
+
+  renderer_details_->Request();
 }
 
-void MemoryInternalsProxy::OnV8MemoryUpdate(const base::ProcessId pid,
-                                            const size_t v8_allocated,
-                                            const size_t v8_used) {
+void MemoryInternalsProxy::OnProcessAvailable(const ProcessData& browser) {
+  base::ListValue* process_info = new ListValue();
+  base::ListValue* extension_info = new ListValue();
+  information_->Set("processes", process_info);
+  information_->Set("extensions", extension_info);
+  for (PMIIterator iter = browser.processes.begin();
+       iter != browser.processes.end(); ++iter) {
+    base::DictionaryValue* process = new DictionaryValue();
+    if (iter->renderer_type == ProcessMemoryInformation::RENDERER_EXTENSION)
+      extension_info->Append(process);
+    else
+      process_info->Append(process);
+
+    // Information from MemoryDetails.
+    process->SetInteger("pid", iter->pid);
+    process->SetString("type",
+                       ProcessMemoryInformation::GetFullTypeNameInEnglish(
+                           iter->process_type, iter->renderer_type));
+    process->SetInteger("memory_private", iter->working_set.priv);
+
+    // TODO(peria): Replace |titles| with navigation histories.
+    base::ListValue* titles = new ListValue();
+    process->Set("titles", titles);
+    for (size_t i = 0; i < iter->titles.size(); ++i)
+      titles->AppendString(iter->titles[i]);
+  }
+
+  RequestRendererDetails();
+}
+
+void MemoryInternalsProxy::OnRendererAvailable(const base::ProcessId pid,
+                                               const size_t v8_allocated,
+                                               const size_t v8_used) {
+  // Do not update while no renderers are registered.
+  if (renderer_details_->IsClean())
+    return;
+
   base::ListValue* processes;
   if (!information_->GetList("processes", &processes))
     return;
@@ -155,74 +208,34 @@
     int id;
     if (!process->GetInteger("pid", &id) || id != static_cast<int>(pid))
       continue;
-    process->SetInteger("v8_alloc", v8_allocated);
-    process->SetInteger("v8_used", v8_used);
+    // Convert units from Bytes to KiB.
+    process->SetInteger("v8_alloc", v8_allocated / 1024);
+    process->SetInteger("v8_used", v8_used / 1024);
     break;
   }
 
-  renderer_details_->RemoveWebContents();
+  renderer_details_->RemoveWebContents(pid);
   if (renderer_details_->IsClean())
-    CallJavaScriptFunctionOnUIThread("g_main_view.onSetSnapshot", information_);
+    FinishCollection();
 }
 
-void MemoryInternalsProxy::RequestV8MemoryUpdate() {
-  renderer_details_->Clear();
-#if !defined(OS_ANDROID)
-  for (TabContentsIterator iter; !iter.done(); iter.Next())
-    renderer_details_->AddWebContents(*iter);
-#endif
-
-  // if no contents are shown, update UI.
-  if (renderer_details_->IsClean())
-    CallJavaScriptFunctionOnUIThread("g_main_view.onSetSnapshot", information_);
-
-  renderer_details_->Request();
-}
-
-void MemoryInternalsProxy::OnDetailsAvailable(const ProcessData& browser) {
-  information_->Clear();
-
+void MemoryInternalsProxy::FinishCollection() {
   // System information, which is independent from processes.
   information_->SetInteger("uptime", base::SysInfo::Uptime());
   information_->SetString("os", base::SysInfo::OperatingSystemName());
   information_->SetString("os_version",
                           base::SysInfo::OperatingSystemVersion());
 
-  base::ListValue* processes = new ListValue();
-  base::ListValue* extensions = new ListValue();
-  information_->Set("processes", processes);
-  information_->Set("extensions", extensions);
-  for (ProcessMemoryInformationList::const_iterator
-           iter = browser.processes.begin();
-       iter != browser.processes.end(); ++iter) {
-    base::DictionaryValue* process = new DictionaryValue();
-    if (iter->process_type == content::PROCESS_TYPE_RENDERER &&
-        iter->renderer_type == ProcessMemoryInformation::RENDERER_EXTENSION)
-      extensions->Append(process);
-    else
-      processes->Append(process);
-
-    // Information from MemoryDetails.
-    process->SetInteger("pid", iter->pid);
-    process->SetString("type",
-                    ProcessMemoryInformation::GetFullTypeNameInEnglish(
-                        iter->process_type, iter->renderer_type));
-    process->SetInteger("memory_private", iter->working_set.priv);
-    base::ListValue* titles = new ListValue();
-    process->Set("titles", titles);
-    for (size_t i = 0; i < iter->titles.size(); ++i)
-      titles->AppendString(iter->titles[i]);
-  }
-
-  RequestV8MemoryUpdate();
+  CallJavaScriptFunctionOnUIThread("g_main_view.onSetSnapshot", *information_);
 }
 
 void MemoryInternalsProxy::CallJavaScriptFunctionOnUIThread(
-    const std::string& function, base::Value* args) {
+    const std::string& function, const base::Value& args) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  std::vector<const base::Value*> args_vector;
-  args_vector.push_back(args);
+  std::vector<const base::Value*> args_vector(1, &args);
   string16 update = content::WebUI::GetJavascriptCall(function, args_vector);
-  UpdateUIOnUIThread(update);
+  // Don't forward updates to a destructed UI.
+  if (handler_)
+    handler_->OnUpdate(update);
 }
diff --git a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h
index 5c5ee78..271f639 100644
--- a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h
+++ b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h
@@ -27,36 +27,42 @@
  public:
   MemoryInternalsProxy();
 
-  // Register a handler and start receiving callbacks from memory internals.
+  // Registers a handler.
   void Attach(MemoryInternalsHandler* handler);
 
-  // Unregister the same and stop receiving callbacks.
+  // Unregisters a handler.
   void Detach();
 
-  // Have memory internal clients send all the data they have.
-  void GetInfo(const base::ListValue* list);
+  // Sends a message to an internal client to send all process information it
+  // knows.
+  void StartFetch(const base::ListValue* list);
 
  private:
   friend struct
       content::BrowserThread::DeleteOnThread<content::BrowserThread::UI>;
   friend class base::DeleteHelper<MemoryInternalsProxy>;
+
+  typedef ProcessMemoryInformationList::const_iterator PMIIterator;
+
   virtual ~MemoryInternalsProxy();
 
-  // Sends a message from IO thread to update UI on UI thread.
-  void UpdateUIOnUIThread(const string16& update);
+  // Enumerates all processes information, appending a few common information.
+  void OnProcessAvailable(const ProcessData& browser);
 
-  // Measure memory usage of V8.
-  void OnV8MemoryUpdate(const base::ProcessId pid,
-                        const size_t v8_allocated,
-                        const size_t v8_used);
-  void RequestV8MemoryUpdate();
+  // Measures memory usage of V8.
+  void OnRendererAvailable(const base::ProcessId pid,
+                           const size_t v8_allocated,
+                           const size_t v8_used);
 
-  // Convert memory information into DictionaryValue format.
-  void OnDetailsAvailable(const ProcessData& browser);
+  // Requests all renderer processes to get detailed memory information.
+  void RequestRendererDetails();
 
-  // Call a JavaScript function on the page. Takes ownership of |args|.
+  // Be called on finish of collection.
+  void FinishCollection();
+
+  // Calls a JavaScript function on a UI page.
   void CallJavaScriptFunctionOnUIThread(const std::string& function,
-                                        base::Value* args);
+                                        const base::Value& args);
 
   MemoryInternalsHandler* handler_;
   base::DictionaryValue* information_;
diff --git a/chrome/browser/ui/webui/metrics_handler.cc b/chrome/browser/ui/webui/metrics_handler.cc
index 9394e07..e387a07 100644
--- a/chrome/browser/ui/webui/metrics_handler.cc
+++ b/chrome/browser/ui/webui/metrics_handler.cc
@@ -10,9 +10,9 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/metrics/metric_event_duration_details.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/webui/nacl_ui.cc b/chrome/browser/ui/webui/nacl_ui.cc
index 114ba80..744d9cf 100644
--- a/chrome/browser/ui/webui/nacl_ui.cc
+++ b/chrome/browser/ui/webui/nacl_ui.cc
@@ -162,7 +162,7 @@
   // However, do not trust that the path returned by the PathService exists.
   // Check for existence here.
   ValidatePnaclPathCallback(
-    got_path && !pnacl_path.empty() && file_util::PathExists(pnacl_path));
+    got_path && !pnacl_path.empty() && base::PathExists(pnacl_path));
 }
 
 void NaClDomHandlerProxy::ValidatePnaclPathCallback(bool is_valid) {
@@ -228,6 +228,10 @@
 
 void NaClDomHandler::HandleRequestNaClInfo(const ListValue* args) {
   page_has_requested_data_ = true;
+  // Force re-validation of pnacl's path in the next call to
+  // MaybeRespondToPage(), in case PNaCl went from not-installed
+  // to installed since the request.
+  pnacl_path_validated_ = false;
   MaybeRespondToPage();
 }
 
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index 7b65a8e..6de1c00 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -31,6 +31,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_remover.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/download_util.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -44,7 +45,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/extensions/extension_basic_info.h"
 #include "chrome/common/cancelable_task_tracker.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/extensions/extension_set.h"
@@ -78,7 +78,6 @@
 #include "ui/base/resource/resource_bundle.h"
 
 #if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/system/syslogs_provider.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -323,7 +322,7 @@
 void CloseAndDeleteDebugLogFile(PassPlatformFile pass_platform_file,
                                 const base::FilePath& file_path) {
   CloseDebugLogFile(pass_platform_file);
-  base::Delete(file_path, false);
+  base::DeleteFile(file_path, false);
 }
 
 // Called upon completion of |WriteDebugLogToFile|. Closes file
@@ -1587,7 +1586,7 @@
   }
 
   chromeos::NetworkLibrary* network_library =
-      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+      chromeos::NetworkLibrary::Get();
   network_library->LoadOncNetworks(network_configs, onc_source);
 
   // Now that we've added the networks, we need to rescan them so they'll be
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
index 486e28e..aacd04b 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
@@ -25,7 +25,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui_message_handler.h"
-#include "googleurl/src/gurl.h"
 #include "net/base/address_list.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_log.h"
@@ -39,6 +38,7 @@
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 using content::WebUIMessageHandler;
diff --git a/chrome/browser/ui/webui/ntp/android/bookmarks_handler.cc b/chrome/browser/ui/webui/ntp/android/bookmarks_handler.cc
index ba76509..3981a7c 100644
--- a/chrome/browser/ui/webui/ntp/android/bookmarks_handler.cc
+++ b/chrome/browser/ui/webui/ntp/android/bookmarks_handler.cc
@@ -6,6 +6,7 @@
 
 #include "base/logging.h"
 #include "base/memory/ref_counted_memory.h"
+#include "base/prefs/pref_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/android/tab_android.h"
@@ -15,6 +16,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/webui/favicon_source.h"
+#include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/url_data_source.h"
 #include "content/public/browser/web_contents.h"
@@ -219,10 +221,17 @@
 
   DictionaryValue* filler_value = new DictionaryValue();
   filler_value->SetString("title", node->GetTitle());
-  // Mark reserved system nodes and partner bookmarks as uneditable
+
+  // Mark reserved system nodes and partner bookmarks as uneditable.
+  // Also mark them uneditable when it is disabled by a preference
+  // (which can be forced by a policy).
   // (i.e. the bookmark bar along with the "Other Bookmarks" folder).
-  filler_value->SetBoolean("editable",
-                           partner_bookmarks_shim_->IsBookmarkEditable(node));
+  const PrefService* pref = Profile::FromBrowserContext(
+      web_ui()->GetWebContents()->GetBrowserContext())->GetPrefs();
+  bool editable = partner_bookmarks_shim_->IsBookmarkEditable(node) &&
+                  pref->GetBoolean(prefs::kEditBookmarksEnabled);
+  filler_value->SetBoolean("editable", editable);
+
   if (node->is_url()) {
     filler_value->SetBoolean("folder", false);
     filler_value->SetString("url", node->url().spec());
diff --git a/chrome/browser/ui/webui/ntp/android/context_menu_handler.cc b/chrome/browser/ui/webui/ntp/android/context_menu_handler.cc
index d323da0..75a0d81 100644
--- a/chrome/browser/ui/webui/ntp/android/context_menu_handler.cc
+++ b/chrome/browser/ui/webui/ntp/android/context_menu_handler.cc
@@ -70,7 +70,7 @@
       return;
     }
 
-    WebMenuItem menu_item;
+    content::MenuItem menu_item;
     menu_item.action = id;
     if (!item_list_value->GetString(1, &(menu_item.label))) {
       Value* value = NULL;
diff --git a/chrome/browser/ui/webui/ntp/android/new_tab_page_ready_handler.cc b/chrome/browser/ui/webui/ntp/android/new_tab_page_ready_handler.cc
index ff84527..d81f34b 100644
--- a/chrome/browser/ui/webui/ntp/android/new_tab_page_ready_handler.cc
+++ b/chrome/browser/ui/webui/ntp/android/new_tab_page_ready_handler.cc
@@ -7,7 +7,7 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/values.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
diff --git a/chrome/browser/ui/webui/ntp/android/partner_bookmarks_shim_unittest.cc b/chrome/browser/ui/webui/ntp/android/partner_bookmarks_shim_unittest.cc
index 5099727..10d4582 100644
--- a/chrome/browser/ui/webui/ntp/android/partner_bookmarks_shim_unittest.cc
+++ b/chrome/browser/ui/webui/ntp/android/partner_bookmarks_shim_unittest.cc
@@ -13,8 +13,8 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 class PartnerBookmarksShimTest : public testing::Test {
  public:
diff --git a/chrome/browser/ui/webui/ntp/android/promo_handler.cc b/chrome/browser/ui/webui/ntp/android/promo_handler.cc
index 4f5eec3..4c8ba25 100644
--- a/chrome/browser/ui/webui/ntp/android/promo_handler.cc
+++ b/chrome/browser/ui/webui/ntp/android/promo_handler.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/android/intent_helper.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/signin_manager.h"
@@ -22,7 +23,6 @@
 #include "chrome/browser/web_resource/notification_promo.h"
 #include "chrome/browser/web_resource/notification_promo_mobile_ntp.h"
 #include "chrome/browser/web_resource/promo_resource_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/browser_thread.h"
@@ -123,7 +123,7 @@
 }
 
 // static
-void PromoHandler::RegisterUserPrefs(
+void PromoHandler::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kNtpPromoDesktopSessionFound,
diff --git a/chrome/browser/ui/webui/ntp/android/promo_handler.h b/chrome/browser/ui/webui/ntp/android/promo_handler.h
index b22a913..33a7e9f 100644
--- a/chrome/browser/ui/webui/ntp/android/promo_handler.h
+++ b/chrome/browser/ui/webui/ntp/android/promo_handler.h
@@ -29,7 +29,7 @@
   virtual void RegisterMessages() OVERRIDE;
 
   // Register preferences.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  private:
   // NotificationObserver override and implementation.
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
index 82c0078..28d5d57 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -6,6 +6,7 @@
 
 #include <vector>
 
+#include "apps/app_launcher.h"
 #include "apps/metrics_names.h"
 #include "apps/pref_names.h"
 #include "base/auto_reset.h"
@@ -18,6 +19,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -37,7 +39,6 @@
 #include "chrome/browser/ui/webui/extensions/extension_basic_info.h"
 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/extensions/extension_icon_set.h"
@@ -49,13 +50,13 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/common/favicon_url.h"
-#include "googleurl/src/gurl.h"
 #include "grit/browser_resources.h"
 #include "grit/generated_resources.h"
 #include "net/base/escape.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/favicon_size.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/gurl.h"
 
 using chrome::AppLaunchParams;
 using chrome::OpenApplication;
@@ -74,6 +75,13 @@
   return app->ShouldDisplayInNewTabPage() && !blocked_by_policy;
 }
 
+void RecordAppLauncherPromoHistogram(
+      apps::AppLauncherPromoHistogramValues value) {
+  DCHECK_LT(value, apps::APP_LAUNCHER_PROMO_MAX);
+  UMA_HISTOGRAM_ENUMERATION(
+      "Apps.AppLauncherPromo", value, apps::APP_LAUNCHER_PROMO_MAX);
+}
+
 }  // namespace
 
 const net::UnescapeRule::Type kUnescapeRules =
@@ -88,6 +96,10 @@
       ignore_changes_(false),
       attempted_bookmark_app_install_(false),
       has_loaded_apps_(false) {
+  if (apps::IsAppLauncherEnabled())
+    RecordAppLauncherPromoHistogram(apps::APP_LAUNCHER_PROMO_ALREADY_INSTALLED);
+  else if (apps::ShouldShowAppLauncherPromo())
+    RecordAppLauncherPromoHistogram(apps::APP_LAUNCHER_PROMO_SHOWN);
 }
 
 AppLauncherHandler::~AppLauncherHandler() {}
@@ -753,7 +765,7 @@
 }
 
 // static
-void AppLauncherHandler::RegisterUserPrefs(
+void AppLauncherHandler::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterListPref(prefs::kNtpAppPageNames,
                              user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
@@ -800,14 +812,6 @@
 }
 
 // static
-void AppLauncherHandler::RecordAppLauncherPromoHistogram(
-      apps::AppLauncherPromoHistogramValues value) {
-  DCHECK_LT(value, apps::APP_LAUNCHER_PROMO_MAX);
-  UMA_HISTOGRAM_ENUMERATION(
-      "Apps.AppLauncherPromo", value, apps::APP_LAUNCHER_PROMO_MAX);
-}
-
-// static
 void AppLauncherHandler::RecordWebStoreLaunch() {
   RecordAppLaunchType(extension_misc::APP_LAUNCH_NTP_WEBSTORE,
       extensions::Manifest::TYPE_HOSTED_APP);
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.h b/chrome/browser/ui/webui/ntp/app_launcher_handler.h
index 7a5dc0f..f75cd2d 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler.h
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.h
@@ -116,7 +116,7 @@
   void OnLearnMore(const base::ListValue* args);
 
   // Register app launcher preferences.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Records the given type of app launch for UMA.
   static void RecordAppLaunchType(extension_misc::AppLaunchBucket bucket,
@@ -128,10 +128,6 @@
   // Records an app launch from the main view of the app list.
   static void RecordAppListMainLaunch(const extensions::Extension* extension);
 
-  // Records the given |value| in the apps::kAppLauncherPromoHistogram.
-  static void RecordAppLauncherPromoHistogram(
-      apps::AppLauncherPromoHistogramValues value);
-
  private:
   struct AppInstallInfo {
     AppInstallInfo();
diff --git a/chrome/browser/ui/webui/ntp/foreign_session_handler.cc b/chrome/browser/ui/webui/ntp/foreign_session_handler.cc
index 8a0cec6..ab58537 100644
--- a/chrome/browser/ui/webui/ntp/foreign_session_handler.cc
+++ b/chrome/browser/ui/webui/ntp/foreign_session_handler.cc
@@ -16,6 +16,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_restore.h"
@@ -24,7 +25,6 @@
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
 #include "chrome/browser/ui/webui/session_favicon_source.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/time_format.h"
 #include "chrome/common/url_constants.h"
@@ -58,7 +58,7 @@
 }
 
 // static
-void ForeignSessionHandler::RegisterUserPrefs(
+void ForeignSessionHandler::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterDictionaryPref(
       prefs::kNtpCollapsedForeignSessions,
diff --git a/chrome/browser/ui/webui/ntp/foreign_session_handler.h b/chrome/browser/ui/webui/ntp/foreign_session_handler.h
index fd470ca..25fb14e 100644
--- a/chrome/browser/ui/webui/ntp/foreign_session_handler.h
+++ b/chrome/browser/ui/webui/ntp/foreign_session_handler.h
@@ -33,7 +33,7 @@
   ForeignSessionHandler();
   virtual ~ForeignSessionHandler() {}
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   static void OpenForeignSessionTab(content::WebUI* web_ui,
                                     const std::string& session_string_value,
diff --git a/chrome/browser/ui/webui/ntp/most_visited_browsertest.cc b/chrome/browser/ui/webui/ntp/most_visited_browsertest.cc
index 954a875..4acb0c0 100644
--- a/chrome/browser/ui/webui/ntp/most_visited_browsertest.cc
+++ b/chrome/browser/ui/webui/ntp/most_visited_browsertest.cc
@@ -6,7 +6,7 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "chrome/test/base/web_ui_browsertest.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 class MostVisitedWebUITest : public WebUIBrowserTest {
  public:
diff --git a/chrome/browser/ui/webui/ntp/most_visited_handler.cc b/chrome/browser/ui/webui/ntp/most_visited_handler.cc
index 5574ceb..fc538c1 100644
--- a/chrome/browser/ui/webui/ntp/most_visited_handler.cc
+++ b/chrome/browser/ui/webui/ntp/most_visited_handler.cc
@@ -20,6 +20,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/page_usage_data.h"
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
@@ -31,7 +32,6 @@
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
 #include "chrome/browser/ui/webui/ntp/ntp_stats.h"
 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -42,11 +42,11 @@
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/locale_settings.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
 
 using content::UserMetricsAction;
 
@@ -330,7 +330,7 @@
 }
 
 // static
-void MostVisitedHandler::RegisterUserPrefs(
+void MostVisitedHandler::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterDictionaryPref(
       prefs::kNtpMostVisitedURLsBlacklist,
diff --git a/chrome/browser/ui/webui/ntp/most_visited_handler.h b/chrome/browser/ui/webui/ntp/most_visited_handler.h
index 0fc4126..37f20e1 100644
--- a/chrome/browser/ui/webui/ntp/most_visited_handler.h
+++ b/chrome/browser/ui/webui/ntp/most_visited_handler.h
@@ -70,7 +70,7 @@
     return most_visited_urls_;
   }
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  private:
   struct MostVisitedPage;
diff --git a/chrome/browser/ui/webui/ntp/new_tab_page_handler.cc b/chrome/browser/ui/webui/ntp/new_tab_page_handler.cc
index 84ac8e2..c8e5deb 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_page_handler.cc
+++ b/chrome/browser/ui/webui/ntp/new_tab_page_handler.cc
@@ -170,7 +170,7 @@
 }
 
 // static
-void NewTabPageHandler::RegisterUserPrefs(
+void NewTabPageHandler::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   // TODO(estade): should be syncable.
   registry->RegisterIntegerPref(
diff --git a/chrome/browser/ui/webui/ntp/new_tab_page_handler.h b/chrome/browser/ui/webui/ntp/new_tab_page_handler.h
index 6a00f8b..dbca446 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_page_handler.h
+++ b/chrome/browser/ui/webui/ntp/new_tab_page_handler.h
@@ -7,7 +7,7 @@
 
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/web_ui_message_handler.h"
 
 class PrefRegistrySimple;
@@ -25,7 +25,7 @@
   NewTabPageHandler();
 
   // Register NTP per-profile preferences.
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Registers values (strings etc.) for the page.
   static void GetLocalizedValues(Profile* profile, DictionaryValue* values);
diff --git a/chrome/browser/ui/webui/ntp/new_tab_page_sync_handler_browsertest.cc b/chrome/browser/ui/webui/ntp/new_tab_page_sync_handler_browsertest.cc
index af1b8c2..b64bdad 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_page_sync_handler_browsertest.cc
+++ b/chrome/browser/ui/webui/ntp/new_tab_page_sync_handler_browsertest.cc
@@ -15,8 +15,8 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "url/gurl.h"
 
 using ::testing::_;
 
diff --git a/chrome/browser/ui/webui/ntp/new_tab_ui.cc b/chrome/browser/ui/webui/ntp/new_tab_ui.cc
index 2dab46a..3c5de26 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_ui.cc
+++ b/chrome/browser/ui/webui/ntp/new_tab_ui.cc
@@ -12,6 +12,7 @@
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/metrics_handler.h"
 #include "chrome/browser/ui/webui/ntp/favicon_webui_handler.h"
@@ -20,7 +21,6 @@
 #include "chrome/browser/ui/webui/ntp/ntp_resource_cache.h"
 #include "chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h"
 #include "chrome/browser/ui/webui/ntp/recently_closed_tabs_handler.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -228,15 +228,16 @@
 }
 
 // static
-void NewTabUI::RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+void NewTabUI::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
 #if !defined(OS_ANDROID)
-  AppLauncherHandler::RegisterUserPrefs(registry);
-  NewTabPageHandler::RegisterUserPrefs(registry);
+  AppLauncherHandler::RegisterProfilePrefs(registry);
+  NewTabPageHandler::RegisterProfilePrefs(registry);
   if (NewTabUI::IsDiscoveryInNTPEnabled())
-    SuggestionsHandler::RegisterUserPrefs(registry);
+    SuggestionsHandler::RegisterProfilePrefs(registry);
 #endif
-  MostVisitedHandler::RegisterUserPrefs(registry);
-  browser_sync::ForeignSessionHandler::RegisterUserPrefs(registry);
+  MostVisitedHandler::RegisterProfilePrefs(registry);
+  browser_sync::ForeignSessionHandler::RegisterProfilePrefs(registry);
 }
 
 // static
diff --git a/chrome/browser/ui/webui/ntp/new_tab_ui.h b/chrome/browser/ui/webui/ntp/new_tab_ui.h
index bbc4ff8..6831428 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_ui.h
+++ b/chrome/browser/ui/webui/ntp/new_tab_ui.h
@@ -34,7 +34,7 @@
   explicit NewTabUI(content::WebUI* web_ui);
   virtual ~NewTabUI();
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // Returns whether or not to show apps pages.
   static bool ShouldShowApps();
diff --git a/chrome/browser/ui/webui/ntp/new_tab_ui_browsertest.cc b/chrome/browser/ui/webui/ntp/new_tab_ui_browsertest.cc
index 6a7f072..b64eace 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/ntp/new_tab_ui_browsertest.cc
@@ -16,7 +16,7 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_navigation_observer.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::OpenURLParams;
 using content::Referrer;
diff --git a/chrome/browser/ui/webui/ntp/ntp_login_handler.cc b/chrome/browser/ui/webui/ntp/ntp_login_handler.cc
index cfafc72..a5c8050 100644
--- a/chrome/browser/ui/webui/ntp/ntp_login_handler.cc
+++ b/chrome/browser/ui/webui/ntp/ntp_login_handler.cc
@@ -15,6 +15,7 @@
 #include "base/values.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -31,7 +32,6 @@
 #include "chrome/browser/ui/sync/sync_promo_ui.h"
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
 #include "chrome/browser/web_resource/promo_resource_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
index 15d0f19..8204901 100644
--- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
+++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -18,6 +18,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/first_run/first_run.h"
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
@@ -35,7 +36,6 @@
 #include "chrome/browser/ui/webui/ntp/ntp_login_handler.h"
 #include "chrome/browser/ui/webui/sync_setup_handler.h"
 #include "chrome/browser/web_resource/notification_promo.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_constants.h"
diff --git a/chrome/browser/ui/webui/ntp/suggestions_page_handler.cc b/chrome/browser/ui/webui/ntp/suggestions_page_handler.cc
index 661e39e..f5a4d46 100644
--- a/chrome/browser/ui/webui/ntp/suggestions_page_handler.cc
+++ b/chrome/browser/ui/webui/ntp/suggestions_page_handler.cc
@@ -15,6 +15,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/page_usage_data.h"
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/profiles/profile.h"
@@ -23,7 +24,6 @@
 #include "chrome/browser/ui/webui/ntp/suggestions_combiner.h"
 #include "chrome/browser/ui/webui/ntp/suggestions_source_top_sites.h"
 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/url_constants.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/navigation_controller.h"
@@ -34,7 +34,7 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/common/page_transition_types.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 
 using content::UserMetricsAction;
 
@@ -192,7 +192,7 @@
 }
 
 // static
-void SuggestionsHandler::RegisterUserPrefs(
+void SuggestionsHandler::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   // TODO(georgey) add user preferences (such as own blacklist) as needed.
 }
diff --git a/chrome/browser/ui/webui/ntp/suggestions_page_handler.h b/chrome/browser/ui/webui/ntp/suggestions_page_handler.h
index 8b5a243..562347c 100644
--- a/chrome/browser/ui/webui/ntp/suggestions_page_handler.h
+++ b/chrome/browser/ui/webui/ntp/suggestions_page_handler.h
@@ -68,7 +68,7 @@
   // SuggestionsCombiner::Delegate implementation.
   virtual void OnSuggestionsReady() OVERRIDE;
 
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  private:
   // Puts the passed URL in the blacklist (so it does not show as a thumbnail).
diff --git a/chrome/browser/ui/webui/ntp/thumbnail_source.cc b/chrome/browser/ui/webui/ntp/thumbnail_source.cc
index a1767d7..f9321a5 100644
--- a/chrome/browser/ui/webui/ntp/thumbnail_source.cc
+++ b/chrome/browser/ui/webui/ntp/thumbnail_source.cc
@@ -14,10 +14,10 @@
 #include "chrome/browser/thumbnails/thumbnail_service.h"
 #include "chrome/browser/thumbnails/thumbnail_service_factory.h"
 #include "chrome/common/url_constants.h"
-#include "googleurl/src/gurl.h"
 #include "grit/theme_resources.h"
 #include "net/url_request/url_request.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
diff --git a/chrome/browser/ui/webui/options/advanced_options_utils_x11.cc b/chrome/browser/ui/webui/options/advanced_options_utils_x11.cc
index b568e93..bbe55c8 100644
--- a/chrome/browser/ui/webui/options/advanced_options_utils_x11.cc
+++ b/chrome/browser/ui/webui/options/advanced_options_utils_x11.cc
@@ -82,7 +82,7 @@
   bool found = false;
   for (size_t i = 0; i < paths.size(); ++i) {
     base::FilePath file(paths[i]);
-    if (file_util::PathExists(file.Append(command[0]))) {
+    if (base::PathExists(file.Append(command[0]))) {
       found = true;
       break;
     }
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc
index 04f7ceb..f207374 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.cc
+++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -22,6 +22,7 @@
 #include "base/values.h"
 #include "chrome/browser/auto_launch_trial.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chrome_page_zoom.h"
 #include "chrome/browser/custom_home_pages_table_model.h"
 #include "chrome/browser/download/download_prefs.h"
@@ -55,7 +56,6 @@
 #include "chrome/browser/ui/options/options_util.h"
 #include "chrome/browser/ui/webui/favicon_source.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -659,17 +659,6 @@
   SendProfilesInfo();
 }
 
-void BrowserOptionsHandler::UpdateInstantCheckboxState() {
-  Profile* profile = Profile::FromWebUI(web_ui());
-
-  web_ui()->CallJavascriptFunction(
-      "BrowserOptions.updateInstantCheckboxState",
-      base::FundamentalValue(chrome::IsInstantCheckboxVisible()),
-      base::FundamentalValue(chrome::IsInstantCheckboxEnabled(profile)),
-      base::FundamentalValue(chrome::IsInstantCheckboxChecked(profile)),
-      StringValue(chrome::GetInstantCheckboxLabel(profile)));
-}
-
 void BrowserOptionsHandler::PageLoadStarted() {
   page_initialized_ = false;
 }
@@ -749,10 +738,6 @@
       prefs::kSigninAllowed,
       base::Bind(&BrowserOptionsHandler::OnSigninAllowedPrefChange,
                  base::Unretained(this)));
-  profile_pref_registrar_.Add(
-      prefs::kSearchSuggestEnabled,
-      base::Bind(&BrowserOptionsHandler::UpdateInstantCheckboxState,
-                 base::Unretained(this)));
 
 #if !defined(OS_CHROMEOS)
   profile_pref_registrar_.Add(
@@ -765,7 +750,6 @@
 void BrowserOptionsHandler::InitializePage() {
   page_initialized_ = true;
 
-  // Note that OnTemplateURLServiceChanged calls UpdateInstantCheckboxState.
   OnTemplateURLServiceChanged();
 
   ObserveThemeChanged();
@@ -959,10 +943,6 @@
       base::FundamentalValue(default_index),
       base::FundamentalValue(
           template_url_service_->is_default_search_managed()));
-
-  // Update the state of the Instant checkbox as the new search engine may not
-  // support Instant.
-  UpdateInstantCheckboxState();
 }
 
 void BrowserOptionsHandler::SetDefaultSearchEngine(const ListValue* args) {
@@ -1366,12 +1346,18 @@
 scoped_ptr<DictionaryValue> BrowserOptionsHandler::GetSyncStateDictionary() {
   scoped_ptr<DictionaryValue> sync_status(new DictionaryValue);
   Profile* profile = Profile::FromWebUI(web_ui());
+  if (ManagedUserService::ProfileIsManaged(profile)) {
+    sync_status->SetBoolean("supervisedUser", true);
+    sync_status->SetBoolean("signinAllowed", false);
+    return sync_status.Pass();
+  }
   if (profile->IsGuestSession()) {
     // Cannot display signin status when running in guest mode on chromeos
     // because there is no SigninManager.
     sync_status->SetBoolean("signinAllowed", false);
     return sync_status.Pass();
   }
+  sync_status->SetBoolean("supervisedUser", false);
 
   bool signout_prohibited = false;
 #if !defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc b/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc
index d18f733..6049f87 100644
--- a/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc
+++ b/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc
@@ -2,9 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/callback.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_types.h"
@@ -64,7 +66,8 @@
     policy.Set(policy::key::kOpenNetworkConfiguration,
                policy::POLICY_LEVEL_MANDATORY,
                policy::POLICY_SCOPE_USER,
-               Value::CreateStringValue(user_policy_blob));
+               Value::CreateStringValue(user_policy_blob),
+               NULL);
     provider_.UpdateChromePolicy(policy);
     content::RunAllPendingInMessageLoop();
   }
diff --git a/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.js b/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.js
index 4dd58bd..3ab913c 100644
--- a/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.js
+++ b/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.js
@@ -25,10 +25,10 @@
   assertEquals(this.browsePreload, document.location.href);
 
   var inputField = $('userNameEdit');
-  var overlay = $('accountsPage').parentNode;
+  var accountsOptionsPage = AccountsOptions.getInstance();
 
   // Overlay is visible.
-  assertFalse(overlay.classList.contains('transparent'));
+  assertTrue(accountsOptionsPage.visible);
 
   // Simulate pressing the enter key in the edit field.
   inputField.dispatchEvent(createEnterKeyboardEvent('keydown'));
@@ -36,5 +36,5 @@
   inputField.dispatchEvent(createEnterKeyboardEvent('keyup'));
 
   // Verify the overlay is still visible.
-  assertFalse(overlay.classList.contains('transparent'));
+  assertTrue(accountsOptionsPage.visible);
 });
diff --git a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
index 2de2418..800c6dc 100644
--- a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/camera_detector.h"
 #include "chrome/browser/chromeos/login/default_user_images.h"
 #include "chrome/browser/chromeos/login/user_image.h"
@@ -20,7 +21,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/chrome_select_file_policy.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
@@ -28,7 +28,6 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/common/url_constants.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "net/base/data_url.h"
@@ -36,6 +35,7 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/views/widget/widget.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
diff --git a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
index 46467bd..e946409 100644
--- a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
@@ -12,14 +12,15 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/proxy_cros_settings_parser.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/chromeos/ui_account_tweaks.h"
 #include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
@@ -108,13 +109,15 @@
 
   CoreOptionsHandler::InitializeHandler();
 
-  PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
+  Profile* profile = Profile::FromWebUI(web_ui());
+  PrefService* prefs = profile->GetPrefs();
   proxy_prefs_.Init(prefs);
   proxy_prefs_.Add(prefs::kProxy,
                    base::Bind(&CoreChromeOSOptionsHandler::OnPreferenceChanged,
                               base::Unretained(this),
                               prefs));
-  proxy_config_service_.SetPrefs(prefs);
+  proxy_config_service_.SetPrefs(ProfileHelper::IsSigninProfile(profile),
+                                 prefs);
 }
 
 base::Value* CoreChromeOSOptionsHandler::FetchPref(
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
index a49dd5c..29ccd6f 100644
--- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
@@ -12,6 +12,8 @@
 
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
+#include "ash/system/chromeos/network/network_connect.h"
+#include "ash/system/chromeos/network/network_icon.h"
 #include "base/base64.h"
 #include "base/basictypes.h"
 #include "base/bind.h"
@@ -26,8 +28,8 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/choose_mobile_network_dialog.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/cros/network_property_ui_data.h"
 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
@@ -45,10 +47,19 @@
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/time_format.h"
 #include "chromeos/chromeos_switches.h"
+#include "chromeos/network/device_state.h"
+#include "chromeos/network/favorite_state.h"
+#include "chromeos/network/network_configuration_handler.h"
+#include "chromeos/network/network_connection_handler.h"
+#include "chromeos/network/network_device_handler.h"
+#include "chromeos/network/network_event_log.h"
 #include "chromeos/network/network_ip_config.h"
+#include "chromeos/network/network_profile.h"
+#include "chromeos/network/network_profile_handler.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
 #include "chromeos/network/network_ui_data.h"
 #include "chromeos/network/network_util.h"
 #include "chromeos/network/onc/onc_constants.h"
@@ -72,11 +83,14 @@
 #include "ui/views/widget/widget.h"
 #include "ui/webui/web_ui_util.h"
 
+namespace chromeos {
+namespace options {
+
 namespace {
 
 // Keys for the network description dictionary passed to the web ui. Make sure
 // to keep the strings in sync with what the JavaScript side uses.
-const char kNetworkInfoKeyActivationState[] = "activation_state";
+const char kNetworkInfoKeyActivationState[] = "activationState";
 const char kNetworkInfoKeyConnectable[] = "connectable";
 const char kNetworkInfoKeyConnected[] = "connected";
 const char kNetworkInfoKeyConnecting[] = "connecting";
@@ -200,7 +214,7 @@
 const char kTagPolicy[] = "policy";
 const char kTagPreferred[] = "preferred";
 const char kTagPrlVersion[] = "prlVersion";
-const char kTagProvider_type[] = "provider_type";
+const char kTagProviderType[] = "providerType";
 const char kTagProviderApnList[] = "providerApnList";
 const char kTagRecommended[] = "recommended";
 const char kTagRecommendedValue[] = "recommendedValue";
@@ -209,7 +223,6 @@
 const char kTagRestrictedPool[] = "restrictedPool";
 const char kTagRoamingState[] = "roamingState";
 const char kTagServerHostname[] = "serverHostname";
-const char kTagService_name[] = "service_name";
 const char kTagCarriers[] = "carriers";
 const char kTagCurrentCarrierIndex[] = "currentCarrierIndex";
 const char kTagServiceName[] = "serviceName";
@@ -240,169 +253,241 @@
 const char kTagWiredList[] = "wiredList";
 const char kTagWirelessList[] = "wirelessList";
 
+const int kPreferredPriority = 1;
+
+void ShillError(const std::string& function,
+                const std::string& error_name,
+                scoped_ptr<base::DictionaryValue> error_data) {
+  NET_LOG_ERROR("Shill Error from InternetOptionsHandler: " + error_name,
+                function);
+}
+
+const NetworkState* GetNetworkState(const std::string& service_path) {
+  return NetworkHandler::Get()->network_state_handler()->
+      GetNetworkState(service_path);
+}
+
+void SetNetworkProperty(const std::string& service_path,
+                        const std::string& property,
+                        base::Value* value) {
+  NET_LOG_EVENT("SetNetworkProperty: " + property, service_path);
+  base::DictionaryValue properties;
+  properties.Set(property, value);
+  NetworkHandler::Get()->network_configuration_handler()->SetProperties(
+      service_path, properties,
+      base::Bind(&base::DoNothing),
+      base::Bind(&ShillError, "SetNetworkProperty"));
+}
+
+std::string ActivationStateString(const std::string& activation_state) {
+  int id;
+  if (activation_state == flimflam::kActivationStateActivated)
+    id = IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATED;
+  else if (activation_state == flimflam::kActivationStateActivating)
+    id = IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATING;
+  else if (activation_state == flimflam::kActivationStateNotActivated)
+    id = IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_NOT_ACTIVATED;
+  else if (activation_state == flimflam::kActivationStatePartiallyActivated)
+    id = IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_PARTIALLY_ACTIVATED;
+  else
+    id = IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_UNKNOWN;
+  return l10n_util::GetStringUTF8(id);
+}
+
+std::string RoamingStateString(const std::string& roaming_state) {
+  int id;
+  if (roaming_state == flimflam::kRoamingStateHome)
+    id = IDS_CHROMEOS_NETWORK_ROAMING_STATE_HOME;
+  else if (roaming_state == flimflam::kRoamingStateRoaming)
+    id = IDS_CHROMEOS_NETWORK_ROAMING_STATE_ROAMING;
+  else
+    id = IDS_CHROMEOS_NETWORK_ROAMING_STATE_UNKNOWN;
+  return l10n_util::GetStringUTF8(id);
+}
+
+std::string ConnectionStateString(const std::string& state) {
+  int id;
+  if (state == flimflam::kUnknownString)
+    id = IDS_CHROMEOS_NETWORK_STATE_UNKNOWN;
+  else if (state == flimflam::kStateIdle)
+    id = IDS_CHROMEOS_NETWORK_STATE_IDLE;
+  else if (state == flimflam::kStateCarrier)
+    id = IDS_CHROMEOS_NETWORK_STATE_CARRIER;
+  else if (state == flimflam::kStateAssociation)
+    id = IDS_CHROMEOS_NETWORK_STATE_ASSOCIATION;
+  else if (state == flimflam::kStateConfiguration)
+    id = IDS_CHROMEOS_NETWORK_STATE_CONFIGURATION;
+  else if (state == flimflam::kStateReady)
+    id = IDS_CHROMEOS_NETWORK_STATE_READY;
+  else if (state == flimflam::kStateDisconnect)
+    id = IDS_CHROMEOS_NETWORK_STATE_DISCONNECT;
+  else if (state == flimflam::kStateFailure)
+    id = IDS_CHROMEOS_NETWORK_STATE_FAILURE;
+  else if (state == flimflam::kStateActivationFailure)
+    id = IDS_CHROMEOS_NETWORK_STATE_ACTIVATION_FAILURE;
+  else if (state == flimflam::kStatePortal)
+    id = IDS_CHROMEOS_NETWORK_STATE_PORTAL;
+  else if (state == flimflam::kStateOnline)
+    id = IDS_CHROMEOS_NETWORK_STATE_ONLINE;
+  else
+    id = IDS_CHROMEOS_NETWORK_STATE_UNRECOGNIZED;
+  return l10n_util::GetStringUTF8(id);
+}
+
+std::string EncryptionString(const std::string& security,
+                             const std::string& eap_method) {
+  if (security == flimflam::kSecurityNone)
+    return "";
+  if (security == flimflam::kSecurityWpa)
+    return "WPA";
+  if (security == flimflam::kSecurityWep)
+    return "WEP";
+  if (security == flimflam::kSecurityRsn)
+    return "RSN";
+  if (security == flimflam::kSecurityPsk)
+    return "PSK";
+  if (security == flimflam::kSecurity8021x) {
+    std::string result = "8021X";
+    if (eap_method == flimflam::kEapMethodPEAP)
+      result += "PEAP";
+    else if (eap_method == flimflam::kEapMethodTLS)
+      result += "TLS";
+    else if (eap_method == flimflam::kEapMethodTTLS)
+      result += "TTLS";
+    else if (eap_method == flimflam::kEapMethodLEAP)
+      result += "LEAP";
+    return result;
+  }
+  return "Unknown";
+}
+
+std::string ProviderTypeString(
+    const std::string& provider_type,
+    const base::DictionaryValue& shill_properties) {
+  int id;
+  if (provider_type == flimflam::kProviderL2tpIpsec) {
+    std::string client_cert_id;
+    shill_properties.GetString(
+        flimflam::kL2tpIpsecClientCertIdProperty, &client_cert_id);
+    if (client_cert_id.empty())
+      id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_PSK;
+    else
+      id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_USER_CERT;
+  } else if (provider_type == flimflam::kProviderOpenVpn) {
+    id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_OPEN_VPN;
+  } else {
+    id = IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN;
+  }
+  return l10n_util::GetStringUTF8(id);
+}
+
 // A helper class for building network information dictionaries to be sent to
 // the webui code.
 class NetworkInfoDictionary {
  public:
-  // Initializes the dictionary with default values.
-  explicit NetworkInfoDictionary(ui::ScaleFactor icon_scale_factor);
-
-  // Copies in service path, connect{ing|ed|able} flags and connection type from
-  // the provided network object. Also chooses an appropriate icon based on the
-  // network type.
-  NetworkInfoDictionary(const chromeos::Network* network,
+  // Sets properties based on |network| and sets an appropriate icon based
+  // on the network type and |icon_scale_factor|.
+  NetworkInfoDictionary(const NetworkState* network,
                         ui::ScaleFactor icon_scale_factor);
-
-  // Initializes a remembered network entry, pulling information from the passed
-  // network object and the corresponding remembered network object. |network|
-  // may be NULL.
-  NetworkInfoDictionary(const chromeos::Network* network,
-                        const chromeos::Network* remembered,
+  NetworkInfoDictionary(const FavoriteState* network,
                         ui::ScaleFactor icon_scale_factor);
 
-  // Setters for filling in information.
-  void set_service_path(const std::string& service_path) {
-    service_path_ = service_path;
-  }
-  void set_icon(const gfx::ImageSkia& icon) {
-    gfx::ImageSkiaRep image_rep = icon.GetRepresentation(icon_scale_factor_);
-    icon_url_ = icon.isNull() ? "" : webui::GetBitmapDataUrl(
-        image_rep.sk_bitmap());
-  }
-  void set_name(const std::string& name) {
-    name_ = name;
-  }
-  void set_connecting(bool connecting) {
-    connecting_ = connecting;
-  }
-  void set_connected(bool connected) {
-    connected_ = connected;
-  }
-  void set_connectable(bool connectable) {
-    connectable_ = connectable;
-  }
-  void set_connection_type(chromeos::ConnectionType connection_type) {
-    connection_type_ = connection_type;
-  }
-  void set_remembered(bool remembered) {
-    remembered_ = remembered;
-  }
-  void set_shared(bool shared) {
-    shared_ = shared;
-  }
-  void set_activation_state(chromeos::ActivationState activation_state) {
-    activation_state_ = activation_state;
-  }
-  void set_policy_managed(bool policy_managed) {
-    policy_managed_ = policy_managed;
-  }
-
   // Builds the DictionaryValue representation from the previously set
   // parameters. Ownership of the returned pointer is transferred to the caller.
-  DictionaryValue* BuildDictionary();
+  base::DictionaryValue* BuildDictionary();
 
  private:
-  // Values to be filled into the dictionary.
+  void SetIcon(const gfx::ImageSkia& icon,
+               ui::ScaleFactor icon_scale_factor) {
+    gfx::ImageSkiaRep image_rep = icon.GetRepresentation(icon_scale_factor);
+    icon_url_ = icon.isNull() ? "" : webui::GetBitmapDataUrl(
+        image_rep.sk_bitmap());
+  }
+
   std::string service_path_;
   std::string icon_url_;
   std::string name_;
   bool connecting_;
   bool connected_;
   bool connectable_;
-  chromeos::ConnectionType connection_type_;
+  std::string connection_type_;
   bool remembered_;
   bool shared_;
-  chromeos::ActivationState activation_state_;
+  std::string activation_state_;
   bool policy_managed_;
-  ui::ScaleFactor icon_scale_factor_;
 
   DISALLOW_COPY_AND_ASSIGN(NetworkInfoDictionary);
 };
 
-NetworkInfoDictionary::NetworkInfoDictionary(
-    ui::ScaleFactor icon_scale_factor)
-    : icon_scale_factor_(icon_scale_factor) {
-  set_connecting(false);
-  set_connected(false);
-  set_connectable(false);
-  set_remembered(false);
-  set_shared(false);
-  set_activation_state(chromeos::ACTIVATION_STATE_UNKNOWN);
-  set_policy_managed(false);
-}
-
-NetworkInfoDictionary::NetworkInfoDictionary(const chromeos::Network* network,
+NetworkInfoDictionary::NetworkInfoDictionary(const NetworkState* network,
                                              ui::ScaleFactor icon_scale_factor)
-    : icon_scale_factor_(icon_scale_factor) {
-  set_service_path(network->service_path());
-  set_icon(chromeos::NetworkMenuIcon::GetImage(network,
-      chromeos::NetworkMenuIcon::COLOR_DARK));
-  set_name(network->name());
-  set_connecting(network->connecting());
-  set_connected(network->connected());
-  set_connectable(network->connectable());
-  set_connection_type(network->type());
-  set_remembered(false);
-  set_shared(false);
-  set_policy_managed(network->ui_data().is_managed());
+    : service_path_(network->path()),
+      name_(network->name()),
+      connecting_(network->IsConnectingState()),
+      connected_(network->IsConnectedState()),
+      connectable_(network->connectable()),
+      connection_type_(network->type()),
+      remembered_(false),
+      shared_(false),
+      activation_state_(network->activation_state()),
+      policy_managed_(network->IsManaged()) {
+  if (network->type() == flimflam::kTypeEthernet)
+    name_ = l10n_util::GetStringUTF8(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET);
+  gfx::ImageSkia icon = ash::network_icon::GetImageForNetwork(
+      network, ash::network_icon::ICON_TYPE_LIST);
+  SetIcon(icon, icon_scale_factor);
 }
 
-NetworkInfoDictionary::NetworkInfoDictionary(
-    const chromeos::Network* network,
-    const chromeos::Network* remembered,
-    ui::ScaleFactor icon_scale_factor)
-    : icon_scale_factor_(icon_scale_factor) {
-  set_service_path(remembered->service_path());
-  set_icon(chromeos::NetworkMenuIcon::GetImage(
-      network ? network : remembered, chromeos::NetworkMenuIcon::COLOR_DARK));
-  set_name(remembered->name());
-  set_connecting(network ? network->connecting() : false);
-  set_connected(network ? network->connected() : false);
-  set_connectable(true);
-  set_connection_type(remembered->type());
-  set_remembered(true);
-  set_shared(remembered->profile_type() == chromeos::PROFILE_SHARED);
-  set_policy_managed(remembered->ui_data().is_managed());
+NetworkInfoDictionary::NetworkInfoDictionary(const FavoriteState* favorite,
+                                             ui::ScaleFactor icon_scale_factor)
+    : service_path_(favorite->path()),
+      name_(favorite->name()),
+      connecting_(false),
+      connected_(false),
+      connectable_(false),
+      connection_type_(favorite->type()),
+      remembered_(true),
+      shared_(favorite->IsShared()),
+      policy_managed_(favorite->IsManaged()) {
+  if (favorite->type() == flimflam::kTypeEthernet)
+    name_ = l10n_util::GetStringUTF8(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET);
+  gfx::ImageSkia icon = ash::network_icon::GetImageForDisconnectedNetwork(
+      ash::network_icon::ICON_TYPE_LIST, favorite->type());
+  SetIcon(icon, icon_scale_factor);
 }
 
-DictionaryValue* NetworkInfoDictionary::BuildDictionary() {
+base::DictionaryValue* NetworkInfoDictionary::BuildDictionary() {
   std::string status;
-
   if (remembered_) {
     if (shared_)
       status = l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SHARED_NETWORK);
   } else {
-    // 802.1X networks can be connected but not have saved credentials, and
-    // hence be "not configured".  Give preference to the "connected" and
-    // "connecting" states.  http://crosbug.com/14459
-    int connection_state = IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED;
+    int id;
     if (connected_)
-      connection_state = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED;
+      id = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED;
     else if (connecting_)
-      connection_state = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING;
+      id = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING;
     else if (!connectable_)
-      connection_state = IDS_STATUSBAR_NETWORK_DEVICE_NOT_CONFIGURED;
-    status = l10n_util::GetStringUTF8(connection_state);
-    if (connection_type_ == chromeos::TYPE_CELLULAR) {
-      if (activation_state_ != chromeos::ACTIVATION_STATE_ACTIVATED) {
-        status.append(" / ");
-        status.append(chromeos::CellularNetwork::ActivationStateToString(
-            activation_state_));
-      }
+      id = IDS_STATUSBAR_NETWORK_DEVICE_NOT_CONFIGURED;
+    else
+      id = IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED;
+    std::string status = l10n_util::GetStringUTF8(id);
+    if (connection_type_ == flimflam::kTypeCellular &&
+        activation_state_ != flimflam::kActivationStateActivated) {
+      status.append(" / ");
+      status.append(ActivationStateString(activation_state_));
     }
   }
 
-  scoped_ptr<DictionaryValue> network_info(new DictionaryValue());
-  network_info->SetInteger(kNetworkInfoKeyActivationState,
-                           static_cast<int>(activation_state_));
+  scoped_ptr<base::DictionaryValue> network_info(new base::DictionaryValue());
+  network_info->SetString(kNetworkInfoKeyActivationState, activation_state_);
   network_info->SetBoolean(kNetworkInfoKeyConnectable, connectable_);
   network_info->SetBoolean(kNetworkInfoKeyConnected, connected_);
   network_info->SetBoolean(kNetworkInfoKeyConnecting, connecting_);
   network_info->SetString(kNetworkInfoKeyIconURL, icon_url_);
   network_info->SetString(kNetworkInfoKeyNetworkName, name_);
   network_info->SetString(kNetworkInfoKeyNetworkStatus, status);
-  network_info->SetInteger(kNetworkInfoKeyNetworkType,
-                           static_cast<int>(connection_type_));
+  network_info->SetString(kNetworkInfoKeyNetworkType, connection_type_);
   network_info->SetBoolean(kNetworkInfoKeyRemembered, remembered_);
   network_info->SetString(kNetworkInfoKeyServicePath, service_path_);
   network_info->SetBoolean(kNetworkInfoKeyPolicyManaged, policy_managed_);
@@ -414,9 +499,10 @@
 // fetches "SavedIP.*" properties. Caller must take ownership of returned
 // dictionary.  If non-NULL, |ip_parameters_set| returns a count of the number
 // of IP routing parameters that get set.
-DictionaryValue* BuildIPInfoDictionary(const DictionaryValue& shill_properties,
-                                       bool static_ip,
-                                       int* routing_parameters_set) {
+base::DictionaryValue* BuildIPInfoDictionary(
+    const base::DictionaryValue& shill_properties,
+    bool static_ip,
+    int* routing_parameters_set) {
   std::string address_key;
   std::string prefix_len_key;
   std::string gateway_key;
@@ -433,7 +519,7 @@
     name_servers_key = shill::kSavedIPNameServersProperty;
   }
 
-  scoped_ptr<DictionaryValue> ip_info_dict(new DictionaryValue);
+  scoped_ptr<base::DictionaryValue> ip_info_dict(new base::DictionaryValue);
   std::string address;
   int routing_parameters = 0;
   if (shill_properties.GetStringWithoutPathExpansion(address_key, &address)) {
@@ -445,8 +531,7 @@
   if (shill_properties.GetIntegerWithoutPathExpansion(
       prefix_len_key, &prefix_len)) {
     ip_info_dict->SetInteger(kIpConfigPrefixLength, prefix_len);
-    std::string netmask =
-        chromeos::network_util::PrefixLengthToNetmask(prefix_len);
+    std::string netmask = network_util::PrefixLengthToNetmask(prefix_len);
     ip_info_dict->SetString(kIpConfigNetmask, netmask);
     VLOG(2) << "Found " << prefix_len_key << ": "
             <<  prefix_len << " (" << netmask << ")";
@@ -471,26 +556,25 @@
   return ip_info_dict.release();
 }
 
-static bool CanForgetNetworkType(int type) {
-  return type == chromeos::TYPE_WIFI ||
-         type == chromeos::TYPE_WIMAX ||
-         type == chromeos::TYPE_VPN;
+static bool CanForgetNetworkType(const std::string& type) {
+  return type == flimflam::kTypeWifi ||
+         type == flimflam::kTypeWimax ||
+         type == flimflam::kTypeVPN;
 }
 
-static bool CanAddNetworkType(int type) {
-  return type == chromeos::TYPE_WIFI ||
-         type == chromeos::TYPE_VPN ||
-         type == chromeos::TYPE_CELLULAR;
+static bool CanAddNetworkType(const std::string& type) {
+  return type == flimflam::kTypeWifi ||
+         type == flimflam::kTypeVPN ||
+         type == flimflam::kTypeCellular;
 }
 
 // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does and
 // store it under |key| in |settings|. Takes ownership of |value|.
-void SetValueDictionary(
-    DictionaryValue* settings,
-    const char* key,
-    base::Value* value,
-    const chromeos::NetworkPropertyUIData& ui_data) {
-  DictionaryValue* dict = new DictionaryValue();
+void SetValueDictionary(base::DictionaryValue* settings,
+                        const char* key,
+                        base::Value* value,
+                        const NetworkPropertyUIData& ui_data) {
+  base::DictionaryValue* dict = new base::DictionaryValue();
   // DictionaryValue::Set() takes ownership of |value|.
   dict->Set(kTagValue, value);
   const base::Value* recommended_value = ui_data.default_value();
@@ -504,98 +588,166 @@
   settings->Set(key, dict);
 }
 
+std::string CopyStringFromDictionary(const base::DictionaryValue& source,
+                                     const std::string& src_key,
+                                     const std::string& dest_key,
+                                     base::DictionaryValue* dest) {
+  std::string string_value;
+  if (source.GetStringWithoutPathExpansion(src_key, &string_value))
+    dest->SetStringWithoutPathExpansion(dest_key, string_value);
+  return string_value;
+}
+
+void CopyIntegerFromDictionary(const base::DictionaryValue& source,
+                               const std::string& src_key,
+                               const std::string& dest_key,
+                               bool as_string,
+                               base::DictionaryValue* dest) {
+  int int_value;
+  if (!source.GetIntegerWithoutPathExpansion(src_key, &int_value))
+    return;
+  if (as_string) {
+    std::string str = base::StringPrintf("%d", int_value);
+    dest->SetStringWithoutPathExpansion(dest_key, str);
+  } else {
+    dest->SetIntegerWithoutPathExpansion(dest_key, int_value);
+  }
+}
+
 // Fills |dictionary| with the configuration details of |vpn|. |onc| is required
 // for augmenting the policy-managed information.
-void PopulateVPNDetails(
-    const chromeos::VirtualNetwork* vpn,
-    const base::DictionaryValue& onc,
-    DictionaryValue* dictionary) {
-  dictionary->SetString(kTagService_name, vpn->name());
-  bool remembered = (vpn->profile_type() != chromeos::PROFILE_NONE);
-  dictionary->SetBoolean(kTagRemembered, remembered);
-  dictionary->SetString(kTagProvider_type, vpn->GetProviderTypeString());
-  dictionary->SetString(kTagUsername, vpn->username());
+void PopulateVPNDetails(const NetworkState* vpn,
+                        const base::DictionaryValue& shill_properties,
+                        base::DictionaryValue* dictionary) {
+  // Name and Remembered set in PopulateConnectionDetails().
+  const base::DictionaryValue* provider_properties = NULL;
+  if (!shill_properties.GetDictionary(
+          flimflam::kProviderProperty, &provider_properties))
+    return;
+  std::string provider_type;
+  shill_properties.GetString(flimflam::kProviderTypeProperty, &provider_type);
+  dictionary->SetString(kTagProviderType,
+                        ProviderTypeString(provider_type, shill_properties));
 
-  chromeos::NetworkPropertyUIData hostname_ui_data;
+  std::string username;
+  if (provider_type == flimflam::kProviderOpenVpn)
+    shill_properties.GetString(flimflam::kOpenVPNUserProperty, &username);
+  else
+    shill_properties.GetString(flimflam::kL2tpIpsecUserProperty, &username);
+  dictionary->SetString(kTagUsername, username);
+
+  // TODO(stevenjb): Move FindOncFornetwork()
+  const base::DictionaryValue* onc = NetworkLibrary::Get()->
+      FindOncForNetwork(vpn->guid());
+  NetworkPropertyUIData hostname_ui_data;
   hostname_ui_data.ParseOncProperty(
-      vpn->ui_data().onc_source(), &onc,
-      base::StringPrintf("%s.%s",
-                         chromeos::onc::network_config::kVPN,
-                         chromeos::onc::vpn::kHost));
+      vpn->onc_source(), onc,
+      base::StringPrintf("%s.%s", onc::network_config::kVPN, onc::vpn::kHost));
+  std::string provider_host;
+  shill_properties.GetString(flimflam::kProviderHostProperty, &provider_host);
   SetValueDictionary(dictionary, kTagServerHostname,
-                     new base::StringValue(vpn->server_hostname()),
+                     new base::StringValue(provider_host),
                      hostname_ui_data);
 }
 
 // Given a list of supported carrier's by the device, return the index of
 // the carrier the device is currently using.
 int FindCurrentCarrierIndex(const base::ListValue* carriers,
-                            const chromeos::NetworkDevice* device) {
+                            const DeviceState* device) {
   DCHECK(carriers);
   DCHECK(device);
-
-  bool gsm = (device->technology_family() == chromeos::TECHNOLOGY_FAMILY_GSM);
+  bool gsm = (device->technology_family() == flimflam::kTechnologyFamilyGsm);
   int index = 0;
   for (base::ListValue::const_iterator it = carriers->begin();
-       it != carriers->end();
-       ++it, ++index) {
+       it != carriers->end(); ++it, ++index) {
     std::string value;
-    if ((*it)->GetAsString(&value)) {
-      // For GSM devices the device name will be empty, so simply select
-      // the Generic UMTS carrier option if present.
-      if (gsm && (value == shill::kCarrierGenericUMTS)) {
-        return index;
-      } else {
-        // For other carriers, the service name will match the carrier name.
-        if (value == device->carrier())
-          return index;
-      }
-    }
+    if (!(*it)->GetAsString(&value))
+      continue;
+    // For GSM devices the device name will be empty, so simply select
+    // the Generic UMTS carrier option if present.
+    if (gsm && (value == shill::kCarrierGenericUMTS))
+      return index;
+    // For other carriers, the service name will match the carrier name.
+    if (value == device->carrier())
+      return index;
   }
-
   return -1;
 }
 
-chromeos::ConnectionType ParseNetworkTypeString(const std::string& type) {
-  if (type == flimflam::kTypeEthernet)
-    return chromeos::TYPE_ETHERNET;
-  if (type == flimflam::kTypeWifi)
-    return chromeos::TYPE_WIFI;
-  if (type == flimflam::kTypeWimax)
-    return chromeos::TYPE_WIMAX;
-  if (type == flimflam::kTypeCellular)
-    return chromeos::TYPE_CELLULAR;
-  if (type == flimflam::kTypeVPN)
-    return chromeos::TYPE_VPN;
-  return chromeos::TYPE_UNKNOWN;
+void PopulateWifiDetails(const NetworkState* wifi,
+                         const base::DictionaryValue& shill_properties,
+                         base::DictionaryValue* dictionary);
+// TODO(stevenjb): Move implementation here.
+
+void PopulateWimaxDetails(const NetworkState* wimax,
+                          const base::DictionaryValue& shill_properties,
+                          base::DictionaryValue* dictionary);
+// TODO(stevenjb): Move implementation here.
+
+base::DictionaryValue* CreateDictionaryFromCellularApn(
+    const base::DictionaryValue* apn);
+// TODO(stevenjb): Move implementation here.
+
+void PopulateCellularDetails(const NetworkState* cellular,
+                             const base::DictionaryValue& shill_properties,
+                             base::DictionaryValue* dictionary);
+// TODO(stevenjb): Move implementation here.
+
+void PopulateConnectionDetails(const NetworkState* network,
+                               const base::DictionaryValue& shill_properties,
+                               base::DictionaryValue* dictionary);
+// TODO(stevenjb): Move implementation here.
+
+// Helper methods for SetIPConfigProperties
+void AppendPropertyKeyIfPresent(const std::string& key,
+                                const base::DictionaryValue& old_properties,
+                                std::vector<std::string>* property_keys) {
+  if (old_properties.HasKey(key))
+    property_keys->push_back(key);
+}
+
+void AddStringPropertyIfChanged(const std::string& key,
+                                const std::string& new_value,
+                                const base::DictionaryValue& old_properties,
+                                base::DictionaryValue* new_properties) {
+  std::string old_value;
+  if (!old_properties.GetStringWithoutPathExpansion(key, &old_value) ||
+      new_value != old_value) {
+    new_properties->SetStringWithoutPathExpansion(key, new_value);
+  }
+}
+
+void AddIntegerPropertyIfChanged(const std::string& key,
+                                 int new_value,
+                                 const base::DictionaryValue& old_properties,
+                                 base::DictionaryValue* new_properties) {
+  int old_value;
+  if (!old_properties.GetIntegerWithoutPathExpansion(key, &old_value) ||
+      new_value != old_value) {
+    new_properties->SetIntegerWithoutPathExpansion(key, new_value);
+  }
 }
 
 }  // namespace
 
-namespace options {
-
 InternetOptionsHandler::InternetOptionsHandler()
     : weak_factory_(this) {
   registrar_.Add(this, chrome::NOTIFICATION_REQUIRE_PIN_SETTING_CHANGE_ENDED,
-      content::NotificationService::AllSources());
+                 content::NotificationService::AllSources());
   registrar_.Add(this, chrome::NOTIFICATION_ENTER_PIN_ENDED,
-      content::NotificationService::AllSources());
-  cros_ = chromeos::CrosLibrary::Get()->GetNetworkLibrary();
-  if (cros_) {
-    cros_->AddNetworkManagerObserver(this);
-    MonitorNetworks();
-  }
+                 content::NotificationService::AllSources());
+  NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
 }
 
 InternetOptionsHandler::~InternetOptionsHandler() {
-  if (cros_) {
-    cros_->RemoveNetworkManagerObserver(this);
-    cros_->RemoveObserverForAllNetworks(this);
+  if (NetworkHandler::IsInitialized()) {
+    NetworkHandler::Get()->network_state_handler()->RemoveObserver(
+        this, FROM_HERE);
   }
 }
 
 void InternetOptionsHandler::GetLocalizedValues(
-    DictionaryValue* localized_strings) {
+    base::DictionaryValue* localized_strings) {
   DCHECK(localized_strings);
 
   static OptionsStringResource resources[] = {
@@ -754,13 +906,13 @@
   chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner);
   localized_strings->SetString("ownerUserId", UTF8ToUTF16(owner));
 
-  DictionaryValue* network_dictionary = new DictionaryValue;
+  base::DictionaryValue* network_dictionary = new base::DictionaryValue;
   FillNetworkInfo(network_dictionary);
   localized_strings->Set("networkData", network_dictionary);
 }
 
 void InternetOptionsHandler::InitializePage() {
-  DictionaryValue dictionary;
+  base::DictionaryValue dictionary;
   dictionary.SetString(kTagCellular,
       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK));
   dictionary.SetString(kTagWifi,
@@ -769,7 +921,7 @@
       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_VPN));
   web_ui()->CallJavascriptFunction(kSetDefaultNetworkIconsFunction,
                                    dictionary);
-  cros_->RequestNetworkScan();
+  NetworkHandler::Get()->network_state_handler()->RequestScan();
 }
 
 void InternetOptionsHandler::RegisterMessages() {
@@ -830,116 +982,173 @@
                  base::Unretained(this)));
 }
 
-void InternetOptionsHandler::EnableWifiCallback(const ListValue* args) {
-  cros_->EnableWifiNetworkDevice(true);
+void InternetOptionsHandler::EnableWifiCallback(const base::ListValue* args) {
+  NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
+      flimflam::kTypeWifi, true,
+      base::Bind(&ShillError, "EnableWifiCallback"));
 }
 
-void InternetOptionsHandler::DisableWifiCallback(const ListValue* args) {
-  cros_->EnableWifiNetworkDevice(false);
+void InternetOptionsHandler::DisableWifiCallback(const base::ListValue* args) {
+  NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
+      flimflam::kTypeWifi, false,
+      base::Bind(&ShillError, "DisableWifiCallback"));
 }
 
-void InternetOptionsHandler::EnableCellularCallback(const ListValue* args) {
-  const chromeos::NetworkDevice* mobile = cros_->FindMobileDevice();
-  if (!mobile) {
-    LOG(ERROR) << "Didn't find mobile device, it should have been available.";
-    cros_->EnableCellularNetworkDevice(true);
-  } else if (!mobile->is_sim_locked()) {
-    if (mobile->is_sim_absent()) {
-      std::string setup_url;
-      chromeos::MobileConfig* config = chromeos::MobileConfig::GetInstance();
-      if (config->IsReady()) {
-        const chromeos::MobileConfig::LocaleConfig* locale_config =
-            config->GetLocaleConfig();
-        if (locale_config)
-          setup_url = locale_config->setup_url();
+void InternetOptionsHandler::EnableCellularCallback(
+    const base::ListValue* args) {
+  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
+  if (!handler->IsTechnologyEnabled(NetworkStateHandler::kMatchTypeMobile)) {
+    handler->SetTechnologyEnabled(
+        NetworkStateHandler::kMatchTypeMobile, true,
+        base::Bind(&ShillError, "EnableCellularCallback"));
+    return;
+  }
+  const DeviceState* device = handler->GetDeviceStateByType(
+      NetworkStateHandler::kMatchTypeMobile);
+  if (!device) {
+    LOG(ERROR) << "Mobile device not found.";
+    return;
+  }
+  if (!device->sim_lock_type().empty()) {
+    SimDialogDelegate::ShowDialog(GetNativeWindow(),
+                                  SimDialogDelegate::SIM_DIALOG_UNLOCK);
+    return;
+  }
+  if (device->IsSimAbsent()) {
+    MobileConfig* config = MobileConfig::GetInstance();
+    if (config->IsReady()) {
+      const MobileConfig::LocaleConfig* locale_config =
+          config->GetLocaleConfig();
+      if (locale_config) {
+        std::string setup_url = locale_config->setup_url();
+        if (!setup_url.empty()) {
+          chrome::ShowSingletonTab(GetAppropriateBrowser(), GURL(setup_url));
+          return;
+        }
       }
-      if (!setup_url.empty()) {
-        chrome::ShowSingletonTab(GetAppropriateBrowser(), GURL(setup_url));
-      } else {
-        // TODO(nkostylev): Show generic error message. http://crosbug.com/15444
-      }
-    } else {
-      cros_->EnableCellularNetworkDevice(true);
     }
-  } else {
-    chromeos::SimDialogDelegate::ShowDialog(GetNativeWindow(),
-        chromeos::SimDialogDelegate::SIM_DIALOG_UNLOCK);
+    // TODO(nkostylev): Show generic error message. http://crosbug.com/15444
   }
+  LOG(ERROR) << "EnableCellularCallback called for enabled mobile device";
 }
 
-void InternetOptionsHandler::DisableCellularCallback(const ListValue* args) {
-  cros_->EnableCellularNetworkDevice(false);
+void InternetOptionsHandler::DisableCellularCallback(
+    const base::ListValue* args) {
+  NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
+      NetworkStateHandler::kMatchTypeMobile, false,
+      base::Bind(&ShillError, "DisableCellularCallback"));
 }
 
-void InternetOptionsHandler::EnableWimaxCallback(const ListValue* args) {
-  cros_->EnableWimaxNetworkDevice(true);
+void InternetOptionsHandler::EnableWimaxCallback(const base::ListValue* args) {
+  NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
+      flimflam::kTypeWimax, true,
+      base::Bind(&ShillError, "EnableWimaxCallback"));
 }
 
-void InternetOptionsHandler::DisableWimaxCallback(const ListValue* args) {
-  cros_->EnableWimaxNetworkDevice(false);
+void InternetOptionsHandler::DisableWimaxCallback(const base::ListValue* args) {
+  NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
+      flimflam::kTypeWimax, false,
+      base::Bind(&ShillError, "DisableWimaxCallback"));
 }
 
-void InternetOptionsHandler::ShowMorePlanInfoCallback(const ListValue* args) {
+void InternetOptionsHandler::ShowMorePlanInfoCallback(
+    const base::ListValue* args) {
   if (!web_ui())
     return;
-
   std::string service_path;
   if (args->GetSize() != 1 || !args->GetString(0, &service_path)) {
     NOTREACHED();
     return;
   }
-  chromeos::network_connect::ShowMobileSetup(service_path);
+  network_connect::ShowMobileSetup(service_path);
 }
 
-void InternetOptionsHandler::BuyDataPlanCallback(const ListValue* args) {
+void InternetOptionsHandler::BuyDataPlanCallback(const base::ListValue* args) {
   if (!web_ui())
     return;
-
   std::string service_path;
   if (args->GetSize() != 1 || !args->GetString(0, &service_path)) {
     NOTREACHED();
     return;
   }
-  chromeos::network_connect::ShowMobileSetup(service_path);
+  network_connect::ShowMobileSetup(service_path);
 }
 
-void InternetOptionsHandler::SetApnCallback(const ListValue* args) {
+void InternetOptionsHandler::SetApnCallback(const base::ListValue* args) {
   std::string service_path;
-  std::string apn;
-  std::string username;
-  std::string password;
-  if (args->GetSize() != 4 ||
-      !args->GetString(0, &service_path) ||
-      !args->GetString(1, &apn) ||
+  if (!args->GetString(0, &service_path)) {
+    NOTREACHED();
+    return;
+  }
+  NetworkHandler::Get()->network_configuration_handler()->GetProperties(
+      service_path,
+      base::Bind(&InternetOptionsHandler::SetApnProperties,
+                 weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
+      base::Bind(&ShillError, "SetApnCallback"));
+}
+
+void InternetOptionsHandler::SetApnProperties(
+    const base::ListValue* args,
+    const std::string& service_path,
+    const base::DictionaryValue& shill_properties) {
+  std::string apn, username, password;
+  if (!args->GetString(1, &apn) ||
       !args->GetString(2, &username) ||
       !args->GetString(3, &password)) {
     NOTREACHED();
     return;
   }
+  NET_LOG_EVENT("SetApnCallback", service_path);
 
-  chromeos::CellularNetwork* network =
-        cros_->FindCellularNetworkByPath(service_path);
-  if (network) {
-    network->SetApn(chromeos::CellularApn(
-        apn, network->apn().network_id, username, password));
+  if (apn.empty()) {
+    std::vector<std::string> properties_to_clear;
+    properties_to_clear.push_back(flimflam::kCellularApnProperty);
+    NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
+      service_path, properties_to_clear,
+      base::Bind(&base::DoNothing),
+      base::Bind(&ShillError, "ClearCellularApnProperties"));
+    return;
   }
+
+  const base::DictionaryValue* shill_apn_dict = NULL;
+  std::string network_id;
+  if (shill_properties.GetDictionaryWithoutPathExpansion(
+          flimflam::kCellularApnProperty, &shill_apn_dict)) {
+    shill_apn_dict->GetStringWithoutPathExpansion(
+        flimflam::kApnNetworkIdProperty, &network_id);
+  }
+  base::DictionaryValue properties;
+  base::DictionaryValue* apn_dict = new base::DictionaryValue;
+  apn_dict->SetStringWithoutPathExpansion(flimflam::kApnProperty, apn);
+  apn_dict->SetStringWithoutPathExpansion(flimflam::kApnNetworkIdProperty,
+                                          network_id);
+  apn_dict->SetStringWithoutPathExpansion(flimflam::kApnUsernameProperty,
+                                          username);
+  apn_dict->SetStringWithoutPathExpansion(flimflam::kApnPasswordProperty,
+                                          password);
+  properties.SetWithoutPathExpansion(flimflam::kCellularApnProperty, apn_dict);
+  NetworkHandler::Get()->network_configuration_handler()->SetProperties(
+      service_path, properties,
+      base::Bind(&base::DoNothing),
+      base::Bind(&ShillError, "SetApnProperties"));
 }
 
-void InternetOptionsHandler::CarrierStatusCallback(
-    const std::string& service_path,
-    chromeos::NetworkMethodErrorType error,
-    const std::string& error_message) {
-  if ((error == chromeos::NETWORK_METHOD_ERROR_NONE) &&
-      cros_->CellularDeviceUsesDirectActivation()) {
-    chromeos::network_connect::ActivateCellular(service_path);
-    UpdateConnectionData(cros_->FindNetworkByPath(service_path));
+void InternetOptionsHandler::CarrierStatusCallback() {
+  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
+  const DeviceState* device =
+      handler->GetDeviceStateByType(flimflam::kTypeCellular);
+  if (device && (device->carrier() == shill::kCarrierSprint)) {
+    const NetworkState* network =
+        handler->FirstNetworkByType(flimflam::kTypeCellular);
+    if (network) {
+      chromeos::network_connect::ActivateCellular(network->path());
+      UpdateConnectionData(network->path());
+    }
   }
-
   UpdateCarrier();
 }
 
-
-void InternetOptionsHandler::SetCarrierCallback(const ListValue* args) {
+void InternetOptionsHandler::SetCarrierCallback(const base::ListValue* args) {
   std::string service_path;
   std::string carrier;
   if (args->GetSize() != 2 ||
@@ -948,18 +1157,22 @@
     NOTREACHED();
     return;
   }
-
-  chromeos::NetworkLibrary* cros_net =
-      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
-  if (cros_net) {
-    cros_net->SetCarrier(
-        carrier,
-        base::Bind(&InternetOptionsHandler::CarrierStatusCallback,
-                   weak_factory_.GetWeakPtr()));
+  const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
+      GetDeviceStateByType(flimflam::kTypeCellular);
+  if (!device) {
+    LOG(WARNING) << "SetCarrierCallback with no cellular device.";
+    return;
   }
+  NetworkHandler::Get()->network_device_handler()->SetCarrier(
+      device->path(),
+      carrier,
+      base::Bind(&InternetOptionsHandler::CarrierStatusCallback,
+                 weak_factory_.GetWeakPtr()),
+      base::Bind(&ShillError, "SetCarrierCallback"));
 }
 
-void InternetOptionsHandler::SetSimCardLockCallback(const ListValue* args) {
+void InternetOptionsHandler::SetSimCardLockCallback(
+    const base::ListValue* args) {
   bool require_pin_new_value;
   if (!args->GetBoolean(0, &require_pin_new_value)) {
     NOTREACHED();
@@ -970,21 +1183,22 @@
   // 3. If card is locked it will first call PIN unlock operation
   // 4. Then it will call Set RequirePin, passing the same PIN.
   // 5. We'll get notified by REQUIRE_PIN_SETTING_CHANGE_ENDED notification.
-  chromeos::SimDialogDelegate::SimDialogMode mode;
+  SimDialogDelegate::SimDialogMode mode;
   if (require_pin_new_value)
-    mode = chromeos::SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON;
+    mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON;
   else
-    mode = chromeos::SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF;
-  chromeos::SimDialogDelegate::ShowDialog(GetNativeWindow(), mode);
+    mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF;
+  SimDialogDelegate::ShowDialog(GetNativeWindow(), mode);
 }
 
-void InternetOptionsHandler::ChangePinCallback(const ListValue* args) {
-  chromeos::SimDialogDelegate::ShowDialog(GetNativeWindow(),
-      chromeos::SimDialogDelegate::SIM_DIALOG_CHANGE_PIN);
+void InternetOptionsHandler::ChangePinCallback(const base::ListValue* args) {
+  SimDialogDelegate::ShowDialog(GetNativeWindow(),
+      SimDialogDelegate::SIM_DIALOG_CHANGE_PIN);
 }
 
-void InternetOptionsHandler::RefreshNetworksCallback(const ListValue* args) {
-  cros_->RequestNetworkScan();
+void InternetOptionsHandler::RefreshNetworksCallback(
+    const base::ListValue* args) {
+  NetworkHandler::Get()->network_state_handler()->RequestScan();
 }
 
 std::string InternetOptionsHandler::GetIconDataUrl(int resource_id) const {
@@ -996,16 +1210,29 @@
 }
 
 void InternetOptionsHandler::RefreshNetworkData() {
-  DictionaryValue dictionary;
+  base::DictionaryValue dictionary;
   FillNetworkInfo(&dictionary);
   web_ui()->CallJavascriptFunction(
       kRefreshNetworkDataFunction, dictionary);
 }
 
 void InternetOptionsHandler::UpdateConnectionData(
-    const chromeos::Network* network) {
-  DictionaryValue dictionary;
-  PopulateConnectionDetails(network, &dictionary);
+    const std::string& service_path) {
+  NetworkHandler::Get()->network_configuration_handler()->GetProperties(
+      service_path,
+      base::Bind(&InternetOptionsHandler::UpdateConnectionDataCallback,
+                 weak_factory_.GetWeakPtr()),
+      base::Bind(&ShillError, "UpdateConnectionData"));
+}
+
+void InternetOptionsHandler::UpdateConnectionDataCallback(
+    const std::string& service_path,
+    const base::DictionaryValue& shill_properties) {
+  const NetworkState* network = GetNetworkState(service_path);
+  if (!network)
+    return;
+  base::DictionaryValue dictionary;
+  PopulateConnectionDetails(network, shill_properties, &dictionary);
   web_ui()->CallJavascriptFunction(kUpdateConnectionDataFunction, dictionary);
 }
 
@@ -1013,55 +1240,24 @@
   web_ui()->CallJavascriptFunction(kUpdateCarrierFunction);
 }
 
-void InternetOptionsHandler::OnNetworkManagerChanged(
-    chromeos::NetworkLibrary* cros) {
+void InternetOptionsHandler::NetworkManagerChanged() {
   if (!web_ui())
     return;
-  MonitorNetworks();
   RefreshNetworkData();
 }
 
-void InternetOptionsHandler::OnNetworkChanged(
-    chromeos::NetworkLibrary* cros,
-    const chromeos::Network* network) {
-  if (web_ui()) {
-    RefreshNetworkData();
-    UpdateConnectionData(network);
-  }
+void InternetOptionsHandler::NetworkListChanged() {
+  if (!web_ui())
+    return;
+  RefreshNetworkData();
 }
 
-// Monitor wireless networks for changes. It is only necessary
-// to set up individual observers for the cellular networks
-// (if any) and for the connected Wi-Fi network (if any). The
-// only change we are interested in for Wi-Fi networks is signal
-// strength. For non-connected Wi-Fi networks, all information is
-// reported via scan results, which trigger network manager
-// updates. Only the connected Wi-Fi network has changes reported
-// via service property updates.
-void InternetOptionsHandler::MonitorNetworks() {
-  cros_->RemoveObserverForAllNetworks(this);
-  const chromeos::WifiNetwork* wifi_network = cros_->wifi_network();
-  if (wifi_network)
-    cros_->AddNetworkObserver(wifi_network->service_path(), this);
-
-  // Always monitor all mobile networks, if any, so that changes
-  // in network technology, roaming status, and signal strength
-  // will be shown.
-  const chromeos::WimaxNetworkVector& wimax_networks =
-      cros_->wimax_networks();
-  for (size_t i = 0; i < wimax_networks.size(); ++i) {
-    chromeos::WimaxNetwork* wimax_network = wimax_networks[i];
-    cros_->AddNetworkObserver(wimax_network->service_path(), this);
-  }
-  const chromeos::CellularNetworkVector& cell_networks =
-      cros_->cellular_networks();
-  for (size_t i = 0; i < cell_networks.size(); ++i) {
-    chromeos::CellularNetwork* cell_network = cell_networks[i];
-    cros_->AddNetworkObserver(cell_network->service_path(), this);
-  }
-  const chromeos::VirtualNetwork* virtual_network = cros_->virtual_network();
-  if (virtual_network)
-    cros_->AddNetworkObserver(virtual_network->service_path(), this);
+void InternetOptionsHandler::NetworkPropertiesUpdated(
+    const NetworkState* network) {
+  if (!web_ui())
+    return;
+  RefreshNetworkData();
+  UpdateConnectionData(network->path());
 }
 
 void InternetOptionsHandler::Observe(
@@ -1085,77 +1281,67 @@
   }
 }
 
-void InternetOptionsHandler::SetServerHostnameCallback(const ListValue* args) {
-  std::string service_path;
-  std::string server_hostname;
-
+void InternetOptionsHandler::SetServerHostnameCallback(
+    const base::ListValue* args) {
+  std::string service_path, server_hostname;
   if (args->GetSize() < 2 ||
       !args->GetString(0, &service_path) ||
       !args->GetString(1, &server_hostname)) {
     NOTREACHED();
     return;
   }
-
-  chromeos::VirtualNetwork* vpn = cros_->FindVirtualNetworkByPath(service_path);
-  if (!vpn)
-    return;
-
-  if (server_hostname != vpn->server_hostname())
-    vpn->SetServerHostname(server_hostname);
+  SetNetworkProperty(service_path, flimflam::kProviderHostProperty,
+                     base::Value::CreateStringValue(server_hostname));
 }
 
-void InternetOptionsHandler::SetPreferNetworkCallback(const ListValue* args) {
-  std::string service_path;
-  std::string prefer_network_str;
-
+void InternetOptionsHandler::SetPreferNetworkCallback(
+    const base::ListValue* args) {
+  std::string service_path, prefer_network_str;
   if (args->GetSize() < 2 ||
       !args->GetString(0, &service_path) ||
       !args->GetString(1, &prefer_network_str)) {
     NOTREACHED();
     return;
   }
-
-  chromeos::Network* network = cros_->FindNetworkByPath(service_path);
-  if (!network)
-    return;
-
-  bool prefer_network = prefer_network_str == kTagTrue;
-  if (prefer_network != network->preferred())
-    network->SetPreferred(prefer_network);
+  int priority = (prefer_network_str == kTagTrue) ? kPreferredPriority : 0;
+  SetNetworkProperty(service_path, flimflam::kPriorityProperty,
+                     base::Value::CreateIntegerValue(priority));
 }
 
-void InternetOptionsHandler::SetAutoConnectCallback(const ListValue* args) {
-  std::string service_path;
-  std::string auto_connect_str;
-
+void InternetOptionsHandler::SetAutoConnectCallback(
+    const base::ListValue* args) {
+  std::string service_path, auto_connect_str;
   if (args->GetSize() < 2 ||
       !args->GetString(0, &service_path) ||
       !args->GetString(1, &auto_connect_str)) {
     NOTREACHED();
     return;
   }
-
-  chromeos::Network* network = cros_->FindNetworkByPath(service_path);
-  if (!network)
-    return;
-
   bool auto_connect = auto_connect_str == kTagTrue;
-  if (auto_connect != network->auto_connect())
-    network->SetAutoConnect(auto_connect);
+  SetNetworkProperty(service_path, flimflam::kAutoConnectProperty,
+                     base::Value::CreateBooleanValue(auto_connect));
 }
 
-void InternetOptionsHandler::SetIPConfigCallback(const ListValue* args) {
+void InternetOptionsHandler::SetIPConfigCallback(const base::ListValue* args) {
   std::string service_path;
-  bool dhcp_for_ip;
-  std::string address;
-  std::string netmask;
-  std::string gateway;
-  std::string name_server_type;
-  std::string name_servers;
+  if (!args->GetString(0, &service_path)) {
+    NOTREACHED();
+    return;
+  }
+  NetworkHandler::Get()->network_configuration_handler()->GetProperties(
+      service_path,
+      base::Bind(&InternetOptionsHandler::SetIPConfigProperties,
+                 weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
+      base::Bind(&ShillError, "SetIPConfigCallback"));
+}
 
-  if (args->GetSize() < 7 ||
-      !args->GetString(0, &service_path) ||
-      !args->GetBoolean(1, &dhcp_for_ip) ||
+void InternetOptionsHandler::SetIPConfigProperties(
+    const base::ListValue* args,
+    const std::string& service_path,
+    const base::DictionaryValue& shill_properties) {
+  std::string address, netmask, gateway, name_server_type, name_servers;
+  bool dhcp_for_ip;
+  if (!args->GetBoolean(1, &dhcp_for_ip) ||
       !args->GetString(2, &address) ||
       !args->GetString(3, &netmask) ||
       !args->GetString(4, &gateway) ||
@@ -1164,185 +1350,167 @@
     NOTREACHED();
     return;
   }
+  NET_LOG_EVENT("SetIPConfigProperties", service_path);
 
-  int dhcp_usage_mask = 0;
+  std::vector<std::string> properties_to_clear;
+  base::DictionaryValue properties_to_set;
+
   if (dhcp_for_ip) {
-    dhcp_usage_mask = (chromeos::NetworkLibrary::USE_DHCP_ADDRESS |
-                       chromeos::NetworkLibrary::USE_DHCP_NETMASK |
-                       chromeos::NetworkLibrary::USE_DHCP_GATEWAY);
-  }
-  if (name_server_type == kNameServerTypeAutomatic) {
-    dhcp_usage_mask |= chromeos::NetworkLibrary::USE_DHCP_NAME_SERVERS;
-    name_servers.clear();
-  } else if (name_server_type == kNameServerTypeGoogle) {
-    name_servers = kGoogleNameServers;
+    AppendPropertyKeyIfPresent(shill::kStaticIPAddressProperty,
+                               shill_properties, &properties_to_clear);
+    AppendPropertyKeyIfPresent(shill::kStaticIPPrefixlenProperty,
+                               shill_properties, &properties_to_clear);
+    AppendPropertyKeyIfPresent(shill::kStaticIPGatewayProperty,
+                               shill_properties, &properties_to_clear);
+  } else {
+    AddStringPropertyIfChanged(
+        shill::kStaticIPAddressProperty,
+        address, shill_properties, &properties_to_set);
+    int prefixlen = network_util::NetmaskToPrefixLength(netmask);
+    if (prefixlen > 0) {
+      LOG(ERROR) << "Invalid prefix length for: " << service_path;
+      prefixlen = 0;
+    }
+    AddIntegerPropertyIfChanged(
+        shill::kStaticIPPrefixlenProperty,
+        prefixlen, shill_properties, &properties_to_set);
+    AddStringPropertyIfChanged(
+        shill::kStaticIPGatewayProperty,
+        gateway, shill_properties, &properties_to_set);
   }
 
-  cros_->SetIPParameters(service_path,
-                         address,
-                         netmask,
-                         gateway,
-                         name_servers,
-                         dhcp_usage_mask);
+  if (name_server_type == kNameServerTypeAutomatic) {
+    AppendPropertyKeyIfPresent(shill::kStaticIPNameServersProperty,
+                               shill_properties, &properties_to_clear);
+  } else {
+    if (name_server_type == kNameServerTypeGoogle)
+      name_servers = kGoogleNameServers;
+    AddStringPropertyIfChanged(
+        shill::kStaticIPNameServersProperty,
+        name_servers, shill_properties, &properties_to_set);
+  }
+
+  if (!properties_to_clear.empty()) {
+    NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
+      service_path, properties_to_clear,
+      base::Bind(&base::DoNothing),
+      base::Bind(&ShillError, "ClearIPConfigProperties"));
+  }
+  if (!properties_to_set.empty()) {
+    NetworkHandler::Get()->network_configuration_handler()->SetProperties(
+        service_path, properties_to_set,
+        base::Bind(&base::DoNothing),
+        base::Bind(&ShillError, "SetIPConfigProperties"));
+  }
+  std::string device_path;
+  shill_properties.GetStringWithoutPathExpansion(
+      flimflam::kDeviceProperty, &device_path);
+  if (!device_path.empty()) {
+    // TODO(stevenjb): Enable this once 18873007 has landed.
+    // NetworkHandler::Get()->network_device_handler()->RequestRefreshIPConfigs(
+    //     device_path);
+  }
 }
 
 void InternetOptionsHandler::PopulateDictionaryDetailsCallback(
     const std::string& service_path,
-    const base::DictionaryValue* shill_properties) {
-  if (!shill_properties)
+    const base::DictionaryValue& shill_properties) {
+  const NetworkState* network = GetNetworkState(service_path);
+  if (!network) {
+    LOG(ERROR) << "Network properties not found: " << service_path;
     return;
-  chromeos::Network* network = cros_->FindNetworkByPath(service_path);
-  if (!network)
-    return;
-
-  if (network->device_path().empty()) {
-    PopulateIPConfigsCallback(service_path,
-                              shill_properties,
-                              chromeos::NetworkIPConfigVector(),
-                              std::string());
-  } else {
-    // Have to copy the properties because the object will go out of scope when
-    // this function call completes (it's owned by the calling function).
-    base::DictionaryValue* shill_props_copy = shill_properties->DeepCopy();
-    cros_->GetIPConfigs(
-        network->device_path(),
-        chromeos::NetworkLibrary::FORMAT_COLON_SEPARATED_HEX,
-        base::Bind(&InternetOptionsHandler::PopulateIPConfigsCallback,
-                   weak_factory_.GetWeakPtr(),
-                   service_path,
-                   base::Owned(shill_props_copy)));
   }
-}
 
-void InternetOptionsHandler::PopulateIPConfigsCallback(
-    const std::string& service_path,
-    const base::DictionaryValue* shill_properties,
-    const chromeos::NetworkIPConfigVector& ipconfigs,
-    const std::string& hardware_address) {
-  if (!shill_properties)
-    return;
-  if (VLOG_IS_ON(2)) {
-    std::string properties_json;
-    base::JSONWriter::WriteWithOptions(shill_properties,
-                                       base::JSONWriter::OPTIONS_PRETTY_PRINT,
-                                       &properties_json);
-    VLOG(2) << "Shill Properties: " << std::endl << properties_json;
-  }
-  chromeos::Network* network = cros_->FindNetworkByPath(service_path);
-  if (!network)
-    return;
-
-  const chromeos::NetworkUIData& ui_data = network->ui_data();
-  const chromeos::NetworkPropertyUIData property_ui_data(ui_data.onc_source());
-  const base::DictionaryValue* onc =
-      cros_->FindOncForNetwork(network->unique_id());
+  const NetworkPropertyUIData property_ui_data(network->onc_source());
+  const base::DictionaryValue* onc = NetworkLibrary::Get()->
+      FindOncForNetwork(network->guid());
 
   base::DictionaryValue dictionary;
-  if (!hardware_address.empty())
-    dictionary.SetString(kTagHardwareAddress, hardware_address);
 
-  // The DHCP IPConfig contains the values that are actually in use at the
-  // moment, even if some are overridden by static IP values.
-  scoped_ptr<DictionaryValue> ipconfig_dhcp(new DictionaryValue);
-  std::string ipconfig_name_servers;
-  for (chromeos::NetworkIPConfigVector::const_iterator it = ipconfigs.begin();
-       it != ipconfigs.end(); ++it) {
-    const chromeos::NetworkIPConfig& ipconfig = *it;
-    if (ipconfig.type == chromeos::IPCONFIG_TYPE_DHCP) {
-      ipconfig_dhcp->SetString(kIpConfigAddress, ipconfig.address);
-      VLOG(2) << "Found DHCP Address: " << ipconfig.address;
-      ipconfig_dhcp->SetString(kIpConfigNetmask, ipconfig.netmask);
-      VLOG(2) << "Found DHCP Netmask: " << ipconfig.netmask;
-      ipconfig_dhcp->SetString(kIpConfigGateway, ipconfig.gateway);
-      VLOG(2) << "Found DHCP Gateway: " << ipconfig.gateway;
-      ipconfig_dhcp->SetString(kIpConfigNameServers, ipconfig.name_servers);
-      ipconfig_name_servers = ipconfig.name_servers; // save for later
-      VLOG(2) << "Found DHCP Name Servers: " << ipconfig.name_servers;
-      break;
-    }
-  }
-  SetValueDictionary(&dictionary, kDictionaryIpConfig, ipconfig_dhcp.release(),
+  // Device hardware address
+  const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
+      GetDeviceState(network->device_path());
+  if (device)
+    dictionary.SetString(kTagHardwareAddress, device->mac_address());
+
+  // IP config
+  scoped_ptr<base::DictionaryValue> ipconfig_dhcp(new base::DictionaryValue);
+  ipconfig_dhcp->SetString(kIpConfigAddress, network->ip_address());
+  ipconfig_dhcp->SetString(kIpConfigNetmask, network->GetNetmask());
+  ipconfig_dhcp->SetString(kIpConfigGateway, network->gateway());
+  std::string ipconfig_name_servers = network->GetDnsServersAsString();
+  ipconfig_dhcp->SetString(kIpConfigNameServers, ipconfig_name_servers);
+  SetValueDictionary(&dictionary,
+                     kDictionaryIpConfig,
+                     ipconfig_dhcp.release(),
                      property_ui_data);
 
   std::string name_server_type = kNameServerTypeAutomatic;
-  if (shill_properties) {
-    int automatic_ip_config = 0;
-    scoped_ptr<DictionaryValue> static_ip_dict(
-        BuildIPInfoDictionary(*shill_properties, true, &automatic_ip_config));
-    dictionary.SetBoolean(kIpConfigAutoConfig, automatic_ip_config == 0);
-    DCHECK(automatic_ip_config == 3 || automatic_ip_config == 0)
-        << "UI doesn't support automatic specification of individual "
-        << "static IP parameters.";
-    scoped_ptr<DictionaryValue> saved_ip_dict(
-        BuildIPInfoDictionary(*shill_properties, false, NULL));
-    dictionary.Set(kDictionarySavedIp, saved_ip_dict.release());
+  int automatic_ip_config = 0;
+  scoped_ptr<base::DictionaryValue> static_ip_dict(
+      BuildIPInfoDictionary(shill_properties, true, &automatic_ip_config));
+  dictionary.SetBoolean(kIpConfigAutoConfig, automatic_ip_config == 0);
+  DCHECK(automatic_ip_config == 3 || automatic_ip_config == 0)
+      << "UI doesn't support automatic specification of individual "
+      << "static IP parameters.";
+  scoped_ptr<base::DictionaryValue> saved_ip_dict(
+      BuildIPInfoDictionary(shill_properties, false, NULL));
+  dictionary.Set(kDictionarySavedIp, saved_ip_dict.release());
 
-    // Determine what kind of name server setting we have by comparing the
-    // StaticIP and Google values with the ipconfig values.
-    std::string static_ip_nameservers;
-    static_ip_dict->GetString(kIpConfigNameServers, &static_ip_nameservers);
-
-    if (!static_ip_nameservers.empty() &&
-        static_ip_nameservers == ipconfig_name_servers) {
-      name_server_type = kNameServerTypeUser;
-    }
-    if (ipconfig_name_servers == kGoogleNameServers) {
-      name_server_type = kNameServerTypeGoogle;
-    }
-    SetValueDictionary(&dictionary,
-                       kDictionaryStaticIp,
-                       static_ip_dict.release(),
-                       property_ui_data);
-  } else {
-    LOG(ERROR) << "Unable to fetch IP configuration for " << service_path;
-    // If we were unable to fetch shill_properties for some reason,
-    // then just go with some defaults.
-    dictionary.SetBoolean(kIpConfigAutoConfig, false);
-    dictionary.Set(kDictionarySavedIp, new DictionaryValue);
-    SetValueDictionary(&dictionary, kDictionaryStaticIp, new DictionaryValue,
-                       property_ui_data);
+  // Determine what kind of name server setting we have by comparing the
+  // StaticIP and Google values with the ipconfig values.
+  std::string static_ip_nameservers;
+  static_ip_dict->GetString(kIpConfigNameServers, &static_ip_nameservers);
+  if (!static_ip_nameservers.empty() &&
+      static_ip_nameservers == ipconfig_name_servers) {
+    name_server_type = kNameServerTypeUser;
   }
+  if (ipconfig_name_servers == kGoogleNameServers) {
+    name_server_type = kNameServerTypeGoogle;
+  }
+  SetValueDictionary(&dictionary,
+                     kDictionaryStaticIp,
+                     static_ip_dict.release(),
+                     property_ui_data);
 
-  chromeos::ConnectionType type = network->type();
-  dictionary.SetInteger(kTagType, type);
-  dictionary.SetString(kTagServicePath, network->service_path());
+  std::string type = network->type();
+  dictionary.SetString(kTagType, type);
+  dictionary.SetString(kTagServicePath, network->path());
   dictionary.SetString(kTagNameServerType, name_server_type);
   dictionary.SetString(kTagNameServersGoogle, kGoogleNameServers);
 
   // Only show proxy for remembered networks.
-  chromeos::NetworkProfileType network_profile = network->profile_type();
-  dictionary.SetBoolean(kTagShowProxy,
-                        network_profile != chromeos::PROFILE_NONE);
+  dictionary.SetBoolean(kTagShowProxy, !network->profile_path().empty());
 
   // Enable static ip config for ethernet. For wifi, enable if flag is set.
-  bool staticIPConfig = type == chromeos::TYPE_ETHERNET ||
-      (type == chromeos::TYPE_WIFI &&
+  bool staticIPConfig = type == flimflam::kTypeEthernet ||
+      (type == flimflam::kTypeWifi &&
        CommandLine::ForCurrentProcess()->HasSwitch(
            chromeos::switches::kEnableStaticIPConfig));
   dictionary.SetBoolean(kTagShowStaticIPConfig, staticIPConfig);
 
-  dictionary.SetBoolean(kTagShowPreferred,
-                        network_profile == chromeos::PROFILE_USER);
+  dictionary.SetBoolean(kTagShowPreferred, !network->profile_path().empty());
+  bool preferred = network->priority() > 0;
   SetValueDictionary(&dictionary, kTagPreferred,
-                     new base::FundamentalValue(network->preferred()),
+                     new base::FundamentalValue(preferred),
                      property_ui_data);
 
-  chromeos::NetworkPropertyUIData auto_connect_ui_data(ui_data.onc_source());
+  NetworkPropertyUIData auto_connect_ui_data(network->onc_source());
   std::string onc_path_to_auto_connect;
-  if (type == chromeos::TYPE_WIFI) {
+  if (type == flimflam::kTypeWifi) {
     onc_path_to_auto_connect = base::StringPrintf(
         "%s.%s",
-        chromeos::onc::network_config::kWiFi,
-        chromeos::onc::wifi::kAutoConnect);
-  } else if (type == chromeos::TYPE_VPN) {
+        onc::network_config::kWiFi,
+        onc::wifi::kAutoConnect);
+  } else if (type == flimflam::kTypeVPN) {
     onc_path_to_auto_connect = base::StringPrintf(
         "%s.%s",
-        chromeos::onc::network_config::kVPN,
-        chromeos::onc::vpn::kAutoConnect);
+        onc::network_config::kVPN,
+        onc::vpn::kAutoConnect);
   }
   if (!onc_path_to_auto_connect.empty()) {
     auto_connect_ui_data.ParseOncProperty(
-        ui_data.onc_source(),
+        network->onc_source(),
         onc,
         onc_path_to_auto_connect);
   }
@@ -1350,165 +1518,216 @@
                      new base::FundamentalValue(network->auto_connect()),
                      auto_connect_ui_data);
 
-  PopulateConnectionDetails(network, &dictionary);
-  web_ui()->CallJavascriptFunction(
-      kShowDetailedInfoFunction, dictionary);
+  PopulateConnectionDetails(network, shill_properties, &dictionary);
+
+  // Show details dialog
+  web_ui()->CallJavascriptFunction(kShowDetailedInfoFunction, dictionary);
 }
 
-void InternetOptionsHandler::PopulateConnectionDetails(
-    const chromeos::Network* network,
-    DictionaryValue* dictionary) {
-  dictionary->SetString(kNetworkInfoKeyServicePath, network->service_path());
-  chromeos::ConnectionType type = network->type();
-  dictionary->SetBoolean(kTagConnecting, network->connecting());
-  dictionary->SetBoolean(kTagConnected, network->connected());
-  dictionary->SetString(kTagConnectionState, network->GetStateString());
+namespace {
+
+void PopulateConnectionDetails(const NetworkState* network,
+                               const base::DictionaryValue& shill_properties,
+                               base::DictionaryValue* dictionary) {
+  dictionary->SetString(kNetworkInfoKeyServicePath, network->path());
+  dictionary->SetString(kTagServiceName, network->name());
+  dictionary->SetBoolean(kTagConnecting, network->IsConnectingState());
+  dictionary->SetBoolean(kTagConnected, network->IsConnectedState());
+  dictionary->SetString(kTagConnectionState,
+                        ConnectionStateString(network->connection_state()));
   dictionary->SetString(kTagNetworkName, network->name());
+  dictionary->SetString(kTagErrorState,
+                        ash::network_connect::ErrorString(network->error()));
 
-  if (type == chromeos::TYPE_WIFI) {
-    dictionary->SetBoolean(kTagDeviceConnected, cros_->wifi_connected());
-    PopulateWifiDetails(static_cast<const chromeos::WifiNetwork*>(network),
-                        dictionary);
-  } else if (type == chromeos::TYPE_WIMAX) {
-    dictionary->SetBoolean(kTagDeviceConnected, cros_->wimax_connected());
-    PopulateWimaxDetails(static_cast<const chromeos::WimaxNetwork*>(network),
-                         dictionary);
-  } else if (type == chromeos::TYPE_CELLULAR) {
-    dictionary->SetBoolean(kTagDeviceConnected, cros_->cellular_connected());
-    PopulateCellularDetails(
-        static_cast<const chromeos::CellularNetwork*>(network),
-        dictionary);
-  } else if (type == chromeos::TYPE_VPN) {
-    dictionary->SetBoolean(kTagDeviceConnected,
-                           cros_->virtual_network_connected());
-    const base::DictionaryValue* onc =
-        cros_->FindOncForNetwork(network->unique_id());
-    PopulateVPNDetails(static_cast<const chromeos::VirtualNetwork*>(network),
-                       *onc,
-                       dictionary);
-  } else if (type == chromeos::TYPE_ETHERNET) {
-    dictionary->SetBoolean(kTagDeviceConnected, cros_->ethernet_connected());
-  }
+  dictionary->SetBoolean(kTagRemembered, !network->profile_path().empty());
+  bool shared = network->IsShared();
+  dictionary->SetBoolean(kTagShared, shared);
+
+  const std::string& type = network->type();
+  const NetworkState* connected_network =
+      NetworkHandler::Get()->network_state_handler()->ConnectedNetworkByType(
+          type);
+
+  dictionary->SetBoolean(kTagDeviceConnected, connected_network != NULL);
+
+  if (type == flimflam::kTypeWifi)
+    PopulateWifiDetails(network, shill_properties, dictionary);
+  else if (type == flimflam::kTypeWimax)
+    PopulateWimaxDetails(network, shill_properties, dictionary);
+  else if (type == flimflam::kTypeCellular)
+    PopulateCellularDetails(network, shill_properties, dictionary);
+  else if (type == flimflam::kTypeVPN)
+    PopulateVPNDetails(network, shill_properties, dictionary);
 }
 
-void InternetOptionsHandler::PopulateWifiDetails(
-    const chromeos::WifiNetwork* wifi,
-    DictionaryValue* dictionary) {
+void PopulateWifiDetails(const NetworkState* wifi,
+                         const base::DictionaryValue& shill_properties,
+                         base::DictionaryValue* dictionary) {
   dictionary->SetString(kTagSsid, wifi->name());
-  bool remembered = (wifi->profile_type() != chromeos::PROFILE_NONE);
-  dictionary->SetBoolean(kTagRemembered, remembered);
-  bool shared = wifi->profile_type() == chromeos::PROFILE_SHARED;
-  dictionary->SetBoolean(kTagShared, shared);
-  dictionary->SetString(kTagEncryption, wifi->GetEncryptionString());
-  dictionary->SetString(kTagBssid, wifi->bssid());
-  dictionary->SetInteger(kTagFrequency, wifi->frequency());
-  dictionary->SetInteger(kTagStrength, wifi->strength());
+  dictionary->SetInteger(kTagStrength, wifi->signal_strength());
+
+  std::string security, eap_method;
+  shill_properties.GetStringWithoutPathExpansion(
+      flimflam::kSecurityProperty, &security);
+  shill_properties.GetStringWithoutPathExpansion(
+      flimflam::kEapMethodProperty, &eap_method);
+  dictionary->SetString(kTagEncryption, EncryptionString(security, eap_method));
+  CopyStringFromDictionary(shill_properties, flimflam::kWifiBSsid,
+                           kTagBssid, dictionary);
+  CopyIntegerFromDictionary(shill_properties, flimflam::kWifiFrequency,
+                            kTagFrequency, false, dictionary);
 }
 
-void InternetOptionsHandler::PopulateWimaxDetails(
-    const chromeos::WimaxNetwork* wimax,
-    DictionaryValue* dictionary) {
-  bool remembered = (wimax->profile_type() != chromeos::PROFILE_NONE);
-  dictionary->SetBoolean(kTagRemembered, remembered);
-  bool shared = wimax->profile_type() == chromeos::PROFILE_SHARED;
-  dictionary->SetBoolean(kTagShared, shared);
-  if (wimax->passphrase_required())
-    dictionary->SetString(kTagIdentity, wimax->eap_identity());
-
-  dictionary->SetInteger(kTagStrength, wimax->strength());
+void PopulateWimaxDetails(const NetworkState* wimax,
+                          const base::DictionaryValue& shill_properties,
+                          base::DictionaryValue* dictionary) {
+  dictionary->SetInteger(kTagStrength, wimax->signal_strength());
+  CopyStringFromDictionary(shill_properties, flimflam::kEapIdentityProperty,
+                           kTagIdentity, dictionary);
 }
 
-DictionaryValue* InternetOptionsHandler::CreateDictionaryFromCellularApn(
-    const chromeos::CellularApn& apn) {
-  DictionaryValue* dictionary = new DictionaryValue();
-  dictionary->SetString(kTagApn, apn.apn);
-  dictionary->SetString(kTagNetworkId, apn.network_id);
-  dictionary->SetString(kTagUsername, apn.username);
-  dictionary->SetString(kTagPassword, apn.password);
-  dictionary->SetString(kTagName, apn.name);
-  dictionary->SetString(kTagLocalizedName, apn.localized_name);
-  dictionary->SetString(kTagLanguage, apn.language);
+base::DictionaryValue* CreateDictionaryFromCellularApn(
+    const base::DictionaryValue* apn) {
+  base::DictionaryValue* dictionary = new base::DictionaryValue();
+  CopyStringFromDictionary(*apn, flimflam::kApnProperty,
+                           kTagApn, dictionary);
+  CopyStringFromDictionary(*apn, flimflam::kApnNetworkIdProperty,
+                           kTagNetworkId, dictionary);
+  CopyStringFromDictionary(*apn, flimflam::kApnUsernameProperty,
+                           kTagUsername, dictionary);
+  CopyStringFromDictionary(*apn, flimflam::kApnPasswordProperty,
+                           kTagPassword, dictionary);
+  CopyStringFromDictionary(*apn, flimflam::kApnNameProperty,
+                           kTagName, dictionary);
+  CopyStringFromDictionary(*apn, flimflam::kApnLocalizedNameProperty,
+                           kTagLocalizedName, dictionary);
+  CopyStringFromDictionary(*apn, flimflam::kApnLanguageProperty,
+                           kTagLanguage, dictionary);
   return dictionary;
 }
 
-void InternetOptionsHandler::PopulateCellularDetails(
-    const chromeos::CellularNetwork* cellular,
-    DictionaryValue* dictionary) {
+void PopulateCellularDetails(const NetworkState* cellular,
+                             const base::DictionaryValue& shill_properties,
+                             base::DictionaryValue* dictionary) {
   dictionary->SetBoolean(kTagCarrierSelectFlag,
                          CommandLine::ForCurrentProcess()->HasSwitch(
                              chromeos::switches::kEnableCarrierSwitching));
   // Cellular network / connection settings.
-  dictionary->SetString(kTagServiceName, cellular->name());
-  dictionary->SetString(kTagNetworkTechnology,
-                        cellular->GetNetworkTechnologyString());
-  dictionary->SetString(kTagOperatorName, cellular->operator_name());
-  dictionary->SetString(kTagOperatorCode, cellular->operator_code());
+  dictionary->SetString(kTagNetworkTechnology, cellular->technology());
   dictionary->SetString(kTagActivationState,
-                        cellular->GetActivationStateString());
+                        ActivationStateString(cellular->activation_state()));
   dictionary->SetString(kTagRoamingState,
-                        cellular->GetRoamingStateString());
+                        RoamingStateString(cellular->roaming()));
+  bool restricted = cellular->connection_state() == flimflam::kStatePortal;
   dictionary->SetString(kTagRestrictedPool,
-                        cellular->restricted_pool() ?
+                        restricted ?
                         l10n_util::GetStringUTF8(
                             IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL) :
                         l10n_util::GetStringUTF8(
                             IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL));
-  dictionary->SetString(kTagErrorState, cellular->GetErrorString());
-  dictionary->SetString(kTagSupportUrl, cellular->payment_url());
+  CopyStringFromDictionary(shill_properties, flimflam::kOperatorNameProperty,
+                          kTagOperatorName, dictionary);
+  CopyStringFromDictionary(shill_properties, flimflam::kOperatorCodeProperty,
+                          kTagOperatorCode, dictionary);
 
-  dictionary->Set(kTagApn, CreateDictionaryFromCellularApn(cellular->apn()));
-  dictionary->Set(kTagLastGoodApn,
-                  CreateDictionaryFromCellularApn(cellular->last_good_apn()));
+  const base::DictionaryValue* olp = NULL;
+  if (shill_properties.GetDictionary(flimflam::kPaymentPortalProperty, &olp)) {
+    std::string url;
+    olp->GetStringWithoutPathExpansion(flimflam::kPaymentPortalURL, &url);
+    dictionary->SetString(kTagSupportUrl, url);
+  }
+
+  const base::DictionaryValue* source_apn = NULL;
+  if (shill_properties.GetDictionary(
+          flimflam::kCellularApnProperty, &source_apn)) {
+    base::DictionaryValue* apn = CreateDictionaryFromCellularApn(source_apn);
+    if (apn)
+      dictionary->Set(kTagApn, apn);
+  }
+  if (shill_properties.GetDictionary(
+          flimflam::kCellularLastGoodApnProperty, &source_apn)) {
+    base::DictionaryValue* apn = CreateDictionaryFromCellularApn(source_apn);
+    if (apn)
+      dictionary->Set(kTagLastGoodApn, apn);
+  }
+
+  // These default to empty and are only set if device != NULL.
+  std::string carrier_id;
+  std::string mdn;
 
   // Device settings.
-  const chromeos::NetworkDevice* device =
-      cros_->FindNetworkDeviceByPath(cellular->device_path());
+  const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
+      GetDeviceState(cellular->device_path());
   if (device) {
-    const chromeos::NetworkPropertyUIData cellular_property_ui_data(
-        cellular->ui_data().onc_source());
-    dictionary->SetString(kTagManufacturer, device->manufacturer());
-    dictionary->SetString(kTagModelId, device->model_id());
-    dictionary->SetString(kTagFirmwareRevision, device->firmware_revision());
-    dictionary->SetString(kTagHardwareRevision, device->hardware_revision());
-    dictionary->SetString(kTagPrlVersion,
-                          base::StringPrintf("%u", device->prl_version()));
-    dictionary->SetString(kTagMeid, device->meid());
-    dictionary->SetString(kTagIccid, device->iccid());
-    dictionary->SetString(kTagImei, device->imei());
-    dictionary->SetString(kTagMdn, device->mdn());
-    dictionary->SetString(kTagImsi, device->imsi());
-    dictionary->SetString(kTagEsn, device->esn());
-    dictionary->SetString(kTagMin, device->min());
-    dictionary->SetBoolean(kTagGsm,
-        device->technology_family() == chromeos::TECHNOLOGY_FAMILY_GSM);
+    // TODO(stevenjb): Add NetworkDeviceHandler::GetProperties() and use that
+    // to retrieve the complete dictionary of device properties, instead of
+    // caching them (will be done for the new UI).
+    const base::DictionaryValue& device_properties = device->properties();
+    const NetworkPropertyUIData cellular_property_ui_data(
+        cellular->onc_source());
+    CopyStringFromDictionary(device_properties, flimflam::kManufacturerProperty,
+                            kTagManufacturer, dictionary);
+    CopyStringFromDictionary(device_properties, flimflam::kModelIDProperty,
+                            kTagModelId, dictionary);
+    CopyStringFromDictionary(device_properties,
+                            flimflam::kFirmwareRevisionProperty,
+                            kTagFirmwareRevision, dictionary);
+    CopyStringFromDictionary(device_properties,
+                            flimflam::kHardwareRevisionProperty,
+                            kTagHardwareRevision, dictionary);
+    CopyIntegerFromDictionary(device_properties, flimflam::kPRLVersionProperty,
+                             kTagPrlVersion, true, dictionary);
+    CopyStringFromDictionary(device_properties, flimflam::kMeidProperty,
+                            kTagMeid, dictionary);
+    CopyStringFromDictionary(device_properties, flimflam::kIccidProperty,
+                            kTagIccid, dictionary);
+    CopyStringFromDictionary(device_properties, flimflam::kImeiProperty,
+                            kTagImei, dictionary);
+    mdn = CopyStringFromDictionary(device_properties, flimflam::kMdnProperty,
+                                   kTagMdn, dictionary);
+    CopyStringFromDictionary(device_properties, flimflam::kImsiProperty,
+                            kTagImsi, dictionary);
+    CopyStringFromDictionary(device_properties, flimflam::kEsnProperty,
+                            kTagEsn, dictionary);
+    CopyStringFromDictionary(device_properties, flimflam::kMinProperty,
+                            kTagMin, dictionary);
+    std::string family;
+    device_properties.GetStringWithoutPathExpansion(
+        flimflam::kTechnologyFamilyProperty, &family);
+    dictionary->SetBoolean(kTagGsm, family == flimflam::kNetworkTechnologyGsm);
+
     SetValueDictionary(
         dictionary, kTagSimCardLockEnabled,
-        new base::FundamentalValue(
-            device->sim_pin_required() == chromeos::SIM_PIN_REQUIRED),
+        new base::FundamentalValue(device->sim_lock_enabled()),
         cellular_property_ui_data);
 
-    chromeos::MobileConfig* config = chromeos::MobileConfig::GetInstance();
+    carrier_id = device->home_provider_id();
+
+    MobileConfig* config = MobileConfig::GetInstance();
     if (config->IsReady()) {
-      const std::string& carrier_id = cros_->GetCellularHomeCarrierId();
-      const chromeos::MobileConfig::Carrier* carrier =
-          config->GetCarrier(carrier_id);
+      const MobileConfig::Carrier* carrier = config->GetCarrier(carrier_id);
       if (carrier && !carrier->top_up_url().empty())
         dictionary->SetString(kTagCarrierUrl, carrier->top_up_url());
     }
 
-    const chromeos::CellularApnList& apn_list = device->provider_apn_list();
-    ListValue* apn_list_value = new ListValue();
-    for (chromeos::CellularApnList::const_iterator it = apn_list.begin();
-         it != apn_list.end(); ++it) {
-      apn_list_value->Append(CreateDictionaryFromCellularApn(*it));
+    base::ListValue* apn_list_value = new base::ListValue();
+    const base::ListValue* apn_list;
+    if (device_properties.GetList(
+            flimflam::kCellularApnListProperty, &apn_list)) {
+      for (base::ListValue::const_iterator iter = apn_list->begin();
+           iter != apn_list->end(); ++iter) {
+        const base::DictionaryValue* dict;
+        if ((*iter)->GetAsDictionary(&dict))
+          apn_list_value->Append(CreateDictionaryFromCellularApn(dict));
+      }
     }
     SetValueDictionary(dictionary, kTagProviderApnList, apn_list_value,
                        cellular_property_ui_data);
-
     if (CommandLine::ForCurrentProcess()->HasSwitch(
             chromeos::switches::kEnableCarrierSwitching)) {
-      base::ListValue* supported_carriers = device->supported_carriers();
-      if (supported_carriers) {
+      const base::ListValue* supported_carriers;
+      if (device_properties.GetList(
+              shill::kSupportedCarriersProperty, &supported_carriers)) {
         dictionary->Set(kTagCarriers, supported_carriers->DeepCopy());
         dictionary->SetInteger(kTagCurrentCarrierIndex,
                                FindCurrentCarrierIndex(supported_carriers,
@@ -1521,50 +1740,42 @@
     }
   }
 
-  SetCellularButtonsVisibility(cellular,
-                               device,
-                               dictionary,
-                               cros_->GetCellularHomeCarrierId());
-}
-
-void InternetOptionsHandler::SetCellularButtonsVisibility(
-    const chromeos::CellularNetwork* cellular,
-    const chromeos::NetworkDevice* device,
-    DictionaryValue* dictionary,
-    const std::string& carrier_id) {
+  // Set Cellular Buttons Visibility
   dictionary->SetBoolean(
       kTagDisableConnectButton,
-      cellular->activation_state() == chromeos::ACTIVATION_STATE_ACTIVATING ||
-          cellular->connecting());
+      cellular->activation_state() == flimflam::kActivationStateActivating ||
+      cellular->IsConnectingState());
 
-  if (cellular->activation_state() != chromeos::ACTIVATION_STATE_ACTIVATING &&
-      cellular->activation_state() != chromeos::ACTIVATION_STATE_ACTIVATED) {
+  if (cellular->activation_state() != flimflam::kActivationStateActivating &&
+      cellular->activation_state() != flimflam::kActivationStateActivated) {
     dictionary->SetBoolean(kTagShowActivateButton, true);
   } else {
-    const chromeos::MobileConfig::Carrier* carrier =
-        chromeos::MobileConfig::GetInstance()->GetCarrier(carrier_id);
+    const MobileConfig::Carrier* carrier =
+        MobileConfig::GetInstance()->GetCarrier(carrier_id);
     if (carrier && carrier->show_portal_button()) {
       // The button should be shown for a LTE network even when the LTE network
       // is not connected, but CrOS is online. This is done to enable users to
       // update their plan even if they are out of credits.
       // The button should not be shown when the device's mdn is not set,
       // because the network's proper portal url cannot be generated without it
-      chromeos::NetworkTechnology technology = cellular->network_technology();
+      const NetworkState* default_network =
+          NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
       bool force_show_view_account_button =
-          (technology == chromeos::NETWORK_TECHNOLOGY_LTE ||
-           technology == chromeos::NETWORK_TECHNOLOGY_LTE_ADVANCED) &&
-          cros_->connected_network() &&
-          cros_->connected_network()->online() &&
-          device && !device->mdn().empty();
+          (cellular->technology() == flimflam::kNetworkTechnologyLte ||
+           cellular->technology() == flimflam::kNetworkTechnologyLteAdvanced) &&
+          default_network &&
+          !mdn.empty();
 
       // The button will trigger ShowMorePlanInfoCallback() which will open
       // carrier specific portal.
-      if (cellular->connected() || force_show_view_account_button)
+      if (cellular->IsConnectedState() || force_show_view_account_button)
         dictionary->SetBoolean(kTagShowViewAccountButton, true);
     }
   }
 }
 
+}  // namespace
+
 gfx::NativeWindow InternetOptionsHandler::GetNativeWindow() const {
   return web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow();
 }
@@ -1575,199 +1786,165 @@
       chrome::HOST_DESKTOP_TYPE_ASH);
 }
 
-void InternetOptionsHandler::NetworkCommandCallback(const ListValue* args) {
-  std::string str_type;
+void InternetOptionsHandler::NetworkCommandCallback(
+    const base::ListValue* args) {
+  std::string type;
   std::string service_path;
   std::string command;
   if (args->GetSize() != 3 ||
-      !args->GetString(0, &str_type) ||
+      !args->GetString(0, &type) ||
       !args->GetString(1, &service_path) ||
       !args->GetString(2, &command)) {
     NOTREACHED();
     return;
   }
 
-  // First try as a string, e.g. "wifi".
-  chromeos::ConnectionType type = ParseNetworkTypeString(str_type);
-  // Next try casting as an enum.
-  if (type == chromeos::TYPE_UNKNOWN)
-    type = (chromeos::ConnectionType) atoi(str_type.c_str());
-
   // Process commands that do not require an existing network.
   if (command == kTagAddConnection) {
     if (CanAddNetworkType(type))
       AddConnection(type);
-    return;
   } else if (command == kTagForget) {
-    if (CanForgetNetworkType(type))
-      cros_->ForgetNetwork(service_path);
-    return;
-  }
-
-  // Process commands that require an active network.
-  chromeos::Network *network = NULL;
-  if (!service_path.empty())
-    network = cros_->FindNetworkByPath(service_path);
-
-  if (!network) {
-    VLOG(2) << "Network command: " << command
-            << "Called with unknown service-path: " << service_path;
-    return;
-  }
-  DCHECK_EQ(network->type(), type)
-      << "Provided type: " << type << " does not match: " << network->type()
-      << " For network: " << service_path;
-
-  if (command == kTagOptions) {
-    cros_->RequestNetworkServiceProperties(
+    if (CanForgetNetworkType(type)) {
+      NetworkHandler::Get()->network_configuration_handler()->
+          RemoveConfiguration(
+              service_path,
+              base::Bind(&base::DoNothing),
+              base::Bind(&ShillError, "NetworkCommand: " + command));
+    }
+  } else if (command == kTagOptions) {
+    NetworkHandler::Get()->network_configuration_handler()->GetProperties(
         service_path,
         base::Bind(&InternetOptionsHandler::PopulateDictionaryDetailsCallback,
-                   weak_factory_.GetWeakPtr()));
+                   weak_factory_.GetWeakPtr()),
+        base::Bind(&ShillError, "NetworkCommand: " + command));
   } else if (command == kTagConnect) {
-    chromeos::network_connect::ConnectToNetwork(
+    network_connect::ConnectToNetwork(
         service_path, GetNativeWindow());
-  } else if (command == kTagDisconnect && type != chromeos::TYPE_ETHERNET) {
-    cros_->DisconnectFromNetwork(network);
-  } else if (command == kTagActivate && type == chromeos::TYPE_CELLULAR) {
-    chromeos::network_connect::ActivateCellular(service_path);
+  } else if (command == kTagDisconnect) {
+    NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
+        service_path,
+        base::Bind(&base::DoNothing),
+        base::Bind(&ShillError, "NetworkCommand: " + command));
+  } else if (command == kTagActivate && type == flimflam::kTypeCellular) {
+    network_connect::ActivateCellular(service_path);
     // Activation may update network properties (e.g. ActivationState), so
     // request them here in case they change.
-    UpdateConnectionData(network);
+    UpdateConnectionData(service_path);
   } else {
     VLOG(1) << "Unknown command: " << command;
     NOTREACHED();
   }
 }
 
-void InternetOptionsHandler::AddConnection(chromeos::ConnectionType type) {
-  switch (type) {
-    case chromeos::TYPE_WIFI:
-    case chromeos::TYPE_VPN:
-      chromeos::NetworkConfigView::ShowForType(type,
-                                               GetNativeWindow());
-      break;
-    case chromeos::TYPE_CELLULAR:
-      chromeos::ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
-      break;
-    default:
-      NOTREACHED();
-  }
+void InternetOptionsHandler::AddConnection(const std::string& type) {
+  if (type == flimflam::kTypeWifi)
+    NetworkConfigView::ShowForType(chromeos::TYPE_WIFI, GetNativeWindow());
+  else if (type == flimflam::kTypeVPN)
+    NetworkConfigView::ShowForType(chromeos::TYPE_VPN, GetNativeWindow());
+  else if (type == flimflam::kTypeCellular)
+    ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
+  else
+    NOTREACHED();
 }
 
-ListValue* InternetOptionsHandler::GetWiredList() {
-  ListValue* list = new ListValue();
-
-  // If ethernet is not enabled, then don't add anything.
-  if (cros_->ethernet_enabled()) {
-    const chromeos::EthernetNetwork* ethernet_network =
-        cros_->ethernet_network();
-    if (ethernet_network) {
-      NetworkInfoDictionary network_dict(ethernet_network,
-                                         web_ui()->GetDeviceScaleFactor());
-      network_dict.set_name(
-          l10n_util::GetStringUTF8(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET)),
-      list->Append(network_dict.BuildDictionary());
-    }
-  }
+base::ListValue* InternetOptionsHandler::GetWiredList() {
+  base::ListValue* list = new base::ListValue();
+  const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
+      FirstNetworkByType(flimflam::kTypeEthernet);
+  if (!network)
+    return list;
+  NetworkInfoDictionary network_dict(network, web_ui()->GetDeviceScaleFactor());
+  list->Append(network_dict.BuildDictionary());
   return list;
 }
 
-ListValue* InternetOptionsHandler::GetWirelessList() {
-  ListValue* list = new ListValue();
+base::ListValue* InternetOptionsHandler::GetWirelessList() {
+  base::ListValue* list = new base::ListValue();
 
-  const chromeos::WifiNetworkVector& wifi_networks = cros_->wifi_networks();
-  for (chromeos::WifiNetworkVector::const_iterator it =
-      wifi_networks.begin(); it != wifi_networks.end(); ++it) {
-    NetworkInfoDictionary network_dict(*it, web_ui()->GetDeviceScaleFactor());
-    network_dict.set_connectable(cros_->CanConnectToNetwork(*it));
-    list->Append(network_dict.BuildDictionary());
-  }
-
-  const chromeos::WimaxNetworkVector& wimax_networks = cros_->wimax_networks();
-  for (chromeos::WimaxNetworkVector::const_iterator it =
-      wimax_networks.begin(); it != wimax_networks.end(); ++it) {
-    NetworkInfoDictionary network_dict(*it, web_ui()->GetDeviceScaleFactor());
-    network_dict.set_connectable(cros_->CanConnectToNetwork(*it));
-    list->Append(network_dict.BuildDictionary());
-  }
-
-  const chromeos::CellularNetworkVector cellular_networks =
-      cros_->cellular_networks();
-  for (chromeos::CellularNetworkVector::const_iterator it =
-      cellular_networks.begin(); it != cellular_networks.end(); ++it) {
-    NetworkInfoDictionary network_dict(*it, web_ui()->GetDeviceScaleFactor());
-    network_dict.set_connectable(cros_->CanConnectToNetwork(*it));
-    network_dict.set_activation_state((*it)->activation_state());
+  NetworkStateHandler::NetworkStateList networks;
+  NetworkHandler::Get()->network_state_handler()->GetNetworkList(&networks);
+  for (NetworkStateHandler::NetworkStateList::const_iterator iter =
+           networks.begin(); iter != networks.end(); ++iter) {
+    const NetworkState* network = *iter;
+    if (network->type() != flimflam::kTypeWifi &&
+        network->type() != flimflam::kTypeWimax &&
+        network->type() != flimflam::kTypeCellular)
+      continue;
+    NetworkInfoDictionary network_dict(
+        network, web_ui()->GetDeviceScaleFactor());
     list->Append(network_dict.BuildDictionary());
   }
 
   return list;
 }
 
-ListValue* InternetOptionsHandler::GetVPNList() {
-  ListValue* list = new ListValue();
+base::ListValue* InternetOptionsHandler::GetVPNList() {
+  base::ListValue* list = new base::ListValue();
 
-  const chromeos::VirtualNetworkVector& virtual_networks =
-      cros_->virtual_networks();
-  for (chromeos::VirtualNetworkVector::const_iterator it =
-      virtual_networks.begin(); it != virtual_networks.end(); ++it) {
-    NetworkInfoDictionary network_dict(*it, web_ui()->GetDeviceScaleFactor());
-    network_dict.set_connectable(cros_->CanConnectToNetwork(*it));
+  NetworkStateHandler::NetworkStateList networks;
+  NetworkHandler::Get()->network_state_handler()->GetNetworkList(&networks);
+  for (NetworkStateHandler::NetworkStateList::const_iterator iter =
+           networks.begin(); iter != networks.end(); ++iter) {
+    const NetworkState* network = *iter;
+    if (network->type() != flimflam::kTypeVPN)
+      continue;
+    NetworkInfoDictionary network_dict(
+        network, web_ui()->GetDeviceScaleFactor());
     list->Append(network_dict.BuildDictionary());
   }
 
   return list;
 }
 
-ListValue* InternetOptionsHandler::GetRememberedList() {
-  ListValue* list = new ListValue();
+base::ListValue* InternetOptionsHandler::GetRememberedList() {
+  base::ListValue* list = new base::ListValue();
 
-  for (chromeos::WifiNetworkVector::const_iterator rit =
-           cros_->remembered_wifi_networks().begin();
-       rit != cros_->remembered_wifi_networks().end(); ++rit) {
-    chromeos::WifiNetwork* remembered = *rit;
-    chromeos::WifiNetwork* wifi = static_cast<chromeos::WifiNetwork*>(
-        cros_->FindNetworkByUniqueId(remembered->unique_id()));
-
-    NetworkInfoDictionary network_dict(wifi,
-                                       remembered,
-                                       web_ui()->GetDeviceScaleFactor());
-    list->Append(network_dict.BuildDictionary());
-  }
-
-  for (chromeos::VirtualNetworkVector::const_iterator rit =
-           cros_->remembered_virtual_networks().begin();
-       rit != cros_->remembered_virtual_networks().end(); ++rit) {
-    chromeos::VirtualNetwork* remembered = *rit;
-    chromeos::VirtualNetwork* vpn = static_cast<chromeos::VirtualNetwork*>(
-        cros_->FindNetworkByUniqueId(remembered->unique_id()));
-
-    NetworkInfoDictionary network_dict(vpn,
-                                       remembered,
-                                       web_ui()->GetDeviceScaleFactor());
+  NetworkStateHandler::FavoriteStateList favorites;
+  NetworkHandler::Get()->network_state_handler()->GetFavoriteList(&favorites);
+  for (NetworkStateHandler::FavoriteStateList::const_iterator iter =
+           favorites.begin(); iter != favorites.end(); ++iter) {
+    const FavoriteState* favorite = *iter;
+    if (favorite->type() != flimflam::kTypeWifi &&
+        favorite->type() != flimflam::kTypeVPN)
+      continue;
+    NetworkInfoDictionary network_dict(
+        favorite, web_ui()->GetDeviceScaleFactor());
     list->Append(network_dict.BuildDictionary());
   }
 
   return list;
 }
 
-void InternetOptionsHandler::FillNetworkInfo(DictionaryValue* dictionary) {
+void InternetOptionsHandler::FillNetworkInfo(
+    base::DictionaryValue* dictionary) {
+  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
   dictionary->Set(kTagWiredList, GetWiredList());
   dictionary->Set(kTagWirelessList, GetWirelessList());
   dictionary->Set(kTagVpnList, GetVPNList());
   dictionary->Set(kTagRememberedList, GetRememberedList());
-  dictionary->SetBoolean(kTagWifiAvailable, cros_->wifi_available());
-  dictionary->SetBoolean(kTagWifiEnabled, cros_->wifi_enabled());
-  dictionary->SetBoolean(kTagCellularAvailable, cros_->cellular_available());
-  dictionary->SetBoolean(kTagCellularEnabled, cros_->cellular_enabled());
 
-  const chromeos::NetworkDevice* cellular_device = cros_->FindCellularDevice();
+  dictionary->SetBoolean(kTagWifiAvailable,
+                         handler->IsTechnologyAvailable(flimflam::kTypeWifi));
+  dictionary->SetBoolean(kTagWifiEnabled,
+                         handler->IsTechnologyEnabled(flimflam::kTypeWifi));
+
+  dictionary->SetBoolean(kTagCellularAvailable,
+                         handler->IsTechnologyAvailable(
+                             NetworkStateHandler::kMatchTypeMobile));
+  dictionary->SetBoolean(kTagCellularEnabled,
+                         handler->IsTechnologyEnabled(
+                             NetworkStateHandler::kMatchTypeMobile));
+  const DeviceState* cellular =
+      handler->GetDeviceStateByType(NetworkStateHandler::kMatchTypeMobile);
   dictionary->SetBoolean(
       kTagCellularSupportsScan,
-      cellular_device && cellular_device->support_network_scan());
+      cellular && cellular->support_network_scan());
 
-  dictionary->SetBoolean(kTagWimaxEnabled, cros_->wimax_enabled());
-  dictionary->SetBoolean(kTagWimaxAvailable, cros_->wimax_available());
+  dictionary->SetBoolean(kTagWimaxAvailable,
+                         handler->IsTechnologyAvailable(flimflam::kTypeWimax));
+  dictionary->SetBoolean(kTagWimaxEnabled,
+                         handler->IsTechnologyEnabled(flimflam::kTypeWimax));
 }
 
 }  // namespace options
+}  // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h
index 59ef335..5cf033e 100644
--- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h
+++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h
@@ -8,15 +8,20 @@
 #include <string>
 
 #include "base/compiler_specific.h"
-#include "chrome/browser/chromeos/cros/network_constants.h"
-#include "chrome/browser/chromeos/cros/network_library.h"
+#include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/webui/options/options_ui.h"
-#include "chromeos/network/network_ui_data.h"
+#include "chromeos/network/network_state_handler_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "ui/gfx/native_widget_types.h"
 
 class Browser;
 
+namespace chromeos {
+class DeviceState;
+class NetworkState;
+class NetworkStateHandlerObserver;
+}
+
 namespace gfx {
 class ImageSkia;
 }
@@ -25,40 +30,87 @@
 class WidgetDelegate;
 }
 
+namespace chromeos {
 namespace options {
 
 // ChromeOS internet options page UI handler.
 class InternetOptionsHandler
-  : public OptionsPageUIHandler,
-    public chromeos::NetworkLibrary::NetworkManagerObserver,
-    public chromeos::NetworkLibrary::NetworkObserver {
+    : public ::options::OptionsPageUIHandler,
+      public chromeos::NetworkStateHandlerObserver {
  public:
   InternetOptionsHandler();
   virtual ~InternetOptionsHandler();
 
-  // OptionsPageUIHandler implementation.
+ private:
+  // OptionsPageUIHandler
   virtual void GetLocalizedValues(
       base::DictionaryValue* localized_strings) OVERRIDE;
   virtual void InitializePage() OVERRIDE;
 
-  // WebUIMessageHandler implementation.
+  // WebUIMessageHandler (from OptionsPageUIHandler)
   virtual void RegisterMessages() OVERRIDE;
 
-  // NetworkLibrary::NetworkManagerObserver implementation.
-  virtual void OnNetworkManagerChanged(
-      chromeos::NetworkLibrary* network_lib) OVERRIDE;
-  // NetworkLibrary::NetworkObserver implementation.
-  virtual void OnNetworkChanged(chromeos::NetworkLibrary* network_lib,
-                                const chromeos::Network* network) OVERRIDE;
+  // Callbacks to set network state properties.
+  void EnableWifiCallback(const base::ListValue* args);
+  void DisableWifiCallback(const base::ListValue* args);
+  void EnableCellularCallback(const base::ListValue* args);
+  void DisableCellularCallback(const base::ListValue* args);
+  void EnableWimaxCallback(const base::ListValue* args);
+  void DisableWimaxCallback(const base::ListValue* args);
+  void ShowMorePlanInfoCallback(const base::ListValue* args);
+  void BuyDataPlanCallback(const base::ListValue* args);
+  void SetApnCallback(const base::ListValue* args);
+  void SetApnProperties(const base::ListValue* args,
+                        const std::string& service_path,
+                        const base::DictionaryValue& shill_properties);
+  void CarrierStatusCallback();
+  void SetCarrierCallback(const base::ListValue* args);
+  void SetSimCardLockCallback(const base::ListValue* args);
+  void ChangePinCallback(const base::ListValue* args);
+  void RefreshNetworksCallback(const base::ListValue* args);
 
-  // content::NotificationObserver implementation.
+  // Retrieves a data url for a resource.
+  std::string GetIconDataUrl(int resource_id) const;
+
+  // Refreshes the display of network information.
+  void RefreshNetworkData();
+
+  // Updates the display of network connection information for the details page
+  // if visible.
+  void UpdateConnectionData(const std::string& service_path);
+  void UpdateConnectionDataCallback(
+      const std::string& service_path,
+      const base::DictionaryValue& shill_properties);
+  // Called when carrier data has been updated to informs the JS.
+  void UpdateCarrier();
+
+  // NetworkStateHandlerObserver
+  virtual void NetworkManagerChanged() OVERRIDE;
+  virtual void NetworkListChanged() OVERRIDE;
+  virtual void NetworkPropertiesUpdated(
+      const chromeos::NetworkState* network) OVERRIDE;
+
+  // content::NotificationObserver (from OptionsPageUIHandler)
   virtual void Observe(int type,
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
- private:
-  // Opens a modal popup dialog.
-  void CreateModalPopup(views::WidgetDelegate* view);
+  // Additional callbacks to set network state properties.
+  void SetServerHostnameCallback(const base::ListValue* args);
+  void SetPreferNetworkCallback(const base::ListValue* args);
+  void SetAutoConnectCallback(const base::ListValue* args);
+  void SetIPConfigCallback(const base::ListValue* args);
+  void SetIPConfigProperties(const base::ListValue* args,
+                             const std::string& service_path,
+                             const base::DictionaryValue& shill_properties);
+
+  // Retrieves the properties for |service_path| and calls showDetailedInfo
+  // with the results.
+  void PopulateDictionaryDetailsCallback(
+      const std::string& service_path,
+      const base::DictionaryValue& shill_properties);
+
+  // Gets the native window for hosting dialogs, etc.
   gfx::NativeWindow GetNativeWindow() const;
 
   // Returns the last active browser. If there is no such browser, creates a new
@@ -67,97 +119,27 @@
 
   // Handle various network commands and clicks on a network item
   // in the network list.
-  // |args| has to be [ network_type, service_path, command ]
-  // and command is one of the strings
-  //  options, connect disconnect, activate, forget, add
+  // |args| must be { network_type, service_path, command } with 'command'
+  // one of: [ add, forget, options, connect disconnect, activate ]
   void NetworkCommandCallback(const base::ListValue* args);
 
   // Helper functions called by NetworkCommandCallback(...)
-  void AddConnection(chromeos::ConnectionType type);
-
-  void SetCellularButtonsVisibility(
-      const chromeos::CellularNetwork* cellular,
-      const chromeos::NetworkDevice* device,
-      base::DictionaryValue* dictionary,
-      const std::string& carrier_id);
-
-  void SetServerHostnameCallback(const base::ListValue* args);
-  void SetPreferNetworkCallback(const base::ListValue* args);
-  void SetAutoConnectCallback(const base::ListValue* args);
-  void SetSharedCallback(const base::ListValue* args);
-  void SetIPConfigCallback(const base::ListValue* args);
-  void EnableWifiCallback(const base::ListValue* args);
-  void DisableWifiCallback(const base::ListValue* args);
-  void EnableCellularCallback(const base::ListValue* args);
-  void DisableCellularCallback(const base::ListValue* args);
-  void EnableWimaxCallback(const base::ListValue* args);
-  void DisableWimaxCallback(const base::ListValue* args);
-  void BuyDataPlanCallback(const base::ListValue* args);
-  void SetApnCallback(const base::ListValue* args);
-  void SetCarrierCallback(const base::ListValue* args);
-  void SetSimCardLockCallback(const base::ListValue* args);
-  void ChangePinCallback(const base::ListValue* args);
-  void ShareNetworkCallback(const base::ListValue* args);
-  void ShowMorePlanInfoCallback(const base::ListValue* args);
-  void RefreshNetworksCallback(const base::ListValue* args);
-
-  // Populates the ui with the details of the given device path. This forces
-  // an overlay to be displayed in the UI. Called after the asynchronous
-  // request for Shill's service properties.
-  void PopulateDictionaryDetailsCallback(
-      const std::string& service_path,
-      const base::DictionaryValue* shill_properties);
-  void PopulateIPConfigsCallback(
-      const std::string& service_path,
-      const base::DictionaryValue* shill_properties,
-      const chromeos::NetworkIPConfigVector& ipconfigs,
-      const std::string& hardware_address);
-  void PopulateConnectionDetails(const chromeos::Network* network,
-                                 base::DictionaryValue* dictionary);
-  void PopulateWifiDetails(const chromeos::WifiNetwork* wifi,
-                           base::DictionaryValue* dictionary);
-  void PopulateWimaxDetails(const chromeos::WimaxNetwork* wimax,
-                            base::DictionaryValue* dictionary);
-  void PopulateCellularDetails(const chromeos::CellularNetwork* cellular,
-                               base::DictionaryValue* dictionary);
-
-  // Converts CellularApn stuct into dictionary for JS.
-  base::DictionaryValue* CreateDictionaryFromCellularApn(
-      const chromeos::CellularApn& apn);
+  void AddConnection(const std::string& type);
 
   // Creates the map of wired networks.
   base::ListValue* GetWiredList();
+
   // Creates the map of wireless networks.
   base::ListValue* GetWirelessList();
+
   // Creates the map of virtual networks.
   base::ListValue* GetVPNList();
+
   // Creates the map of remembered networks.
   base::ListValue* GetRememberedList();
+
   // Fills network information into JS dictionary for displaying network lists.
   void FillNetworkInfo(base::DictionaryValue* dictionary);
-  // Refreshes the display of network information.
-  void RefreshNetworkData();
-  // Updates the display of network connection information for the details page
-  // if it's up.
-  void UpdateConnectionData(const chromeos::Network* network);
-  // Updates the carrier change status.
-  void UpdateCarrier();
-  // Adds observers for wireless networks, if any, so that we can dynamically
-  // display the correct icon for that network's signal strength and, in the
-  // case of cellular networks, network technology and roaming status.
-  void MonitorNetworks();
-
-  // Callback for SetCarrier to notify once it's complete.
-  void CarrierStatusCallback(
-      const std::string& path,
-      chromeos::NetworkMethodErrorType error,
-      const std::string& error_message);
-
-  // Retrieves a data url for a resource.
-  std::string GetIconDataUrl(int resource_id) const;
-
-  // Convenience pointer to netwrok library (will not change).
-  chromeos::NetworkLibrary* cros_;
 
   content::NotificationRegistrar registrar_;
 
@@ -170,5 +152,6 @@
 };
 
 }  // namespace options
+}  // namespace chromeos
 
 #endif  // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_INTERNET_OPTIONS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/chromeos/user_image_source.cc b/chrome/browser/ui/webui/options/chromeos/user_image_source.cc
index 24140bd..47133ee 100644
--- a/chrome/browser/ui/webui/options/chromeos/user_image_source.cc
+++ b/chrome/browser/ui/webui/options/chromeos/user_image_source.cc
@@ -10,11 +10,11 @@
 #include "chrome/browser/chromeos/login/default_user_images.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/common/url_constants.h"
-#include "googleurl/src/url_parse.h"
 #include "grit/theme_resources.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/codec/png_codec.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/url_parse.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc
index d2530d0..248890b 100644
--- a/chrome/browser/ui/webui/options/content_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/content_settings_handler.cc
@@ -14,6 +14,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/content_settings_details.h"
 #include "chrome/browser/content_settings/content_settings_utils.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
@@ -26,7 +27,6 @@
 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_list.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/content_settings.h"
 #include "chrome/common/content_settings_pattern.h"
@@ -100,6 +100,7 @@
   {CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, "media-stream-mic"},
   {CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, "media-stream-camera"},
   {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, "ppapi-broker"},
+  {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, "multiple-automatic-downloads"},
 };
 
 ContentSettingsType ContentSettingsTypeFromGroupName(const std::string& name) {
@@ -380,6 +381,15 @@
     { "ppapi_broker_allow", IDS_PPAPI_BROKER_ALLOW_RADIO },
     { "ppapi_broker_ask", IDS_PPAPI_BROKER_ASK_RADIO },
     { "ppapi_broker_block", IDS_PPAPI_BROKER_BLOCK_RADIO },
+    // Multiple automatic downloads
+    { "multiple-automatic-downloads_header",
+      IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL },
+    { "multiple-automatic-downloads_allow",
+      IDS_AUTOMATIC_DOWNLOADS_ALLOW_RADIO },
+    { "multiple-automatic-downloads_ask",
+      IDS_AUTOMATIC_DOWNLOADS_ASK_RADIO },
+    { "multiple-automatic-downloads_block",
+      IDS_AUTOMATIC_DOWNLOADS_BLOCK_RADIO },
   };
 
   RegisterStrings(localized_strings, resources, arraysize(resources));
@@ -410,6 +420,8 @@
                 IDS_MEDIA_STREAM_TAB_LABEL);
   RegisterTitle(localized_strings, "ppapi-broker",
                 IDS_PPAPI_BROKER_TAB_LABEL);
+  RegisterTitle(localized_strings, "multiple-automatic-downloads",
+                IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL);
 
   localized_strings->SetBoolean("newContentSettings",
       CommandLine::ForCurrentProcess()->HasSwitch(switches::kContentSettings2));
@@ -705,6 +717,7 @@
     case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
+    case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
       break;
     default:
       UpdateExceptionsViewFromOTRHostContentSettingsMap(type);
@@ -1209,6 +1222,10 @@
       content::RecordAction(
           UserMetricsAction("Options_DefaultMediaStreamMicSettingChanged"));
       break;
+    case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
+      content::RecordAction(UserMetricsAction(
+          "Options_DefaultMultipleAutomaticDownloadsSettingChanged"));
+      break;
     default:
       break;
   }
diff --git a/chrome/browser/ui/webui/options/core_options_handler.cc b/chrome/browser/ui/webui/options/core_options_handler.cc
index e063533..5544b21 100644
--- a/chrome/browser/ui/webui/options/core_options_handler.cc
+++ b/chrome/browser/ui/webui/options/core_options_handler.cc
@@ -13,22 +13,22 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/net/url_fixer_upper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/options/options_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_ui.h"
-#include "googleurl/src/gurl.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/locale_settings.h"
 #include "grit/theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
 
 using content::UserMetricsAction;
 
diff --git a/chrome/browser/ui/webui/options/edit_dictionary_browsertest.js b/chrome/browser/ui/webui/options/edit_dictionary_browsertest.js
index ad8ce80..603bd5a 100644
--- a/chrome/browser/ui/webui/options/edit_dictionary_browsertest.js
+++ b/chrome/browser/ui/webui/options/edit_dictionary_browsertest.js
@@ -76,6 +76,18 @@
   expectEquals(3, EditDictionaryOverlay.getWordListForTesting().items.length);
 });
 
+TEST_F('EditDictionaryWebUITest', 'testNoCloseOnSearchEnter', function() {
+  var editDictionaryPage = EditDictionaryOverlay.getInstance();
+  assertTrue(editDictionaryPage.visible);
+  var searchField = $('language-dictionary-overlay-search-field');
+  searchField.dispatchEvent(new KeyboardEvent('keydown', {
+    'bubbles': true,
+    'cancelable': true,
+    'keyIdentifier': 'Enter'
+  }));
+  assertTrue(editDictionaryPage.visible);
+});
+
 // Verify that dictionary shows newly added words that arrived in a
 // notification, but ignores duplicate add notifications.
 TEST_F('EditDictionaryWebUITest', 'testAddNotification', function() {
diff --git a/chrome/browser/ui/webui/options/font_settings_handler.cc b/chrome/browser/ui/webui/options/font_settings_handler.cc
index 969c7a5..23f7d6a 100644
--- a/chrome/browser/ui/webui/options/font_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/font_settings_handler.cc
@@ -16,9 +16,9 @@
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/character_encoding.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/options/font_settings_utils.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/font_list_async.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/ui/webui/options/handler_options_handler.cc b/chrome/browser/ui/webui/options/handler_options_handler.cc
index 4a07f13..b5a0398 100644
--- a/chrome/browser/ui/webui/options/handler_options_handler.cc
+++ b/chrome/browser/ui/webui/options/handler_options_handler.cc
@@ -11,9 +11,9 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/web_ui.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/webui/options/import_data_handler.cc b/chrome/browser/ui/webui/options/import_data_handler.cc
index ccb0165..b456d25 100644
--- a/chrome/browser/ui/webui/options/import_data_handler.cc
+++ b/chrome/browser/ui/webui/options/import_data_handler.cc
@@ -18,8 +18,8 @@
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/importer/external_process_importer_host.h"
-#include "chrome/browser/importer/importer_creator.h"
 #include "chrome/browser/importer/importer_list.h"
+#include "chrome/browser/importer/importer_uma.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "content/public/browser/web_ui.h"
diff --git a/chrome/browser/ui/webui/options/manage_profile_handler.cc b/chrome/browser/ui/webui/options/manage_profile_handler.cc
index 94a0929..a338ccb 100644
--- a/chrome/browser/ui/webui/options/manage_profile_handler.cc
+++ b/chrome/browser/ui/webui/options/manage_profile_handler.cc
@@ -13,6 +13,8 @@
 #include "base/value_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/managed_mode/managed_user_service.h"
 #include "chrome/browser/profiles/gaia_info_update_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
@@ -23,7 +25,6 @@
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/ui/browser_finder.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
@@ -262,7 +263,7 @@
 
   Profile* profile =
       g_browser_process->profile_manager()->GetProfile(profile_file_path);
-  if (!profile)
+  if (!profile || ManagedUserService::ProfileIsManaged(profile))
     return;
 
   string16 new_profile_name;
diff --git a/chrome/browser/ui/webui/options/media_galleries_handler.cc b/chrome/browser/ui/webui/options/media_galleries_handler.cc
index c157a1b..5e23b40 100644
--- a/chrome/browser/ui/webui/options/media_galleries_handler.cc
+++ b/chrome/browser/ui/webui/options/media_galleries_handler.cc
@@ -8,12 +8,12 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/media_galleries/media_file_system_registry.h"
 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/storage_monitor/storage_monitor.h"
 #include "chrome/browser/ui/chrome_select_file_policy.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/webui/options/options_ui.cc b/chrome/browser/ui/webui/options/options_ui.cc
index 11a58b1..a56215f 100644
--- a/chrome/browser/ui/webui/options/options_ui.cc
+++ b/chrome/browser/ui/webui/options/options_ui.cc
@@ -296,7 +296,8 @@
                           new chromeos::options::DisplayOptionsHandler());
   AddOptionsPageUIHandler(localized_strings,
                           new chromeos::options::DisplayOverscanHandler());
-  AddOptionsPageUIHandler(localized_strings, new InternetOptionsHandler());
+  AddOptionsPageUIHandler(localized_strings,
+                          new chromeos::options::InternetOptionsHandler());
   AddOptionsPageUIHandler(localized_strings,
                           new chromeos::options::LanguageChewingHandler());
   AddOptionsPageUIHandler(localized_strings,
diff --git a/chrome/browser/ui/webui/options/password_manager_handler.cc b/chrome/browser/ui/webui/options/password_manager_handler.cc
index 93d4d08..3d30678 100644
--- a/chrome/browser/ui/webui/options/password_manager_handler.cc
+++ b/chrome/browser/ui/webui/options/password_manager_handler.cc
@@ -9,9 +9,9 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/notification_details.h"
diff --git a/chrome/browser/ui/webui/options/preferences_browsertest.cc b/chrome/browser/ui/webui/options/preferences_browsertest.cc
index da6b08d..6735944 100644
--- a/chrome/browser/ui/webui/options/preferences_browsertest.cc
+++ b/chrome/browser/ui/webui/options/preferences_browsertest.cc
@@ -7,18 +7,20 @@
 #include <iostream>
 #include <sstream>
 
+#include "base/callback.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/prefs/pref_service.h"
 #include "base/stl_util.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -28,9 +30,9 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "policy/policy_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 #if defined(OS_CHROMEOS)
 #include "base/strings/stringprintf.h"
@@ -198,8 +200,10 @@
     const std::vector<base::Value*>& values,
     policy::PolicyLevel level) {
   policy::PolicyMap map;
-  for (size_t i = 0; i < names.size(); ++i)
-    map.Set(names[i], level, policy::POLICY_SCOPE_USER, values[i]->DeepCopy());
+  for (size_t i = 0; i < names.size(); ++i) {
+    map.Set(names[i], level, policy::POLICY_SCOPE_USER,
+            values[i]->DeepCopy(), NULL);
+  }
   policy_provider_.UpdateChromePolicy(map);
 }
 
diff --git a/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc b/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc
index 32012fc..f28ec88 100644
--- a/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc
@@ -10,16 +10,19 @@
 #include "base/strings/string16.h"
 #include "base/values.h"
 #include "chrome/browser/google/google_util.h"
+#include "chrome/browser/profile_resetter/brandcode_config_fetcher.h"
+#include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
 #include "chrome/browser/profile_resetter/profile_resetter.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
+#include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_ui.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
 namespace {
 const char kResetProfileSettingsLearnMoreUrl[] =
-    "https://support.google.com/chrome/?p=settings_reset_profile_settings";
+    "https://support.google.com/chrome/?p=ui_reset_settings";
 }  // namespace
 
 namespace options {
@@ -41,6 +44,7 @@
 
   static OptionsStringResource resources[] = {
     { "resetProfileSettingsCommit", IDS_RESET_PROFILE_SETTINGS_COMMIT_BUTTON },
+    { "resetProfileSettingsExplanation", IDS_RESET_PROFILE_SETTINGS_EXPLANATION}
   };
 
   RegisterStrings(localized_strings, resources, arraysize(resources));
@@ -57,21 +61,60 @@
   web_ui()->RegisterMessageCallback("performResetProfileSettings",
       base::Bind(&ResetProfileSettingsHandler::HandleResetProfileSettings,
                  base::Unretained(this)));
+  web_ui()->RegisterMessageCallback("onShowResetProfileDialog",
+      base::Bind(&ResetProfileSettingsHandler::OnShowResetProfileDialog,
+                 base::Unretained(this)));
 }
 
 void ResetProfileSettingsHandler::HandleResetProfileSettings(
     const ListValue* /*value*/) {
-  DCHECK(resetter_);
-  DCHECK(!resetter_->IsActive());
-
-  resetter_->Reset(
-      ProfileResetter::ALL,
-      base::Bind(&ResetProfileSettingsHandler::OnResetProfileSettingsDone,
-                 AsWeakPtr()));
+  DCHECK(config_fetcher_);
+  if (config_fetcher_->IsActive()) {
+    // Reset once the prefs are fetched.
+    config_fetcher_->SetCallback(
+        base::Bind(&ResetProfileSettingsHandler::ResetProfile,
+                   Unretained(this)));
+  } else {
+    ResetProfile();
+  }
 }
 
 void ResetProfileSettingsHandler::OnResetProfileSettingsDone() {
   web_ui()->CallJavascriptFunction("ResetProfileSettingsOverlay.doneResetting");
 }
 
+void ResetProfileSettingsHandler::OnShowResetProfileDialog(const ListValue*) {
+  // TODO(vasilii): use a real request.
+  config_fetcher_.reset(new BrandcodeConfigFetcher(
+      base::Bind(&ResetProfileSettingsHandler::OnSettingsFetched,
+                 Unretained(this)),
+      GURL("https://tools.google.com/service/update2")));
+}
+
+void ResetProfileSettingsHandler::OnSettingsFetched() {
+  DCHECK(config_fetcher_);
+  DCHECK(!config_fetcher_->IsActive());
+  // The master prefs is fetched. We are waiting for user pressing 'Reset'.
+}
+
+void ResetProfileSettingsHandler::ResetProfile() {
+  DCHECK(resetter_);
+  DCHECK(!resetter_->IsActive());
+  DCHECK(config_fetcher_);
+  DCHECK(!config_fetcher_->IsActive());
+
+  scoped_ptr<BrandcodedDefaultSettings> default_settings =
+      config_fetcher_->GetSettings();
+  config_fetcher_.reset();
+  // If we failed to fetch BrandcodedDefaultSettings, use default settings.
+  if (!default_settings)
+    default_settings.reset(new BrandcodedDefaultSettings);
+  resetter_->Reset(
+      ProfileResetter::ALL,
+      default_settings.Pass(),
+      base::Bind(&ResetProfileSettingsHandler::OnResetProfileSettingsDone,
+                 AsWeakPtr()));
+  content::RecordAction(content::UserMetricsAction("ResetProfile"));
+}
+
 }  // namespace options
diff --git a/chrome/browser/ui/webui/options/reset_profile_settings_handler.h b/chrome/browser/ui/webui/options/reset_profile_settings_handler.h
index 3375fdf..999b023 100644
--- a/chrome/browser/ui/webui/options/reset_profile_settings_handler.h
+++ b/chrome/browser/ui/webui/options/reset_profile_settings_handler.h
@@ -14,6 +14,7 @@
 class ListValue;
 }  // namespace base
 
+class BrandcodeConfigFetcher;
 class ProfileResetter;
 
 namespace options {
@@ -41,8 +42,18 @@
   // Closes the dialog once all requested settings has been reset.
   void OnResetProfileSettingsDone();
 
+  // Called when the confirmation box appears.
+  void OnShowResetProfileDialog(const base::ListValue* value);
+
+  // Called when BrandcodeConfigFetcher completed fetching settings.
+  void OnSettingsFetched();
+
+  void ResetProfile();
+
   scoped_ptr<ProfileResetter> resetter_;
 
+  scoped_ptr<BrandcodeConfigFetcher> config_fetcher_;
+
   DISALLOW_COPY_AND_ASSIGN(ResetProfileSettingsHandler);
 };
 
diff --git a/chrome/browser/ui/webui/options/startup_pages_handler.cc b/chrome/browser/ui/webui/options/startup_pages_handler.cc
index 02d3a85..127cfad 100644
--- a/chrome/browser/ui/webui/options/startup_pages_handler.cc
+++ b/chrome/browser/ui/webui/options/startup_pages_handler.cc
@@ -11,11 +11,11 @@
 #include "chrome/browser/autocomplete/autocomplete_controller.h"
 #include "chrome/browser/autocomplete/autocomplete_input.h"
 #include "chrome/browser/autocomplete/autocomplete_result.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/custom_home_pages_table_model.h"
 #include "chrome/browser/net/url_fixer_upper.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/web_ui.h"
diff --git a/chrome/browser/ui/webui/plugins_ui.cc b/chrome/browser/ui/webui/plugins_ui.cc
index da7cc9f..4ddd8a9 100644
--- a/chrome/browser/ui/webui/plugins_ui.cc
+++ b/chrome/browser/ui/webui/plugins_ui.cc
@@ -20,6 +20,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/plugins/plugin_finder.h"
 #include "chrome/browser/plugins/plugin_metadata.h"
@@ -29,7 +30,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/common/chrome_content_client.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -491,7 +491,8 @@
 }
 
 // static
-void PluginsUI::RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
+void PluginsUI::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(
       prefs::kPluginsShowDetails,
       false,
diff --git a/chrome/browser/ui/webui/plugins_ui.h b/chrome/browser/ui/webui/plugins_ui.h
index a335b80..d97e5d3 100644
--- a/chrome/browser/ui/webui/plugins_ui.h
+++ b/chrome/browser/ui/webui/plugins_ui.h
@@ -22,7 +22,7 @@
 
   static base::RefCountedMemory* GetFaviconResourceBytes(
       ui::ScaleFactor scale_factor);
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(PluginsUI);
diff --git a/chrome/browser/ui/webui/policy_ui.cc b/chrome/browser/ui/webui/policy_ui.cc
index 3b3f1ea..c1c5fc4 100644
--- a/chrome/browser/ui/webui/policy_ui.cc
+++ b/chrome/browser/ui/webui/policy_ui.cc
@@ -15,6 +15,7 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
 #include "chrome/browser/policy/cloud/cloud_policy_client.h"
 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
@@ -32,7 +33,6 @@
 #include "chrome/browser/policy/profile_policy_connector_factory.h"
 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/time_format.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/notification_observer.h"
@@ -62,11 +62,11 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/policy/policy_domain_descriptor.h"
-#include "chrome/browser/policy/policy_schema.h"
 #include "chrome/common/extensions/extension.h"
 #include "chrome/common/extensions/extension_manifest_constants.h"
 #include "chrome/common/extensions/extension_set.h"
 #include "chrome/common/extensions/manifest.h"
+#include "chrome/common/policy/policy_schema.h"
 #endif
 
 namespace em = enterprise_management;
diff --git a/chrome/browser/ui/webui/policy_ui_browsertest.cc b/chrome/browser/ui/webui/policy_ui_browsertest.cc
index 2d8193f..4db7a9f 100644
--- a/chrome/browser/ui/webui/policy_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/policy_ui_browsertest.cc
@@ -4,10 +4,12 @@
 
 #include <vector>
 
+#include "base/callback.h"
 #include "base/json/json_reader.h"
 #include "base/run_loop.h"
 #include "base/values.h"
 #include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/external_data_fetcher.h"
 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
 #include "chrome/browser/policy/policy_map.h"
 #include "chrome/browser/policy/policy_types.h"
@@ -17,12 +19,12 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "policy/policy_constants.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
 
 using testing::AnyNumber;
 using testing::Return;
@@ -202,29 +204,34 @@
   values.Set(policy::key::kRestoreOnStartupURLs,
              policy::POLICY_LEVEL_MANDATORY,
              policy::POLICY_SCOPE_USER,
-             restore_on_startup_urls);
+             restore_on_startup_urls,
+             NULL);
   expected_values[policy::key::kRestoreOnStartupURLs] = "aaa,bbb,ccc";
   values.Set(policy::key::kHomepageLocation,
              policy::POLICY_LEVEL_MANDATORY,
              policy::POLICY_SCOPE_MACHINE,
-             base::Value::CreateStringValue("http://google.com"));
+             base::Value::CreateStringValue("http://google.com"),
+             NULL);
   expected_values[policy::key::kHomepageLocation] = "http://google.com";
   values.Set(policy::key::kRestoreOnStartup,
              policy::POLICY_LEVEL_RECOMMENDED,
              policy::POLICY_SCOPE_USER,
-             base::Value::CreateIntegerValue(4));
+             base::Value::CreateIntegerValue(4),
+             NULL);
   expected_values[policy::key::kRestoreOnStartup] = "4";
   values.Set(policy::key::kShowHomeButton,
              policy::POLICY_LEVEL_RECOMMENDED,
              policy::POLICY_SCOPE_MACHINE,
-             base::Value::CreateBooleanValue(true));
+             base::Value::CreateBooleanValue(true),
+             NULL);
   expected_values[policy::key::kShowHomeButton] = "true";
   // Set the value of a policy that does not exist.
   const std::string kUnknownPolicy = "NoSuchThing";
   values.Set(kUnknownPolicy,
              policy::POLICY_LEVEL_MANDATORY,
              policy::POLICY_SCOPE_USER,
-             base::Value::CreateBooleanValue(true));
+             base::Value::CreateBooleanValue(true),
+             NULL);
   expected_values[kUnknownPolicy] = "true";
   UpdateProviderPolicy(values);
 
diff --git a/chrome/browser/ui/webui/print_preview/sticky_settings.cc b/chrome/browser/ui/webui/print_preview/sticky_settings.cc
index e01da40..626413b 100644
--- a/chrome/browser/ui/webui/print_preview/sticky_settings.cc
+++ b/chrome/browser/ui/webui/print_preview/sticky_settings.cc
@@ -59,7 +59,7 @@
   }
 }
 
-void StickySettings::RegisterUserPrefs(
+void StickySettings::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterDictionaryPref(
       prefs::kPrintPreviewStickySettings,
diff --git a/chrome/browser/ui/webui/print_preview/sticky_settings.h b/chrome/browser/ui/webui/print_preview/sticky_settings.h
index 4864d6c..cdde642 100644
--- a/chrome/browser/ui/webui/print_preview/sticky_settings.h
+++ b/chrome/browser/ui/webui/print_preview/sticky_settings.h
@@ -43,7 +43,7 @@
 
   void SaveInPrefs(PrefService* profile);
   void RestoreFromPrefs(PrefService* profile);
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  private:
 
diff --git a/chrome/browser/ui/webui/quota_internals/quota_internals_types.h b/chrome/browser/ui/webui/quota_internals/quota_internals_types.h
index a559782..0c70a45 100644
--- a/chrome/browser/ui/webui/quota_internals/quota_internals_types.h
+++ b/chrome/browser/ui/webui/quota_internals/quota_internals_types.h
@@ -9,7 +9,7 @@
 #include <string>
 
 #include "base/time/time.h"
-#include "googleurl/src/gurl.h"
+#include "url/gurl.h"
 #include "webkit/common/quota/quota_types.h"
 
 namespace base {
diff --git a/chrome/browser/ui/webui/screenshot_source.cc b/chrome/browser/ui/webui/screenshot_source.cc
index f416fc7..7a8cf20 100644
--- a/chrome/browser/ui/webui/screenshot_source.cc
+++ b/chrome/browser/ui/webui/screenshot_source.cc
@@ -23,8 +23,8 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
-#include "googleurl/src/url_canon.h"
-#include "googleurl/src/url_util.h"
+#include "url/url_canon.h"
+#include "url/url_util.h"
 
 #if defined(USE_ASH)
 #include "ash/shell.h"
@@ -184,7 +184,7 @@
     using content::BrowserThread;
 
     std::string filename =
-                       path.substr(strlen(ScreenshotSource::kScreenshotSaved));
+        path.substr(strlen(ScreenshotSource::kScreenshotSaved));
 
     url_canon::RawCanonOutputT<char16> decoded;
     url_util::DecodeURLEscapeSequences(
@@ -199,12 +199,10 @@
       drive::FileSystemInterface* file_system =
           drive::DriveIntegrationServiceFactory::GetForProfile(
               profile_)->file_system();
-      file_system->GetFileByResourceId(
-          decoded_filename,
-          drive::ClientContext(drive::USER_INITIATED),
+      file_system->GetFileByPath(
+          drive::util::ExtractDrivePath(download_path).Append(decoded_filename),
           base::Bind(&ScreenshotSource::GetSavedScreenshotCallback,
-                     base::Unretained(this), screenshot_path, callback),
-          google_apis::GetContentCallback());
+                     base::Unretained(this), screenshot_path, callback));
     } else {
       BrowserThread::PostTask(
           BrowserThread::FILE, FROM_HERE,
diff --git a/chrome/browser/ui/webui/sync_file_system_internals/file_metadata_handler.cc b/chrome/browser/ui/webui/sync_file_system_internals/file_metadata_handler.cc
index 42025bf..9cefc36 100644
--- a/chrome/browser/ui/webui/sync_file_system_internals/file_metadata_handler.cc
+++ b/chrome/browser/ui/webui/sync_file_system_internals/file_metadata_handler.cc
@@ -11,7 +11,6 @@
 #include "base/values.h"
 #include "chrome/browser/extensions/api/sync_file_system/sync_file_system_api_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync_file_system/file_metadata.h"
 #include "chrome/browser/sync_file_system/sync_file_system_service.h"
 #include "chrome/browser/sync_file_system/sync_file_system_service_factory.h"
 #include "chrome/browser/ui/webui/sync_file_system_internals/extension_statuses_handler.h"
@@ -20,29 +19,12 @@
 #include "content/public/browser/web_ui_data_source.h"
 #include "grit/sync_file_system_internals_resources.h"
 
-using sync_file_system::FileMetadata;
 using sync_file_system::RemoteFileSyncService;
 using sync_file_system::SyncFileSystemServiceFactory;
 using sync_file_system::SyncServiceState;
 
 namespace syncfs_internals {
 
-namespace {
-
-std::string FileTypeToString(sync_file_system::FileType type) {
-  switch (type) {
-    case sync_file_system::TYPE_FILE:
-      return "File";
-    case sync_file_system::TYPE_FOLDER:
-      return "Folder";
-  }
-
-  NOTREACHED() << "Unknown FileType: " << type;
-  return "Unknown";
-}
-
-}  // namespace
-
 FileMetadataHandler::FileMetadataHandler(Profile* profile)
     : profile_(profile),
       weak_factory_(this) {}
@@ -74,16 +56,10 @@
       extension_id);
 
   // Get all metadata for the one specific origin.
-  FileMetadataMap* metadata_map = new FileMetadataMap;
-  size_t* num_results = new size_t(0);
-  SyncFileSystemServiceFactory::GetForProfile(profile_)->GetFileMetadataMap(
+  SyncFileSystemServiceFactory::GetForProfile(profile_)->DumpFiles(
       origin,
-      metadata_map,
-      num_results,
       base::Bind(&FileMetadataHandler::DidGetFileMetadata,
-                 weak_factory_.GetWeakPtr(),
-                 base::Owned(metadata_map),
-                 base::Owned(num_results)));
+                 weak_factory_.GetWeakPtr()));
 }
 
 void FileMetadataHandler::GetExtensions(const base::ListValue* args) {
@@ -93,37 +69,9 @@
   web_ui()->CallJavascriptFunction("FileMetadata.onGetExtensions", list);
 }
 
-// TODO(calvinlo): This would probably be better if there was a drop down UI
-// box to pick one origin at a time. Then this function would only print
-// files for one origin.
-void FileMetadataHandler::DidGetFileMetadata(
-    FileMetadataMap* metadata_map,
-    size_t* num_results,
-    sync_file_system::SyncStatusCode status) {
-  DCHECK(metadata_map);
-  DCHECK(num_results);
-
-  // Flatten map hierarchy in initial version.
-  base::ListValue list;
-  RemoteFileSyncService::FileMetadataMap::const_iterator file_path_itr;
-  for (file_path_itr = metadata_map->begin();
-       file_path_itr != metadata_map->end();
-       ++file_path_itr) {
-    const FileMetadata& metadata_object = file_path_itr->second;
-    std::string status_string = extensions::api::sync_file_system::ToString(
-          extensions::SyncFileStatusToExtensionEnum(
-              metadata_object.sync_status));
-
-    // Convert each file metadata object into primitives for rendering.
-    base::DictionaryValue* dict = new DictionaryValue;
-    dict->SetString("status", status_string);
-    dict->SetString("type", FileTypeToString(metadata_object.type));
-    dict->SetString("title", metadata_object.title);
-    dict->SetString("details", metadata_object.service_specific_metadata);
-    list.Append(dict);
-  }
-
-  web_ui()->CallJavascriptFunction("FileMetadata.onGetFileMetadata", list);
+void FileMetadataHandler::DidGetFileMetadata(const base::ListValue* files) {
+  DCHECK(files);
+  web_ui()->CallJavascriptFunction("FileMetadata.onGetFileMetadata", *files);
 }
 
 }  // namespace syncfs_internals
diff --git a/chrome/browser/ui/webui/sync_file_system_internals/file_metadata_handler.h b/chrome/browser/ui/webui/sync_file_system_internals/file_metadata_handler.h
index 64a8152..9b63730 100644
--- a/chrome/browser/ui/webui/sync_file_system_internals/file_metadata_handler.h
+++ b/chrome/browser/ui/webui/sync_file_system_internals/file_metadata_handler.h
@@ -31,13 +31,8 @@
  private:
   void GetExtensions(const base::ListValue* args);
 
-  typedef sync_file_system::RemoteFileSyncService::FileMetadataMap
-      FileMetadataMap;
   void GetFileMetadata(const base::ListValue* args);
-  void DidGetFileMetadata(
-      FileMetadataMap* metadata_map,
-      size_t* num_results,
-      sync_file_system::SyncStatusCode status);
+  void DidGetFileMetadata(const base::ListValue* files);
 
   Profile* profile_;
   base::WeakPtrFactory<FileMetadataHandler> weak_factory_;
diff --git a/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc b/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc
index 1890731..6134efa 100644
--- a/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc
+++ b/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc
@@ -27,8 +27,7 @@
 namespace syncfs_internals {
 
 SyncFileSystemInternalsHandler::SyncFileSystemInternalsHandler(Profile* profile)
-    : profile_(profile),
-      last_log_id_sent_(-1) {
+    : profile_(profile) {
   sync_file_system::SyncFileSystemService* sync_service =
       SyncFileSystemServiceFactory::GetForProfile(profile);
   DCHECK(sync_service);
@@ -103,20 +102,25 @@
   const std::vector<EventLogger::Event> log =
       sync_file_system::util::GetLogHistory();
 
+  int last_log_id_sent;
+  if (!args->GetInteger(0, &last_log_id_sent))
+    last_log_id_sent = -1;
+
   // Collate events which haven't been sent to WebUI yet.
   base::ListValue list;
   for (std::vector<EventLogger::Event>::const_iterator log_entry = log.begin();
        log_entry != log.end();
        ++log_entry) {
-    if (log_entry->id <= last_log_id_sent_)
+    if (log_entry->id <= last_log_id_sent)
       continue;
 
     base::DictionaryValue* dict = new DictionaryValue;
+    dict->SetInteger("id", log_entry->id);
     dict->SetString("time",
         google_apis::util::FormatTimeAsStringLocaltime(log_entry->when));
     dict->SetString("logEvent", log_entry->what);
     list.Append(dict);
-    last_log_id_sent_ = log_entry->id;
+    last_log_id_sent = log_entry->id;
   }
   if (list.empty())
     return;
diff --git a/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.h b/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.h
index e1b94cf..e3a140d 100644
--- a/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.h
+++ b/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.h
@@ -45,9 +45,6 @@
 
   Profile* profile_;
 
-  // The last log ID sent to the JavaScript side.
-  int last_log_id_sent_;
-
   DISALLOW_COPY_AND_ASSIGN(SyncFileSystemInternalsHandler);
 };
 
diff --git a/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_ui.cc b/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_ui.cc
index 0ea597e..b72054a 100644
--- a/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_ui.cc
+++ b/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_ui.cc
@@ -12,6 +12,7 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "grit/sync_file_system_internals_resources.h"
+#include "ui/ui_resources/grit/ui_resources.h"
 
 namespace {
 
@@ -27,6 +28,8 @@
       "file_metadata.js", IDR_SYNC_FILE_SYSTEM_INTERNALS_FILE_METADATA_JS);
   source->AddResourcePath(
       "sync_service.js", IDR_SYNC_FILE_SYSTEM_INTERNALS_SYNC_SERVICE_JS);
+  source->AddResourcePath("file.png", IDR_DEFAULT_FAVICON);
+  source->AddResourcePath("folder_closed.png", IDR_FOLDER_CLOSED);
   source->SetDefaultResource(IDR_SYNC_FILE_SYSTEM_INTERNALS_MAIN_HTML);
   return source;
 }
diff --git a/chrome/browser/ui/webui/sync_setup_browsertest.js b/chrome/browser/ui/webui/sync_setup_browsertest.js
index d4967a7..91e3d84 100644
--- a/chrome/browser/ui/webui/sync_setup_browsertest.js
+++ b/chrome/browser/ui/webui/sync_setup_browsertest.js
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+GEN('#if !defined(OS_CHROMEOS)');
+
 /**
  * Test fixture for sync setup WebUI testing.
  * @constructor
@@ -13,20 +15,15 @@
   __proto__: testing.Test.prototype,
 
   /**
-   * Browse to settings.
+   * Browse to the settings sub-frame.
    */
   browsePreload: 'chrome://settings-frame',
 
   /** @inheritDoc */
   preLoad: function() {
-    this.makeAndRegisterMockHandler(['stopSyncing',
-                                     'SyncSetupDidClosePage',
-                                     'SyncSetupSubmitAuth',
-                                     'SyncSetupConfigure',
-                                     'SyncSetupPassphrase',
-                                     'SyncSetupPassphraseCancel',
-                                     'SyncSetupShowErrorUI',
+    this.makeAndRegisterMockHandler(['SyncSetupDidClosePage',
                                      'SyncSetupShowSetupUI',
+                                     'SyncSetupStartSignIn',
                                     ]);
   },
 
@@ -34,6 +31,8 @@
    * Verifies starting point is not synced.
    */
   verifyUnsynced: function() {
+    assertFalse(BrowserOptions.getInstance().setupCompleted_);
+    assertFalse(BrowserOptions.getInstance().signedIn_);
   },
 
   /**
@@ -42,20 +41,6 @@
   startSyncing: function() {
     var startStopSyncButton = BrowserOptions.getStartStopSyncButton();
     assertNotEquals(null, startStopSyncButton);
-    this.mockHandler.expects(once()).SyncSetupShowSetupUI().
-        will(callFunction(function() {
-                            OptionsPage.navigateToPage('syncSetup');
-                          }));
-
-    this.mockHandler.expects(once()).SyncSetupShowSetupUI().
-        will(callFunction(function() {
-                            SyncSetupOverlay.showSyncSetupPage(
-                                'login', {
-                                  user: '',
-                                  error: 0,
-                                  editable_user: true,
-                                });
-                          }));
     startStopSyncButton.click();
   },
 };
@@ -74,20 +59,32 @@
   isAsync: true,
 };
 
-// Verify that initial state is unsynced, start syncing, then login.
-// TODO(estade): this doesn't work. DidShowPage is called multiple times.
-TEST_F('SyncSetupWebUITestAsync', 'DISABLED_VerifySignIn', function() {
-  // Start syncing to pull up the sign in page.
-  assertFalse(BrowserOptions.getInstance().syncSetupCompleted);
-  this.startSyncing();
+// Verify that initial state is unsynced, click the sign in button, verify
+// that the sync setup dialog appears, and dismiss it.
+TEST_F('SyncSetupWebUITestAsync', 'VerifySignIn', function() {
+  // Make sure the user is not starting off in the signed in or syncing state.
+  this.verifyUnsynced();
 
-  // Verify the DOM objects on the page.
-  var gaiaEmail = SyncSetupOverlay.getLoginEmail();
-  assertNotEquals(null, gaiaEmail);
-  var gaiaPasswd = SyncSetupOverlay.getLoginPasswd();
-  assertNotEquals(null, gaiaPasswd);
-  var signInButton = SyncSetupOverlay.getSignInButton();
-  assertNotEquals(null, signInButton);
+  // Handle SyncSetupShowSetupUI by navigating to chrome://settings/syncSetup.
+  this.mockHandler.expects(once()).SyncSetupShowSetupUI().
+      will(callFunction(function() {
+                          OptionsPage.navigateToPage('syncSetup');
+                        }));
+
+  // Handle SyncSetupStartSignIn by displaying the sync setup dialog, verifying
+  // that a confirmation dialog appears, and clicking OK to dismiss the dialog.
+  // Note that this test doesn't actually do a gaia sign in.
+  this.mockHandler.expects(once()).SyncSetupStartSignIn().
+      will(callFunction(function() {
+                          SyncSetupOverlay.showSyncSetupPage('configure');
+                          var okButton = $('confirm-everything-ok');
+                          assertNotEquals(null, okButton);
+                          okButton.click();
+                        }));
+
+  // The test completes after the asynchronous close.
+  this.mockHandler.expects(once()).SyncSetupDidClosePage().
+      will(callFunction(testDone));
 
   // For testing, don't wait to execute timeouts.
   var oldSetTimeout = setTimeout;
@@ -95,21 +92,8 @@
     oldSetTimeout(fn, 0);
   };
 
-  // Expect set up submission and close messages sent through chrome.send().
-  this.mockHandler.expects(once()).SyncSetupSubmitAuth(NOT_NULL).
-      will(callFunction(
-          function() {
-            var loginSuccess = localStrings.getString('loginSuccess');
-            expectNotEquals(loginSuccess, signInButton.value);
-            SyncSetupOverlay.showSuccessAndClose();
-            expectEquals(loginSuccess, signInButton.value);
-          }));
-  // The test completes after the asynchronous close.
-  this.mockHandler.expects(once()).SyncSetupDidClosePage().
-      will(callFunction(testDone));
-
-  // Set the email & password, then sign in.
-  gaiaEmail.value = 'foo@bar.baz';
-  gaiaPasswd.value = 'foo@bar.baz';
-  signInButton.click();
+  // Kick off the test by clicking the "Sign in to Chrome..." button.
+  this.startSyncing();
 });
+
+GEN('#endif  // OS_CHROMEOS');
diff --git a/chrome/browser/ui/webui/sync_setup_handler.cc b/chrome/browser/ui/webui/sync_setup_handler.cc
index 11085ea..eab551e 100644
--- a/chrome/browser/ui/webui/sync_setup_handler.cc
+++ b/chrome/browser/ui/webui/sync_setup_handler.cc
@@ -204,10 +204,6 @@
   return true;
 }
 
-bool IsKeystoreEncryptionEnabled() {
-  return true;
-}
-
 }  // namespace
 
 SyncSetupHandler::SyncSetupHandler(ProfileManager* profile_manager)
@@ -248,9 +244,6 @@
   localized_strings->SetString(
       "encryptionHelpURL", chrome::kSyncEncryptionHelpURL);
   localized_strings->SetString(
-      "passphraseEncryptionMessage",
-      GetStringFUTF16(IDS_SYNC_PASSPHRASE_ENCRYPTION_MESSAGE, product_name));
-  localized_strings->SetString(
       "encryptionSectionMessage",
       GetStringFUTF16(IDS_SYNC_ENCRYPTION_SECTION_MESSAGE, product_name));
   localized_strings->SetString(
@@ -297,21 +290,13 @@
     { "openTabs", IDS_SYNC_DATATYPE_TABS },
     { "syncZeroDataTypesError", IDS_SYNC_ZERO_DATA_TYPES_ERROR },
     { "serviceUnavailableError", IDS_SYNC_SETUP_ABORTED_BY_PENDING_CLEAR },
-    { "googleOption", IDS_SYNC_PASSPHRASE_OPT_GOOGLE },
-    { "explicitOption", IDS_SYNC_PASSPHRASE_OPT_EXPLICIT },
-    { "sectionGoogleMessage", IDS_SYNC_PASSPHRASE_MSG_GOOGLE },
-    { "sectionExplicitMessage", IDS_SYNC_PASSPHRASE_MSG_EXPLICIT },
-    { "passphraseLabel", IDS_SYNC_PASSPHRASE_LABEL },
     { "confirmLabel", IDS_SYNC_CONFIRM_PASSPHRASE_LABEL },
     { "emptyErrorMessage", IDS_SYNC_EMPTY_PASSPHRASE_ERROR },
     { "mismatchErrorMessage", IDS_SYNC_PASSPHRASE_MISMATCH_ERROR },
-    { "passphraseWarning", IDS_SYNC_PASSPHRASE_WARNING },
     { "customizeLinkLabel", IDS_SYNC_CUSTOMIZE_LINK_LABEL },
     { "confirmSyncPreferences", IDS_SYNC_CONFIRM_SYNC_PREFERENCES },
     { "syncEverything", IDS_SYNC_SYNC_EVERYTHING },
     { "useDefaultSettings", IDS_SYNC_USE_DEFAULT_SETTINGS },
-    { "passphraseSectionTitle", IDS_SYNC_PASSPHRASE_SECTION_TITLE },
-    { "enterPassphraseTitle", IDS_SYNC_ENTER_PASSPHRASE_TITLE },
     { "enterPassphraseBody", IDS_SYNC_ENTER_PASSPHRASE_BODY },
     { "enterGooglePassphraseBody", IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY },
     { "passphraseLabel", IDS_SYNC_PASSPHRASE_LABEL },
@@ -322,9 +307,6 @@
     { "sectionExplicitMessagePrefix", IDS_SYNC_PASSPHRASE_MSG_EXPLICIT_PREFIX },
     { "sectionExplicitMessagePostfix",
         IDS_SYNC_PASSPHRASE_MSG_EXPLICIT_POSTFIX },
-    { "encryptedDataTypesTitle", IDS_SYNC_ENCRYPTION_DATA_TYPES_TITLE },
-    { "encryptSensitiveOption", IDS_SYNC_ENCRYPT_SENSITIVE_DATA },
-    { "encryptAllOption", IDS_SYNC_ENCRYPT_ALL_DATA },
     // TODO(rogerta): browser/resource/sync_promo/sync_promo.html and related
     // file may not be needed any more.  If not, then the following promo
     // strings can also be removed.
@@ -421,59 +403,50 @@
   // IsPassphraseRequiredForDecryption(), because we want to show the passphrase
   // UI even if no encrypted data types are enabled.
   args.SetBoolean("showPassphrase", service->IsPassphraseRequired());
-  // Keystore encryption is behind a flag. Only show the new encryption settings
-  // if keystore encryption is enabled.
-  args.SetBoolean("keystoreEncryptionEnabled", IsKeystoreEncryptionEnabled());
 
-  // Set the proper encryption settings messages if keystore encryption is
-  // enabled.
-  if (IsKeystoreEncryptionEnabled()) {
-    // To distinguish between FROZEN_IMPLICIT_PASSPHRASE and CUSTOM_PASSPHRASE
-    // we only set usePassphrase for CUSTOM_PASSPHRASE.
-    args.SetBoolean("usePassphrase",
-                    service->GetPassphraseType() == syncer::CUSTOM_PASSPHRASE);
-    base::Time passphrase_time = service->GetExplicitPassphraseTime();
-    syncer::PassphraseType passphrase_type = service->GetPassphraseType();
-    if (!passphrase_time.is_null()) {
-      string16 passphrase_time_str = base::TimeFormatShortDate(passphrase_time);
-      args.SetString(
-          "enterPassphraseBody",
-          GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE,
-                          passphrase_time_str));
-      args.SetString(
-          "enterGooglePassphraseBody",
-          GetStringFUTF16(IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE,
-                          passphrase_time_str));
-      switch (passphrase_type) {
-        case syncer::FROZEN_IMPLICIT_PASSPHRASE:
-          args.SetString(
-              "fullEncryptionBody",
-              GetStringFUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_GOOGLE_WITH_DATE,
-                              passphrase_time_str));
-          break;
-        case syncer::CUSTOM_PASSPHRASE:
-          args.SetString(
-              "fullEncryptionBody",
-              GetStringFUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM_WITH_DATE,
-                              passphrase_time_str));
-          break;
-        default:
-          args.SetString(
-              "fullEncryptionBody",
-              GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM));
-          break;
-      }
-    } else if (passphrase_type == syncer::CUSTOM_PASSPHRASE) {
-      args.SetString(
-          "fullEncryptionBody",
-          GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM));
-    } else {
-      args.SetString(
-          "fullEncryptionBody",
-          GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_DATA));
+  // To distinguish between FROZEN_IMPLICIT_PASSPHRASE and CUSTOM_PASSPHRASE
+  // we only set usePassphrase for CUSTOM_PASSPHRASE.
+  args.SetBoolean("usePassphrase",
+                  service->GetPassphraseType() == syncer::CUSTOM_PASSPHRASE);
+  base::Time passphrase_time = service->GetExplicitPassphraseTime();
+  syncer::PassphraseType passphrase_type = service->GetPassphraseType();
+  if (!passphrase_time.is_null()) {
+    string16 passphrase_time_str = base::TimeFormatShortDate(passphrase_time);
+    args.SetString(
+        "enterPassphraseBody",
+        GetStringFUTF16(IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE,
+                        passphrase_time_str));
+    args.SetString(
+        "enterGooglePassphraseBody",
+        GetStringFUTF16(IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE,
+                        passphrase_time_str));
+    switch (passphrase_type) {
+      case syncer::FROZEN_IMPLICIT_PASSPHRASE:
+        args.SetString(
+            "fullEncryptionBody",
+            GetStringFUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_GOOGLE_WITH_DATE,
+                            passphrase_time_str));
+        break;
+      case syncer::CUSTOM_PASSPHRASE:
+        args.SetString(
+            "fullEncryptionBody",
+            GetStringFUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM_WITH_DATE,
+                            passphrase_time_str));
+        break;
+      default:
+        args.SetString(
+            "fullEncryptionBody",
+            GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM));
+        break;
     }
+  } else if (passphrase_type == syncer::CUSTOM_PASSPHRASE) {
+    args.SetString(
+        "fullEncryptionBody",
+        GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_BODY_CUSTOM));
   } else {
-    args.SetBoolean("usePassphrase", service->IsUsingSecondaryPassphrase());
+    args.SetString(
+        "fullEncryptionBody",
+        GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_DATA));
   }
 
   StringValue page("configure");
@@ -525,10 +498,6 @@
       base::Bind(&SyncSetupHandler::HandleConfigure,
                  base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
-      "SyncSetupShowErrorUI",
-      base::Bind(&SyncSetupHandler::HandleShowErrorUI,
-                 base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
       "SyncSetupShowSetupUI",
       base::Bind(&SyncSetupHandler::HandleShowSetupUI,
                  base::Unretained(this)));
@@ -551,7 +520,7 @@
 }
 
 #if !defined(OS_CHROMEOS)
-void SyncSetupHandler::DisplayGaiaLogin(bool fatal_error) {
+void SyncSetupHandler::DisplayGaiaLogin() {
   DCHECK(!sync_startup_tracker_);
   // Advanced options are no longer being configured if the login screen is
   // visible. If the user exits the signin wizard after this without
@@ -838,18 +807,10 @@
     ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_CHOOSE);
 }
 
-void SyncSetupHandler::HandleShowErrorUI(const ListValue* args) {
-  DCHECK(!configuring_sync_);
-
+void SyncSetupHandler::HandleShowSetupUI(const ListValue* args) {
   ProfileSyncService* service = GetSyncService();
   DCHECK(service);
 
-  // Bring up the existing wizard, or just display it on this page.
-  if (!FocusExistingWizardIfPresent())
-    OpenSyncSetup();
-}
-
-void SyncSetupHandler::HandleShowSetupUI(const ListValue* args) {
   SigninManagerBase* signin =
       SigninManagerFactory::GetForProfile(GetProfile());
   if (signin->GetAuthenticatedUsername().empty()) {
@@ -862,7 +823,10 @@
     CloseOverlay();
     return;
   }
-  OpenSyncSetup();
+
+  // Bring up the existing wizard, or just display it on this page.
+  if (!FocusExistingWizardIfPresent())
+    OpenSyncSetup();
 }
 
 #if defined(OS_CHROMEOS)
@@ -986,11 +950,22 @@
 #if !defined(OS_CHROMEOS)
   SigninManagerBase* signin =
       SigninManagerFactory::GetForProfile(GetProfile());
-  if (signin->GetAuthenticatedUsername().empty() ||
-      signin->signin_global_error()->HasMenuItem()) {
-    // User is not logged in, or login has been specially requested - need to
-    // display login UI (cases 1-3).
-    DisplayGaiaLogin(false);
+
+  if (signin->GetAuthenticatedUsername().empty()) {
+    // User is not logged in (cases 1-2). Display login UI.
+    DisplayGaiaLogin();
+    return;
+  }
+
+  if (SigninGlobalError::GetForProfile(GetProfile())->HasMenuItem()) {
+    // Login has been specially requested because previously working credentials
+    // have expired (case 3). Load the sync setup page with a spinner dialog,
+    // and then display the gaia auth page. The user may abandon re-auth by
+    // clicking cancel on the spinner dialog or closing the gaia login tab.
+    StringValue page("spinner");
+    web_ui()->CallJavascriptFunction("SyncSetupOverlay.showSyncSetupPage",
+                                     page);
+    DisplayGaiaLogin();
     return;
   }
 #endif
diff --git a/chrome/browser/ui/webui/sync_setup_handler.h b/chrome/browser/ui/webui/sync_setup_handler.h
index 4285beb..26aa049 100644
--- a/chrome/browser/ui/webui/sync_setup_handler.h
+++ b/chrome/browser/ui/webui/sync_setup_handler.h
@@ -131,18 +131,14 @@
   void HandleConfigure(const base::ListValue* args);
   void HandlePassphraseEntry(const base::ListValue* args);
   void HandlePassphraseCancel(const base::ListValue* args);
-  // TODO(atwilson): Not sure if HandleShowErrorUI() is still required.
-  // May be able to combine with HandleShowSetupUI().
-  void HandleShowErrorUI(const base::ListValue* args);
   void HandleShowSetupUI(const base::ListValue* args);
   void HandleDoSignOutOnAuthError(const base::ListValue* args);
   void HandleStartSignin(const base::ListValue* args);
   void HandleStopSyncing(const base::ListValue* args);
   void HandleCloseTimeout(const base::ListValue* args);
 #if !defined(OS_CHROMEOS)
-  // Displays the GAIA login form. If |fatal_error| is true, displays the fatal
-  // error UI.
-  void DisplayGaiaLogin(bool fatal_error);
+  // Displays the GAIA login form.
+  void DisplayGaiaLogin();
 
   // When web-flow is enabled, displays the Gaia login form in a new tab.
   // This function is virtual so that tests can override.
diff --git a/chrome/browser/ui/webui/sync_setup_handler_unittest.cc b/chrome/browser/ui/webui/sync_setup_handler_unittest.cc
index 20aa733..d0c36e7 100644
--- a/chrome/browser/ui/webui/sync_setup_handler_unittest.cc
+++ b/chrome/browser/ui/webui/sync_setup_handler_unittest.cc
@@ -9,12 +9,13 @@
 #include "base/command_line.h"
 #include "base/json/json_writer.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
 #include "base/prefs/pref_service.h"
 #include "base/stl_util.h"
 #include "base/values.h"
 #include "chrome/browser/signin/fake_auth_status_provider.h"
 #include "chrome/browser/signin/fake_signin_manager.h"
+#include "chrome/browser/signin/profile_oauth2_token_service.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/signin/signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
@@ -28,6 +29,7 @@
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "grit/generated_resources.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -147,33 +149,6 @@
   }
 }
 
-// Validates that the expected args are being passed off to javascript.
-void CheckShowSyncSetupArgs(const DictionaryValue* dictionary,
-                            std::string error_message,
-                            bool fatal_error,
-                            int error,
-                            std::string user,
-                            bool user_is_editable,
-                            std::string captcha_url) {
-  // showSyncSetupPage() expects to be passed a dictionary with the following
-  // named values set:
-  //   error_message: custom error message to display.
-  //   fatalError: true if there was a fatal error while logging in.
-  //   error: GoogleServiceAuthError from previous login attempt (0 if none).
-  //   user: The email the user most recently entered.
-  //   editable_user: Whether the username field should be editable.
-  //   captchaUrl: The captcha image to display to the user (empty if none).
-  //
-  // The code below validates these arguments.
-
-  CheckString(dictionary, "errorMessage", error_message, true);
-  CheckString(dictionary, "user", user, false);
-  CheckString(dictionary, "captchaUrl", captcha_url, false);
-  CheckInt(dictionary, "error", error);
-  CheckBool(dictionary, "fatalError", fatal_error, true);
-  CheckBool(dictionary, "editableUser", user_is_editable);
-}
-
 // Checks to make sure that the values stored in |dictionary| match the values
 // expected by the showSyncSetupPage() JS function for a given set of data
 // types.
@@ -332,18 +307,21 @@
   virtual void SetUp() OVERRIDE {
     error_ = GoogleServiceAuthError::AuthErrorNone();
     profile_.reset(ProfileSyncServiceMock::MakeSignedInTestingProfile());
+
     mock_pss_ = static_cast<ProfileSyncServiceMock*>(
         ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
             profile_.get(),
             ProfileSyncServiceMock::BuildMockProfileSyncService));
-    mock_pss_->Initialize();
-
+    EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_));
     ON_CALL(*mock_pss_, GetPassphraseType()).WillByDefault(
         Return(syncer::IMPLICIT_PASSPHRASE));
     ON_CALL(*mock_pss_, GetPassphraseTime()).WillByDefault(
         Return(base::Time()));
     ON_CALL(*mock_pss_, GetExplicitPassphraseTime()).WillByDefault(
         Return(base::Time()));
+
+    mock_pss_->Initialize();
+
 #if defined(OS_CHROMEOS)
     mock_signin_ = static_cast<SigninManagerBase*>(
         SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse(
@@ -384,7 +362,6 @@
         .WillRepeatedly(Return(true));
     EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
         .WillRepeatedly(Return(true));
-    EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_));
     EXPECT_CALL(*mock_pss_, sync_initialized()).WillRepeatedly(Return(true));
   }
 
@@ -432,11 +409,10 @@
       handler_->sync_startup_tracker_->OnStateChanged();
   }
 
+  content::TestBrowserThreadBundle thread_bundle_;
   scoped_ptr<Profile> profile_;
   ProfileSyncServiceMock* mock_pss_;
   GoogleServiceAuthError error_;
-  // MessageLoop instance is required to work with OneShotTimer.
-  base::MessageLoop message_loop_;
   SigninManagerBase* mock_signin_;
   TestWebUI web_ui_;
   scoped_ptr<TestingSyncSetupHandler> handler_;
@@ -451,8 +427,6 @@
       .WillRepeatedly(Return(false));
   EXPECT_CALL(*mock_pss_, IsOAuthRefreshTokenAvailable())
       .WillRepeatedly(Return(false));
-  const GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
-  EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error));
   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
       .WillRepeatedly(Return(false));
   handler_->HandleStartSignin(NULL);
@@ -500,7 +474,6 @@
   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
       .WillRepeatedly(Return(false));
   error_ = GoogleServiceAuthError::AuthErrorNone();
-  EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_));
   EXPECT_CALL(*mock_pss_, sync_initialized()).WillRepeatedly(Return(false));
 
   // We're simulating a user setting up sync, which would cause the backend to
@@ -530,7 +503,6 @@
   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
       .WillRepeatedly(Return(false));
   error_ = GoogleServiceAuthError::AuthErrorNone();
-  EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_));
   // Sync backend is stopped initially, and will start up.
   EXPECT_CALL(*mock_pss_, sync_initialized())
       .WillRepeatedly(Return(false));
@@ -590,7 +562,6 @@
   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
       .WillRepeatedly(Return(false));
   error_ = GoogleServiceAuthError::AuthErrorNone();
-  EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_));
   EXPECT_CALL(*mock_pss_, sync_initialized())
       .WillOnce(Return(false))
       .WillRepeatedly(Return(true));
@@ -621,7 +592,6 @@
   EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
       .WillRepeatedly(Return(false));
   error_ = GoogleServiceAuthError::AuthErrorNone();
-  EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_));
   EXPECT_CALL(*mock_pss_, sync_initialized()).WillRepeatedly(Return(false));
 
   handler_->OpenSyncSetup();
@@ -934,7 +904,8 @@
 
   SetupInitializedProfileSyncService();
   mock_signin_->SetAuthenticatedUsername(kTestUser);
-  FakeAuthStatusProvider provider(mock_signin_->signin_global_error());
+  FakeAuthStatusProvider provider(
+      SigninGlobalError::GetForProfile(profile_.get()));
   provider.SetAuthError(error_);
   EXPECT_CALL(*mock_pss_, IsSyncEnabledAndLoggedIn())
       .WillRepeatedly(Return(true));
@@ -944,7 +915,6 @@
       .WillRepeatedly(Return(false));
   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error_));
   EXPECT_CALL(*mock_pss_, sync_initialized()).WillRepeatedly(Return(false));
 
 #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/task_manager/task_manager_handler.cc b/chrome/browser/ui/webui/task_manager/task_manager_handler.cc
index 42a74a4..8ce0d82 100644
--- a/chrome/browser/ui/webui/task_manager/task_manager_handler.cc
+++ b/chrome/browser/ui/webui/task_manager/task_manager_handler.cc
@@ -11,10 +11,10 @@
 #include "base/bind_helpers.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/task_manager/task_manager.h"
 #include "chrome/browser/ui/host_desktop.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_view_host.h"
diff --git a/chrome/browser/ui/webui/theme_handler.cc b/chrome/browser/ui/webui/theme_handler.cc
index 02ae9bd..4112d2b 100644
--- a/chrome/browser/ui/webui/theme_handler.cc
+++ b/chrome/browser/ui/webui/theme_handler.cc
@@ -5,11 +5,11 @@
 #include "chrome/browser/ui/webui/theme_handler.h"
 
 #include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/ui/webui/theme_source.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_ui.h"
 #include "grit/theme_resources.h"
diff --git a/chrome/browser/ui/webui/theme_source.cc b/chrome/browser/ui/webui/theme_source.cc
index 8222132..5c7f8c6 100644
--- a/chrome/browser/ui/webui/theme_source.cc
+++ b/chrome/browser/ui/webui/theme_source.cc
@@ -17,11 +17,11 @@
 #include "chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/browser_thread.h"
-#include "googleurl/src/gurl.h"
 #include "net/url_request/url_request.h"
 #include "ui/base/layout.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/webui/web_ui_util.h"
+#include "url/gurl.h"
 
 using content::BrowserThread;
 
diff --git a/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc b/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc
index 6f5b606..d7ebb10 100644
--- a/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc
+++ b/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc
@@ -23,6 +23,10 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 
+#if !defined(OS_IOS)
+#include "third_party/cld/encodings/compact_lang_det/compact_lang_det.h"
+#endif
+
 namespace {
 
 // Sets the languages to |dict|. Each key is a language code and each value is
@@ -65,6 +69,11 @@
       command_line.HasSwitch(switches::kEnableTranslateSettings);
   source->AddBoolean("enable-translate-settings", enable_translate_settings);
 
+#if !defined(OS_IOS)
+  std::string cld_version = CompactLangDet::DetectLanguageVersion();
+  source->AddString("cld-version", cld_version);
+#endif
+
   return source;
 }
 
diff --git a/chrome/browser/ui/webui/uber/uber_ui.cc b/chrome/browser/ui/webui/uber/uber_ui.cc
index 0f6c6c3..2c68102 100644
--- a/chrome/browser/ui/webui/uber/uber_ui.cc
+++ b/chrome/browser/ui/webui/uber/uber_ui.cc
@@ -6,12 +6,12 @@
 
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
 #include "chrome/browser/ui/webui/extensions/extensions_ui.h"
 #include "chrome/browser/ui/webui/options/options_ui.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/extension_set.h"
 #include "chrome/common/extensions/manifest_url_handler.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/version_handler.cc b/chrome/browser/ui/webui/version_handler.cc
index c469d18..d6064fe 100644
--- a/chrome/browser/ui/webui/version_handler.cc
+++ b/chrome/browser/ui/webui/version_handler.cc
@@ -14,9 +14,9 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/browser/web_ui.h"
-#include "googleurl/src/gurl.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
 #include "webkit/plugins/plugin_constants.h"
 
 namespace {
diff --git a/chrome/browser/ui/webui/web_dialog_web_contents_delegate_unittest.cc b/chrome/browser/ui/webui/web_dialog_web_contents_delegate_unittest.cc
index 9749e76..2caef65 100644
--- a/chrome/browser/ui/webui/web_dialog_web_contents_delegate_unittest.cc
+++ b/chrome/browser/ui/webui/web_dialog_web_contents_delegate_unittest.cc
@@ -19,10 +19,10 @@
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/web_contents_tester.h"
-#include "googleurl/src/gurl.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/rect.h"
+#include "url/gurl.h"
 
 using content::OpenURLParams;
 using content::Referrer;
diff --git a/chrome/browser/ui/zoom/zoom_controller.cc b/chrome/browser/ui/zoom/zoom_controller.cc
index e7ddd18..c5e9a1d 100644
--- a/chrome/browser/ui/zoom/zoom_controller.cc
+++ b/chrome/browser/ui/zoom/zoom_controller.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/ui/zoom/zoom_controller.h"
 
 #include "base/prefs/pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_finder.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/host_zoom_map.h"
 #include "content/public/browser/navigation_entry.h"
@@ -33,14 +33,13 @@
   default_zoom_level_.Init(prefs::kDefaultZoomLevel, profile->GetPrefs(),
                            base::Bind(&ZoomController::UpdateState,
                                       base::Unretained(this),
-                                      std::string(),
-                                      false));
+                                      std::string()));
 
   content::HostZoomMap::GetForBrowserContext(
       browser_context_)->AddZoomLevelChangedCallback(
           zoom_callback_);
 
-  UpdateState(std::string(), false);
+  UpdateState(std::string());
 }
 
 ZoomController::~ZoomController() {
@@ -66,19 +65,15 @@
     const content::FrameNavigateParams& params) {
   // If the main frame's content has changed, the new page may have a different
   // zoom level from the old one.
-  UpdateState(std::string(), false);
+  UpdateState(std::string());
 }
 
 void ZoomController::OnZoomLevelChanged(
     const content::HostZoomMap::ZoomLevelChange& change) {
-// If this is a temporary zoom change, force the bubble.
-  bool force_bubble =
-      change.mode == content::HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM;
-  UpdateState(change.host, force_bubble);
+  UpdateState(change.host);
 }
 
-void ZoomController::UpdateState(const std::string& host,
-                                 bool force_bubble) {
+void ZoomController::UpdateState(const std::string& host) {
   // If |host| is empty, all observers should be updated.
   if (!host.empty()) {
     // Use the active navigation entry's URL instead of the WebContents' so
@@ -93,6 +88,7 @@
 
   bool dummy;
   zoom_percent_ = web_contents()->GetZoomPercent(&dummy, &dummy);
+
   if (observer_)
-    observer_->OnZoomChanged(web_contents(), !host.empty() || force_bubble);
+    observer_->OnZoomChanged(web_contents(), !host.empty());
 }
diff --git a/chrome/browser/ui/zoom/zoom_controller.h b/chrome/browser/ui/zoom/zoom_controller.h
index 431f42c..c63234d 100644
--- a/chrome/browser/ui/zoom/zoom_controller.h
+++ b/chrome/browser/ui/zoom/zoom_controller.h
@@ -49,10 +49,8 @@
   // Updates the zoom icon and zoom percentage based on current values and
   // notifies the observer if changes have occurred. |host| may be empty,
   // meaning the change should apply to ~all sites. If it is not empty, the
-  // change only affects sites with the given host. If |force_bubble| is true,
-  // the zoom bubble will appear even if |host| is empty, handling the case of
-  // temporary zoom (e.g., zooming within the PDF plugin).
-  void UpdateState(const std::string& host, bool force_bubble);
+  // change only affects sites with the given host.
+  void UpdateState(const std::string& host);
 
   // The current zoom percentage.
   int zoom_percent_;
diff --git a/chrome/browser/undo/undo_manager.cc b/chrome/browser/undo/undo_manager.cc
new file mode 100644
index 0000000..6b1c3de
--- /dev/null
+++ b/chrome/browser/undo/undo_manager.cc
@@ -0,0 +1,146 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/undo/undo_manager.h"
+
+#include "base/auto_reset.h"
+#include "base/logging.h"
+#include "chrome/browser/undo/undo_operation.h"
+
+// UndoGroup ------------------------------------------------------------------
+
+UndoGroup::UndoGroup() {
+}
+
+UndoGroup::~UndoGroup() {
+}
+
+void UndoGroup::AddOperation(scoped_ptr<UndoOperation> operation) {
+  operations_.push_back(operation.release());
+}
+
+void UndoGroup::Undo() {
+  for (ScopedVector<UndoOperation>::reverse_iterator ri = operations_.rbegin();
+       ri != operations_.rend(); ++ri) {
+    (*ri)->Undo();
+  }
+}
+
+// UndoManager ----------------------------------------------------------------
+
+UndoManager::UndoManager()
+    : group_actions_count_(0),
+      undo_suspended_count_(0),
+      performing_undo_(false),
+      performing_redo_(false) {
+}
+
+UndoManager::~UndoManager() {
+  DCHECK_EQ(0, group_actions_count_);
+  DCHECK_EQ(0, undo_suspended_count_);
+  DCHECK(!performing_undo_);
+  DCHECK(!performing_redo_);
+}
+
+void UndoManager::Undo() {
+  Undo(&performing_undo_, &undo_actions_);
+}
+
+void UndoManager::Redo() {
+  Undo(&performing_redo_, &redo_actions_);
+}
+
+void UndoManager::AddUndoOperation(scoped_ptr<UndoOperation> operation) {
+  if (IsUndoTrakingSuspended()) {
+    RemoveAllActions();
+    operation.reset();
+    return;
+  }
+
+  if (group_actions_count_) {
+    pending_grouped_action_->AddOperation(operation.Pass());
+  } else {
+    UndoGroup* new_action = new UndoGroup();
+    new_action->AddOperation(operation.Pass());
+    GetActiveUndoGroup()->insert(GetActiveUndoGroup()->end(), new_action);
+
+    // A new user action invalidates any available redo actions.
+    RemoveAllRedoActions();
+  }
+}
+
+void UndoManager::StartGroupingActions() {
+  if (!group_actions_count_)
+    pending_grouped_action_.reset(new UndoGroup());
+  ++group_actions_count_;
+}
+
+void UndoManager::EndGroupingActions() {
+  --group_actions_count_;
+  if (group_actions_count_ > 0)
+    return;
+
+  // Check that StartGroupingActions and EndGroupingActions are paired.
+  DCHECK_GE(group_actions_count_, 0);
+
+  bool is_user_action = !performing_undo_ && !performing_redo_;
+  if (pending_grouped_action_->has_operations()) {
+    GetActiveUndoGroup()->push_back(pending_grouped_action_.release());
+    // User actions invalidate any available redo actions.
+    if (is_user_action)
+      RemoveAllRedoActions();
+  } else {
+    // No changes were executed since we started grouping actions, so the
+    // pending UndoGroup should be discarded.
+    pending_grouped_action_.reset();
+
+    // This situation is only expected when it is a user initiated action.
+    // Undo/Redo should have at least one operation performed.
+    DCHECK(is_user_action);
+  }
+}
+
+void UndoManager::SuspendUndoTracking() {
+  ++undo_suspended_count_;
+}
+
+void UndoManager::ResumeUndoTracking() {
+  DCHECK_GT(undo_suspended_count_, 0);
+  --undo_suspended_count_;
+}
+
+bool UndoManager::IsUndoTrakingSuspended() const {
+  return undo_suspended_count_ > 0;
+}
+
+void UndoManager::Undo(bool* performing_indicator,
+                       ScopedVector<UndoGroup>* active_undo_group) {
+  // Check that action grouping has been correctly ended.
+  DCHECK(!group_actions_count_);
+
+  if (active_undo_group->empty())
+    return;
+
+  base::AutoReset<bool> incoming_changes(performing_indicator, true);
+  scoped_ptr<UndoGroup> action(active_undo_group->back());
+  active_undo_group->weak_erase(
+      active_undo_group->begin() + active_undo_group->size() - 1);
+
+  StartGroupingActions();
+  action->Undo();
+  EndGroupingActions();
+}
+
+void UndoManager::RemoveAllActions() {
+  undo_actions_.clear();
+  RemoveAllRedoActions();
+}
+
+void UndoManager::RemoveAllRedoActions() {
+  redo_actions_.clear();
+}
+
+ScopedVector<UndoGroup>* UndoManager::GetActiveUndoGroup() {
+  return performing_undo_ ? &redo_actions_ : &undo_actions_;
+}
diff --git a/chrome/browser/undo/undo_manager.h b/chrome/browser/undo/undo_manager.h
new file mode 100644
index 0000000..4031cba
--- /dev/null
+++ b/chrome/browser/undo/undo_manager.h
@@ -0,0 +1,94 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UNDO_UNDO_MANAGER_H_
+#define CHROME_BROWSER_UNDO_UNDO_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+
+class UndoOperation;
+
+// UndoGroup ------------------------------------------------------------------
+
+// UndoGroup represents a user action and stores all the operations that
+// make that action.  Typically there is only one operation per UndoGroup.
+class UndoGroup {
+ public:
+  UndoGroup();
+  ~UndoGroup();
+
+  void AddOperation(scoped_ptr<UndoOperation> operation);
+  bool has_operations() const {
+    return !operations_.empty();
+  }
+
+  void Undo();
+
+ private:
+  ScopedVector<UndoOperation> operations_;
+
+  DISALLOW_COPY_AND_ASSIGN(UndoGroup);
+};
+
+// UndoManager ----------------------------------------------------------------
+
+// Maintains user actions as a group of operations that store enough info to
+// undo and redo those operations.
+class UndoManager {
+ public:
+  UndoManager();
+  ~UndoManager();
+
+  // Perform an undo or redo operation.
+  void Undo();
+  void Redo();
+
+  size_t undo_count() const { return undo_actions_.size(); }
+  size_t redo_count() const { return redo_actions_.size(); }
+
+  void AddUndoOperation(scoped_ptr<UndoOperation> operation);
+
+  // Group multiple operations into one undoable action.
+  void StartGroupingActions();
+  void EndGroupingActions();
+
+  // Suspend undo tracking while processing non-user initiated changes such as
+  // profile synchonization.
+  void SuspendUndoTracking();
+  void ResumeUndoTracking();
+  bool IsUndoTrakingSuspended() const;
+
+ private:
+  void Undo(bool* performing_indicator,
+            ScopedVector<UndoGroup>* active_undo_group);
+
+  void RemoveAllActions();
+  void RemoveAllRedoActions();
+
+  ScopedVector<UndoGroup>* GetActiveUndoGroup();
+
+  // Containers of user actions ready for an undo or redo treated as a stack.
+  ScopedVector<UndoGroup> undo_actions_;
+  ScopedVector<UndoGroup> redo_actions_;
+
+  // Supports grouping operations into a single undo action.
+  int group_actions_count_;
+
+  // The container that is used when actions are grouped.
+  scoped_ptr<UndoGroup> pending_grouped_action_;
+
+  // Supports the suspension of undo tracking.
+  int undo_suspended_count_;
+
+  // Set when executing Undo or Redo so that incoming changes are correctly
+  // processed.
+  bool performing_undo_;
+  bool performing_redo_;
+
+  DISALLOW_COPY_AND_ASSIGN(UndoManager);
+};
+
+#endif  // CHROME_BROWSER_UNDO_UNDO_MANAGER_H_
diff --git a/chrome/browser/undo/undo_manager_test.cc b/chrome/browser/undo/undo_manager_test.cc
new file mode 100644
index 0000000..173bcad
--- /dev/null
+++ b/chrome/browser/undo/undo_manager_test.cc
@@ -0,0 +1,166 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/auto_reset.h"
+#include "chrome/browser/undo/undo_manager.h"
+#include "chrome/browser/undo/undo_operation.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class TestUndoOperation;
+
+class TestUndoService {
+ public:
+  TestUndoService()
+      : performing_redo_(false),
+        undo_operation_count_(0),
+        redo_operation_count_(0) {
+  }
+  ~TestUndoService() {}
+
+  void Redo() {
+    base::AutoReset<bool> incoming_changes(&performing_redo_, true);
+    undo_manager_.Redo();
+  }
+
+  void TriggerOperation();
+
+  void RecordUndoCall() {
+    if (performing_redo_)
+      ++redo_operation_count_;
+    else
+      ++undo_operation_count_;
+  }
+
+  UndoManager undo_manager_;
+
+  bool performing_redo_;
+
+  int undo_operation_count_;
+  int redo_operation_count_;
+};
+
+class TestUndoOperation : public UndoOperation {
+ public:
+  explicit TestUndoOperation(TestUndoService* undo_service)
+      : undo_service_(undo_service) {
+  }
+  virtual ~TestUndoOperation() {}
+
+  virtual void Undo() OVERRIDE {
+    undo_service_->TriggerOperation();
+    undo_service_->RecordUndoCall();
+  }
+
+ private:
+  TestUndoService* undo_service_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestUndoOperation);
+};
+
+void TestUndoService::TriggerOperation() {
+  scoped_ptr<TestUndoOperation> op(new TestUndoOperation(this));
+  undo_manager_.AddUndoOperation(op.PassAs<UndoOperation>());
+}
+
+TEST(UndoServiceTest, AddUndoActions) {
+  TestUndoService undo_service;
+
+  undo_service.TriggerOperation();
+  undo_service.TriggerOperation();
+  EXPECT_EQ(2U, undo_service.undo_manager_.undo_count());
+  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
+}
+
+TEST(UndoServiceTest, UndoMultipleActions) {
+  TestUndoService undo_service;
+
+  undo_service.TriggerOperation();
+  undo_service.TriggerOperation();
+
+  undo_service.undo_manager_.Undo();
+  EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
+  EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());
+
+  undo_service.undo_manager_.Undo();
+  EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
+  EXPECT_EQ(2U, undo_service.undo_manager_.redo_count());
+
+  EXPECT_EQ(2, undo_service.undo_operation_count_);
+  EXPECT_EQ(0, undo_service.redo_operation_count_);
+}
+
+TEST(UndoServiceTest, RedoAction) {
+  TestUndoService undo_service;
+
+  undo_service.TriggerOperation();
+
+  undo_service.undo_manager_.Undo();
+  EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
+  EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());
+
+  undo_service.Redo();
+  EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
+  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
+
+  EXPECT_EQ(1, undo_service.undo_operation_count_);
+  EXPECT_EQ(1, undo_service.redo_operation_count_);
+}
+
+TEST(UndoServiceTest, GroupActions) {
+  TestUndoService undo_service;
+
+  // Add two operations in a single action.
+  undo_service.undo_manager_.StartGroupingActions();
+  undo_service.TriggerOperation();
+  undo_service.TriggerOperation();
+  undo_service.undo_manager_.EndGroupingActions();
+
+  // Check that only one action is created.
+  EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
+  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
+
+  undo_service.undo_manager_.Undo();
+  EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
+  EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());
+
+  undo_service.Redo();
+  EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
+  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
+
+  // Check that both operations were called in Undo and Redo.
+  EXPECT_EQ(2, undo_service.undo_operation_count_);
+  EXPECT_EQ(2, undo_service.redo_operation_count_);
+}
+
+TEST(UndoServiceTest, SuspendUndoTracking) {
+  TestUndoService undo_service;
+
+  undo_service.undo_manager_.SuspendUndoTracking();
+  EXPECT_TRUE(undo_service.undo_manager_.IsUndoTrakingSuspended());
+
+  undo_service.TriggerOperation();
+
+  undo_service.undo_manager_.ResumeUndoTracking();
+  EXPECT_FALSE(undo_service.undo_manager_.IsUndoTrakingSuspended());
+
+  EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
+  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
+}
+
+TEST(UndoServiceTest, RedoEmptyAfterNewAction) {
+  TestUndoService undo_service;
+
+  undo_service.TriggerOperation();
+  undo_service.undo_manager_.Undo();
+  EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
+  EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());
+
+  undo_service.TriggerOperation();
+  EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
+  EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
+}
+
+} // namespace
diff --git a/chrome/browser/undo/undo_operation.h b/chrome/browser/undo/undo_operation.h
new file mode 100644
index 0000000..5802970
--- /dev/null
+++ b/chrome/browser/undo/undo_operation.h
@@ -0,0 +1,16 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UNDO_UNDO_OPERATION_H_
+#define CHROME_BROWSER_UNDO_UNDO_OPERATION_H_
+
+// Base class for all undo operations.
+class UndoOperation {
+ public:
+  virtual ~UndoOperation() {}
+
+  virtual void Undo() = 0;
+};
+
+#endif  // CHROME_BROWSER_UNDO_UNDO_OPERATION_H_
diff --git a/chrome/browser/undo/undo_service.cc b/chrome/browser/undo/undo_service.cc
deleted file mode 100644
index c39cb25..0000000
--- a/chrome/browser/undo/undo_service.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/undo/undo_service.h"
-
-#include "base/logging.h"
-
-UndoService::UndoService(Profile* profile)
-    : profile_(profile),
-      group_actions_count_(0),
-      undo_suspended_count_(0) {
-}
-
-UndoService::~UndoService() {
-}
-
-void UndoService::Undo() {
-}
-
-void UndoService::Redo() {
-}
-
-size_t UndoService::undo_count() const {
-  return 0;
-}
-
-size_t UndoService::redo_count() const {
-  return 0;
-}
-
-void UndoService::StartGroupingActions() {
-  ++group_actions_count_;
-}
-
-void UndoService::EndGroupingActions() {
-  DCHECK_GT(undo_suspended_count_, 0);
-  --group_actions_count_;
-}
-
-void UndoService::SuspendUndoTracking() {
-  ++undo_suspended_count_;
-}
-
-void UndoService::ResumeUndoTracking() {
-  DCHECK_GT(undo_suspended_count_, 0);
-  --undo_suspended_count_;
-}
diff --git a/chrome/browser/undo/undo_service.h b/chrome/browser/undo/undo_service.h
deleted file mode 100644
index 720bc1e..0000000
--- a/chrome/browser/undo/undo_service.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UNDO_UNDO_SERVICE_H_
-#define CHROME_BROWSER_UNDO_UNDO_SERVICE_H_
-
-#include "base/basictypes.h"
-#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
-
-class Profile;
-
-// UndoService ----------------------------------------------------------------
-
-// UndoService will provide undo/redo service for the Profile. UndoService
-// will initially serve the BookmarkModel providing a mechanism to group
-// bookmark operations into user actions that can be undone and redone.
-class UndoService : public BrowserContextKeyedService {
- public:
-  explicit UndoService(Profile* profile);
-  virtual ~UndoService();
-
-  // Undo the last action.
-  void Undo();
-
-  // Redo the last action that was undone.
-  void Redo();
-
-  // Returns the number of undo and redo operations that are avaiable.
-  size_t undo_count() const;
-  size_t redo_count() const;
-
-  // Group multiple operations into one undoable action.
-  void StartGroupingActions();
-  void EndGroupingActions();
-
-  // Suspend tracking of user actions for the purposes of undo.  If operations
-  // are triggered while undo is suspended any undo or redo actions will be
-  // lost. This is needed for non-user modifications such as profile
-  // synchonization.
-  void SuspendUndoTracking();
-  void ResumeUndoTracking();
-
- private:
-  Profile* profile_;
-
-  // Supports grouping operations into a single undo action.
-  int group_actions_count_;
-
-  // Indicates how many times SuspendUndoTracking has been called without the
-  // corresponding ResumeUndoTracking.  While non-zero any modifications will
-  // not trigger undo information to be recorded.
-  int undo_suspended_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(UndoService);
-};
-
-#endif  // CHROME_BROWSER_UNDO_UNDO_SERVICE_H_
diff --git a/chrome/browser/undo/undo_service_factory.cc b/chrome/browser/undo/undo_service_factory.cc
deleted file mode 100644
index e10081c..0000000
--- a/chrome/browser/undo/undo_service_factory.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/undo/undo_service_factory.h"
-
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/undo/undo_service.h"
-#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
-
-// static
-UndoService* UndoServiceFactory::GetForProfile(
-    Profile* profile) {
-  return static_cast<UndoService*>(
-      GetInstance()->GetServiceForBrowserContext(profile, true));
-}
-
-// static
-UndoServiceFactory* UndoServiceFactory::GetInstance() {
-  return Singleton<UndoServiceFactory>::get();
-}
-
-UndoServiceFactory::UndoServiceFactory()
-    : BrowserContextKeyedServiceFactory(
-          "UndoService",
-          BrowserContextDependencyManager::GetInstance()) {
-}
-
-UndoServiceFactory::~UndoServiceFactory() {
-}
-
-BrowserContextKeyedService* UndoServiceFactory::BuildServiceInstanceFor(
-    content::BrowserContext* context) const {
-  Profile* profile = static_cast<Profile*>(context);
-  return new UndoService(profile);
-}
diff --git a/chrome/browser/undo/undo_service_factory.h b/chrome/browser/undo/undo_service_factory.h
deleted file mode 100644
index 0054abc..0000000
--- a/chrome/browser/undo/undo_service_factory.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UNDO_UNDO_SERVICE_FACTORY_H_
-#define CHROME_BROWSER_UNDO_UNDO_SERVICE_FACTORY_H_
-
-#include "base/memory/singleton.h"
-#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
-
-class Profile;
-class UndoService;
-
-// Singleton that owns all UndoService and associates them with Profiles.
-class UndoServiceFactory : public BrowserContextKeyedServiceFactory {
- public:
-  static UndoService* GetForProfile(Profile* profile);
-
-  static UndoServiceFactory* GetInstance();
-
- private:
-  friend struct DefaultSingletonTraits<UndoServiceFactory>;
-
-  UndoServiceFactory();
-  virtual ~UndoServiceFactory();
-
-  // BrowserContextKeyedServiceFactory:
-  virtual BrowserContextKeyedService* BuildServiceInstanceFor(
-      content::BrowserContext* context) const OVERRIDE;
-
-  DISALLOW_COPY_AND_ASSIGN(UndoServiceFactory);
-};
-
-#endif  // CHROME_BROWSER_UNDO_UNDO_SERVICE_FACTORY_H_
diff --git a/chrome/browser/unload_browsertest.cc b/chrome/browser/unload_browsertest.cc
index b39cb8e..bc95910 100644
--- a/chrome/browser/unload_browsertest.cc
+++ b/chrome/browser/unload_browsertest.cc
@@ -10,6 +10,7 @@
 #include "base/logging.h"
 #include "base/process_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/net/url_request_mock_util.h"
 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
@@ -17,7 +18,6 @@
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/upgrade_detector.cc b/chrome/browser/upgrade_detector.cc
index 0463dee..f6b68bc 100644
--- a/chrome/browser/upgrade_detector.cc
+++ b/chrome/browser/upgrade_detector.cc
@@ -7,9 +7,9 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/prefs/pref_registry_simple.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/ui/browser_otr_state.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/upload_list.cc b/chrome/browser/upload_list.cc
index 52c42a7..3f618aa 100644
--- a/chrome/browser/upload_list.cc
+++ b/chrome/browser/upload_list.cc
@@ -49,7 +49,7 @@
 }
 
 void UploadList::LoadUploadList() {
-  if (file_util::PathExists(upload_log_path_)) {
+  if (base::PathExists(upload_log_path_)) {
     std::string contents;
     file_util::ReadFileToString(upload_log_path_, &contents);
     std::vector<std::string> log_entries;
diff --git a/chrome/browser/usb/OWNERS b/chrome/browser/usb/OWNERS
index 2ffd61a..51dcade 100644
--- a/chrome/browser/usb/OWNERS
+++ b/chrome/browser/usb/OWNERS
@@ -1,2 +1,3 @@
+ikarienator@chromium.org
 gdk@chromium.org
 bryeung@chromium.org
diff --git a/chrome/browser/user_data_dir_extractor_win.cc b/chrome/browser/user_data_dir_extractor_win.cc
index 793991a..e295885 100644
--- a/chrome/browser/user_data_dir_extractor_win.cc
+++ b/chrome/browser/user_data_dir_extractor_win.cc
@@ -45,7 +45,7 @@
   // prompt the user to pick a different directory, and restart chrome with
   // the new dir.
   // http://code.google.com/p/chromium/issues/detail?id=11510
-  if (!file_util::PathExists(user_data_dir)) {
+  if (!base::PathExists(user_data_dir)) {
 #if defined(USE_AURA)
     // TODO(beng):
     NOTIMPLEMENTED();
diff --git a/chrome/browser/user_data_dir_extractor_win_browsertest.cc b/chrome/browser/user_data_dir_extractor_win_browsertest.cc
index 731285e..6987b62 100644
--- a/chrome/browser/user_data_dir_extractor_win_browsertest.cc
+++ b/chrome/browser/user_data_dir_extractor_win_browsertest.cc
@@ -8,10 +8,10 @@
 #include "base/path_service.h"
 #include "base/process_util.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/user_data_dir_extractor_win.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/user_style_sheet_watcher.cc b/chrome/browser/user_style_sheet_watcher.cc
index dd7ab40..2dd6414 100644
--- a/chrome/browser/user_style_sheet_watcher.cc
+++ b/chrome/browser/user_style_sheet_watcher.cc
@@ -8,7 +8,7 @@
 #include "base/bind.h"
 #include "base/file_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_notification_types.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/web_contents.h"
@@ -104,12 +104,12 @@
   // We keep the user style sheet in a subdir so we can watch for changes
   // to the file.
   base::FilePath style_sheet_dir = style_sheet_file.DirName();
-  if (!file_util::DirectoryExists(style_sheet_dir)) {
+  if (!base::DirectoryExists(style_sheet_dir)) {
     if (!file_util::CreateDirectory(style_sheet_dir))
       return;
   }
   // Create the file if it doesn't exist.
-  if (!file_util::PathExists(style_sheet_file))
+  if (!base::PathExists(style_sheet_file))
     file_util::WriteFile(style_sheet_file, "", 0);
 
   std::string css;
diff --git a/chrome/browser/value_store/leveldb_value_store.cc b/chrome/browser/value_store/leveldb_value_store.cc
index d192399..1a2dbe6 100644
--- a/chrome/browser/value_store/leveldb_value_store.cc
+++ b/chrome/browser/value_store/leveldb_value_store.cc
@@ -94,7 +94,7 @@
   if (db_ && IsEmpty()) {
     // Close |db_| now to release any lock on the directory.
     db_.reset();
-    if (!base::Delete(db_path_, true)) {
+    if (!base::DeleteFile(db_path_, true)) {
       LOG(WARNING) << "Failed to delete LeveldbValueStore database " <<
           db_path_.value();
     }
@@ -343,6 +343,7 @@
 #endif
 
   leveldb::Options options;
+  options.max_open_files = 0;  // Use minimum.
   options.create_if_missing = true;
   leveldb::DB* db;
   leveldb::Status status = leveldb::DB::Open(options, os_path, &db);
diff --git a/chrome/browser/value_store/value_store_frontend_unittest.cc b/chrome/browser/value_store/value_store_frontend_unittest.cc
index 62295c7..ee66fbb 100644
--- a/chrome/browser/value_store/value_store_frontend_unittest.cc
+++ b/chrome/browser/value_store/value_store_frontend_unittest.cc
@@ -30,7 +30,7 @@
     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
     base::FilePath src_db(test_data_dir.AppendASCII("value_store_db"));
     db_path_ = temp_dir_.path().AppendASCII("temp_db");
-    file_util::CopyDirectory(src_db, db_path_, true);
+    base::CopyDirectory(src_db, db_path_, true);
 
     ResetStorage();
   }
diff --git a/chrome/browser/web_applications/web_app_mac.mm b/chrome/browser/web_applications/web_app_mac.mm
index 2743f32..0644302 100644
--- a/chrome/browser/web_applications/web_app_mac.mm
+++ b/chrome/browser/web_applications/web_app_mac.mm
@@ -21,11 +21,14 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/mac/dock.h"
 #include "chrome/browser/ui/web_applications/web_app_ui.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_paths_internal.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
+#include "chrome/common/extensions/extension.h"
 #include "chrome/common/mac/app_mode_common.h"
 #include "content/public/browser/browser_thread.h"
 #include "grit/chromium_strings.h"
@@ -38,6 +41,9 @@
 
 namespace {
 
+// Launch Services Key to run as an agent app, which doesn't launch in the dock.
+NSString* const kLSUIElement = @"LSUIElement";
+
 class ScopedCarbonHandle {
  public:
   ScopedCarbonHandle(size_t initial_size) : handle_(NewHandle(initial_size)) {
@@ -128,7 +134,7 @@
 base::FilePath GetWritableApplicationsDirectory() {
   base::FilePath path;
   if (base::mac::GetLocalDirectory(NSApplicationDirectory, &path) &&
-      file_util::PathIsWritable(path)) {
+      base::PathIsWritable(path)) {
     return path;
   }
   if (base::mac::GetUserDirectory(NSApplicationDirectory, &path))
@@ -166,7 +172,7 @@
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
   base::FilePath shim_path = web_app::GetAppInstallPath(shortcut_info);
 
-  if (shim_path.empty() || !file_util::PathExists(shim_path)) {
+  if (shim_path.empty() || !base::PathExists(shim_path)) {
     // The user may have deleted the copy in the Applications folder, use the
     // one in the web app's app_data_path.
     base::FilePath app_data_path = web_app::GetWebAppDataDirectory(
@@ -174,7 +180,7 @@
     shim_path = app_data_path.Append(shim_path.BaseName());
   }
 
-  if (!file_util::PathExists(shim_path))
+  if (!base::PathExists(shim_path))
     return;
 
   CommandLine command_line(CommandLine::NO_PROGRAM);
@@ -229,10 +235,73 @@
 
 void DeletePathAndParentIfEmpty(const base::FilePath& app_path) {
   DCHECK(!app_path.empty());
-  base::Delete(app_path, true);
+  base::DeleteFile(app_path, true);
   base::FilePath apps_folder = app_path.DirName();
   if (file_util::IsDirectoryEmpty(apps_folder))
-    base::Delete(apps_folder, false);
+    base::DeleteFile(apps_folder, false);
+}
+
+bool IsShimForProfile(const base::FilePath& base_name,
+                      const std::string& profile_base_name) {
+  if (!StartsWithASCII(base_name.value(), profile_base_name, true))
+    return false;
+
+  if (base_name.Extension() != ".app")
+    return false;
+
+  std::string app_id = base_name.RemoveExtension().value();
+  // Strip (profile_base_name + " ") from the start.
+  app_id = app_id.substr(profile_base_name.size() + 1);
+  return extensions::Extension::IdIsValid(app_id);
+}
+
+std::vector<base::FilePath> GetAllAppBundlesInPath(
+    const base::FilePath& internal_shortcut_path,
+    const std::string& profile_base_name) {
+  std::vector<base::FilePath> bundle_paths;
+
+  base::FileEnumerator enumerator(internal_shortcut_path,
+                                  true /* recursive */,
+                                  base::FileEnumerator::DIRECTORIES);
+  for (base::FilePath bundle_path = enumerator.Next();
+       !bundle_path.empty(); bundle_path = enumerator.Next()) {
+    if (IsShimForProfile(bundle_path.BaseName(), profile_base_name))
+      bundle_paths.push_back(bundle_path);
+  }
+
+  return bundle_paths;
+}
+
+ShellIntegration::ShortcutInfo BuildShortcutInfoFromBundle(
+    const base::FilePath& bundle_path) {
+  NSString* plist_path = base::mac::FilePathToNSString(
+      bundle_path.Append("Contents").Append("Info.plist"));
+  NSMutableDictionary* plist =
+      [NSMutableDictionary dictionaryWithContentsOfFile:plist_path];
+
+  ShellIntegration::ShortcutInfo shortcut_info;
+  shortcut_info.extension_id = base::SysNSStringToUTF8(
+      [plist valueForKey:app_mode::kCrAppModeShortcutIDKey]);
+  shortcut_info.is_platform_app = true;
+  shortcut_info.url = GURL(base::SysNSStringToUTF8(
+      [plist valueForKey:app_mode::kCrAppModeShortcutURLKey]));
+  shortcut_info.title = base::SysNSStringToUTF16(
+      [plist valueForKey:app_mode::kCrAppModeShortcutNameKey]);
+  shortcut_info.profile_name = base::SysNSStringToUTF8(
+      [plist valueForKey:app_mode::kCrAppModeProfileNameKey]);
+
+  // Figure out the profile_path. Since the user_data_dir could contain the
+  // path to the web app data dir.
+  base::FilePath user_data_dir = base::mac::NSStringToFilePath(
+      [plist valueForKey:app_mode::kCrAppModeUserDataDirKey]);
+  base::FilePath profile_base_name = base::mac::NSStringToFilePath(
+      [plist valueForKey:app_mode::kCrAppModeProfileDirKey]);
+  if (user_data_dir.DirName().DirName().BaseName() == profile_base_name)
+    shortcut_info.profile_path = user_data_dir.DirName().DirName();
+  else
+    shortcut_info.profile_path = user_data_dir.Append(profile_base_name);
+
+  return shortcut_info;
 }
 
 }  // namespace
@@ -269,7 +338,7 @@
     const base::FilePath& staging_path) const {
   // Update the app's plist and icon in a temp directory. This works around
   // a Finder bug where the app's icon doesn't properly update.
-  if (!file_util::CopyDirectory(GetAppLoaderPath(), staging_path, true)) {
+  if (!base::CopyDirectory(GetAppLoaderPath(), staging_path, true)) {
     LOG(ERROR) << "Copying app to staging path: " << staging_path.value()
                << " failed.";
     return false;
@@ -304,7 +373,7 @@
   for (std::vector<base::FilePath>::const_iterator it = folders.begin();
        it != folders.end(); ++it) {
     const base::FilePath& dst_path = *it;
-    if (!file_util::CopyDirectory(staging_path, dst_path, true)) {
+    if (!base::CopyDirectory(staging_path, dst_path, true)) {
       LOG(ERROR) << "Copying app to dst path: " << dst_path.value()
                  << " failed";
       return succeeded;
@@ -319,7 +388,7 @@
 
 bool WebAppShortcutCreator::CreateShortcuts() {
   base::FilePath dst_path = GetDestinationPath();
-  if (dst_path.empty() || !file_util::DirectoryExists(dst_path.DirName())) {
+  if (dst_path.empty() || !base::DirectoryExists(dst_path.DirName())) {
     LOG(ERROR) << "Couldn't find an Applications directory to copy app to.";
     return false;
   }
@@ -349,11 +418,19 @@
   if (success_count != paths.size())
     return false;
 
+  if (info_.extension_id == app_mode::kAppListModeId) {
+    NSString* internal_app_list_app_path = base::SysUTF8ToNSString(
+        app_data_path_.Append(GetShortcutName()).AsUTF8Unsafe());
+    dock::AddIcon(internal_app_list_app_path, nil);
+  }
+
   RevealAppShimInFinder();
   return true;
 }
 
 void WebAppShortcutCreator::DeleteShortcuts() {
+  // TODO(jackhou): For the first two cases, we need to check if the
+  // user_data_dir matches that of the current browser process.
   base::FilePath dst_path = GetDestinationPath();
   if (!dst_path.empty())
     DeletePathAndParentIfEmpty(dst_path.Append(GetShortcutName()));
@@ -361,7 +438,7 @@
   // In case the user has moved/renamed/copied the app bundle.
   base::FilePath bundle_path = GetAppBundleById(GetBundleIdentifier());
   if (!bundle_path.empty())
-    base::Delete(bundle_path, true);
+    base::DeleteFile(bundle_path, true);
 
   // Delete the internal one.
   DeletePathAndParentIfEmpty(app_data_path_.Append(GetShortcutName()));
@@ -369,7 +446,7 @@
 
 bool WebAppShortcutCreator::UpdateShortcuts() {
   std::vector<base::FilePath> paths;
-  base::Delete(app_data_path_.Append(GetShortcutName()), true);
+  base::DeleteFile(app_data_path_.Append(GetShortcutName()), true);
   paths.push_back(app_data_path_);
 
   base::FilePath dst_path = GetDestinationPath();
@@ -377,11 +454,11 @@
 
   // If the path does not exist, check if a matching bundle can be found
   // elsewhere.
-  if (dst_path.empty() || !file_util::PathExists(app_path))
+  if (dst_path.empty() || !base::PathExists(app_path))
     app_path = GetAppBundleById(GetBundleIdentifier());
 
   if (!app_path.empty()) {
-    base::Delete(app_path, true);
+    base::DeleteFile(app_path, true);
     paths.push_back(app_path.DirName());
   }
 
@@ -450,6 +527,11 @@
             forKey:app_mode::kCrAppModeProfileNameKey];
   [plist setObject:[NSNumber numberWithBool:YES]
             forKey:app_mode::kLSHasLocalizedDisplayNameKey];
+  if (info_.extension_id == app_mode::kAppListModeId) {
+    // Prevent the app list from bouncing in the dock, and getting a run light.
+    [plist setObject:[NSNumber numberWithBool:YES]
+              forKey:kLSUIElement];
+  }
 
   base::FilePath app_name = app_path.BaseName().RemoveExtension();
   [plist setObject:base::mac::FilePathToNSString(app_name)
@@ -626,7 +708,18 @@
 }
 
 void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) {
-  // TODO(mgiuca): Implement this on Mac.
+  const std::string profile_base_name = profile_path.BaseName().value();
+  std::vector<base::FilePath> bundles = GetAllAppBundlesInPath(
+      profile_path.Append(chrome::kWebAppDirname), profile_base_name);
+
+  for (std::vector<base::FilePath>::const_iterator it = bundles.begin();
+       it != bundles.end(); ++it) {
+    ShellIntegration::ShortcutInfo shortcut_info =
+        BuildShortcutInfoFromBundle(*it);
+    WebAppShortcutCreator shortcut_creator(
+        it->DirName(), shortcut_info, base::mac::BaseBundleID());
+    shortcut_creator.DeleteShortcuts();
+  }
 }
 
 }  // namespace internals
diff --git a/chrome/browser/web_applications/web_app_mac_unittest.mm b/chrome/browser/web_applications/web_app_mac_unittest.mm
index a96ff4c..ad056e7 100644
--- a/chrome/browser/web_applications/web_app_mac_unittest.mm
+++ b/chrome/browser/web_applications/web_app_mac_unittest.mm
@@ -85,8 +85,8 @@
   EXPECT_CALL(shortcut_creator, RevealAppShimInFinder());
 
   EXPECT_TRUE(shortcut_creator.CreateShortcuts());
-  EXPECT_TRUE(file_util::PathExists(app_in_app_data_path_path));
-  EXPECT_TRUE(file_util::PathExists(dst_path));
+  EXPECT_TRUE(base::PathExists(app_in_app_data_path_path));
+  EXPECT_TRUE(base::PathExists(dst_path));
   EXPECT_EQ(dst_path.BaseName(), shortcut_creator.GetShortcutName());
 
   base::FilePath plist_path = dst_path.Append("Contents").Append("Info.plist");
@@ -139,12 +139,12 @@
 
   shortcut_creator.BuildShortcut(other_folder.Append(app_name));
 
-  EXPECT_TRUE(base::Delete(
+  EXPECT_TRUE(base::DeleteFile(
       other_folder.Append(app_name).Append("Contents"), true));
 
   EXPECT_TRUE(shortcut_creator.UpdateShortcuts());
-  EXPECT_FALSE(file_util::PathExists(dst_folder.Append(app_name)));
-  EXPECT_TRUE(file_util::PathExists(
+  EXPECT_FALSE(base::PathExists(dst_folder.Append(app_name)));
+  EXPECT_TRUE(base::PathExists(
       other_folder.Append(app_name).Append("Contents")));
 
   // Also test case where GetAppBundleById fails.
@@ -153,12 +153,12 @@
 
   shortcut_creator.BuildShortcut(other_folder.Append(app_name));
 
-  EXPECT_TRUE(base::Delete(
+  EXPECT_TRUE(base::DeleteFile(
       other_folder.Append(app_name).Append("Contents"), true));
 
   EXPECT_FALSE(shortcut_creator.UpdateShortcuts());
-  EXPECT_FALSE(file_util::PathExists(dst_folder.Append(app_name)));
-  EXPECT_FALSE(file_util::PathExists(
+  EXPECT_FALSE(base::PathExists(dst_folder.Append(app_name)));
+  EXPECT_FALSE(base::PathExists(
       other_folder.Append(app_name).Append("Contents")));
 }
 
@@ -200,7 +200,7 @@
   EXPECT_CALL(shortcut_creator, RevealAppShimInFinder());
 
   EXPECT_TRUE(shortcut_creator.CreateShortcuts());
-  EXPECT_TRUE(file_util::PathExists(dst_path));
+  EXPECT_TRUE(base::PathExists(dst_path));
 
   ssize_t status = getxattr(
       dst_path.value().c_str(), "com.apple.quarantine", NULL, 0, 0, 0);
diff --git a/chrome/browser/web_applications/web_app_win.cc b/chrome/browser/web_applications/web_app_win.cc
index 6e19753..3a6446d 100644
--- a/chrome/browser/web_applications/web_app_win.cc
+++ b/chrome/browser/web_applications/web_app_win.cc
@@ -75,8 +75,8 @@
       icon_file.ReplaceExtension(kIconChecksumFileExt));
 
   // Returns true if icon_file or checksum file is missing.
-  if (!file_util::PathExists(icon_file) ||
-      !file_util::PathExists(checksum_file))
+  if (!base::PathExists(icon_file) ||
+      !base::PathExists(checksum_file))
     return true;
 
   base::MD5Digest persisted_image_checksum;
@@ -143,7 +143,7 @@
         shortcut_file = shortcut_file.InsertBeforeExtensionASCII(
             base::StringPrintf(" (%d)", i));
       }
-      if (file_util::PathExists(shortcut_file) &&
+      if (base::PathExists(shortcut_file) &&
           IsAppShortcutForProfile(shortcut_file, profile_path)) {
         shortcut_paths.push_back(shortcut_file);
       }
@@ -166,7 +166,7 @@
     web_app::ShortcutCreationPolicy creation_policy,
     std::vector<base::FilePath>* out_filenames) {
   // Ensure web_app_path exists.
-  if (!file_util::PathExists(web_app_path) &&
+  if (!base::PathExists(web_app_path) &&
       !file_util::CreateDirectory(web_app_path)) {
     return false;
   }
@@ -243,7 +243,7 @@
     shortcut_properties.set_icon(icon_file, 0);
     shortcut_properties.set_app_id(app_id);
     shortcut_properties.set_dual_mode(false);
-    if (!file_util::PathExists(shortcut_file.DirName()) &&
+    if (!base::PathExists(shortcut_file.DirName()) &&
         !file_util::CreateDirectory(shortcut_file.DirName())) {
       NOTREACHED();
       return false;
@@ -320,7 +320,7 @@
       // Any shortcut could have been pinned, either by chrome or the user, so
       // they are all unpinned.
       base::win::TaskbarUnpinShortcutLink(j->value().c_str());
-      base::Delete(*j, false);
+      base::DeleteFile(*j, false);
     }
   }
 }
@@ -444,7 +444,7 @@
   // and let the shell know the icon has been modified.
   base::FilePath icon_file = web_app_path.Append(file_name).AddExtension(
       FILE_PATH_LITERAL(".ico"));
-  if (file_util::PathExists(icon_file)) {
+  if (base::PathExists(icon_file)) {
     web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info.favicon);
   }
 }
@@ -461,7 +461,7 @@
   if (PathService::Get(base::DIR_START_MENU, &chrome_apps_dir)) {
     chrome_apps_dir = chrome_apps_dir.Append(GetAppShortcutsSubdirName());
     if (file_util::IsDirectoryEmpty(chrome_apps_dir))
-      base::Delete(chrome_apps_dir, false);
+      base::DeleteFile(chrome_apps_dir, false);
   }
 }
 
@@ -474,7 +474,7 @@
   if (PathService::Get(base::DIR_START_MENU, &chrome_apps_dir)) {
     chrome_apps_dir = chrome_apps_dir.Append(GetAppShortcutsSubdirName());
     if (file_util::IsDirectoryEmpty(chrome_apps_dir))
-      base::Delete(chrome_apps_dir, false);
+      base::DeleteFile(chrome_apps_dir, false);
   }
 }
 
diff --git a/chrome/browser/web_resource/json_asynchronous_unpacker.cc b/chrome/browser/web_resource/json_asynchronous_unpacker.cc
index 8eee8aa..a0f242f 100644
--- a/chrome/browser/web_resource/json_asynchronous_unpacker.cc
+++ b/chrome/browser/web_resource/json_asynchronous_unpacker.cc
@@ -8,9 +8,7 @@
 #include "chrome/browser/web_resource/web_resource_service.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_utility_messages.h"
-#include "chrome/common/web_resource/web_resource_unpacker.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/resource_dispatcher_host.h"
 #include "content/public/browser/utility_process_host.h"
 #include "content/public/browser/utility_process_host_client.h"
 
@@ -34,29 +32,13 @@
   virtual void Start(const std::string& json_data) OVERRIDE {
     AddRef();  // balanced in Cleanup.
 
-    // TODO(willchan): Look for a better signal of whether we're in a unit test
-    // or not. Using |ResourceDispatcherHost::Get()| for this is pretty lame.
-    // If we don't have a ResourceDispatcherHost, assume we're in a test and
-    // run the unpacker directly in-process.
-    bool use_utility_process =
-        content::ResourceDispatcherHost::Get() &&
-        !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess);
-    if (use_utility_process) {
-      BrowserThread::ID thread_id;
-      CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_id));
-      BrowserThread::PostTask(
-          BrowserThread::IO, FROM_HERE,
-          base::Bind(
-              &JSONAsynchronousUnpackerImpl::StartProcessOnIOThread,
-              this, thread_id, json_data));
-    } else {
-      WebResourceUnpacker unpacker(json_data);
-      if (unpacker.Run()) {
-        OnUnpackWebResourceSucceeded(*unpacker.parsed_json());
-      } else {
-        OnUnpackWebResourceFailed(unpacker.error_message());
-      }
-    }
+    BrowserThread::ID thread_id;
+    CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_id));
+    BrowserThread::PostTask(
+        BrowserThread::IO, FROM_HERE,
+        base::Bind(
+            &JSONAsynchronousUnpackerImpl::StartProcessOnIOThread,
+            this, thread_id, json_data));
   }
 
  private:
diff --git a/chrome/browser/web_resource/notification_promo.cc b/chrome/browser/web_resource/notification_promo.cc
index 222f4f5..cda26f6 100644
--- a/chrome/browser/web_resource/notification_promo.cc
+++ b/chrome/browser/web_resource/notification_promo.cc
@@ -316,7 +316,7 @@
 }
 
 // static
-void NotificationPromo::RegisterUserPrefs(
+void NotificationPromo::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   // TODO(dbeam): Registered only for migration. Remove in M28 when
   // we're reasonably sure all prefs are gone.
diff --git a/chrome/browser/web_resource/notification_promo.h b/chrome/browser/web_resource/notification_promo.h
index 0cc8ace..9b3ee45 100644
--- a/chrome/browser/web_resource/notification_promo.h
+++ b/chrome/browser/web_resource/notification_promo.h
@@ -70,7 +70,7 @@
 
   // Register preferences.
   static void RegisterPrefs(PrefRegistrySimple* registry);
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
   static void MigrateUserPrefs(PrefService* user_prefs);
 
  private:
diff --git a/chrome/browser/web_resource/promo_resource_service.cc b/chrome/browser/web_resource/promo_resource_service.cc
index 2c02f63..2431436 100644
--- a/chrome/browser/web_resource/promo_resource_service.cc
+++ b/chrome/browser/web_resource/promo_resource_service.cc
@@ -12,8 +12,8 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/web_resource/notification_promo.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -68,7 +68,7 @@
 }
 
 // static
-void PromoResourceService::RegisterUserPrefs(
+void PromoResourceService::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   // TODO(dbeam): This is registered only for migration; remove in M28
   // when all prefs have been cleared.  http://crbug.com/168887
@@ -76,7 +76,7 @@
       prefs::kNtpPromoResourceCacheUpdate,
       "0",
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-  NotificationPromo::RegisterUserPrefs(registry);
+  NotificationPromo::RegisterProfilePrefs(registry);
 }
 
 // static
diff --git a/chrome/browser/web_resource/promo_resource_service.h b/chrome/browser/web_resource/promo_resource_service.h
index 0e065d7..6ebf6fd 100644
--- a/chrome/browser/web_resource/promo_resource_service.h
+++ b/chrome/browser/web_resource/promo_resource_service.h
@@ -29,7 +29,7 @@
 class PromoResourceService : public WebResourceService {
  public:
   static void RegisterPrefs(PrefRegistrySimple* registry);
-  static void RegisterUserPrefs(user_prefs::PrefRegistrySyncable* registry);
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
   static void MigrateUserPrefs(PrefService* user_prefs);
 
   PromoResourceService();
diff --git a/chrome/browser/web_resource/promo_resource_service_mobile_ntp_unittest.cc b/chrome/browser/web_resource/promo_resource_service_mobile_ntp_unittest.cc
index fd98b20..2c57b24 100644
--- a/chrome/browser/web_resource/promo_resource_service_mobile_ntp_unittest.cc
+++ b/chrome/browser/web_resource/promo_resource_service_mobile_ntp_unittest.cc
@@ -11,9 +11,9 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/web_resource/notification_promo.h"
 #include "chrome/browser/web_resource/promo_resource_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
diff --git a/chrome/browser/web_resource/promo_resource_service_unittest.cc b/chrome/browser/web_resource/promo_resource_service_unittest.cc
index bea1751..3d48e1c 100644
--- a/chrome/browser/web_resource/promo_resource_service_unittest.cc
+++ b/chrome/browser/web_resource/promo_resource_service_unittest.cc
@@ -15,10 +15,10 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/web_resource/notification_promo.h"
 #include "chrome/browser/web_resource/promo_resource_service.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
diff --git a/chrome/browser/web_resource/resource_request_allowed_notifier_unittest.cc b/chrome/browser/web_resource/resource_request_allowed_notifier_unittest.cc
index c8f8e03..ef632fe 100644
--- a/chrome/browser/web_resource/resource_request_allowed_notifier_unittest.cc
+++ b/chrome/browser/web_resource/resource_request_allowed_notifier_unittest.cc
@@ -3,9 +3,9 @@
 // found in the LICENSE file.
 
 #include "base/prefs/testing_pref_service.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/web_resource/eula_accepted_notifier.h"
 #include "chrome/browser/web_resource/resource_request_allowed_notifier_test_util.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/test/test_browser_thread.h"
diff --git a/chrome/browser/webdata/web_data_service.cc b/chrome/browser/webdata/web_data_service.cc
index 15dd155..5367fd34 100644
--- a/chrome/browser/webdata/web_data_service.cc
+++ b/chrome/browser/webdata/web_data_service.cc
@@ -6,13 +6,13 @@
 
 #include "base/bind.h"
 #include "base/stl_util.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/webdata/keyword_table.h"
 #include "chrome/browser/webdata/logins_table.h"
 #include "chrome/browser/webdata/token_service_table.h"
 #include "chrome/browser/webdata/web_apps_table.h"
 #include "chrome/browser/webdata/web_intents_table.h"
-#include "chrome/common/chrome_notification_types.h"
 #include "components/webdata/common/web_database_service.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"