Refactor preference syncing.

The following are the primary changes:
1. Whenever a profile preference is registered, it must specify whether that
preference should be synced or not. Local state preferences do not require this.
However, we DCHECK that local state preferences are in fact registered to the
 local state.
2. We've created a new sync model associator interface, which all datatypes
will eventually implement. This new model associator is designed to be
decoupled from much of the sync internals, and to be owned by the chrome service
being synced. It also implements most of the functionality previous handled by
the change processor.
3. The PrefService now owns its sync model associator
(pref_model_associator), which partially implements the new model associator
functionality. Further work will be done to remove the use of sync
transactions from the model associator, as well as to migrate other datatypes.

BUG=76232
TEST=

Review URL: http://codereview.chromium.org/6905044

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84603 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/about_flags_unittest.cc b/chrome/browser/about_flags_unittest.cc
index 32b002d..21a85cb7 100644
--- a/chrome/browser/about_flags_unittest.cc
+++ b/chrome/browser/about_flags_unittest.cc
@@ -86,11 +86,18 @@
 class AboutFlagsTest : public ::testing::Test {
  protected:
   AboutFlagsTest() {
-    prefs_.RegisterListPref(prefs::kEnabledLabsExperiments);
+    prefs_.RegisterListPref(prefs::kEnabledLabsExperiments,
+                            PrefService::UNSYNCABLE_PREF);
 #if defined(OS_CHROMEOS)
-    prefs_.RegisterBooleanPref(prefs::kLabsMediaplayerEnabled, false);
-    prefs_.RegisterBooleanPref(prefs::kLabsAdvancedFilesystemEnabled, false);
-    prefs_.RegisterBooleanPref(prefs::kUseVerticalTabs, false);
+    prefs_.RegisterBooleanPref(prefs::kLabsMediaplayerEnabled,
+                               false,
+                               PrefService::UNSYNCABLE_PREF);
+    prefs_.RegisterBooleanPref(prefs::kLabsAdvancedFilesystemEnabled,
+                               false,
+                               PrefService::UNSYNCABLE_PREF);
+    prefs_.RegisterBooleanPref(prefs::kUseVerticalTabs,
+                               false,
+                               PrefService::UNSYNCABLE_PREF);
 #endif
     testing::ClearState();
   }
diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc
index 699b93d0..c5f6781 100644
--- a/chrome/browser/autofill/autofill_manager.cc
+++ b/chrome/browser/autofill/autofill_manager.cc
@@ -250,16 +250,24 @@
 
 // static
 void AutofillManager::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kAutofillEnabled, true);
+  prefs->RegisterBooleanPref(prefs::kAutofillEnabled,
+                             true,
+                             PrefService::SYNCABLE_PREF);
 #if defined(OS_MACOSX)
-  prefs->RegisterBooleanPref(prefs::kAutofillAuxiliaryProfilesEnabled, true);
+  prefs->RegisterBooleanPref(prefs::kAutofillAuxiliaryProfilesEnabled,
+                             true,
+                             PrefService::SYNCABLE_PREF);
 #else
-  prefs->RegisterBooleanPref(prefs::kAutofillAuxiliaryProfilesEnabled, false);
+  prefs->RegisterBooleanPref(prefs::kAutofillAuxiliaryProfilesEnabled,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
 #endif
   prefs->RegisterDoublePref(prefs::kAutofillPositiveUploadRate,
-                            kAutofillPositiveUploadRateDefaultValue);
+                            kAutofillPositiveUploadRateDefaultValue,
+                            PrefService::UNSYNCABLE_PREF);
   prefs->RegisterDoublePref(prefs::kAutofillNegativeUploadRate,
-                            kAutofillNegativeUploadRateDefaultValue);
+                            kAutofillNegativeUploadRateDefaultValue,
+                            PrefService::UNSYNCABLE_PREF);
 }
 
 void AutofillManager::DidNavigateMainFramePostCommit(
diff --git a/chrome/browser/background_contents_service.cc b/chrome/browser/background_contents_service.cc
index 4ac5c5f6..1c22b51 100644
--- a/chrome/browser/background_contents_service.cc
+++ b/chrome/browser/background_contents_service.cc
@@ -553,7 +553,8 @@
 
 // static
 void BackgroundContentsService::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterDictionaryPref(prefs::kRegisteredBackgroundContents);
+  prefs->RegisterDictionaryPref(prefs::kRegisteredBackgroundContents,
+                                PrefService::UNSYNCABLE_PREF);
 }
 
 void BackgroundContentsService::AddTabContents(
diff --git a/chrome/browser/bookmarks/bookmark_utils.cc b/chrome/browser/bookmarks/bookmark_utils.cc
index d5846a6..22a2d21 100644
--- a/chrome/browser/bookmarks/bookmark_utils.cc
+++ b/chrome/browser/bookmarks/bookmark_utils.cc
@@ -624,8 +624,12 @@
 }
 
 void RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kShowBookmarkBar, false);
-  prefs->RegisterBooleanPref(prefs::kEditBookmarksEnabled, true);
+  prefs->RegisterBooleanPref(prefs::kShowBookmarkBar,
+                             false,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kEditBookmarksEnabled,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
 }
 
 void GetURLAndTitleToBookmark(TabContents* tab_contents,
diff --git a/chrome/browser/chromeos/audio_mixer_alsa.cc b/chrome/browser/chromeos/audio_mixer_alsa.cc
index 1bb3edc..a97e27a 100644
--- a/chrome/browser/chromeos/audio_mixer_alsa.cc
+++ b/chrome/browser/chromeos/audio_mixer_alsa.cc
@@ -198,9 +198,13 @@
 // static
 void AudioMixerAlsa::RegisterPrefs(PrefService* local_state) {
   if (!local_state->FindPreference(prefs::kAudioVolume))
-    local_state->RegisterDoublePref(prefs::kAudioVolume, kPrefVolumeInvalid);
+    local_state->RegisterDoublePref(prefs::kAudioVolume,
+                                    kPrefVolumeInvalid,
+                                    PrefService::UNSYNCABLE_PREF);
   if (!local_state->FindPreference(prefs::kAudioMute))
-    local_state->RegisterIntegerPref(prefs::kAudioMute, kPrefMuteInvalid);
+    local_state->RegisterIntegerPref(prefs::kAudioMute,
+                                     kPrefMuteInvalid,
+                                     PrefService::UNSYNCABLE_PREF);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/chromeos/customization_document.cc b/chrome/browser/chromeos/customization_document.cc
index 37323cf..35557d9 100644
--- a/chrome/browser/chromeos/customization_document.cc
+++ b/chrome/browser/chromeos/customization_document.cc
@@ -264,7 +264,8 @@
 
 // static
 void ServicesCustomizationDocument::RegisterPrefs(PrefService* local_state) {
-  local_state->RegisterBooleanPref(kServicesCustomizationAppliedPref, false);
+  local_state->RegisterBooleanPref(kServicesCustomizationAppliedPref, false,
+                                   PrefService::UNSYNCABLE_PREF);
 }
 
 // static
diff --git a/chrome/browser/chromeos/login/user_manager.cc b/chrome/browser/chromeos/login/user_manager.cc
index a296993..30afc50e 100644
--- a/chrome/browser/chromeos/login/user_manager.cc
+++ b/chrome/browser/chromeos/login/user_manager.cc
@@ -236,8 +236,9 @@
 
 // static
 void UserManager::RegisterPrefs(PrefService* local_state) {
-  local_state->RegisterListPref(kLoggedInUsers);
-  local_state->RegisterDictionaryPref(kUserImages);
+  local_state->RegisterListPref(kLoggedInUsers, PrefService::UNSYNCABLE_PREF);
+  local_state->RegisterDictionaryPref(kUserImages,
+                                      PrefService::UNSYNCABLE_PREF);
 }
 
 std::vector<UserManager::User> UserManager::GetUsers() const {
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index 1f9db18..d04aae1 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -436,14 +436,24 @@
 
 // static
 void WizardController::RegisterPrefs(PrefService* local_state) {
-  local_state->RegisterBooleanPref(kOobeComplete, false);
-  local_state->RegisterIntegerPref(kDeviceRegistered, -1);
-  local_state->RegisterBooleanPref(kEulaAccepted, false);
-  local_state->RegisterStringPref(kInitialLocale, "en-US");
+  local_state->RegisterBooleanPref(kOobeComplete,
+                                   false,
+                                   PrefService::UNSYNCABLE_PREF);
+  local_state->RegisterIntegerPref(kDeviceRegistered,
+                                   -1,
+                                   PrefService::UNSYNCABLE_PREF);
+  local_state->RegisterBooleanPref(kEulaAccepted,
+                                   false,
+                                   PrefService::UNSYNCABLE_PREF);
+  local_state->RegisterStringPref(kInitialLocale,
+                                  "en-US",
+                                  PrefService::UNSYNCABLE_PREF);
   // Check if the pref is already registered in case
   // Preferences::RegisterUserPrefs runs before this code in the future.
   if (local_state->FindPreference(prefs::kAccessibilityEnabled) == NULL) {
-    local_state->RegisterBooleanPref(prefs::kAccessibilityEnabled, false);
+    local_state->RegisterBooleanPref(prefs::kAccessibilityEnabled,
+                                     false,
+                                     PrefService::UNSYNCABLE_PREF);
   }
 }
 
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index 5dbb17348..8e040c0 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -33,109 +33,154 @@
 
 // static
 void Preferences::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kTapToClickEnabled, false);
-  prefs->RegisterBooleanPref(prefs::kLabsMediaplayerEnabled, false);
-  prefs->RegisterBooleanPref(prefs::kLabsAdvancedFilesystemEnabled, false);
+  prefs->RegisterBooleanPref(prefs::kTapToClickEnabled,
+                             false,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kLabsMediaplayerEnabled,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kLabsAdvancedFilesystemEnabled,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
   // Check if the accessibility pref is already registered, which can happen
   // in WizardController::RegisterPrefs. We still want to try to register
   // the pref here in case of Chrome/Linux with ChromeOS=1.
   if (prefs->FindPreference(prefs::kAccessibilityEnabled) == NULL) {
-    prefs->RegisterBooleanPref(prefs::kAccessibilityEnabled, false);
+    prefs->RegisterBooleanPref(prefs::kAccessibilityEnabled,
+                               false,
+                               PrefService::UNSYNCABLE_PREF);
   }
-  prefs->RegisterIntegerPref(prefs::kTouchpadSensitivity, 3);
-  // Set the default based on the hour clock type of the current locale.
+  prefs->RegisterIntegerPref(prefs::kTouchpadSensitivity,
+                             3,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterBooleanPref(prefs::kUse24HourClock,
-                             base::GetHourClockType() == base::k24HourClock);
-  prefs->RegisterStringPref(prefs::kLanguageCurrentInputMethod, "");
-  prefs->RegisterStringPref(prefs::kLanguagePreviousInputMethod, "");
+                             base::GetHourClockType() == base::k24HourClock,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kLanguageCurrentInputMethod,
+                            "",
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kLanguagePreviousInputMethod,
+                            "",
+                            PrefService::UNSYNCABLE_PREF);
   prefs->RegisterStringPref(prefs::kLanguageHotkeyNextEngineInMenu,
-                            language_prefs::kHotkeyNextEngineInMenu);
+                            language_prefs::kHotkeyNextEngineInMenu,
+                            PrefService::UNSYNCABLE_PREF);
   prefs->RegisterStringPref(prefs::kLanguageHotkeyPreviousEngine,
-                            language_prefs::kHotkeyPreviousEngine);
+                            language_prefs::kHotkeyPreviousEngine,
+                            PrefService::UNSYNCABLE_PREF);
   prefs->RegisterStringPref(prefs::kLanguagePreferredLanguages,
-                            kFallbackInputMethodLocale);
-  prefs->RegisterStringPref(
-      prefs::kLanguagePreloadEngines,
-      input_method::GetHardwareInputMethodId());
+                            kFallbackInputMethodLocale,
+                            PrefService::SYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kLanguagePreloadEngines,
+                            input_method::GetHardwareInputMethodId(),
+                            PrefService::SYNCABLE_PREF);
   for (size_t i = 0; i < language_prefs::kNumChewingBooleanPrefs; ++i) {
     prefs->RegisterBooleanPref(
         language_prefs::kChewingBooleanPrefs[i].pref_name,
-        language_prefs::kChewingBooleanPrefs[i].default_pref_value);
+        language_prefs::kChewingBooleanPrefs[i].default_pref_value,
+        PrefService::UNSYNCABLE_PREF);
   }
   for (size_t i = 0; i < language_prefs::kNumChewingMultipleChoicePrefs; ++i) {
     prefs->RegisterStringPref(
         language_prefs::kChewingMultipleChoicePrefs[i].pref_name,
-        language_prefs::kChewingMultipleChoicePrefs[i].default_pref_value);
+        language_prefs::kChewingMultipleChoicePrefs[i].default_pref_value,
+        PrefService::UNSYNCABLE_PREF);
   }
   prefs->RegisterIntegerPref(
       language_prefs::kChewingHsuSelKeyType.pref_name,
-      language_prefs::kChewingHsuSelKeyType.default_pref_value);
+      language_prefs::kChewingHsuSelKeyType.default_pref_value,
+      PrefService::UNSYNCABLE_PREF);
 
   for (size_t i = 0; i < language_prefs::kNumChewingIntegerPrefs; ++i) {
     prefs->RegisterIntegerPref(
         language_prefs::kChewingIntegerPrefs[i].pref_name,
-        language_prefs::kChewingIntegerPrefs[i].default_pref_value);
+        language_prefs::kChewingIntegerPrefs[i].default_pref_value,
+        PrefService::UNSYNCABLE_PREF);
   }
   prefs->RegisterStringPref(
       prefs::kLanguageHangulKeyboard,
-      language_prefs::kHangulKeyboardNameIDPairs[0].keyboard_id);
+      language_prefs::kHangulKeyboardNameIDPairs[0].keyboard_id,
+      PrefService::SYNCABLE_PREF);
   prefs->RegisterStringPref(prefs::kLanguageHangulHanjaKeys,
-                            language_prefs::kHangulHanjaKeys);
+                            language_prefs::kHangulHanjaKeys,
+                            PrefService::UNSYNCABLE_PREF);
   for (size_t i = 0; i < language_prefs::kNumPinyinBooleanPrefs; ++i) {
     prefs->RegisterBooleanPref(
         language_prefs::kPinyinBooleanPrefs[i].pref_name,
-        language_prefs::kPinyinBooleanPrefs[i].default_pref_value);
+        language_prefs::kPinyinBooleanPrefs[i].default_pref_value,
+        PrefService::UNSYNCABLE_PREF);
   }
   for (size_t i = 0; i < language_prefs::kNumPinyinIntegerPrefs; ++i) {
     prefs->RegisterIntegerPref(
         language_prefs::kPinyinIntegerPrefs[i].pref_name,
-        language_prefs::kPinyinIntegerPrefs[i].default_pref_value);
+        language_prefs::kPinyinIntegerPrefs[i].default_pref_value,
+        PrefService::UNSYNCABLE_PREF);
   }
   prefs->RegisterIntegerPref(
       language_prefs::kPinyinDoublePinyinSchema.pref_name,
-      language_prefs::kPinyinDoublePinyinSchema.default_pref_value);
+      language_prefs::kPinyinDoublePinyinSchema.default_pref_value,
+      PrefService::UNSYNCABLE_PREF);
 
   for (size_t i = 0; i < language_prefs::kNumMozcBooleanPrefs; ++i) {
     prefs->RegisterBooleanPref(
         language_prefs::kMozcBooleanPrefs[i].pref_name,
-        language_prefs::kMozcBooleanPrefs[i].default_pref_value);
+        language_prefs::kMozcBooleanPrefs[i].default_pref_value,
+        PrefService::UNSYNCABLE_PREF);
   }
   for (size_t i = 0; i < language_prefs::kNumMozcMultipleChoicePrefs; ++i) {
     prefs->RegisterStringPref(
         language_prefs::kMozcMultipleChoicePrefs[i].pref_name,
-        language_prefs::kMozcMultipleChoicePrefs[i].default_pref_value);
+        language_prefs::kMozcMultipleChoicePrefs[i].default_pref_value,
+        PrefService::UNSYNCABLE_PREF);
   }
   for (size_t i = 0; i < language_prefs::kNumMozcIntegerPrefs; ++i) {
     prefs->RegisterIntegerPref(
         language_prefs::kMozcIntegerPrefs[i].pref_name,
-        language_prefs::kMozcIntegerPrefs[i].default_pref_value);
+        language_prefs::kMozcIntegerPrefs[i].default_pref_value,
+        PrefService::UNSYNCABLE_PREF);
   }
   prefs->RegisterIntegerPref(prefs::kLanguageXkbRemapSearchKeyTo,
-                             input_method::kSearchKey);
+                             input_method::kSearchKey,
+                             PrefService::SYNCABLE_PREF);
   prefs->RegisterIntegerPref(prefs::kLanguageXkbRemapControlKeyTo,
-                             input_method::kLeftControlKey);
+                             input_method::kLeftControlKey,
+                             PrefService::SYNCABLE_PREF);
   prefs->RegisterIntegerPref(prefs::kLanguageXkbRemapAltKeyTo,
-                             input_method::kLeftAltKey);
-  prefs->RegisterBooleanPref(prefs::kLanguageXkbAutoRepeatEnabled, true);
+                             input_method::kLeftAltKey,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kLanguageXkbAutoRepeatEnabled,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterIntegerPref(prefs::kLanguageXkbAutoRepeatDelay,
-                             language_prefs::kXkbAutoRepeatDelayInMs);
+                             language_prefs::kXkbAutoRepeatDelayInMs,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterIntegerPref(prefs::kLanguageXkbAutoRepeatInterval,
-                             language_prefs::kXkbAutoRepeatIntervalInMs);
+                             language_prefs::kXkbAutoRepeatIntervalInMs,
+                             PrefService::UNSYNCABLE_PREF);
 
   // Screen lock default to off.
-  prefs->RegisterBooleanPref(prefs::kEnableScreenLock, false);
+  prefs->RegisterBooleanPref(prefs::kEnableScreenLock,
+                             false,
+                             PrefService::SYNCABLE_PREF);
 
   // Mobile plan notifications default to on.
-  prefs->RegisterBooleanPref(prefs::kShowPlanNotifications, true);
+  prefs->RegisterBooleanPref(prefs::kShowPlanNotifications,
+                             true,
+                             PrefService::SYNCABLE_PREF);
 
   // 3G first-time usage promo will be shown at least once.
-  prefs->RegisterBooleanPref(prefs::kShow3gPromoNotification, true);
+  prefs->RegisterBooleanPref(prefs::kShow3gPromoNotification,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
 
   // Carrier deal notification shown count defaults to 0.
-  prefs->RegisterIntegerPref(prefs::kCarrierDealPromoShown, 0);
+  prefs->RegisterIntegerPref(prefs::kCarrierDealPromoShown,
+                             0,
+                             PrefService::UNSYNCABLE_PREF);
 
   // The map of timestamps of the last used file browser handlers.
-  prefs->RegisterDictionaryPref(prefs::kLastUsedFileBrowserHandlers);
+  prefs->RegisterDictionaryPref(prefs::kLastUsedFileBrowserHandlers,
+                                PrefService::UNSYNCABLE_PREF);
 }
 
 void Preferences::Init(PrefService* prefs) {
diff --git a/chrome/browser/chromeos/status/input_method_menu.cc b/chrome/browser/chromeos/status/input_method_menu.cc
index 71d1e64..9594b4f 100644
--- a/chrome/browser/chromeos/status/input_method_menu.cc
+++ b/chrome/browser/chromeos/status/input_method_menu.cc
@@ -644,7 +644,9 @@
 }
 
 void InputMethodMenu::RegisterPrefs(PrefService* local_state) {
-  local_state->RegisterStringPref(language_prefs::kPreferredKeyboardLayout, "");
+  local_state->RegisterStringPref(language_prefs::kPreferredKeyboardLayout,
+                                  "",
+                                  PrefService::UNSYNCABLE_PREF);
 }
 
 void InputMethodMenu::Observe(NotificationType type,
diff --git a/chrome/browser/chromeos/user_cros_settings_provider.cc b/chrome/browser/chromeos/user_cros_settings_provider.cc
index 8286428..f44cb43 100644
--- a/chrome/browser/chromeos/user_cros_settings_provider.cc
+++ b/chrome/browser/chromeos/user_cros_settings_provider.cc
@@ -77,17 +77,25 @@
 
 void RegisterSetting(PrefService* local_state, const std::string& pref_path) {
   local_state->RegisterBooleanPref((pref_path + kTrustedSuffix).c_str(),
-                                   false);
+                                   false,
+                                   PrefService::UNSYNCABLE_PREF);
   if (IsControlledBooleanSetting(pref_path)) {
     if (pref_path == kSignedDataRoamingEnabled)
-      local_state->RegisterBooleanPref(pref_path.c_str(), false);
+      local_state->RegisterBooleanPref(pref_path.c_str(),
+                                       false,
+                                       PrefService::UNSYNCABLE_PREF);
     else
-      local_state->RegisterBooleanPref(pref_path.c_str(), true);
+      local_state->RegisterBooleanPref(pref_path.c_str(),
+                                       true,
+                                       PrefService::UNSYNCABLE_PREF);
   } else if (IsControlledStringSetting(pref_path)) {
-    local_state->RegisterStringPref(pref_path.c_str(), "");
+    local_state->RegisterStringPref(pref_path.c_str(),
+                                    "",
+                                    PrefService::UNSYNCABLE_PREF);
   } else {
     DCHECK(IsControlledListSetting(pref_path));
-    local_state->RegisterListPref(pref_path.c_str());
+    local_state->RegisterListPref(pref_path.c_str(),
+                                  PrefService::UNSYNCABLE_PREF);
   }
 }
 
diff --git a/chrome/browser/content_settings/content_settings_notification_provider.cc b/chrome/browser/content_settings/content_settings_notification_provider.cc
index 835bb144..fe3554ca 100644
--- a/chrome/browser/content_settings/content_settings_notification_provider.cc
+++ b/chrome/browser/content_settings/content_settings_notification_provider.cc
@@ -35,9 +35,11 @@
 // static
 void NotificationProvider::RegisterUserPrefs(PrefService* user_prefs) {
   if (!user_prefs->FindPreference(prefs::kDesktopNotificationAllowedOrigins))
-    user_prefs->RegisterListPref(prefs::kDesktopNotificationAllowedOrigins);
+    user_prefs->RegisterListPref(prefs::kDesktopNotificationAllowedOrigins,
+                                 PrefService::SYNCABLE_PREF);
   if (!user_prefs->FindPreference(prefs::kDesktopNotificationDeniedOrigins))
-    user_prefs->RegisterListPref(prefs::kDesktopNotificationDeniedOrigins);
+    user_prefs->RegisterListPref(prefs::kDesktopNotificationDeniedOrigins,
+                                 PrefService::SYNCABLE_PREF);
 }
 
 // TODO(markusheintz): Re-factoring in progress. Do not move or touch the
diff --git a/chrome/browser/content_settings/content_settings_policy_provider.cc b/chrome/browser/content_settings/content_settings_policy_provider.cc
index d80da5d..0855c2d 100644
--- a/chrome/browser/content_settings/content_settings_policy_provider.cc
+++ b/chrome/browser/content_settings/content_settings_policy_provider.cc
@@ -241,15 +241,20 @@
   // Preferences for default content setting policies. A policy is not set of
   // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT.
   prefs->RegisterIntegerPref(prefs::kManagedDefaultCookiesSetting,
-      CONTENT_SETTING_DEFAULT);
+                             CONTENT_SETTING_DEFAULT,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterIntegerPref(prefs::kManagedDefaultImagesSetting,
-      CONTENT_SETTING_DEFAULT);
+                             CONTENT_SETTING_DEFAULT,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterIntegerPref(prefs::kManagedDefaultJavaScriptSetting,
-      CONTENT_SETTING_DEFAULT);
+                             CONTENT_SETTING_DEFAULT,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterIntegerPref(prefs::kManagedDefaultPluginsSetting,
-      CONTENT_SETTING_DEFAULT);
+                             CONTENT_SETTING_DEFAULT,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterIntegerPref(prefs::kManagedDefaultPopupsSetting,
-      CONTENT_SETTING_DEFAULT);
+                             CONTENT_SETTING_DEFAULT,
+                             PrefService::UNSYNCABLE_PREF);
 }
 
 // ////////////////////////////////////////////////////////////////////////////
@@ -257,17 +262,28 @@
 
 // static
 void PolicyProvider::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterListPref(prefs::kManagedCookiesAllowedForUrls);
-  prefs->RegisterListPref(prefs::kManagedCookiesBlockedForUrls);
-  prefs->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls);
-  prefs->RegisterListPref(prefs::kManagedImagesAllowedForUrls);
-  prefs->RegisterListPref(prefs::kManagedImagesBlockedForUrls);
-  prefs->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls);
-  prefs->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls);
-  prefs->RegisterListPref(prefs::kManagedPluginsAllowedForUrls);
-  prefs->RegisterListPref(prefs::kManagedPluginsBlockedForUrls);
-  prefs->RegisterListPref(prefs::kManagedPopupsAllowedForUrls);
-  prefs->RegisterListPref(prefs::kManagedPopupsBlockedForUrls);
+  prefs->RegisterListPref(prefs::kManagedCookiesAllowedForUrls,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kManagedCookiesBlockedForUrls,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kManagedImagesAllowedForUrls,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kManagedImagesBlockedForUrls,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kManagedPluginsAllowedForUrls,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kManagedPluginsBlockedForUrls,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kManagedPopupsAllowedForUrls,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kManagedPopupsBlockedForUrls,
+                          PrefService::UNSYNCABLE_PREF);
 }
 
 PolicyProvider::PolicyProvider(Profile* profile)
diff --git a/chrome/browser/content_settings/content_settings_pref_provider.cc b/chrome/browser/content_settings/content_settings_pref_provider.cc
index acf4e91..467d502d 100644
--- a/chrome/browser/content_settings/content_settings_pref_provider.cc
+++ b/chrome/browser/content_settings/content_settings_pref_provider.cc
@@ -313,12 +313,14 @@
   DictionaryValue* default_content_settings = new DictionaryValue();
   SetDefaultContentSettings(default_content_settings);
   prefs->RegisterDictionaryPref(prefs::kDefaultContentSettings,
-                                default_content_settings);
+                                default_content_settings,
+                                PrefService::SYNCABLE_PREF);
 
   // Obsolete prefs, for migrations:
   prefs->RegisterIntegerPref(
       prefs::kDesktopNotificationDefaultContentSetting,
-          kDefaultSettings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS]);
+      kDefaultSettings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS],
+      PrefService::SYNCABLE_PREF);
 }
 
 // ////////////////////////////////////////////////////////////////////////////
@@ -327,13 +329,18 @@
 
 // static
 void PrefProvider::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterIntegerPref(prefs::kContentSettingsVersion,
-      ContentSettingsPattern::kContentSettingsPatternVersion);
-  prefs->RegisterDictionaryPref(prefs::kContentSettingsPatterns);
+  prefs->RegisterIntegerPref(
+      prefs::kContentSettingsVersion,
+      ContentSettingsPattern::kContentSettingsPatternVersion,
+      PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kContentSettingsPatterns,
+                                PrefService::SYNCABLE_PREF);
 
   // Obsolete prefs, for migration:
-  prefs->RegisterListPref(prefs::kPopupWhitelistedHosts);
-  prefs->RegisterDictionaryPref(prefs::kPerHostContentSettings);
+  prefs->RegisterListPref(prefs::kPopupWhitelistedHosts,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kPerHostContentSettings,
+                                PrefService::UNSYNCABLE_PREF);
 }
 
 PrefProvider::PrefProvider(Profile* profile)
diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc
index 09f4f5c..ffc253b0 100644
--- a/chrome/browser/content_settings/host_content_settings_map.cc
+++ b/chrome/browser/content_settings/host_content_settings_map.cc
@@ -113,13 +113,20 @@
 
 // static
 void HostContentSettingsMap::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kBlockThirdPartyCookies, false);
-  prefs->RegisterBooleanPref(prefs::kBlockNonsandboxedPlugins, false);
-  prefs->RegisterIntegerPref(prefs::kContentSettingsWindowLastTabIndex, 0);
+  prefs->RegisterBooleanPref(prefs::kBlockThirdPartyCookies,
+                             false,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kBlockNonsandboxedPlugins,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterIntegerPref(prefs::kContentSettingsWindowLastTabIndex,
+                             0,
+                             PrefService::UNSYNCABLE_PREF);
 
   // Obsolete prefs, for migration:
   prefs->RegisterIntegerPref(prefs::kCookieBehavior,
-                             net::StaticCookiePolicy::ALLOW_ALL_COOKIES);
+                             net::StaticCookiePolicy::ALLOW_ALL_COOKIES,
+                             PrefService::UNSYNCABLE_PREF);
 
   // Register the prefs for the content settings providers.
   content_settings::PrefDefaultProvider::RegisterUserPrefs(prefs);
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
index f2ea2f6..7edb280 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -274,9 +274,12 @@
 }
 
 void ProtocolHandlerRegistry::RegisterPrefs(PrefService* prefService) {
-  prefService->RegisterListPref(prefs::kRegisteredProtocolHandlers);
-  prefService->RegisterListPref(prefs::kIgnoredProtocolHandlers);
-  prefService->RegisterBooleanPref(prefs::kCustomHandlersEnabled, true);
+  prefService->RegisterListPref(prefs::kRegisteredProtocolHandlers,
+                                PrefService::UNSYNCABLE_PREF);
+  prefService->RegisterListPref(prefs::kIgnoredProtocolHandlers,
+                                PrefService::UNSYNCABLE_PREF);
+  prefService->RegisterBooleanPref(prefs::kCustomHandlersEnabled, true,
+                                   PrefService::UNSYNCABLE_PREF);
 }
 
 void ProtocolHandlerRegistry::SetDefault(const ProtocolHandler& handler) {
diff --git a/chrome/browser/debugger/devtools_manager.cc b/chrome/browser/debugger/devtools_manager.cc
index 61dec4b..34e935d5 100644
--- a/chrome/browser/debugger/devtools_manager.cc
+++ b/chrome/browser/debugger/devtools_manager.cc
@@ -36,7 +36,9 @@
 
 // static
 void DevToolsManager::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kDevToolsOpenDocked, true);
+  prefs->RegisterBooleanPref(prefs::kDevToolsOpenDocked,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
 }
 
 DevToolsManager::DevToolsManager()
diff --git a/chrome/browser/debugger/devtools_window.cc b/chrome/browser/debugger/devtools_window.cc
index 8145ff7..f824768 100644
--- a/chrome/browser/debugger/devtools_window.cc
+++ b/chrome/browser/debugger/devtools_window.cc
@@ -226,7 +226,7 @@
 
   PrefService* prefs = profile_->GetPrefs();
   if (!prefs->FindPreference(wp_key.c_str())) {
-    prefs->RegisterDictionaryPref(wp_key.c_str());
+    prefs->RegisterDictionaryPref(wp_key.c_str(), PrefService::UNSYNCABLE_PREF);
   }
 
   const DictionaryValue* wp_pref = prefs->GetDictionary(wp_key.c_str());
diff --git a/chrome/browser/download/download_prefs.cc b/chrome/browser/download/download_prefs.cc
index 6d1cd6753..d55db9a22 100644
--- a/chrome/browser/download/download_prefs.cc
+++ b/chrome/browser/download/download_prefs.cc
@@ -46,17 +46,25 @@
 
 // static
 void DownloadPrefs::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kPromptForDownload, false);
-  prefs->RegisterStringPref(prefs::kDownloadExtensionsToOpen, "");
-  prefs->RegisterBooleanPref(prefs::kDownloadDirUpgraded, false);
+  prefs->RegisterBooleanPref(prefs::kPromptForDownload,
+                             false,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDownloadExtensionsToOpen,
+                            "",
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kDownloadDirUpgraded,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterIntegerPref(prefs::kSaveFileType,
-                             SavePackage::SAVE_AS_COMPLETE_HTML);
+                             SavePackage::SAVE_AS_COMPLETE_HTML,
+                             PrefService::UNSYNCABLE_PREF);
 
   // The default download path is userprofile\download.
   const FilePath& default_download_path =
       download_util::GetDefaultDownloadDirectory();
   prefs->RegisterFilePathPref(prefs::kDownloadDefaultDirectory,
-                              default_download_path);
+                              default_download_path,
+                              PrefService::UNSYNCABLE_PREF);
 
 #if defined(OS_CHROMEOS)
   // Ensure that the download directory specified in the preferences exists.
diff --git a/chrome/browser/extensions/apps_promo.cc b/chrome/browser/extensions/apps_promo.cc
index efbcecd..8c43af9 100644
--- a/chrome/browser/extensions/apps_promo.cc
+++ b/chrome/browser/extensions/apps_promo.cc
@@ -29,10 +29,15 @@
 void AppsPromo::RegisterUserPrefs(PrefService* prefs) {
   // Set the default value for the counter to max+1 since we don't install
   // default apps for new users.
-  prefs->RegisterIntegerPref(
-      prefs::kAppsPromoCounter, kDefaultAppsCounterMax + 1);
-  prefs->RegisterBooleanPref(prefs::kDefaultAppsInstalled, false);
-  prefs->RegisterStringPref(prefs::kNTPWebStorePromoLastId, std::string());
+  prefs->RegisterIntegerPref(prefs::kAppsPromoCounter,
+                             kDefaultAppsCounterMax + 1,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kDefaultAppsInstalled,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kNTPWebStorePromoLastId,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
 }
 
 // static
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index b77181f..e6c9395 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -1544,12 +1544,20 @@
 
 // static
 void ExtensionPrefs::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterDictionaryPref(kExtensionsPref);
-  prefs->RegisterListPref(kExtensionToolbar);
-  prefs->RegisterIntegerPref(prefs::kExtensionToolbarSize, -1);
-  prefs->RegisterDictionaryPref(kExtensionsBlacklistUpdate);
-  prefs->RegisterListPref(prefs::kExtensionInstallAllowList);
-  prefs->RegisterListPref(prefs::kExtensionInstallDenyList);
-  prefs->RegisterListPref(prefs::kExtensionInstallForceList);
-  prefs->RegisterStringPref(kWebStoreLogin, std::string() /* default_value */);
+  prefs->RegisterDictionaryPref(kExtensionsPref, PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(kExtensionToolbar, PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterIntegerPref(prefs::kExtensionToolbarSize,
+                             -1,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(kExtensionsBlacklistUpdate,
+                                PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kExtensionInstallAllowList,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kExtensionInstallDenyList,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kExtensionInstallForceList,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(kWebStoreLogin,
+                            std::string() /* default_value */,
+                            PrefService::UNSYNCABLE_PREF);
 }
diff --git a/chrome/browser/extensions/extension_prefs_unittest.cc b/chrome/browser/extensions/extension_prefs_unittest.cc
index 866b52f3..bf7f0a27 100644
--- a/chrome/browser/extensions/extension_prefs_unittest.cc
+++ b/chrome/browser/extensions/extension_prefs_unittest.cc
@@ -678,10 +678,18 @@
   }
 
   void RegisterPreferences() {
-    prefs()->pref_service()->RegisterStringPref(kPref1, kDefaultPref1);
-    prefs()->pref_service()->RegisterStringPref(kPref2, kDefaultPref2);
-    prefs()->pref_service()->RegisterStringPref(kPref3, kDefaultPref3);
-    prefs()->pref_service()->RegisterStringPref(kPref4, kDefaultPref4);
+    prefs()->pref_service()->RegisterStringPref(kPref1,
+                                                kDefaultPref1,
+                                                PrefService::UNSYNCABLE_PREF);
+    prefs()->pref_service()->RegisterStringPref(kPref2,
+                                                kDefaultPref2,
+                                                PrefService::UNSYNCABLE_PREF);
+    prefs()->pref_service()->RegisterStringPref(kPref3,
+                                                kDefaultPref3,
+                                                PrefService::UNSYNCABLE_PREF);
+    prefs()->pref_service()->RegisterStringPref(kPref4,
+                                                kDefaultPref4,
+                                                PrefService::UNSYNCABLE_PREF);
   }
 
   void InstallExtControlledPref(Extension *ext,
diff --git a/chrome/browser/extensions/extension_updater.cc b/chrome/browser/extensions/extension_updater.cc
index 57adabdb..a340755 100644
--- a/chrome/browser/extensions/extension_updater.cc
+++ b/chrome/browser/extensions/extension_updater.cc
@@ -499,12 +499,15 @@
 static void EnsureInt64PrefRegistered(PrefService* prefs,
                                       const char name[]) {
   if (!prefs->FindPreference(name))
-    prefs->RegisterInt64Pref(name, 0);
+    prefs->RegisterInt64Pref(name, 0, PrefService::UNSYNCABLE_PREF);
 }
 
 static void EnsureBlacklistVersionPrefRegistered(PrefService* prefs) {
-  if (!prefs->FindPreference(kExtensionBlacklistUpdateVersion))
-    prefs->RegisterStringPref(kExtensionBlacklistUpdateVersion, "0");
+  if (!prefs->FindPreference(kExtensionBlacklistUpdateVersion)) {
+    prefs->RegisterStringPref(kExtensionBlacklistUpdateVersion,
+                              "0",
+                              PrefService::UNSYNCABLE_PREF);
+  }
 }
 
 // The overall goal here is to balance keeping clients up to date while
diff --git a/chrome/browser/extensions/extension_web_ui.cc b/chrome/browser/extensions/extension_web_ui.cc
index 6c7e0d86..e398c468 100644
--- a/chrome/browser/extensions/extension_web_ui.cc
+++ b/chrome/browser/extensions/extension_web_ui.cc
@@ -240,7 +240,8 @@
 
 // static
 void ExtensionWebUI::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterDictionaryPref(kExtensionURLOverrides);
+  prefs->RegisterDictionaryPref(kExtensionURLOverrides,
+                                PrefService::UNSYNCABLE_PREF);
 }
 
 // static
diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc
index 5b1fe2b..8022dc4 100644
--- a/chrome/browser/extensions/extensions_ui.cc
+++ b/chrome/browser/extensions/extensions_ui.cc
@@ -839,5 +839,7 @@
 
 // static
 void ExtensionsUI::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kExtensionsUIDeveloperMode, false);
+  prefs->RegisterBooleanPref(prefs::kExtensionsUIDeveloperMode,
+                             false,
+                             PrefService::SYNCABLE_PREF);
 }
diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc
index a7390ec..24ff8e9 100644
--- a/chrome/browser/first_run/first_run.cc
+++ b/chrome/browser/first_run/first_run.cc
@@ -409,8 +409,7 @@
   if (!local_state)
     return false;
   if (!local_state->FindPreference(prefs::kShouldUseOEMFirstRunBubble)) {
-    local_state->RegisterBooleanPref(prefs::kShouldUseOEMFirstRunBubble,
-                                     false);
+    local_state->RegisterBooleanPref(prefs::kShouldUseOEMFirstRunBubble, false);
     local_state->SetBoolean(prefs::kShouldUseOEMFirstRunBubble, true);
   }
   return true;
diff --git a/chrome/browser/geolocation/geolocation_content_settings_map.cc b/chrome/browser/geolocation/geolocation_content_settings_map.cc
index 5239bf2..daee1bd 100644
--- a/chrome/browser/geolocation/geolocation_content_settings_map.cc
+++ b/chrome/browser/geolocation/geolocation_content_settings_map.cc
@@ -50,8 +50,10 @@
 // static
 void GeolocationContentSettingsMap::RegisterUserPrefs(PrefService* prefs) {
   prefs->RegisterIntegerPref(prefs::kGeolocationDefaultContentSetting,
-                             CONTENT_SETTING_ASK);
-  prefs->RegisterDictionaryPref(prefs::kGeolocationContentSettings);
+                             CONTENT_SETTING_ASK,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kGeolocationContentSettings,
+                                PrefService::SYNCABLE_PREF);
 }
 
 ContentSetting GeolocationContentSettingsMap::GetDefaultContentSetting() const {
diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc
index 35fbb31..d063092 100644
--- a/chrome/browser/instant/instant_controller.cc
+++ b/chrome/browser/instant/instant_controller.cc
@@ -58,10 +58,18 @@
 
 // static
 void InstantController::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kInstantConfirmDialogShown, false);
-  prefs->RegisterBooleanPref(prefs::kInstantEnabled, false);
-  prefs->RegisterBooleanPref(prefs::kInstantEnabledOnce, false);
-  prefs->RegisterInt64Pref(prefs::kInstantEnabledTime, false);
+  prefs->RegisterBooleanPref(prefs::kInstantConfirmDialogShown,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kInstantEnabled,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kInstantEnabledOnce,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterInt64Pref(prefs::kInstantEnabledTime,
+                           false,
+                           PrefService::UNSYNCABLE_PREF);
   PromoCounter::RegisterUserPrefs(prefs, prefs::kInstantPromo);
 }
 
diff --git a/chrome/browser/instant/promo_counter.cc b/chrome/browser/instant/promo_counter.cc
index 91df78e..52e1afcc 100644
--- a/chrome/browser/instant/promo_counter.cc
+++ b/chrome/browser/instant/promo_counter.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -39,9 +39,15 @@
 // static
 void PromoCounter::RegisterUserPrefs(PrefService* prefs,
                                      const std::string& base_key) {
-  prefs->RegisterBooleanPref((base_key + kShowKey).c_str(), true);
-  prefs->RegisterIntegerPref((base_key + kNumSessionsKey).c_str(), 0);
-  prefs->RegisterInt64Pref((base_key + kInitialTimeKey).c_str(), 0);
+  prefs->RegisterBooleanPref((base_key + kShowKey).c_str(),
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterIntegerPref((base_key + kNumSessionsKey).c_str(),
+                             0,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterInt64Pref((base_key + kInitialTimeKey).c_str(),
+                           0,
+                           PrefService::UNSYNCABLE_PREF);
 }
 
 bool PromoCounter::ShouldShow(base::Time current_time) {
diff --git a/chrome/browser/net/net_pref_observer.cc b/chrome/browser/net/net_pref_observer.cc
index 597af940..b125dae 100644
--- a/chrome/browser/net/net_pref_observer.cc
+++ b/chrome/browser/net/net_pref_observer.cc
@@ -71,7 +71,13 @@
 
 // static
 void NetPrefObserver::RegisterPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kNetworkPredictionEnabled, true);
-  prefs->RegisterBooleanPref(prefs::kDisableSpdy, false);
-  prefs->RegisterBooleanPref(prefs::kHttpThrottlingEnabled, false);
+  prefs->RegisterBooleanPref(prefs::kNetworkPredictionEnabled,
+                             true,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kDisableSpdy,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kHttpThrottlingEnabled,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
 }
diff --git a/chrome/browser/net/predictor_api.cc b/chrome/browser/net/predictor_api.cc
index 5cdf5c9..9f80f280 100644
--- a/chrome/browser/net/predictor_api.cc
+++ b/chrome/browser/net/predictor_api.cc
@@ -145,8 +145,10 @@
 }
 
 void RegisterUserPrefs(PrefService* user_prefs) {
-  user_prefs->RegisterListPref(prefs::kDnsPrefetchingStartupList);
-  user_prefs->RegisterListPref(prefs::kDnsPrefetchingHostReferralList);
+  user_prefs->RegisterListPref(prefs::kDnsPrefetchingStartupList,
+                               PrefService::UNSYNCABLE_PREF);
+  user_prefs->RegisterListPref(prefs::kDnsPrefetchingHostReferralList,
+                               PrefService::UNSYNCABLE_PREF);
 }
 
 // When enabled, we use the following instance to service all requests in the
@@ -414,8 +416,10 @@
   int current_version =
       local_state->GetInteger(prefs::kMultipleProfilePrefMigration);
   if ((current_version & browser::DNS_PREFS) == 0) {
-    local_state->RegisterListPref(prefs::kDnsStartupPrefetchList);
-    local_state->RegisterListPref(prefs::kDnsHostReferralList);
+    local_state->RegisterListPref(prefs::kDnsStartupPrefetchList,
+                                  PrefService::UNSYNCABLE_PREF);
+    local_state->RegisterListPref(prefs::kDnsHostReferralList,
+                                  PrefService::UNSYNCABLE_PREF);
     local_state->ClearPref(prefs::kDnsStartupPrefetchList);
     local_state->ClearPref(prefs::kDnsHostReferralList);
     local_state->SetInteger(prefs::kMultipleProfilePrefMigration,
diff --git a/chrome/browser/net/pref_proxy_config_service.cc b/chrome/browser/net/pref_proxy_config_service.cc
index f867923..a07a340 100644
--- a/chrome/browser/net/pref_proxy_config_service.cc
+++ b/chrome/browser/net/pref_proxy_config_service.cc
@@ -269,5 +269,7 @@
 // static
 void PrefProxyConfigService::RegisterPrefs(PrefService* pref_service) {
   DictionaryValue* default_settings = ProxyConfigDictionary::CreateSystem();
-  pref_service->RegisterDictionaryPref(prefs::kProxy, default_settings);
+  pref_service->RegisterDictionaryPref(prefs::kProxy,
+                                       default_settings,
+                                       PrefService::UNSYNCABLE_PREF);
 }
diff --git a/chrome/browser/net/ssl_config_service_manager_pref.cc b/chrome/browser/net/ssl_config_service_manager_pref.cc
index 71e385b..54ab554 100644
--- a/chrome/browser/net/ssl_config_service_manager_pref.cc
+++ b/chrome/browser/net/ssl_config_service_manager_pref.cc
@@ -125,15 +125,18 @@
   net::SSLConfig default_config;
   if (!prefs->FindPreference(prefs::kCertRevocationCheckingEnabled)) {
     prefs->RegisterBooleanPref(prefs::kCertRevocationCheckingEnabled,
-                               default_config.rev_checking_enabled);
+                               default_config.rev_checking_enabled,
+                               PrefService::UNSYNCABLE_PREF);
   }
   if (!prefs->FindPreference(prefs::kSSL3Enabled)) {
     prefs->RegisterBooleanPref(prefs::kSSL3Enabled,
-                               default_config.ssl3_enabled);
+                               default_config.ssl3_enabled,
+                               PrefService::UNSYNCABLE_PREF);
   }
   if (!prefs->FindPreference(prefs::kTLS1Enabled)) {
     prefs->RegisterBooleanPref(prefs::kTLS1Enabled,
-                               default_config.tls1_enabled);
+                               default_config.tls1_enabled,
+                               PrefService::UNSYNCABLE_PREF);
   }
 }
 
diff --git a/chrome/browser/password_manager/password_manager.cc b/chrome/browser/password_manager/password_manager.cc
index b5dc14c3a..b08330fd 100644
--- a/chrome/browser/password_manager/password_manager.cc
+++ b/chrome/browser/password_manager/password_manager.cc
@@ -24,8 +24,12 @@
 
 // static
 void PasswordManager::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kPasswordManagerEnabled, true);
-  prefs->RegisterBooleanPref(prefs::kPasswordManagerAllowShowPasswords, true);
+  prefs->RegisterBooleanPref(prefs::kPasswordManagerEnabled,
+                             true,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kPasswordManagerAllowShowPasswords,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
 }
 
 // This routine is called when PasswordManagers are constructed.
diff --git a/chrome/browser/password_manager/password_store_default.cc b/chrome/browser/password_manager/password_store_default.cc
index d99ba4a..0adf126 100644
--- a/chrome/browser/password_manager/password_store_default.cc
+++ b/chrome/browser/password_manager/password_store_default.cc
@@ -94,7 +94,8 @@
   }
   if (handles_.empty()) {
     profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
-                                              true);
+                                              true,
+                                              PrefService::UNSYNCABLE_PREF);
   }
 }
 
diff --git a/chrome/browser/password_manager/password_store_default_unittest.cc b/chrome/browser/password_manager/password_store_default_unittest.cc
index 212de2fe..1b6bd8d 100644
--- a/chrome/browser/password_manager/password_store_default_unittest.cc
+++ b/chrome/browser/password_manager/password_store_default_unittest.cc
@@ -152,7 +152,8 @@
 TEST_F(PasswordStoreDefaultTest, NonASCIIData) {
   // Prentend that the migration has already taken place.
   profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
-                                            true);
+                                            true,
+                                            PrefService::UNSYNCABLE_PREF);
 
   // Initializing the PasswordStore shouldn't trigger a migration.
   scoped_refptr<PasswordStoreDefault> store(
@@ -399,7 +400,8 @@
 
   // Prentend that the migration has already taken place.
   profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
-                                            true);
+                                            true,
+                                            PrefService::UNSYNCABLE_PREF);
 
   // Initializing the PasswordStore shouldn't trigger a migration.
   scoped_refptr<PasswordStore> store(
@@ -430,7 +432,8 @@
 TEST_F(PasswordStoreDefaultTest, Notifications) {
   // Prentend that the migration has already taken place.
   profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
-                                            true);
+                                            true,
+                                            PrefService::UNSYNCABLE_PREF);
 
   // Initializing the PasswordStore shouldn't trigger a migration.
   scoped_refptr<PasswordStore> store(
diff --git a/chrome/browser/password_manager/password_store_win_unittest.cc b/chrome/browser/password_manager/password_store_win_unittest.cc
index 6477b12..310b9e2 100644
--- a/chrome/browser/password_manager/password_store_win_unittest.cc
+++ b/chrome/browser/password_manager/password_store_win_unittest.cc
@@ -169,7 +169,8 @@
 
   // Prentend that the migration has already taken place.
   profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
-                                            true);
+                                            true,
+                                            PrefService::UNSYNCABLE_PREF);
 
   // Initializing the PasswordStore shouldn't trigger a migration.
   scoped_refptr<PasswordStore> store(
@@ -228,7 +229,8 @@
 TEST_F(PasswordStoreWinTest, OutstandingWDSQueries) {
   // Prentend that the migration has already taken place.
   profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
-                                            true);
+                                            true,
+                                            PrefService::UNSYNCABLE_PREF);
 
   // Initializing the PasswordStore shouldn't trigger a migration.
   scoped_refptr<PasswordStore> store(
@@ -278,7 +280,8 @@
 
   // Prentend that the migration has already taken place.
   profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
-                                            true);
+                                            true,
+                                            PrefService::UNSYNCABLE_PREF);
 
   // Initializing the PasswordStore shouldn't trigger a migration.
   scoped_refptr<PasswordStore> store(
diff --git a/chrome/browser/password_manager/password_store_x_unittest.cc b/chrome/browser/password_manager/password_store_x_unittest.cc
index 721368d..7e6ed72 100644
--- a/chrome/browser/password_manager/password_store_x_unittest.cc
+++ b/chrome/browser/password_manager/password_store_x_unittest.cc
@@ -475,7 +475,8 @@
 
   // Prentend that the migration has already taken place.
   profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
-                                            true);
+                                            true,
+                                            PrefService::UNSYNCABLE_PREF);
 
   // Initializing the PasswordStore shouldn't trigger a migration.
   scoped_refptr<PasswordStoreX> store(
@@ -508,7 +509,8 @@
 TEST_P(PasswordStoreXTest, Notifications) {
   // Pretend that the migration has already taken place.
   profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
-                                            true);
+                                            true,
+                                            PrefService::UNSYNCABLE_PREF);
 
   // Initializing the PasswordStore shouldn't trigger a migration.
   scoped_refptr<PasswordStoreX> store(
@@ -646,7 +648,8 @@
 
   // Pretend that the WDS migration has already taken place.
   profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
-                                            true);
+                                            true,
+                                            PrefService::UNSYNCABLE_PREF);
 
   // Initializing the PasswordStore shouldn't trigger a native migration (yet).
   scoped_refptr<PasswordStoreX> store(
diff --git a/chrome/browser/plugin_updater.cc b/chrome/browser/plugin_updater.cc
index 95c2c5fa..6033c73 100644
--- a/chrome/browser/plugin_updater.cc
+++ b/chrome/browser/plugin_updater.cc
@@ -339,8 +339,12 @@
   FilePath internal_dir;
   PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &internal_dir);
   prefs->RegisterFilePathPref(prefs::kPluginsLastInternalDirectory,
-                              internal_dir);
-  prefs->RegisterListPref(prefs::kPluginsDisabledPlugins);
-  prefs->RegisterListPref(prefs::kPluginsDisabledPluginsExceptions);
-  prefs->RegisterListPref(prefs::kPluginsEnabledPlugins);
+                              internal_dir,
+                              PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kPluginsDisabledPlugins,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kPluginsDisabledPluginsExceptions,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kPluginsEnabledPlugins,
+                          PrefService::UNSYNCABLE_PREF);
 }
diff --git a/chrome/browser/policy/cloud_policy_subsystem.cc b/chrome/browser/policy/cloud_policy_subsystem.cc
index 77752b07..5ed979a96 100644
--- a/chrome/browser/policy/cloud_policy_subsystem.cc
+++ b/chrome/browser/policy/cloud_policy_subsystem.cc
@@ -145,7 +145,8 @@
 // static
 void CloudPolicySubsystem::RegisterPrefs(PrefService* pref_service) {
   pref_service->RegisterIntegerPref(prefs::kPolicyRefreshRate,
-                                    kDefaultPolicyRefreshRateMs);
+                                    kDefaultPolicyRefreshRateMs,
+                                    PrefService::UNSYNCABLE_PREF);
 }
 
 void CloudPolicySubsystem::UpdatePolicyRefreshRate() {
diff --git a/chrome/browser/policy/managed_prefs_banner_base_unittest.cc b/chrome/browser/policy/managed_prefs_banner_base_unittest.cc
index 3f2569d..82d5f27 100644
--- a/chrome/browser/policy/managed_prefs_banner_base_unittest.cc
+++ b/chrome/browser/policy/managed_prefs_banner_base_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -16,11 +16,17 @@
  public:
   virtual void SetUp() {
     user_prefs_.reset(new TestingPrefService);
-    user_prefs_->RegisterBooleanPref(prefs::kHomePageIsNewTabPage, false);
-    user_prefs_->RegisterBooleanPref(prefs::kSearchSuggestEnabled, false);
+    user_prefs_->RegisterBooleanPref(prefs::kHomePageIsNewTabPage,
+                                     false,
+                                     PrefService::UNSYNCABLE_PREF);
+    user_prefs_->RegisterBooleanPref(prefs::kSearchSuggestEnabled,
+                                     false,
+                                     PrefService::UNSYNCABLE_PREF);
     local_state_.reset(new TestingPrefService);
-    local_state_->RegisterBooleanPref(prefs::kHomePageIsNewTabPage, false);
-    local_state_->RegisterBooleanPref(prefs::kMetricsReportingEnabled, false);
+    local_state_->RegisterBooleanPref(prefs::kHomePageIsNewTabPage,
+                                      false);
+    local_state_->RegisterBooleanPref(prefs::kMetricsReportingEnabled,
+                                      false);
   }
 
   scoped_ptr<TestingPrefService> local_state_;
diff --git a/chrome/browser/prefs/pref_member_unittest.cc b/chrome/browser/prefs/pref_member_unittest.cc
index 9fca66b3..3cc4cb6 100644
--- a/chrome/browser/prefs/pref_member_unittest.cc
+++ b/chrome/browser/prefs/pref_member_unittest.cc
@@ -21,10 +21,12 @@
 const char kStringPref[] = "string";
 
 void RegisterTestPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(kBoolPref, false);
-  prefs->RegisterIntegerPref(kIntPref, 0);
-  prefs->RegisterDoublePref(kDoublePref, 0.0);
-  prefs->RegisterStringPref(kStringPref, "default");
+  prefs->RegisterBooleanPref(kBoolPref, false, PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterIntegerPref(kIntPref, 0, PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDoublePref(kDoublePref, 0.0, PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(kStringPref,
+                            "default",
+                            PrefService::UNSYNCABLE_PREF);
 }
 
 class GetPrefValueCallback
diff --git a/chrome/browser/prefs/pref_model_associator.cc b/chrome/browser/prefs/pref_model_associator.cc
new file mode 100644
index 0000000..9875d77a
--- /dev/null
+++ b/chrome/browser/prefs/pref_model_associator.cc
@@ -0,0 +1,505 @@
+// 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/prefs/pref_model_associator.h"
+
+#include "base/auto_reset.h"
+#include "base/json/json_reader.h"
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sync/engine/syncapi.h"
+#include "chrome/browser/sync/glue/generic_change_processor.h"
+#include "chrome/browser/sync/profile_sync_service.h"
+#include "chrome/browser/sync/protocol/preference_specifics.pb.h"
+#include "chrome/common/pref_names.h"
+#include "content/browser/browser_thread.h"
+#include "content/common/json_value_serializer.h"
+#include "content/common/notification_service.h"
+
+using syncable::PREFERENCES;
+
+PrefModelAssociator::PrefModelAssociator()
+    : pref_service_(NULL),
+      sync_service_(NULL),
+      models_associated_(false),
+      processing_syncer_changes_(false),
+      change_processor_(NULL) {
+}
+
+PrefModelAssociator::PrefModelAssociator(
+    PrefService* pref_service)
+    : pref_service_(pref_service),
+      sync_service_(NULL),
+      models_associated_(false),
+      processing_syncer_changes_(false),
+      change_processor_(NULL) {
+  DCHECK(CalledOnValidThread());
+}
+
+PrefModelAssociator::~PrefModelAssociator() {
+  DCHECK(CalledOnValidThread());
+  change_processor_ = NULL;
+  sync_service_ = NULL;
+  pref_service_ = NULL;
+}
+
+bool PrefModelAssociator::InitPrefNodeAndAssociate(
+    sync_api::WriteTransaction* trans,
+    const sync_api::BaseNode& root,
+    const PrefService::Preference* pref) {
+  DCHECK(pref);
+
+  base::JSONReader reader;
+  std::string tag = pref->name();
+  sync_api::WriteNode node(trans);
+  if (node.InitByClientTagLookup(PREFERENCES, tag)) {
+    // The server has a value for the preference.
+    const sync_pb::PreferenceSpecifics& preference(
+        node.GetPreferenceSpecifics());
+    DCHECK_EQ(tag, preference.name());
+
+    if (!pref->IsUserModifiable()) {
+      Associate(pref, node.GetId());
+      return true;
+    }
+
+    scoped_ptr<Value> value(
+        reader.JsonToValue(preference.value(), false, false));
+    std::string pref_name = preference.name();
+    if (!value.get()) {
+      LOG(ERROR) << "Failed to deserialize preference value: "
+                 << reader.GetErrorMessage();
+      return false;
+    }
+
+    // Merge the server value of this preference with the local value.
+    scoped_ptr<Value> new_value(MergePreference(*pref, *value));
+
+    // Update the local preference based on what we got from the
+    // sync server.
+    if (new_value->IsType(Value::TYPE_NULL)) {
+      pref_service_->ClearPref(pref_name.c_str());
+    } else if (!new_value->IsType(pref->GetType())) {
+      LOG(WARNING) << "Synced value for " << preference.name()
+                   << " is of type " << new_value->GetType()
+                   << " which doesn't match pref type " << pref->GetType();
+    } else if (!pref->GetValue()->Equals(new_value.get())) {
+      pref_service_->Set(pref_name.c_str(), *new_value);
+    }
+
+    SendUpdateNotificationsIfNecessary(pref_name);
+
+    // If the merge resulted in an updated value, write it back to
+    // the sync node.
+    if (!value->Equals(new_value.get()) &&
+        !WritePreferenceToNode(pref->name(), *new_value, &node)) {
+      return false;
+    }
+    Associate(pref, node.GetId());
+  } else if (pref->IsUserControlled()) {
+    // The server doesn't have a value, but we have a user-controlled value,
+    // so we push it to the server.
+    sync_api::WriteNode write_node(trans);
+    if (!write_node.InitUniqueByCreation(PREFERENCES, root, tag)) {
+      LOG(ERROR) << "Failed to create preference sync node.";
+      return false;
+    }
+
+    // Update the sync node with the local value for this preference.
+    if (!WritePreferenceToNode(pref->name(), *pref->GetValue(), &write_node))
+      return false;
+
+    Associate(pref, write_node.GetId());
+  } else {
+    // This preference is handled by policy, not the user, and therefore
+    // we do not associate it.
+  }
+
+  return true;
+}
+
+bool PrefModelAssociator::AssociateModels() {
+  DCHECK(CalledOnValidThread());
+
+  int64 root_id;
+  if (!GetSyncIdForTaggedNode(syncable::ModelTypeToRootTag(PREFERENCES),
+                              &root_id)) {
+    LOG(ERROR) << "Server did not create the top-level preferences node. We "
+               << "might be running against an out-of-date server.";
+    return false;
+  }
+
+  sync_api::WriteTransaction trans(sync_service_->GetUserShare());
+  sync_api::ReadNode root(&trans);
+  if (!root.InitByIdLookup(root_id)) {
+    LOG(ERROR) << "Server did not create the top-level preferences node. We "
+               << "might be running against an out-of-date server.";
+    return false;
+  }
+
+  for (std::set<std::string>::iterator it = synced_preferences_.begin();
+       it != synced_preferences_.end(); ++it) {
+    std::string name = *it;
+    const PrefService::Preference* pref =
+        pref_service_->FindPreference(name.c_str());
+    VLOG(1) << "Associating preference " << name;
+    DCHECK(pref);
+    if (!pref->IsUserModifiable())
+      continue;  // We don't sync preferences the user cannot change.
+    InitPrefNodeAndAssociate(&trans, root, pref);
+  }
+  models_associated_ = true;
+  return true;
+}
+
+bool PrefModelAssociator::DisassociateModels() {
+  id_map_.clear();
+  id_map_inverse_.clear();
+  models_associated_ = false;
+  return true;
+}
+
+bool PrefModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) {
+  DCHECK(has_nodes);
+  *has_nodes = false;
+  int64 preferences_sync_id;
+  if (!GetSyncIdForTaggedNode(syncable::ModelTypeToRootTag(PREFERENCES),
+                              &preferences_sync_id)) {
+    LOG(ERROR) << "Server did not create the top-level preferences node. We "
+               << "might be running against an out-of-date server.";
+    return false;
+  }
+  sync_api::ReadTransaction trans(sync_service_->GetUserShare());
+
+  sync_api::ReadNode preferences_node(&trans);
+  if (!preferences_node.InitByIdLookup(preferences_sync_id)) {
+    LOG(ERROR) << "Server did not create the top-level preferences node. We "
+               << "might be running against an out-of-date server.";
+    return false;
+  }
+
+  // The sync model has user created nodes if the preferences folder has any
+  // children.
+  *has_nodes = sync_api::kInvalidId != preferences_node.GetFirstChildId();
+  return true;
+}
+
+int64 PrefModelAssociator::GetSyncIdFromChromeId(
+    const std::string& preference_name) {
+  PreferenceNameToSyncIdMap::const_iterator iter =
+      id_map_.find(preference_name);
+  return iter == id_map_.end() ? sync_api::kInvalidId : iter->second;
+}
+
+void PrefModelAssociator::Associate(
+    const PrefService::Preference* preference, int64 sync_id) {
+  DCHECK(CalledOnValidThread());
+
+  std::string name = preference->name();
+  DCHECK_NE(sync_api::kInvalidId, sync_id);
+  DCHECK_EQ(0U, id_map_.count(name));
+  DCHECK_EQ(0U, id_map_inverse_.count(sync_id));
+  id_map_[name] = sync_id;
+  id_map_inverse_[sync_id] = name;
+}
+
+void PrefModelAssociator::Disassociate(int64 sync_id) {
+  DCHECK(CalledOnValidThread());
+  SyncIdToPreferenceNameMap::iterator iter = id_map_inverse_.find(sync_id);
+  if (iter == id_map_inverse_.end())
+    return;
+  id_map_.erase(iter->second);
+  id_map_inverse_.erase(iter);
+}
+
+bool PrefModelAssociator::GetSyncIdForTaggedNode(const std::string& tag,
+                                                 int64* sync_id) {
+  sync_api::ReadTransaction trans(sync_service_->GetUserShare());
+  sync_api::ReadNode sync_node(&trans);
+  if (!sync_node.InitByTagLookup(tag.c_str()))
+    return false;
+  *sync_id = sync_node.GetId();
+  return true;
+}
+
+Value* PrefModelAssociator::MergePreference(
+    const PrefService::Preference& local_pref,
+    const Value& server_value) {
+  const std::string& name(local_pref.name());
+  if (name == prefs::kURLsToRestoreOnStartup ||
+      name == prefs::kDesktopNotificationAllowedOrigins ||
+      name == prefs::kDesktopNotificationDeniedOrigins) {
+    return MergeListValues(*local_pref.GetValue(), server_value);
+  }
+
+  if (name == prefs::kContentSettingsPatterns ||
+      name == prefs::kGeolocationContentSettings) {
+    return MergeDictionaryValues(*local_pref.GetValue(), server_value);
+  }
+
+  // If this is not a specially handled preference, server wins.
+  return server_value.DeepCopy();
+}
+
+bool PrefModelAssociator::WritePreferenceToNode(
+    const std::string& name,
+    const Value& value,
+    sync_api::WriteNode* node) {
+  std::string serialized;
+  JSONStringValueSerializer json(&serialized);
+  if (!json.Serialize(value)) {
+    LOG(ERROR) << "Failed to serialize preference value.";
+    return false;
+  }
+
+  sync_pb::PreferenceSpecifics preference;
+  preference.set_name(name);
+  preference.set_value(serialized);
+  node->SetPreferenceSpecifics(preference);
+  // TODO(viettrungluu): eliminate conversion (it's temporary)
+  node->SetTitle(UTF8ToWide(name));
+  return true;
+}
+
+Value* PrefModelAssociator::MergeListValues(const Value& from_value,
+                                            const Value& to_value) {
+  if (from_value.GetType() == Value::TYPE_NULL)
+    return to_value.DeepCopy();
+  if (to_value.GetType() == Value::TYPE_NULL)
+    return from_value.DeepCopy();
+
+  DCHECK(from_value.GetType() == Value::TYPE_LIST);
+  DCHECK(to_value.GetType() == Value::TYPE_LIST);
+  const ListValue& from_list_value = static_cast<const ListValue&>(from_value);
+  const ListValue& to_list_value = static_cast<const ListValue&>(to_value);
+  ListValue* result = to_list_value.DeepCopy();
+
+  for (ListValue::const_iterator i = from_list_value.begin();
+       i != from_list_value.end(); ++i) {
+    Value* value = (*i)->DeepCopy();
+    result->AppendIfNotPresent(value);
+  }
+  return result;
+}
+
+Value* PrefModelAssociator::MergeDictionaryValues(
+    const Value& from_value,
+    const Value& to_value) {
+  if (from_value.GetType() == Value::TYPE_NULL)
+    return to_value.DeepCopy();
+  if (to_value.GetType() == Value::TYPE_NULL)
+    return from_value.DeepCopy();
+
+  DCHECK_EQ(from_value.GetType(), Value::TYPE_DICTIONARY);
+  DCHECK_EQ(to_value.GetType(), Value::TYPE_DICTIONARY);
+  const DictionaryValue& from_dict_value =
+      static_cast<const DictionaryValue&>(from_value);
+  const DictionaryValue& to_dict_value =
+      static_cast<const DictionaryValue&>(to_value);
+  DictionaryValue* result = to_dict_value.DeepCopy();
+
+  for (DictionaryValue::key_iterator key = from_dict_value.begin_keys();
+       key != from_dict_value.end_keys(); ++key) {
+    Value* from_value;
+    bool success = from_dict_value.GetWithoutPathExpansion(*key, &from_value);
+    DCHECK(success);
+
+    Value* to_key_value;
+    if (result->GetWithoutPathExpansion(*key, &to_key_value)) {
+      if (to_key_value->GetType() == Value::TYPE_DICTIONARY) {
+        Value* merged_value = MergeDictionaryValues(*from_value, *to_key_value);
+        result->SetWithoutPathExpansion(*key, merged_value);
+      }
+      // Note that for all other types we want to preserve the "to"
+      // values so we do nothing here.
+    } else {
+      result->SetWithoutPathExpansion(*key, from_value->DeepCopy());
+    }
+  }
+  return result;
+}
+
+void PrefModelAssociator::SendUpdateNotificationsIfNecessary(
+    const std::string& pref_name) {
+  // The bookmark bar visibility preference requires a special
+  // notification to update the UI.
+  if (0 == pref_name.compare(prefs::kShowBookmarkBar)) {
+    NotificationService::current()->Notify(
+        NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED,
+        Source<PrefModelAssociator>(this),
+        NotificationService::NoDetails());
+  }
+}
+
+// Not implemented.
+void PrefModelAssociator::AbortAssociation() {}
+
+bool PrefModelAssociator::CryptoReadyIfNecessary() {
+  // We only access the cryptographer while holding a transaction.
+  sync_api::ReadTransaction trans(sync_service_->GetUserShare());
+  syncable::ModelTypeSet encrypted_types;
+  sync_service_->GetEncryptedDataTypes(&encrypted_types);
+  return encrypted_types.count(PREFERENCES) == 0 ||
+         sync_service_->IsCryptographerReady(&trans);
+}
+
+void PrefModelAssociator::SetupSync(
+    ProfileSyncService* sync_service,
+    browser_sync::GenericChangeProcessor* change_processor) {
+  sync_service_ = sync_service;
+  change_processor_ = change_processor;
+}
+
+void PrefModelAssociator::ApplyChangesFromSync(
+    const sync_api::BaseTransaction* trans,
+    const sync_api::SyncManager::ChangeRecord* changes,
+    int change_count) {
+  if (!models_associated_)
+    return;
+  AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
+  for (int i = 0; i < change_count; ++i) {
+    if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE ==
+        changes[i].action) {
+      // We never delete preferences.
+      NOTREACHED();
+    }
+
+    sync_api::ReadNode node(trans);
+    if (!node.InitByIdLookup(changes[i].id)) {
+      LOG(ERROR) << "Preference node lookup failed.";
+      return;
+    }
+    DCHECK(PREFERENCES == node.GetModelType());
+    std::string name;
+    sync_pb::PreferenceSpecifics pref_specifics =
+        node.GetPreferenceSpecifics();
+    scoped_ptr<Value> value(ReadPreferenceSpecifics(pref_specifics,
+                                                    &name));
+    // Skip values we can't deserialize.
+    if (!value.get())
+      continue;
+
+    // It is possible that we may receive a change to a preference we do not
+    // want to sync. For example if the user is syncing a Mac client and a
+    // Windows client, the Windows client does not support
+    // kConfirmToQuitEnabled. Ignore updates from these preferences.
+    const char* pref_name = name.c_str();
+    if (!IsPrefRegistered(pref_name))
+      continue;
+
+    const PrefService::Preference* pref =
+        pref_service_->FindPreference(pref_name);
+    DCHECK(pref);
+    if (!pref->IsUserModifiable()) {
+      continue;
+    }
+
+    if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE ==
+        changes[i].action) {
+      pref_service_->ClearPref(pref_name);
+    } else {
+      pref_service_->Set(pref_name, *value);
+
+      // If this is a newly added node, associate.
+      if (sync_api::SyncManager::ChangeRecord::ACTION_ADD ==
+          changes[i].action) {
+        Associate(pref, changes[i].id);
+      }
+
+      SendUpdateNotificationsIfNecessary(name);
+    }
+  }
+}
+
+Value* PrefModelAssociator::ReadPreferenceSpecifics(
+    const sync_pb::PreferenceSpecifics& preference,
+    std::string* name) {
+  base::JSONReader reader;
+  scoped_ptr<Value> value(reader.JsonToValue(preference.value(), false, false));
+  if (!value.get()) {
+    std::string err = "Failed to deserialize preference value: " +
+        reader.GetErrorMessage();
+    LOG(ERROR) << err;
+    return NULL;
+  }
+  *name = preference.name();
+  return value.release();
+}
+
+
+std::set<std::string> PrefModelAssociator::synced_preferences() const {
+  return synced_preferences_;
+}
+
+void PrefModelAssociator::RegisterPref(const char* name) {
+  DCHECK(!models_associated_ && synced_preferences_.count(name) == 0);
+  synced_preferences_.insert(name);
+}
+
+bool PrefModelAssociator::IsPrefRegistered(const char* name) {
+  return synced_preferences_.count(name) > 0;
+}
+
+void PrefModelAssociator::ProcessPrefChange(const std::string& name) {
+  if (processing_syncer_changes_)
+    return;  // These are changes originating from us, ignore.
+
+  // We only process changes if we've already associated models.
+  if (!sync_service_ || !models_associated_)
+    return;
+
+  const PrefService::Preference* preference =
+      pref_service_->FindPreference(name.c_str());
+  if (!IsPrefRegistered(name.c_str()))
+    return;  // We are not syncing this preference.
+
+  // The preference does not have a node. This can happen if the preference
+  // held the default value at association time. Create one and associate.
+  int64 root_id;
+  if (!GetSyncIdForTaggedNode(syncable::ModelTypeToRootTag(PREFERENCES),
+                              &root_id)) {
+    LOG(ERROR) << "Server did not create the top-level preferences node. We "
+               << "might be running against an out-of-date server.";
+    return;
+  }
+
+  int64 sync_id = GetSyncIdFromChromeId(name);
+  if (!preference->IsUserModifiable()) {
+    // If the preference is not currently user modifiable, disassociate, so that
+    // if it becomes user modifiable me pick up the server value.
+    Disassociate(sync_id);
+    return;
+  }
+
+  AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
+  sync_api::WriteTransaction trans(sync_service_->GetUserShare());
+
+  // Since we don't create sync nodes for preferences that are not under control
+  // of the user or still have their default value, this changed preference may
+  // not have a sync node yet. If so, we create a node. Similarly, a preference
+  // may become user-modifiable (e.g. due to laxer policy configuration), in
+  // which case we also need to create a sync node and associate it.
+  if (sync_id == sync_api::kInvalidId) {
+    sync_api::ReadNode root(&trans);
+    if (!root.InitByIdLookup(root_id)) {
+      LOG(ERROR) << "Server did not create the top-level preferences node. We "
+                 << "might be running against an out-of-date server.";
+      return;
+    }
+    InitPrefNodeAndAssociate(&trans, root, preference);
+  } else {
+    sync_api::WriteNode node(&trans);
+    if (!node.InitByIdLookup(sync_id)) {
+      LOG(ERROR) << "Preference node lookup failed.";
+      return;
+    }
+
+    if (!WritePreferenceToNode(name, *preference->GetValue(), &node)) {
+      LOG(ERROR) << "Failed to update preference node.";
+      return;
+    }
+  }
+}
diff --git a/chrome/browser/prefs/pref_model_associator.h b/chrome/browser/prefs/pref_model_associator.h
new file mode 100644
index 0000000..7b24153
--- /dev/null
+++ b/chrome/browser/prefs/pref_model_associator.h
@@ -0,0 +1,152 @@
+// 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_PREFS_PREF_MODEL_ASSOCIATOR_H_
+#define CHROME_BROWSER_PREFS_PREF_MODEL_ASSOCIATOR_H_
+#pragma once
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/threading/non_thread_safe.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/sync/syncable_service.h"
+#include "chrome/browser/sync/unrecoverable_error_handler.h"
+
+class Profile;
+class ProfileSyncService;
+class Value;
+
+namespace sync_api {
+class WriteNode;
+class WriteTransaction;
+}
+
+namespace browser_sync {
+class ChangeProcessor;
+class GenericChangeProcessor;
+}
+
+// Contains all model association related logic:
+// * Algorithm to associate preferences model and sync model.
+// TODO(sync): Rewrite to use change processor instead of transactions.
+// TODO(sync): Merge this into PrefService. We don't actually need the id_map
+// mapping since the sync node tags are the same as the pref names.
+class PrefModelAssociator
+    : public SyncableService,
+      public base::NonThreadSafe {
+ public:
+  explicit PrefModelAssociator(PrefService* pref_service);
+  virtual ~PrefModelAssociator();
+
+  // SyncableService implementation.
+  virtual bool AssociateModels() OVERRIDE;
+  virtual bool DisassociateModels() OVERRIDE;
+  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes) OVERRIDE;
+  virtual void AbortAssociation() OVERRIDE;  // Not implemented.
+  virtual bool CryptoReadyIfNecessary() OVERRIDE;
+  virtual void ApplyChangesFromSync(
+      const sync_api::BaseTransaction* trans,
+      const sync_api::SyncManager::ChangeRecord* changes,
+      int change_count) OVERRIDE;
+  virtual void SetupSync(
+      ProfileSyncService* sync_service,
+      browser_sync::GenericChangeProcessor* change_processor) OVERRIDE;
+
+  // Returns the list of preference names that should be monitored for changes.
+  // Only preferences that are registered will be in this list.
+  std::set<std::string> synced_preferences() const;
+
+  // Register a preference with the specified name for syncing. We do not care
+  // about the type at registration time, but when changes arrive from the
+  // syncer, we check if they can be applied and if not drop them.
+  virtual void RegisterPref(const char* name);
+
+  // Returns true if the specified preference is registered for syncing.
+  virtual bool IsPrefRegistered(const char* name);
+
+  // Process a local preference change.
+  virtual void ProcessPrefChange(const std::string& name);
+
+  // Merges the value of local_pref into the supplied server_value and returns
+  // the result (caller takes ownership). If there is a conflict, the server
+  // value always takes precedence. Note that only certain preferences will
+  // actually be merged, all others will return a copy of the server value. See
+  // the method's implementation for details.
+  static Value* MergePreference(const PrefService::Preference& local_pref,
+                                const Value& server_value);
+
+  // Writes the value of pref into the specified node. Returns true
+  // upon success.
+  static bool WritePreferenceToNode(const std::string& name,
+                                    const Value& value,
+                                    sync_api::WriteNode* node);
+
+  // Extract preference value and name from sync specifics.
+  Value* ReadPreferenceSpecifics(
+      const sync_pb::PreferenceSpecifics& specifics,
+      std::string* name);
+
+  // Returns the sync id for the given preference name, or sync_api::kInvalidId
+  // if the preference name is not associated to any sync id.
+  int64 GetSyncIdFromChromeId(const std::string& node_id);
+ protected:
+  friend class ProfileSyncServicePreferenceTest;
+
+  // For testing.
+  PrefModelAssociator();
+
+  // Create an association for a given preference. A sync node is created if
+  // necessary and the value is read from or written to the node as appropriate.
+  bool InitPrefNodeAndAssociate(sync_api::WriteTransaction* trans,
+                                const sync_api::BaseNode& root,
+                                const PrefService::Preference* pref);
+
+  // Associates the given preference name with the given sync id.
+  void Associate(const PrefService::Preference* node, int64 sync_id);
+
+  // Remove the association that corresponds to the given sync id.
+  void Disassociate(int64 sync_id);
+
+  // Returns whether a node with the given permanent tag was found and update
+  // |sync_id| with that node's id.
+  bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
+
+  // Perform any additional operations that need to happen after a preference
+  // has been updated.
+  void SendUpdateNotificationsIfNecessary(const std::string& pref_name);
+
+  typedef std::map<std::string, int64> PreferenceNameToSyncIdMap;
+  typedef std::map<int64, std::string> SyncIdToPreferenceNameMap;
+
+  static Value* MergeListValues(const Value& from_value, const Value& to_value);
+  static Value* MergeDictionaryValues(const Value& from_value,
+                                      const Value& to_value);
+
+  PrefService* pref_service_;
+  ProfileSyncService* sync_service_;
+
+  // Do we have an active association between the preferences and sync models?
+  // Set by AssociateModels, reset by DisassociateModels.
+  bool models_associated_;
+
+  // Whether we're currently processing changes from the syncer. While this is
+  // true, we ignore any pref changes, since we triggered them.
+  bool processing_syncer_changes_;
+
+  PreferenceNameToSyncIdMap id_map_;
+  SyncIdToPreferenceNameMap id_map_inverse_;
+  std::set<std::string> synced_preferences_;
+
+  // TODO(zea): Get rid of this and use one owned by the PSS.
+  // We create, but don't own this (will be destroyed by data type controller).
+  browser_sync::GenericChangeProcessor* change_processor_;
+
+  DISALLOW_COPY_AND_ASSIGN(PrefModelAssociator);
+};
+
+#endif  // CHROME_BROWSER_PREFS_PREF_MODEL_ASSOCIATOR_H_
diff --git a/chrome/browser/sync/glue/preference_model_associator_unittest.cc b/chrome/browser/prefs/pref_model_associator_unittest.cc
similarity index 91%
rename from chrome/browser/sync/glue/preference_model_associator_unittest.cc
rename to chrome/browser/prefs/pref_model_associator_unittest.cc
index 7ed60b0..6abf38e 100644
--- a/chrome/browser/sync/glue/preference_model_associator_unittest.cc
+++ b/chrome/browser/prefs/pref_model_associator_unittest.cc
@@ -4,14 +4,12 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "base/values.h"
+#include "chrome/browser/prefs/pref_model_associator.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/browser/sync/glue/preference_model_associator.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/testing_profile.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using browser_sync::PreferenceModelAssociator;
-
 class AbstractPreferenceMergeTest : public testing::Test {
  protected:
   virtual void SetUp() {
@@ -81,7 +79,7 @@
       pref_service_->FindPreference(prefs::kHomePage);
   scoped_ptr<Value> server_value(Value::CreateStringValue(server_url0_));
   scoped_ptr<Value> merged_value(
-      PreferenceModelAssociator::MergePreference(*pref, *server_value));
+      PrefModelAssociator::MergePreference(*pref, *server_value));
   EXPECT_TRUE(merged_value->Equals(server_value.get()));
 }
 
@@ -90,7 +88,7 @@
   const PrefService::Preference* pref =
       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
   scoped_ptr<Value> merged_value(
-      PreferenceModelAssociator::MergePreference(*pref, server_url_list_));
+      PrefModelAssociator::MergePreference(*pref, server_url_list_));
   EXPECT_TRUE(merged_value->Equals(&server_url_list_));
 }
 
@@ -105,7 +103,7 @@
   const PrefService::Preference* pref =
       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
   scoped_ptr<Value> merged_value(
-      PreferenceModelAssociator::MergePreference(*pref, *null_value));
+      PrefModelAssociator::MergePreference(*pref, *null_value));
   const ListValue* local_list_value =
         pref_service_->GetList(prefs::kURLsToRestoreOnStartup);
   EXPECT_TRUE(merged_value->Equals(local_list_value));
@@ -122,7 +120,7 @@
   const PrefService::Preference* pref =
       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
   scoped_ptr<Value> merged_value(
-      PreferenceModelAssociator::MergePreference(*pref, *empty_value));
+      PrefModelAssociator::MergePreference(*pref, *empty_value));
   const ListValue* local_list_value =
         pref_service_->GetList(prefs::kURLsToRestoreOnStartup);
   EXPECT_TRUE(merged_value->Equals(local_list_value));
@@ -139,7 +137,7 @@
   const PrefService::Preference* pref =
       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
   scoped_ptr<Value> merged_value(
-      PreferenceModelAssociator::MergePreference(*pref, server_url_list_));
+      PrefModelAssociator::MergePreference(*pref, server_url_list_));
 
   ListValue expected;
   expected.Append(Value::CreateStringValue(server_url0_));
@@ -161,7 +159,7 @@
   const PrefService::Preference* pref =
       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
   scoped_ptr<Value> merged_value(
-      PreferenceModelAssociator::MergePreference(*pref, server_url_list_));
+      PrefModelAssociator::MergePreference(*pref, server_url_list_));
 
   ListValue expected;
   expected.Append(Value::CreateStringValue(server_url0_));
@@ -182,7 +180,7 @@
   const PrefService::Preference* pref =
       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
   scoped_ptr<Value> merged_value(
-      PreferenceModelAssociator::MergePreference(*pref, server_url_list_));
+      PrefModelAssociator::MergePreference(*pref, server_url_list_));
   EXPECT_TRUE(merged_value->Equals(original.get()));
 }
 
@@ -215,7 +213,7 @@
   const PrefService::Preference* pref =
       pref_service_->FindPreference(prefs::kContentSettingsPatterns);
   scoped_ptr<Value> merged_value(
-      PreferenceModelAssociator::MergePreference(*pref, server_patterns_));
+      PrefModelAssociator::MergePreference(*pref, server_patterns_));
   EXPECT_TRUE(merged_value->Equals(&server_patterns_));
 }
 
@@ -230,7 +228,7 @@
   const PrefService::Preference* pref =
       pref_service_->FindPreference(prefs::kContentSettingsPatterns);
   scoped_ptr<Value> merged_value(
-      PreferenceModelAssociator::MergePreference(*pref, *null_value));
+      PrefModelAssociator::MergePreference(*pref, *null_value));
   const DictionaryValue* local_dict_value =
       pref_service_->GetDictionary(prefs::kContentSettingsPatterns);
   EXPECT_TRUE(merged_value->Equals(local_dict_value));
@@ -247,7 +245,7 @@
   const PrefService::Preference* pref =
       pref_service_->FindPreference(prefs::kContentSettingsPatterns);
   scoped_ptr<Value> merged_value(
-      PreferenceModelAssociator::MergePreference(*pref, *empty_value));
+      PrefModelAssociator::MergePreference(*pref, *empty_value));
   const DictionaryValue* local_dict_value =
       pref_service_->GetDictionary(prefs::kContentSettingsPatterns);
   EXPECT_TRUE(merged_value->Equals(local_dict_value));
@@ -260,7 +258,7 @@
     SetContentPattern(local_dict_value, expression2_, content_type0_, 1);
   }
 
-  scoped_ptr<Value> merged_value(PreferenceModelAssociator::MergePreference(
+  scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
       *pref_service_->FindPreference(prefs::kContentSettingsPatterns),
       server_patterns_));
 
@@ -282,7 +280,7 @@
     SetContentPattern(local_dict_value, expression2_, content_type0_, 2);
   }
 
-  scoped_ptr<Value> merged_value(PreferenceModelAssociator::MergePreference(
+  scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
       *pref_service_->FindPreference(prefs::kContentSettingsPatterns),
       server_patterns_));
 
@@ -304,7 +302,7 @@
     SetContentPattern(local_dict_value, expression1_, content_type0_, 1);
   }
 
-  scoped_ptr<Value> merged_value(PreferenceModelAssociator::MergePreference(
+  scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
       *pref_service_->FindPreference(prefs::kContentSettingsPatterns),
       server_patterns_));
   EXPECT_TRUE(merged_value->Equals(&server_patterns_));
@@ -319,7 +317,7 @@
     SetContentPattern(local_dict_value, expression1_, content_type0_, 1);
   }
 
-  scoped_ptr<Value> merged_value(PreferenceModelAssociator::MergePreference(
+  scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
       *pref_service_->FindPreference(prefs::kContentSettingsPatterns),
       server_patterns_));
   EXPECT_TRUE(merged_value->Equals(&server_patterns_));
@@ -347,7 +345,7 @@
       local_list_value->Append(Value::CreateStringValue(url1_));
     }
 
-    scoped_ptr<Value> merged_value(PreferenceModelAssociator::MergePreference(
+    scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
         *pref_service_->FindPreference(pref),
         server_url_list_));
 
@@ -364,7 +362,7 @@
       SetContentPattern(local_dict_value, expression1_, content_type0_, 1);
     }
 
-    scoped_ptr<Value> merged_value(PreferenceModelAssociator::MergePreference(
+    scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
         *pref_service_->FindPreference(pref),
         server_patterns_));
 
diff --git a/chrome/browser/prefs/pref_notifier_impl_unittest.cc b/chrome/browser/prefs/pref_notifier_impl_unittest.cc
index aaea66f..096b625 100644
--- a/chrome/browser/prefs/pref_notifier_impl_unittest.cc
+++ b/chrome/browser/prefs/pref_notifier_impl_unittest.cc
@@ -56,8 +56,12 @@
 class PrefNotifierTest : public testing::Test {
  protected:
   virtual void SetUp() {
-    pref_service_.RegisterBooleanPref(kChangedPref, true);
-    pref_service_.RegisterBooleanPref(kUnchangedPref, true);
+    pref_service_.RegisterBooleanPref(kChangedPref,
+                                      true,
+                                      PrefService::UNSYNCABLE_PREF);
+    pref_service_.RegisterBooleanPref(kUnchangedPref,
+                                      true,
+                                      PrefService::UNSYNCABLE_PREF);
   }
 
   TestingPrefService pref_service_;
diff --git a/chrome/browser/prefs/pref_service.cc b/chrome/browser/prefs/pref_service.cc
index 8ea2d2a4..5096d1d7 100644
--- a/chrome/browser/prefs/pref_service.cc
+++ b/chrome/browser/prefs/pref_service.cc
@@ -18,11 +18,13 @@
 #include "base/string_util.h"
 #include "base/value_conversions.h"
 #include "build/build_config.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/extension_pref_store.h"
 #include "chrome/browser/policy/configuration_policy_pref_store.h"
 #include "chrome/browser/prefs/command_line_pref_store.h"
 #include "chrome/browser/prefs/default_pref_store.h"
 #include "chrome/browser/prefs/overlay_persistent_pref_store.h"
+#include "chrome/browser/prefs/pref_model_associator.h"
 #include "chrome/browser/prefs/pref_notifier_impl.h"
 #include "chrome/browser/prefs/pref_value_store.h"
 #include "chrome/browser/ui/profile_error_dialog.h"
@@ -149,6 +151,7 @@
     : user_pref_store_(user_prefs),
       default_store_(default_store),
       delegate_(delegate) {
+  pref_sync_associator_.reset(new PrefModelAssociator(this));
   pref_notifier_.reset(new PrefNotifierImpl(this));
   pref_value_store_.reset(
       new PrefValueStore(managed_platform_prefs,
@@ -159,6 +162,7 @@
                          recommended_platform_prefs,
                          recommended_cloud_prefs,
                          default_store,
+                         pref_sync_associator_.get(),
                          pref_notifier_.get()));
   InitFromStorage();
 }
@@ -169,6 +173,7 @@
             new OverlayPersistentPrefStore(original.user_pref_store_.get())),
         default_store_(original.default_store_.get()),
         delegate_(NULL) {
+  // Incognito mode doesn't sync, so no need to create PrefModelAssociator.
   pref_notifier_.reset(new PrefNotifierImpl(this));
   pref_value_store_.reset(original.pref_value_store_->CloneAndSpecialize(
       NULL, // managed_platform_prefs
@@ -179,6 +184,7 @@
       NULL, // recommended_platform_prefs
       NULL, // recommended_cloud_prefs
       default_store_.get(),
+      NULL, // pref_sync_associator_
       pref_notifier_.get()));
   InitFromStorage();
 }
@@ -192,6 +198,9 @@
   pref_value_store_.reset();
   user_pref_store_ = NULL;
   default_store_ = NULL;
+  if (pref_sync_associator_.get())
+    pref_sync_associator_->DisassociateModels();
+  pref_sync_associator_.reset();
 }
 
 void PrefService::OnPrefsRead(PersistentPrefStore::PrefReadError error,
@@ -258,72 +267,286 @@
   user_pref_store_->CommitPendingWrite();
 }
 
+namespace {
+
+// If there's no g_browser_process or no local state, return true (for testing).
+bool IsLocalStatePrefService(PrefService* prefs){
+  return (!g_browser_process ||
+          !g_browser_process->local_state() ||
+          g_browser_process->local_state() == prefs);
+}
+
+// If there's no g_browser_process, return true (for testing).
+bool IsProfilePrefService(PrefService* prefs){
+  // TODO(zea): uncomment this once all preferences are only ever registered
+  // with either the local_state's pref service or the profile's pref service.
+  // return (!g_browser_process || g_browser_process->local_state() != prefs);
+  return true;
+}
+
+}  // namespace
+
+
+// Local State prefs.
 void PrefService::RegisterBooleanPref(const char* path,
                                       bool default_value) {
-  RegisterPreference(path, Value::CreateBooleanValue(default_value));
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
+  RegisterPreference(path,
+                     Value::CreateBooleanValue(default_value),
+                     UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterIntegerPref(const char* path, int default_value) {
-  RegisterPreference(path, Value::CreateIntegerValue(default_value));
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
+  RegisterPreference(path,
+                     Value::CreateIntegerValue(default_value),
+                     UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterDoublePref(const char* path, double default_value) {
-  RegisterPreference(path, Value::CreateDoubleValue(default_value));
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
+  RegisterPreference(path,
+                     Value::CreateDoubleValue(default_value),
+                     UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterStringPref(const char* path,
                                      const std::string& default_value) {
-  RegisterPreference(path, Value::CreateStringValue(default_value));
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
+  RegisterPreference(path,
+                     Value::CreateStringValue(default_value),
+                     UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterFilePathPref(const char* path,
                                        const FilePath& default_value) {
-  RegisterPreference(path, Value::CreateStringValue(default_value.value()));
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
+  RegisterPreference(path,
+                     Value::CreateStringValue(default_value.value()),
+                     UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterListPref(const char* path) {
-  RegisterPreference(path, new ListValue());
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
+  RegisterPreference(path,
+                     new ListValue(),
+                     UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterListPref(const char* path, ListValue* default_value) {
-  RegisterPreference(path, default_value);
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
+  RegisterPreference(path,
+                     default_value,
+                     UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterDictionaryPref(const char* path) {
-  RegisterPreference(path, new DictionaryValue());
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
+  RegisterPreference(path,
+                     new DictionaryValue(),
+                     UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterDictionaryPref(const char* path,
                                          DictionaryValue* default_value) {
-  RegisterPreference(path, default_value);
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
+  RegisterPreference(path,
+                     default_value,
+                     UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterLocalizedBooleanPref(const char* path,
                                                int locale_default_message_id) {
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
   RegisterPreference(
       path,
-      CreateLocaleDefaultValue(Value::TYPE_BOOLEAN, locale_default_message_id));
+      CreateLocaleDefaultValue(Value::TYPE_BOOLEAN, locale_default_message_id),
+      UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterLocalizedIntegerPref(const char* path,
                                                int locale_default_message_id) {
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
   RegisterPreference(
       path,
-      CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id));
+      CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id),
+      UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterLocalizedDoublePref(const char* path,
                                               int locale_default_message_id) {
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
   RegisterPreference(
       path,
-      CreateLocaleDefaultValue(Value::TYPE_DOUBLE, locale_default_message_id));
+      CreateLocaleDefaultValue(Value::TYPE_DOUBLE, locale_default_message_id),
+      UNSYNCABLE_PREF);
 }
 
 void PrefService::RegisterLocalizedStringPref(const char* path,
                                               int locale_default_message_id) {
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
   RegisterPreference(
       path,
-      CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id));
+      CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id),
+      UNSYNCABLE_PREF);
+}
+
+void PrefService::RegisterInt64Pref(const char* path, int64 default_value) {
+  // If this fails, the pref service in use is a profile pref service, so the
+  // sync status must be provided (see profile pref registration calls below).
+  DCHECK(IsLocalStatePrefService(this));
+  RegisterPreference(
+      path,
+      Value::CreateStringValue(base::Int64ToString(default_value)),
+      UNSYNCABLE_PREF);
+}
+
+// Profile prefs (must use the sync_status variable).
+void PrefService::RegisterBooleanPref(const char* path,
+                                      bool default_value,
+                                      PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(path,
+                     Value::CreateBooleanValue(default_value),
+                     sync_status);
+}
+
+void PrefService::RegisterIntegerPref(const char* path,
+                                      int default_value,
+                                      PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(path,
+                     Value::CreateIntegerValue(default_value),
+                     sync_status);
+}
+
+void PrefService::RegisterDoublePref(const char* path,
+                                     double default_value,
+                                     PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(path,
+                     Value::CreateDoubleValue(default_value),
+                     sync_status);
+}
+
+void PrefService::RegisterStringPref(const char* path,
+                                     const std::string& default_value,
+                                     PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(path,
+                     Value::CreateStringValue(default_value),
+                     sync_status);
+}
+
+void PrefService::RegisterFilePathPref(const char* path,
+                                       const FilePath& default_value,
+                                       PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(path,
+                     Value::CreateStringValue(default_value.value()),
+                     sync_status);
+}
+
+void PrefService::RegisterListPref(const char* path,
+                                   PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(path, new ListValue(), sync_status);
+}
+
+void PrefService::RegisterListPref(const char* path,
+                                   ListValue* default_value,
+                                   PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(path, default_value, sync_status);
+}
+
+void PrefService::RegisterDictionaryPref(const char* path,
+                                         PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(path, new DictionaryValue(), sync_status);
+}
+
+void PrefService::RegisterDictionaryPref(const char* path,
+                                         DictionaryValue* default_value,
+                                         PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(path, default_value, sync_status);
+}
+
+void PrefService::RegisterLocalizedBooleanPref(const char* path,
+                                               int locale_default_message_id,
+                                               PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(
+      path,
+      CreateLocaleDefaultValue(Value::TYPE_BOOLEAN,locale_default_message_id),
+      sync_status);
+}
+
+void PrefService::RegisterLocalizedIntegerPref(const char* path,
+                                               int locale_default_message_id,
+                                               PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(
+      path,
+      CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id),
+      sync_status);
+}
+
+void PrefService::RegisterLocalizedDoublePref(const char* path,
+                                              int locale_default_message_id,
+                                              PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(
+      path,
+      CreateLocaleDefaultValue(Value::TYPE_DOUBLE, locale_default_message_id),
+      sync_status);
+}
+
+void PrefService::RegisterLocalizedStringPref(const char* path,
+                                              int locale_default_message_id,
+                                              PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(
+      path,
+      CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id),
+      sync_status);
+}
+
+void PrefService::RegisterInt64Pref(const char* path,
+                                    int64 default_value,
+                                    PrefSyncStatus sync_status) {
+  DCHECK(IsProfilePrefService(this));
+  RegisterPreference(
+      path,
+      Value::CreateStringValue(base::Int64ToString(default_value)),
+      sync_status);
 }
 
 bool PrefService::GetBoolean(const char* path) const {
@@ -486,7 +709,9 @@
   pref_notifier_->RemovePrefObserver(path, obs);
 }
 
-void PrefService::RegisterPreference(const char* path, Value* default_value) {
+void PrefService::RegisterPreference(const char* path,
+                                     Value* default_value,
+                                     PrefSyncStatus sync_status) {
   DCHECK(CalledOnValidThread());
 
   // The main code path takes ownership, but most don't. We'll be safe.
@@ -503,6 +728,10 @@
 
   // Hand off ownership.
   default_store_->SetDefaultValue(path, scoped_value.release());
+
+  // Register with sync if necessary.
+  if (sync_status == SYNCABLE_PREF && pref_sync_associator_.get())
+    pref_sync_associator_->RegisterPref(path);
 }
 
 void PrefService::ClearPref(const char* path) {
@@ -561,11 +790,6 @@
   return val;
 }
 
-void PrefService::RegisterInt64Pref(const char* path, int64 default_value) {
-  RegisterPreference(
-      path, Value::CreateStringValue(base::Int64ToString(default_value)));
-}
-
 Value* PrefService::GetMutableUserPref(const char* path,
                                        Value::ValueType type) {
   CHECK(type == Value::TYPE_DICTIONARY || type == Value::TYPE_LIST);
@@ -626,6 +850,10 @@
   user_pref_store_->SetValue(path, owned_value.release());
 }
 
+SyncableService* PrefService::GetSyncableService() {
+  return pref_sync_associator_.get();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // PrefService::Preference
 
diff --git a/chrome/browser/prefs/pref_service.h b/chrome/browser/prefs/pref_service.h
index bf904a4..3990d5a 100644
--- a/chrome/browser/prefs/pref_service.h
+++ b/chrome/browser/prefs/pref_service.h
@@ -21,12 +21,13 @@
 class FilePath;
 class NotificationObserver;
 class PersistentPrefStore;
-class PrefChangeObserver;
+class PrefModelAssociator;
 class PrefNotifier;
 class PrefNotifierImpl;
 class PrefStore;
 class PrefValueStore;
 class Profile;
+class SyncableService;
 
 namespace subtle {
 class PrefMemberBase;
@@ -43,6 +44,14 @@
 class PrefService : public base::NonThreadSafe,
                     public JsonPrefStore::Delegate {
  public:
+  // Enum used when registering preferences to determine if it should be synced
+  // or not. This is only used for profile prefs, not local state prefs.
+  // See the Register*Pref methods for profile prefs below.
+  enum PrefSyncStatus {
+    UNSYNCABLE_PREF,
+    SYNCABLE_PREF
+  };
+
   // A helper class to store all the information associated with a preference.
   class Preference {
    public:
@@ -172,6 +181,8 @@
   void CommitPendingWrite();
 
   // Make the PrefService aware of a pref.
+  // TODO(zea): split local state and profile prefs into their own subclasses.
+  // ---------- Local state prefs  ----------
   void RegisterBooleanPref(const char* path, bool default_value);
   void RegisterIntegerPref(const char* path, int default_value);
   void RegisterDoublePref(const char* path, double default_value);
@@ -182,7 +193,6 @@
   // These take ownership of the default_value:
   void RegisterListPref(const char* path, ListValue* default_value);
   void RegisterDictionaryPref(const char* path, DictionaryValue* default_value);
-
   // These variants use a default value from the locale dll instead.
   void RegisterLocalizedBooleanPref(const char* path,
                                     int locale_default_message_id);
@@ -192,6 +202,51 @@
                                    int locale_default_message_id);
   void RegisterLocalizedStringPref(const char* path,
                                    int locale_default_message_id);
+  void RegisterInt64Pref(const char* path, int64 default_value);
+
+  //  ---------- Profile prefs  ----------
+  // Profile prefs must specify whether the pref should be synchronized across
+  // machines or not (see PrefSyncStatus enum above).
+  void RegisterBooleanPref(const char* path,
+                           bool default_value,
+                           PrefSyncStatus sync_status);
+  void RegisterIntegerPref(const char* path,
+                           int default_value,
+                           PrefSyncStatus sync_status);
+  void RegisterDoublePref(const char* path,
+                          double default_value,
+                          PrefSyncStatus sync_status);
+  void RegisterStringPref(const char* path,
+                          const std::string& default_value,
+                          PrefSyncStatus sync_status);
+  void RegisterFilePathPref(const char* path,
+                            const FilePath& default_value,
+                            PrefSyncStatus sync_status);
+  void RegisterListPref(const char* path, PrefSyncStatus sync_status);
+  void RegisterDictionaryPref(const char* path, PrefSyncStatus sync_status);
+  // These take ownership of the default_value:
+  void RegisterListPref(const char* path,
+                        ListValue* default_value,
+                        PrefSyncStatus sync_status);
+  void RegisterDictionaryPref(const char* path,
+                              DictionaryValue* default_value,
+                              PrefSyncStatus sync_status);
+  // These variants use a default value from the locale dll instead.
+  void RegisterLocalizedBooleanPref(const char* path,
+                                    int locale_default_message_id,
+                                    PrefSyncStatus sync_status);
+  void RegisterLocalizedIntegerPref(const char* path,
+                                    int locale_default_message_id,
+                                    PrefSyncStatus sync_status);
+  void RegisterLocalizedDoublePref(const char* path,
+                                   int locale_default_message_id,
+                                   PrefSyncStatus sync_status);
+  void RegisterLocalizedStringPref(const char* path,
+                                   int locale_default_message_id,
+                                   PrefSyncStatus sync_status);
+  void RegisterInt64Pref(const char* path,
+                         int64 default_value,
+                         PrefSyncStatus sync_status);
 
   // If the path is valid and the value at the end of the path matches the type
   // specified, it will return the specified value.  Otherwise, the default
@@ -228,7 +283,6 @@
   // Value type will be TYPE_STRING.
   void SetInt64(const char* path, int64 value);
   int64 GetInt64(const char* path) const;
-  void RegisterInt64Pref(const char* path, int64 default_value);
 
   // Returns true if a value has been set for the specified path.
   // NOTE: this is NOT the same as FindPreference. In particular
@@ -246,6 +300,10 @@
 
   bool ReadOnly() const;
 
+  // SyncableService getter.
+  // TODO(zea): Have PrefService implement SyncableService directly.
+  SyncableService* GetSyncableService();
+
  protected:
   // Construct a new pref service, specifying the pref sources as explicit
   // PrefStore pointers. This constructor is what CreatePrefService() ends up
@@ -308,7 +366,9 @@
   // NULL as it determines the preference value's type.
   // RegisterPreference must not be called twice for the same path.
   // This method takes ownership of |default_value|.
-  void RegisterPreference(const char* path, Value* default_value);
+  void RegisterPreference(const char* path,
+                          Value* default_value,
+                          PrefSyncStatus sync_status);
 
   // Sets the value for this pref path in the user pref store and informs the
   // PrefNotifier of the change.
@@ -344,6 +404,9 @@
   // is used.
   PrefServiceDelegate* delegate_;
 
+  // The model associator that maintains the links with the sync db.
+  scoped_ptr<PrefModelAssociator> pref_sync_associator_;
+
   DISALLOW_COPY_AND_ASSIGN(PrefService);
 };
 
diff --git a/chrome/browser/prefs/pref_set_observer_unittest.cc b/chrome/browser/prefs/pref_set_observer_unittest.cc
index 41dcfe6..49fc5077 100644
--- a/chrome/browser/prefs/pref_set_observer_unittest.cc
+++ b/chrome/browser/prefs/pref_set_observer_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -16,9 +16,15 @@
  public:
   virtual void SetUp() {
     pref_service_.reset(new TestingPrefService);
-    pref_service_->RegisterStringPref(prefs::kHomePage, "http://google.com");
-    pref_service_->RegisterBooleanPref(prefs::kHomePageIsNewTabPage, false);
-    pref_service_->RegisterStringPref(prefs::kApplicationLocale, "");
+    pref_service_->RegisterStringPref(prefs::kHomePage,
+                                      "http://google.com",
+                                      PrefService::UNSYNCABLE_PREF);
+    pref_service_->RegisterBooleanPref(prefs::kHomePageIsNewTabPage,
+                                       false,
+                                       PrefService::UNSYNCABLE_PREF);
+    pref_service_->RegisterStringPref(prefs::kApplicationLocale,
+                                      "",
+                                      PrefService::UNSYNCABLE_PREF);
   }
 
   PrefSetObserver* CreatePrefSetObserver(NotificationObserver* observer) {
diff --git a/chrome/browser/prefs/pref_value_store.cc b/chrome/browser/prefs/pref_value_store.cc
index 3318a1d..dbb29aebd 100644
--- a/chrome/browser/prefs/pref_value_store.cc
+++ b/chrome/browser/prefs/pref_value_store.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/prefs/pref_value_store.h"
 
+#include "chrome/browser/prefs/pref_model_associator.h"
 #include "chrome/browser/prefs/pref_notifier.h"
 
 PrefValueStore::PrefStoreKeeper::PrefStoreKeeper()
@@ -49,8 +50,10 @@
                                PrefStore* recommended_platform_prefs,
                                PrefStore* recommended_cloud_prefs,
                                PrefStore* default_prefs,
+                               PrefModelAssociator* pref_sync_associator,
                                PrefNotifier* pref_notifier)
-    : pref_notifier_(pref_notifier) {
+    : pref_sync_associator_(pref_sync_associator),
+      pref_notifier_(pref_notifier) {
   InitPrefStore(MANAGED_PLATFORM_STORE, managed_platform_prefs);
   InitPrefStore(MANAGED_CLOUD_STORE, managed_cloud_prefs);
   InitPrefStore(EXTENSION_STORE, extension_prefs);
@@ -74,6 +77,7 @@
     PrefStore* recommended_platform_prefs,
     PrefStore* recommended_cloud_prefs,
     PrefStore* default_prefs,
+    PrefModelAssociator* pref_sync_associator,
     PrefNotifier* pref_notifier) {
   DCHECK(pref_notifier);
   if (!managed_platform_prefs)
@@ -96,7 +100,7 @@
   return new PrefValueStore(
       managed_platform_prefs, managed_cloud_prefs, extension_prefs,
       command_line_prefs, user_prefs, recommended_platform_prefs,
-      recommended_cloud_prefs, default_prefs,
+      recommended_cloud_prefs, default_prefs, pref_sync_associator,
       pref_notifier);
 }
 
@@ -129,8 +133,11 @@
   // If the pref is controlled by a higher-priority store, its effective value
   // cannot have changed.
   PrefStoreType controller = ControllingPrefStoreForPref(path);
-  if (controller == INVALID_STORE || controller >= new_store)
+  if (controller == INVALID_STORE || controller >= new_store) {
     pref_notifier_->OnPreferenceChanged(path);
+    if (pref_sync_associator_)
+      pref_sync_associator_->ProcessPrefChange(path);
+  }
 }
 
 bool PrefValueStore::PrefValueInManagedStore(const char* name) const {
diff --git a/chrome/browser/prefs/pref_value_store.h b/chrome/browser/prefs/pref_value_store.h
index 6a492ba..07a5b61 100644
--- a/chrome/browser/prefs/pref_value_store.h
+++ b/chrome/browser/prefs/pref_value_store.h
@@ -18,6 +18,7 @@
 #include "content/browser/browser_thread.h"
 
 class FilePath;
+class PrefModelAssociator;
 class PrefNotifier;
 class PrefStore;
 
@@ -56,6 +57,7 @@
                  PrefStore* recommended_platform_prefs,
                  PrefStore* recommended_cloud_prefs,
                  PrefStore* default_prefs,
+                 PrefModelAssociator* pref_sync_associator,
                  PrefNotifier* pref_notifier);
   virtual ~PrefValueStore();
 
@@ -69,6 +71,7 @@
                                      PrefStore* recommended_platform_prefs,
                                      PrefStore* recommended_cloud_prefs,
                                      PrefStore* default_prefs,
+                                     PrefModelAssociator* pref_sync_associator,
                                      PrefNotifier* pref_notifier);
 
   // Gets the value for the given preference name that has the specified value
@@ -233,6 +236,9 @@
   // Keeps the PrefStore references in order of precedence.
   PrefStoreKeeper pref_stores_[PREF_STORE_TYPE_MAX + 1];
 
+  // The associator for syncing preferences.
+  PrefModelAssociator* pref_sync_associator_;
+
   // Used for generating PREF_CHANGED and PREF_INITIALIZATION_COMPLETED
   // notifications. This is a weak reference, since the notifier is owned by the
   // corresponding PrefService.
diff --git a/chrome/browser/prefs/pref_value_store_unittest.cc b/chrome/browser/prefs/pref_value_store_unittest.cc
index 6819e46..17d939c 100644
--- a/chrome/browser/prefs/pref_value_store_unittest.cc
+++ b/chrome/browser/prefs/pref_value_store_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/values.h"
 #include "chrome/browser/policy/configuration_policy_pref_store.h"
 #include "chrome/browser/policy/dummy_configuration_policy_provider.h"
+#include "chrome/browser/prefs/pref_model_associator.h"
 #include "chrome/browser/prefs/pref_notifier.h"
 #include "chrome/browser/prefs/pref_value_store.h"
 #include "chrome/browser/prefs/testing_pref_store.h"
@@ -31,6 +32,12 @@
   MOCK_METHOD0(OnInitializationCompleted, void());
 };
 
+// Allows to capture sync model associator interaction.
+class MockPrefModelAssociator : public PrefModelAssociator {
+ public:
+  MOCK_METHOD1(ProcessPrefChange, void(const std::string&));
+};
+
 }  // namespace
 
 // Names of the preferences used in this test.
@@ -121,6 +128,7 @@
     CreateRecommendedPlatformPrefs();
     CreateRecommendedCloudPrefs();
     CreateDefaultPrefs();
+    sync_associator_.reset(new MockPrefModelAssociator());
 
     // Create a fresh PrefValueStore.
     pref_value_store_.reset(new PrefValueStore(
@@ -132,6 +140,7 @@
         recommended_platform_pref_store_,
         recommended_cloud_pref_store_,
         default_pref_store_,
+        sync_associator_.get(),
         &pref_notifier_));
   }
 
@@ -276,6 +285,7 @@
   }
 
   MockPrefNotifier pref_notifier_;
+  scoped_ptr<MockPrefModelAssociator> sync_associator_;
   scoped_ptr<PrefValueStore> pref_value_store_;
 
   scoped_refptr<TestingPrefStore> managed_platform_pref_store_;
@@ -365,11 +375,15 @@
 TEST_F(PrefValueStoreTest, PrefChanges) {
   // Check pref controlled by highest-priority store.
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kManagedPlatformPref));
+  EXPECT_CALL(*sync_associator_,
+      ProcessPrefChange(prefs::kManagedPlatformPref));
   managed_platform_pref_store_->NotifyPrefValueChanged(
       prefs::kManagedPlatformPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)).Times(0);
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(_)).Times(0);
   managed_cloud_pref_store_->NotifyPrefValueChanged(
       prefs::kManagedPlatformPref);
   extension_pref_store_->NotifyPrefValueChanged(
@@ -385,29 +399,41 @@
   default_pref_store_->NotifyPrefValueChanged(
       prefs::kManagedPlatformPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   // Check pref controlled by user store.
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kUserPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kUserPref));
   managed_platform_pref_store_->NotifyPrefValueChanged(prefs::kUserPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kUserPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kUserPref));
   managed_cloud_pref_store_->NotifyPrefValueChanged(prefs::kUserPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kUserPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kUserPref));
   extension_pref_store_->NotifyPrefValueChanged(prefs::kUserPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kUserPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kUserPref));
   command_line_pref_store_->NotifyPrefValueChanged(prefs::kUserPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kUserPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kUserPref));
   user_pref_store_->NotifyPrefValueChanged(prefs::kUserPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)).Times(0);
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(_)).Times(0);
   recommended_platform_pref_store_->NotifyPrefValueChanged(
       prefs::kUserPref);
   recommended_cloud_pref_store_->NotifyPrefValueChanged(
@@ -415,39 +441,56 @@
   default_pref_store_->NotifyPrefValueChanged(
       prefs::kUserPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   // Check pref controlled by default-pref store.
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kDefaultPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kDefaultPref));
   managed_platform_pref_store_->NotifyPrefValueChanged(prefs::kDefaultPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kDefaultPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kDefaultPref));
   managed_cloud_pref_store_->NotifyPrefValueChanged(prefs::kDefaultPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kDefaultPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kDefaultPref));
   extension_pref_store_->NotifyPrefValueChanged(prefs::kDefaultPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kDefaultPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kDefaultPref));
   command_line_pref_store_->NotifyPrefValueChanged(prefs::kDefaultPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kDefaultPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kDefaultPref));
   user_pref_store_->NotifyPrefValueChanged(prefs::kDefaultPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kDefaultPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kDefaultPref));
   recommended_platform_pref_store_->NotifyPrefValueChanged(prefs::kDefaultPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kDefaultPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kDefaultPref));
   recommended_cloud_pref_store_->NotifyPrefValueChanged(prefs::kDefaultPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 
   EXPECT_CALL(pref_notifier_, OnPreferenceChanged(prefs::kDefaultPref));
+  EXPECT_CALL(*sync_associator_, ProcessPrefChange(prefs::kDefaultPref));
   default_pref_store_->NotifyPrefValueChanged(prefs::kDefaultPref);
   Mock::VerifyAndClearExpectations(&pref_notifier_);
+  Mock::VerifyAndClearExpectations(sync_associator_.get());
 }
 
 TEST_F(PrefValueStoreTest, OnInitializationCompleted) {
diff --git a/chrome/browser/prefs/scoped_user_pref_update_unittest.cc b/chrome/browser/prefs/scoped_user_pref_update_unittest.cc
index 88faebe..f68452d 100644
--- a/chrome/browser/prefs/scoped_user_pref_update_unittest.cc
+++ b/chrome/browser/prefs/scoped_user_pref_update_unittest.cc
@@ -18,7 +18,7 @@
 
  protected:
   virtual void SetUp() {
-    prefs_.RegisterDictionaryPref(kPref);
+    prefs_.RegisterDictionaryPref(kPref, PrefService::UNSYNCABLE_PREF);
     registrar_.Init(&prefs_);
     registrar_.Add(kPref, &observer_);
   }
diff --git a/chrome/browser/prefs/session_startup_pref.cc b/chrome/browser/prefs/session_startup_pref.cc
index de5cf76c..59e262f 100644
--- a/chrome/browser/prefs/session_startup_pref.cc
+++ b/chrome/browser/prefs/session_startup_pref.cc
@@ -46,8 +46,11 @@
 // static
 void SessionStartupPref::RegisterUserPrefs(PrefService* prefs) {
   prefs->RegisterIntegerPref(prefs::kRestoreOnStartup,
-      TypeToPrefValue(browser_defaults::kDefaultSessionStartupType));
-  prefs->RegisterListPref(prefs::kURLsToRestoreOnStartup);
+                             TypeToPrefValue(
+                                 browser_defaults::kDefaultSessionStartupType),
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kURLsToRestoreOnStartup,
+                          PrefService::SYNCABLE_PREF);
 }
 
 // static
diff --git a/chrome/browser/printing/cloud_print/cloud_print_url.cc b/chrome/browser/printing/cloud_print/cloud_print_url.cc
index a36cc51..c6e8c7c 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_url.cc
+++ b/chrome/browser/printing/cloud_print/cloud_print_url.cc
@@ -24,7 +24,8 @@
   if (pref_service->FindPreference(prefs::kCloudPrintServiceURL))
     return;
   pref_service->RegisterStringPref(prefs::kCloudPrintServiceURL,
-                                   kDefaultCloudPrintServiceURL);
+                                   kDefaultCloudPrintServiceURL,
+                                   PrefService::UNSYNCABLE_PREF);
 }
 
 // Returns the root service URL for the cloud print service.  The default is to
diff --git a/chrome/browser/printing/print_dialog_cloud.cc b/chrome/browser/printing/print_dialog_cloud.cc
index 64c2fea7..052aa9a 100644
--- a/chrome/browser/printing/print_dialog_cloud.cc
+++ b/chrome/browser/printing/print_dialog_cloud.cc
@@ -533,11 +533,13 @@
   DCHECK(pref_service);
   if (!pref_service->FindPreference(prefs::kCloudPrintDialogWidth)) {
     pref_service->RegisterIntegerPref(prefs::kCloudPrintDialogWidth,
-                                      kDefaultWidth);
+                                      kDefaultWidth,
+                                      PrefService::UNSYNCABLE_PREF);
   }
   if (!pref_service->FindPreference(prefs::kCloudPrintDialogHeight)) {
     pref_service->RegisterIntegerPref(prefs::kCloudPrintDialogHeight,
-                                      kDefaultHeight);
+                                      kDefaultHeight,
+                                      PrefService::UNSYNCABLE_PREF);
   }
 
   int width = pref_service->GetInteger(prefs::kCloudPrintDialogWidth);
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index f83b7f2..a2c0d6f 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -96,37 +96,68 @@
 
 // static
 void Profile::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kSearchSuggestEnabled, true);
-  prefs->RegisterBooleanPref(prefs::kSessionExitedCleanly, true);
-  prefs->RegisterBooleanPref(prefs::kSafeBrowsingEnabled, true);
-  prefs->RegisterBooleanPref(prefs::kSafeBrowsingReportingEnabled, false);
+  prefs->RegisterBooleanPref(prefs::kSearchSuggestEnabled,
+                             true,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kSessionExitedCleanly,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kSafeBrowsingEnabled,
+                             true,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kSafeBrowsingReportingEnabled,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
   // TODO(estade): IDS_SPELLCHECK_DICTIONARY should be an ASCII string.
   prefs->RegisterLocalizedStringPref(prefs::kSpellCheckDictionary,
-      IDS_SPELLCHECK_DICTIONARY);
-  prefs->RegisterBooleanPref(prefs::kEnableSpellCheck, true);
-  prefs->RegisterBooleanPref(prefs::kEnableAutoSpellCorrect, true);
+                                     IDS_SPELLCHECK_DICTIONARY,
+                                     PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kEnableSpellCheck,
+                             true,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kEnableAutoSpellCorrect,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
 #if defined(TOOLKIT_USES_GTK)
   prefs->RegisterBooleanPref(prefs::kUsesSystemTheme,
-                             GtkThemeService::DefaultUsesSystemTheme());
+                             GtkThemeService::DefaultUsesSystemTheme(),
+                             PrefService::UNSYNCABLE_PREF);
 #endif
-  prefs->RegisterFilePathPref(prefs::kCurrentThemePackFilename, FilePath());
+  prefs->RegisterFilePathPref(prefs::kCurrentThemePackFilename,
+                              FilePath(),
+                              PrefService::UNSYNCABLE_PREF);
   prefs->RegisterStringPref(prefs::kCurrentThemeID,
-                            ThemeService::kDefaultThemeID);
-  prefs->RegisterDictionaryPref(prefs::kCurrentThemeImages);
-  prefs->RegisterDictionaryPref(prefs::kCurrentThemeColors);
-  prefs->RegisterDictionaryPref(prefs::kCurrentThemeTints);
-  prefs->RegisterDictionaryPref(prefs::kCurrentThemeDisplayProperties);
-  prefs->RegisterBooleanPref(prefs::kDisableExtensions, false);
-  prefs->RegisterStringPref(prefs::kSelectFileLastDirectory, "");
+                            ThemeService::kDefaultThemeID,
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kCurrentThemeImages,
+                                PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kCurrentThemeColors,
+                                PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kCurrentThemeTints,
+                                PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kCurrentThemeDisplayProperties,
+                                PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kDisableExtensions,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kSelectFileLastDirectory,
+                            "",
+                            PrefService::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
   // kApplicationLocale only in local state.
   // In the future we may want to maintain kApplicationLocale
   // in user's profile for other platforms as well.
-  prefs->RegisterStringPref(prefs::kApplicationLocale, "");
-  prefs->RegisterStringPref(prefs::kApplicationLocaleBackup, "");
-  prefs->RegisterStringPref(prefs::kApplicationLocaleAccepted, "");
+  prefs->RegisterStringPref(prefs::kApplicationLocale,
+                            "",
+                            PrefService::SYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kApplicationLocaleBackup,
+                            "",
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kApplicationLocaleAccepted,
+                            "",
+                            PrefService::UNSYNCABLE_PREF);
 #endif
 }
 
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 8f56eef..216eed9 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -257,8 +257,12 @@
 
 // static
 void ProfileImpl::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kSavingBrowserHistoryDisabled, false);
-  prefs->RegisterBooleanPref(prefs::kClearSiteDataOnExit, false);
+  prefs->RegisterBooleanPref(prefs::kSavingBrowserHistoryDisabled,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kClearSiteDataOnExit,
+                             false,
+                             PrefService::SYNCABLE_PREF);
 }
 
 ProfileImpl::ProfileImpl(const FilePath& path,
diff --git a/chrome/browser/search_engines/template_url_model.cc b/chrome/browser/search_engines/template_url_model.cc
index a2def18..75886a3 100644
--- a/chrome/browser/search_engines/template_url_model.cc
+++ b/chrome/browser/search_engines/template_url_model.cc
@@ -589,26 +589,36 @@
 
 // static
 void TemplateURLModel::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(
-      prefs::kDefaultSearchProviderEnabled, true);
-  prefs->RegisterStringPref(
-      prefs::kDefaultSearchProviderName, std::string());
-  prefs->RegisterStringPref(
-      prefs::kDefaultSearchProviderID, std::string());
-  prefs->RegisterStringPref(
-      prefs::kDefaultSearchProviderPrepopulateID, std::string());
-  prefs->RegisterStringPref(
-      prefs::kDefaultSearchProviderSuggestURL, std::string());
-  prefs->RegisterStringPref(
-      prefs::kDefaultSearchProviderSearchURL, std::string());
-  prefs->RegisterStringPref(
-      prefs::kDefaultSearchProviderInstantURL, std::string());
-  prefs->RegisterStringPref(
-      prefs::kDefaultSearchProviderKeyword, std::string());
-  prefs->RegisterStringPref(
-      prefs::kDefaultSearchProviderIconURL, std::string());
-  prefs->RegisterStringPref(
-      prefs::kDefaultSearchProviderEncodings, std::string());
+  prefs->RegisterBooleanPref(prefs::kDefaultSearchProviderEnabled,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderName,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderID,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderPrepopulateID,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderSuggestURL,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderSearchURL,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderInstantURL,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderKeyword,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderIconURL,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderEncodings,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
 }
 
 void TemplateURLModel::SetKeywordSearchTermsForURL(const TemplateURL* t_url,
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data.cc b/chrome/browser/search_engines/template_url_prepopulate_data.cc
index 4498c489..e19384e8 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data.cc
+++ b/chrome/browser/search_engines/template_url_prepopulate_data.cc
@@ -3341,11 +3341,18 @@
 namespace TemplateURLPrepopulateData {
 
 void RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterIntegerPref(prefs::kCountryIDAtInstall, kCountryIDUnknown);
-  prefs->RegisterListPref(prefs::kSearchProviderOverrides);
-  prefs->RegisterIntegerPref(prefs::kSearchProviderOverridesVersion, -1);
+  prefs->RegisterIntegerPref(prefs::kCountryIDAtInstall,
+                             kCountryIDUnknown,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kSearchProviderOverrides,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterIntegerPref(prefs::kSearchProviderOverridesVersion,
+                             -1,
+                             PrefService::UNSYNCABLE_PREF);
   // Obsolete pref, for migration.
-  prefs->RegisterIntegerPref(prefs::kGeoIDAtInstall, -1);
+  prefs->RegisterIntegerPref(prefs::kGeoIDAtInstall,
+                             -1,
+                             PrefService::UNSYNCABLE_PREF);
 }
 
 int GetDataVersion(PrefService* prefs) {
diff --git a/chrome/browser/sync/abstract_profile_sync_service_test.cc b/chrome/browser/sync/abstract_profile_sync_service_test.cc
index 355437b..366230b 100644
--- a/chrome/browser/sync/abstract_profile_sync_service_test.cc
+++ b/chrome/browser/sync/abstract_profile_sync_service_test.cc
@@ -5,12 +5,6 @@
 #include "chrome/browser/sync/abstract_profile_sync_service_test.h"
 
 #include "chrome/browser/sync/engine/syncapi.h"
-#include "chrome/browser/sync/glue/autofill_model_associator.h"
-#include "chrome/browser/sync/glue/autofill_profile_model_associator.h"
-#include "chrome/browser/sync/glue/password_model_associator.h"
-#include "chrome/browser/sync/glue/preference_model_associator.h"
-#include "chrome/browser/sync/glue/session_model_associator.h"
-#include "chrome/browser/sync/glue/typed_url_model_associator.h"
 #include "chrome/browser/sync/protocol/sync.pb.h"
 #include "chrome/browser/sync/syncable/directory_manager.h"
 #include "chrome/browser/sync/syncable/syncable.h"
@@ -39,27 +33,7 @@
 
 const std::string ProfileSyncServiceTestHelper::GetTagForType(
     ModelType model_type) {
-  switch (model_type) {
-    case syncable::AUTOFILL:
-      return browser_sync::kAutofillTag;
-    case syncable::AUTOFILL_PROFILE:
-      return browser_sync::kAutofillProfileTag;
-    case syncable::PREFERENCES:
-      return browser_sync::kPreferencesTag;
-    case syncable::PASSWORDS:
-      return browser_sync::kPasswordTag;
-    case syncable::NIGORI:
-      return browser_sync::kNigoriTag;
-    case syncable::TYPED_URLS:
-      return browser_sync::kTypedUrlTag;
-    case syncable::SESSIONS:
-      return browser_sync::kSessionsTag;
-    case syncable::BOOKMARKS:
-      return "google_chrome_bookmarks";
-    default:
-      NOTREACHED();
-  }
-  return std::string();
+  return syncable::ModelTypeToRootTag(model_type);
 }
 
 bool ProfileSyncServiceTestHelper::CreateRoot(
diff --git a/chrome/browser/sync/glue/app_data_type_controller.cc b/chrome/browser/sync/glue/app_data_type_controller.cc
index cf025f68..5be7863 100644
--- a/chrome/browser/sync/glue/app_data_type_controller.cc
+++ b/chrome/browser/sync/glue/app_data_type_controller.cc
@@ -35,9 +35,8 @@
   ProfileSyncFactory::SyncComponents sync_components =
       profile_sync_factory_->CreateAppSyncComponents(sync_service_,
                                                      this);
-  model_associator_.reset(sync_components.model_associator);
-  change_processor_.reset(sync_components.change_processor);
-}
+  set_model_associator(sync_components.model_associator);
+  set_change_processor(sync_components.change_processor);}
 
 void AppDataTypeController::RecordUnrecoverableError(
     const tracked_objects::Location& from_here,
diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller.cc b/chrome/browser/sync/glue/bookmark_data_type_controller.cc
index 4415240..7819468 100644
--- a/chrome/browser/sync/glue/bookmark_data_type_controller.cc
+++ b/chrome/browser/sync/glue/bookmark_data_type_controller.cc
@@ -65,8 +65,8 @@
 void BookmarkDataTypeController::CreateSyncComponents() {
   ProfileSyncFactory::SyncComponents sync_components = profile_sync_factory_->
       CreateBookmarkSyncComponents(sync_service_, this);
-  model_associator_.reset(sync_components.model_associator);
-  change_processor_.reset(sync_components.change_processor);
+  set_model_associator(sync_components.model_associator);
+  set_change_processor(sync_components.change_processor);
 }
 
 void BookmarkDataTypeController::RecordUnrecoverableError(
diff --git a/chrome/browser/sync/glue/change_processor.cc b/chrome/browser/sync/glue/change_processor.cc
index f7790707..dcf7800e 100644
--- a/chrome/browser/sync/glue/change_processor.cc
+++ b/chrome/browser/sync/glue/change_processor.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -7,6 +7,11 @@
 
 namespace browser_sync {
 
+ChangeProcessor::ChangeProcessor(UnrecoverableErrorHandler* error_handler)
+    : running_(false),
+      error_handler_(error_handler),
+      share_handle_(NULL) {}
+
 ChangeProcessor::~ChangeProcessor() {
   DCHECK(!running_) << "ChangeProcessor dtor while running";
 }
@@ -31,4 +36,15 @@
   return running_;
 }
 
+// Not implemented by default.
+void ChangeProcessor::CommitChangesFromSyncModel() {}
+
+UnrecoverableErrorHandler* ChangeProcessor::error_handler() {
+  return error_handler_;
+}
+
+sync_api::UserShare* ChangeProcessor::share_handle() {
+  return share_handle_;
+}
+
 }  // namespace browser_sync
diff --git a/chrome/browser/sync/glue/change_processor.h b/chrome/browser/sync/glue/change_processor.h
index 3e8a467..b698809 100644
--- a/chrome/browser/sync/glue/change_processor.h
+++ b/chrome/browser/sync/glue/change_processor.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -20,8 +20,7 @@
 // native model.  This does not currently distinguish between model data types.
 class ChangeProcessor {
  public:
-  explicit ChangeProcessor(UnrecoverableErrorHandler* error_handler)
-      : running_(false), error_handler_(error_handler), share_handle_(NULL) {}
+  explicit ChangeProcessor(UnrecoverableErrorHandler* error_handler);
   virtual ~ChangeProcessor();
 
   // Call when the processor should accept changes from either provided model
@@ -45,11 +44,13 @@
       int change_count) = 0;
 
   // The changes found in ApplyChangesFromSyncModel may be too slow to be
-  // performed while holding a [Read/Write]Transaction lock. This function
-  // is called once the lock is released and performs any slow I/O operations
-  // without unnecessarily slowing the UI. Note that not all datatypes need
-  // this, so we provide an empty default version.
-  virtual void CommitChangesFromSyncModel() { }
+  // performed while holding a [Read/Write]Transaction lock or may interact
+  // with another thread, which might itself be waiting on the transaction lock,
+  // putting us at risk of deadlock.
+  // This function is called once the transactional lock is released and it is
+  // safe to perform inter-thread or slow I/O operations. Note that not all
+  // datatypes need this, so we provide an empty default version.
+  virtual void CommitChangesFromSyncModel();
 
  protected:
   // These methods are invoked by Start() and Stop() to do
@@ -58,8 +59,8 @@
   virtual void StopImpl() = 0;
 
   bool running() { return running_; }
-  UnrecoverableErrorHandler* error_handler() { return error_handler_; }
-  sync_api::UserShare* share_handle() { return share_handle_; }
+  UnrecoverableErrorHandler* error_handler();
+  sync_api::UserShare* share_handle();
 
  private:
   bool running_;  // True if we have been told it is safe to process changes.
diff --git a/chrome/browser/sync/glue/extension_data_type_controller.cc b/chrome/browser/sync/glue/extension_data_type_controller.cc
index 07d4d1c3..11f4a72 100644
--- a/chrome/browser/sync/glue/extension_data_type_controller.cc
+++ b/chrome/browser/sync/glue/extension_data_type_controller.cc
@@ -35,8 +35,8 @@
   ProfileSyncFactory::SyncComponents sync_components =
       profile_sync_factory_->CreateExtensionSyncComponents(sync_service_,
                                                      this);
-  model_associator_.reset(sync_components.model_associator);
-  change_processor_.reset(sync_components.change_processor);
+  set_model_associator(sync_components.model_associator);
+  set_change_processor(sync_components.change_processor);
 }
 
 void ExtensionDataTypeController::RecordUnrecoverableError(
diff --git a/chrome/browser/sync/glue/frontend_data_type_controller.cc b/chrome/browser/sync/glue/frontend_data_type_controller.cc
index edec12c..ca1ed730 100644
--- a/chrome/browser/sync/glue/frontend_data_type_controller.cc
+++ b/chrome/browser/sync/glue/frontend_data_type_controller.cc
@@ -78,19 +78,19 @@
   DCHECK_EQ(state_, ASSOCIATING);
   CreateSyncComponents();
 
-  if (!model_associator_->CryptoReadyIfNecessary()) {
+  if (!model_associator()->CryptoReadyIfNecessary()) {
     StartFailed(NEEDS_CRYPTO, FROM_HERE);
     return false;
   }
 
   bool sync_has_nodes = false;
-  if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) {
+  if (!model_associator()->SyncModelHasUserCreatedNodes(&sync_has_nodes)) {
     StartFailed(UNRECOVERABLE_ERROR, FROM_HERE);
     return false;
   }
 
   base::TimeTicks start_time = base::TimeTicks::Now();
-  bool merge_success = model_associator_->AssociateModels();
+  bool merge_success = model_associator()->AssociateModels();
   RecordAssociationTime(base::TimeTicks::Now() - start_time);
   if (!merge_success) {
     StartFailed(ASSOCIATION_FAILED, FROM_HERE);
@@ -107,7 +107,7 @@
     const tracked_objects::Location& location) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   CleanUpState();
-  model_associator_.reset();
+  set_model_associator(NULL);
   change_processor_.reset();
   state_ = NOT_RUNNING;
   RecordStartFailure(result);
@@ -144,14 +144,14 @@
 
   CleanUpState();
 
-  if (change_processor_ != NULL)
+  if (change_processor_.get())
     sync_service_->DeactivateDataType(this, change_processor_.get());
 
-  if (model_associator_ != NULL)
-    model_associator_->DisassociateModels();
+  if (model_associator())
+    model_associator()->DisassociateModels();
 
+  set_model_associator(NULL);
   change_processor_.reset();
-  model_associator_.reset();
 
   state_ = NOT_RUNNING;
 }
@@ -181,4 +181,22 @@
   sync_service_->OnUnrecoverableError(from_here, message);
 }
 
+AssociatorInterface* FrontendDataTypeController::model_associator() const {
+  return model_associator_.get();
+}
+
+void FrontendDataTypeController::set_model_associator(
+    AssociatorInterface* model_associator) {
+  model_associator_.reset(model_associator);
+}
+
+ChangeProcessor* FrontendDataTypeController::change_processor() const {
+  return change_processor_.get();
+}
+
+void FrontendDataTypeController::set_change_processor(
+    ChangeProcessor* change_processor) {
+  change_processor_.reset(change_processor);
+}
+
 }  // namespace browser_sync
diff --git a/chrome/browser/sync/glue/frontend_data_type_controller.h b/chrome/browser/sync/glue/frontend_data_type_controller.h
index 6a2d863..86c3e60 100644
--- a/chrome/browser/sync/glue/frontend_data_type_controller.h
+++ b/chrome/browser/sync/glue/frontend_data_type_controller.h
@@ -55,6 +55,7 @@
   // UnrecoverableErrorHandler interface.
   virtual void OnUnrecoverableError(const tracked_objects::Location& from_here,
                                     const std::string& message);
+
  protected:
   // For testing only.
   FrontendDataTypeController();
@@ -100,6 +101,11 @@
   // Record causes of start failure.
   virtual void RecordStartFailure(StartResult result) = 0;
 
+  virtual AssociatorInterface* model_associator() const;
+  virtual void set_model_associator(AssociatorInterface* associator);
+  virtual ChangeProcessor* change_processor() const;
+  virtual void set_change_processor(ChangeProcessor* processor);
+
   ProfileSyncFactory* const profile_sync_factory_;
   Profile* const profile_;
   ProfileSyncService* const sync_service_;
@@ -107,6 +113,8 @@
   State state_;
 
   scoped_ptr<StartCallback> start_callback_;
+  // TODO(sync): transition all datatypes to SyncableService and deprecate
+  // AssociatorInterface.
   scoped_ptr<AssociatorInterface> model_associator_;
   scoped_ptr<ChangeProcessor> change_processor_;
 
diff --git a/chrome/browser/sync/glue/frontend_data_type_controller_mock.h b/chrome/browser/sync/glue/frontend_data_type_controller_mock.h
index a32f3f5a..783b203b 100644
--- a/chrome/browser/sync/glue/frontend_data_type_controller_mock.h
+++ b/chrome/browser/sync/glue/frontend_data_type_controller_mock.h
@@ -36,6 +36,10 @@
   MOCK_METHOD2(FinishStart, void(StartResult result,
                                  const tracked_objects::Location& from_here));
   MOCK_METHOD0(CleanUpState, void());
+  MOCK_CONST_METHOD0(model_associator, AssociatorInterface*());
+  MOCK_METHOD1(set_model_associator, void(AssociatorInterface* associator));
+  MOCK_CONST_METHOD0(change_processor, ChangeProcessor*());
+  MOCK_METHOD1(set_change_processor, void(ChangeProcessor* processor));
   MOCK_METHOD2(RecordUnrecoverableError, void(const tracked_objects::Location&,
                                               const std::string&));
   MOCK_METHOD1(RecordAssociationTime, void(base::TimeDelta time));
diff --git a/chrome/browser/sync/glue/generic_change_processor.cc b/chrome/browser/sync/glue/generic_change_processor.cc
new file mode 100644
index 0000000..dabf031
--- /dev/null
+++ b/chrome/browser/sync/glue/generic_change_processor.cc
@@ -0,0 +1,35 @@
+// 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/sync/glue/generic_change_processor.h"
+
+#include "chrome/browser/sync/glue/model_associator.h"
+#include "chrome/browser/sync/syncable_service.h"
+
+namespace browser_sync {
+
+GenericChangeProcessor::GenericChangeProcessor(
+    SyncableService* local_service,
+    UnrecoverableErrorHandler* error_handler)
+    : ChangeProcessor(error_handler),
+      local_service_(local_service) {
+  DCHECK(local_service_);
+}
+GenericChangeProcessor::~GenericChangeProcessor() {
+  // Set to null to ensure it's not used after destruction.
+  local_service_ = NULL;
+}
+
+void GenericChangeProcessor::ApplyChangesFromSyncModel(
+    const sync_api::BaseTransaction* trans,
+    const sync_api::SyncManager::ChangeRecord* changes,
+    int change_count) {
+  local_service_->ApplyChangesFromSync(trans, changes, change_count);
+}
+
+void GenericChangeProcessor::StartImpl(Profile* profile) {}
+
+void GenericChangeProcessor::StopImpl() {}
+
+}  // namespace browser_sync
diff --git a/chrome/browser/sync/glue/generic_change_processor.h b/chrome/browser/sync/glue/generic_change_processor.h
new file mode 100644
index 0000000..a5547c24
--- /dev/null
+++ b/chrome/browser/sync/glue/generic_change_processor.h
@@ -0,0 +1,41 @@
+// 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_SYNC_GLUE_GENERIC_CHANGE_PROCESSOR_H_
+#define CHROME_BROWSER_SYNC_GLUE_GENERIC_CHANGE_PROCESSOR_H_
+#pragma once
+
+#include "chrome/browser/sync/glue/change_processor.h"
+
+class SyncableService;
+
+namespace browser_sync {
+
+// TODO(sync): Have this become a SyncableService implementation and deprecate
+// ChangeProcessor.
+// For now, it acts as a dummy change processor that just passes all
+// ApplySyncChanges commands onto the local SyncableService..
+class GenericChangeProcessor : public ChangeProcessor {
+ public:
+  GenericChangeProcessor(SyncableService* local_service,
+                         UnrecoverableErrorHandler* error_handler);
+  ~GenericChangeProcessor();
+
+  // ChangeProcessor interface.
+  // Just passes all arguments onto the |local_service_|
+  virtual void ApplyChangesFromSyncModel(
+      const sync_api::BaseTransaction* trans,
+      const sync_api::SyncManager::ChangeRecord* changes,
+      int change_count);
+ protected:
+  // ChangeProcessor interface.
+  virtual void StartImpl(Profile* profile);  // Not implemented.
+  virtual void StopImpl();  // Not implemented.
+ private:
+  SyncableService* local_service_;
+};
+
+}  // namespace browser_sync
+
+#endif  // CHROME_BROWSER_SYNC_GLUE_GENERIC_CHANGE_PROCESSOR_H_
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 d26baef..661583b 100644
--- a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
+++ b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
@@ -194,7 +194,7 @@
 
   // Deactivate the change processor on the UI thread. We dont want to listen
   // for any more changes or process them from server.
-  if (change_processor_ != NULL)
+  if (change_processor_.get())
     profile_sync_service_->DeactivateDataType(this, change_processor_.get());
 
   if (StopAssociationAsync()) {
@@ -215,10 +215,10 @@
 
 void NonFrontendDataTypeController::StopAssociation() {
   DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
-  if (model_associator_ != NULL)
+  if (model_associator_.get())
     model_associator_->DisassociateModels();
-  change_processor_.reset();
   model_associator_.reset();
+  change_processor_.reset();
   datatype_stopped_.Signal();
 }
 
diff --git a/chrome/browser/sync/glue/preference_change_processor.cc b/chrome/browser/sync/glue/preference_change_processor.cc
deleted file mode 100644
index 6a6840b..0000000
--- a/chrome/browser/sync/glue/preference_change_processor.cc
+++ /dev/null
@@ -1,228 +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/sync/glue/preference_change_processor.h"
-
-#include <set>
-#include <string>
-
-#include "base/auto_reset.h"
-#include "base/json/json_reader.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/glue/preference_model_associator.h"
-#include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/browser/sync/protocol/preference_specifics.pb.h"
-#include "chrome/common/pref_names.h"
-#include "content/browser/browser_thread.h"
-#include "content/common/json_value_serializer.h"
-#include "content/common/notification_details.h"
-#include "content/common/notification_source.h"
-
-namespace browser_sync {
-
-PreferenceChangeProcessor::PreferenceChangeProcessor(
-    PreferenceModelAssociator* model_associator,
-    UnrecoverableErrorHandler* error_handler)
-    : ChangeProcessor(error_handler),
-      pref_service_(NULL),
-      model_associator_(model_associator),
-      processing_pref_change_(false) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(model_associator);
-  DCHECK(error_handler);
-}
-
-PreferenceChangeProcessor::~PreferenceChangeProcessor() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-}
-
-void PreferenceChangeProcessor::Observe(NotificationType type,
-                                        const NotificationSource& source,
-                                        const NotificationDetails& details) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(running());
-  DCHECK(NotificationType::PREF_CHANGED == type);
-  DCHECK_EQ(pref_service_, Source<PrefService>(source).ptr());
-
-  // Avoid recursion.
-  if (processing_pref_change_)
-    return;
-
-  AutoReset<bool> guard(&processing_pref_change_, true);
-  std::string* name = Details<std::string>(details).ptr();
-  const PrefService::Preference* preference =
-      pref_service_->FindPreference((*name).c_str());
-  DCHECK(preference);
-  int64 sync_id = model_associator_->GetSyncIdFromChromeId(*name);
-  bool user_modifiable = preference->IsUserModifiable();
-  if (!user_modifiable) {
-    // We do not track preferences the user cannot change.
-    model_associator_->Disassociate(sync_id);
-    return;
-  }
-
-  sync_api::WriteTransaction trans(share_handle());
-  sync_api::WriteNode node(&trans);
-
-  // Since we don't create sync nodes for preferences that are not under control
-  // of the user or still have their default value, this changed preference may
-  // not have a sync node yet. If so, we create a node. Similarly, a preference
-  // may become user-modifiable (e.g. due to laxer policy configuration), in
-  // which case we also need to create a sync node and associate it.
-  if (sync_api::kInvalidId == sync_id) {
-    sync_api::ReadNode root(&trans);
-    if (!root.InitByTagLookup(browser_sync::kPreferencesTag)) {
-      error_handler()->OnUnrecoverableError(FROM_HERE, "Can't find root.");
-      return;
-    }
-
-    // InitPrefNodeAndAssociate takes care of writing the value to the sync
-    // node if appropriate.
-    if (!model_associator_->InitPrefNodeAndAssociate(&trans,
-                                                     root,
-                                                     preference)) {
-      error_handler()->OnUnrecoverableError(FROM_HERE,
-                                            "Can't create sync node.");
-    }
-    return;
-  }
-
-  if (!node.InitByIdLookup(sync_id)) {
-    error_handler()->OnUnrecoverableError(FROM_HERE,
-                                          "Preference node lookup failed.");
-    return;
-  }
-
-  if (!PreferenceModelAssociator::WritePreferenceToNode(
-          preference->name(),
-          *preference->GetValue(),
-          &node)) {
-    error_handler()->OnUnrecoverableError(FROM_HERE,
-                                          "Failed to update preference node.");
-    return;
-  }
-}
-
-void PreferenceChangeProcessor::ApplyChangesFromSyncModel(
-    const sync_api::BaseTransaction* trans,
-    const sync_api::SyncManager::ChangeRecord* changes,
-    int change_count) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  if (!running())
-    return;
-  StopObserving();
-
-  for (int i = 0; i < change_count; ++i) {
-    sync_api::ReadNode node(trans);
-    // TODO(ncarter): Can't look up the name for deletions: lookup of
-    // deleted items fails at the syncapi layer.  However, the node should
-    // generally still exist in the syncable database; we just need to
-    // plumb the syncapi so that it succeeds.
-    if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE ==
-        changes[i].action) {
-      // Until the above is fixed, we have no choice but to ignore deletions.
-      LOG(ERROR) << "No way to handle pref deletion";
-      continue;
-    }
-
-    if (!node.InitByIdLookup(changes[i].id)) {
-      error_handler()->OnUnrecoverableError(FROM_HERE,
-                                            "Preference node lookup failed.");
-      return;
-    }
-    DCHECK(syncable::PREFERENCES == node.GetModelType());
-
-    std::string name;
-    scoped_ptr<Value> value(ReadPreference(&node, &name));
-    // Skip values we can't deserialize.
-    if (!value.get())
-      continue;
-
-    // It is possible that we may receive a change to a preference we
-    // do not want to sync.  For example if the user is syncing a Mac
-    // client and a Windows client, the Windows client does not
-    // support kConfirmToQuitEnabled.  Ignore updates from these
-    // preferences.
-    const char* pref_name = name.c_str();
-    if (model_associator_->synced_preferences().count(pref_name) == 0)
-      continue;
-
-    // Don't try to overwrite preferences not controllable by the user.
-    const PrefService::Preference* pref =
-        pref_service_->FindPreference(pref_name);
-    DCHECK(pref);
-    if (!pref->IsUserModifiable())
-      continue;
-
-    if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE ==
-        changes[i].action) {
-      pref_service_->ClearPref(pref_name);
-    } else {
-      pref_service_->Set(pref_name, *value);
-
-      // If this is a newly added node, associate.
-      if (sync_api::SyncManager::ChangeRecord::ACTION_ADD ==
-          changes[i].action) {
-        const PrefService::Preference* preference =
-            pref_service_->FindPreference(name.c_str());
-        model_associator_->Associate(preference, changes[i].id);
-      }
-
-      model_associator_->AfterUpdateOperations(name);
-    }
-  }
-  StartObserving();
-}
-
-Value* PreferenceChangeProcessor::ReadPreference(
-    sync_api::ReadNode* node,
-    std::string* name) {
-  const sync_pb::PreferenceSpecifics& preference(
-      node->GetPreferenceSpecifics());
-  base::JSONReader reader;
-  scoped_ptr<Value> value(reader.JsonToValue(preference.value(), false, false));
-  if (!value.get()) {
-    std::string err = "Failed to deserialize preference value: " +
-        reader.GetErrorMessage();
-    error_handler()->OnUnrecoverableError(FROM_HERE, err);
-    return NULL;
-  }
-  *name = preference.name();
-  return value.release();
-}
-
-void PreferenceChangeProcessor::StartImpl(Profile* profile) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  pref_service_ = profile->GetPrefs();
-  registrar_.Init(pref_service_);
-  StartObserving();
-}
-
-void PreferenceChangeProcessor::StopImpl() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  StopObserving();
-  pref_service_ = NULL;
-}
-
-
-void PreferenceChangeProcessor::StartObserving() {
-  DCHECK(pref_service_);
-  for (std::set<std::string>::const_iterator it =
-      model_associator_->synced_preferences().begin();
-      it != model_associator_->synced_preferences().end(); ++it) {
-    registrar_.Add((*it).c_str(), this);
-  }
-}
-
-void PreferenceChangeProcessor::StopObserving() {
-  DCHECK(pref_service_);
-  for (std::set<std::string>::const_iterator it =
-      model_associator_->synced_preferences().begin();
-      it != model_associator_->synced_preferences().end(); ++it) {
-    registrar_.Remove((*it).c_str(), this);
-  }
-}
-
-}  // namespace browser_sync
diff --git a/chrome/browser/sync/glue/preference_change_processor.h b/chrome/browser/sync/glue/preference_change_processor.h
deleted file mode 100644
index 81117756..0000000
--- a/chrome/browser/sync/glue/preference_change_processor.h
+++ /dev/null
@@ -1,71 +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_SYNC_GLUE_PREFERENCE_CHANGE_PROCESSOR_H_
-#define CHROME_BROWSER_SYNC_GLUE_PREFERENCE_CHANGE_PROCESSOR_H_
-#pragma once
-
-#include <string>
-
-#include "chrome/browser/prefs/pref_change_registrar.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/sync/engine/syncapi.h"
-#include "chrome/browser/sync/glue/change_processor.h"
-#include "chrome/browser/sync/glue/sync_backend_host.h"
-#include "content/common/notification_observer.h"
-
-namespace browser_sync {
-
-class PreferenceModelAssociator;
-class UnrecoverableErrorHandler;
-
-// This class is responsible for taking changes from the PrefService and
-// applying them to the sync_api 'syncable' model, and vice versa. All
-// operations and use of this class are from the UI thread.
-class PreferenceChangeProcessor : public ChangeProcessor,
-                                  public NotificationObserver {
- public:
-  PreferenceChangeProcessor(PreferenceModelAssociator* model_associator,
-                            UnrecoverableErrorHandler* error_handler);
-  virtual ~PreferenceChangeProcessor();
-
-  // NotificationObserver implementation.
-  // PrefService -> sync_api model change application.
-  virtual void Observe(NotificationType type,
-                       const NotificationSource& source,
-                       const NotificationDetails& details);
-
-  // sync_api model -> PrefService change application.
-  virtual void ApplyChangesFromSyncModel(
-      const sync_api::BaseTransaction* trans,
-      const sync_api::SyncManager::ChangeRecord* changes,
-      int change_count);
-
- protected:
-  virtual void StartImpl(Profile* profile);
-  virtual void StopImpl();
-
- private:
-  Value* ReadPreference(sync_api::ReadNode* node, std::string* name);
-
-  void StartObserving();
-  void StopObserving();
-
-  // The model we are processing changes from. Non-NULL when |running_| is true.
-  PrefService* pref_service_;
-
-  // The two models should be associated according to this ModelAssociator.
-  PreferenceModelAssociator* model_associator_;
-
-  // Whether we are currently processing a preference change notification.
-  bool processing_pref_change_;
-
-  PrefChangeRegistrar registrar_;
-
-  DISALLOW_COPY_AND_ASSIGN(PreferenceChangeProcessor);
-};
-
-}  // namespace browser_sync
-
-#endif  // CHROME_BROWSER_SYNC_GLUE_PREFERENCE_CHANGE_PROCESSOR_H_
diff --git a/chrome/browser/sync/glue/preference_data_type_controller.cc b/chrome/browser/sync/glue/preference_data_type_controller.cc
index 3331bd34..5285b92 100644
--- a/chrome/browser/sync/glue/preference_data_type_controller.cc
+++ b/chrome/browser/sync/glue/preference_data_type_controller.cc
@@ -5,7 +5,11 @@
 #include "chrome/browser/sync/glue/preference_data_type_controller.h"
 
 #include "base/metrics/histogram.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sync/glue/generic_change_processor.h"
 #include "chrome/browser/sync/profile_sync_factory.h"
+#include "chrome/browser/sync/syncable_service.h"
 
 namespace browser_sync {
 
@@ -15,20 +19,36 @@
     ProfileSyncService* sync_service)
     : FrontendDataTypeController(profile_sync_factory,
                                  profile,
-                                 sync_service) {
+                                 sync_service),
+      pref_sync_service_(NULL) {
 }
 
-PreferenceDataTypeController::~PreferenceDataTypeController() {}
+PreferenceDataTypeController::~PreferenceDataTypeController() {
+  pref_sync_service_ = NULL;
+}
 
 syncable::ModelType PreferenceDataTypeController::type() const {
   return syncable::PREFERENCES;
 }
 
 void PreferenceDataTypeController::CreateSyncComponents() {
-  ProfileSyncFactory::SyncComponents sync_components = profile_sync_factory_->
-      CreatePreferenceSyncComponents(sync_service_, this);
-  model_associator_.reset(sync_components.model_associator);
-  change_processor_.reset(sync_components.change_processor);
+  ProfileSyncFactory::SyncComponents sync_components =
+      profile_sync_factory_->CreatePreferenceSyncComponents(sync_service_,
+                                                            this);
+  set_model_associator(sync_components.model_associator);
+  set_change_processor(sync_components.change_processor);
+  reinterpret_cast<SyncableService*>(model_associator())->
+      SetupSync(sync_service_,
+                reinterpret_cast<GenericChangeProcessor*>(change_processor()));
+}
+
+AssociatorInterface* PreferenceDataTypeController::model_associator() const {
+  return pref_sync_service_;
+}
+
+void PreferenceDataTypeController::set_model_associator(
+    AssociatorInterface* associator) {
+  pref_sync_service_ = associator;
 }
 
 void PreferenceDataTypeController::RecordUnrecoverableError(
diff --git a/chrome/browser/sync/glue/preference_data_type_controller.h b/chrome/browser/sync/glue/preference_data_type_controller.h
index 3f375b15..f126bdf 100644
--- a/chrome/browser/sync/glue/preference_data_type_controller.h
+++ b/chrome/browser/sync/glue/preference_data_type_controller.h
@@ -8,6 +8,7 @@
 
 #include <string>
 
+#include "base/compiler_specific.h"
 #include "chrome/browser/sync/glue/frontend_data_type_controller.h"
 
 namespace browser_sync {
@@ -21,16 +22,24 @@
   virtual ~PreferenceDataTypeController();
 
   // FrontendDataTypeController implementation.
-  virtual syncable::ModelType type() const;
+  virtual syncable::ModelType type() const OVERRIDE;
+  virtual AssociatorInterface* model_associator() const OVERRIDE;
+  virtual void set_model_associator(AssociatorInterface* associator) OVERRIDE;
 
  private:
   // FrontendDataTypeController implementations.
-  virtual void CreateSyncComponents();
+  // TODO(zea): Remove this once everything uses the NewAssociatorInterface.
+  virtual void CreateSyncComponents() OVERRIDE;
   virtual void RecordUnrecoverableError(
       const tracked_objects::Location& from_here,
-      const std::string& message);
-  virtual void RecordAssociationTime(base::TimeDelta time);
-  virtual void RecordStartFailure(StartResult result);
+      const std::string& message) OVERRIDE;
+  virtual void RecordAssociationTime(base::TimeDelta time) OVERRIDE;
+  virtual void RecordStartFailure(StartResult result) OVERRIDE;
+
+  // Owned by pref service.
+  // TODO(zea): Make this a SyncableService once AssociatorInterface is
+  // deprecated.
+  AssociatorInterface* pref_sync_service_;
 
   DISALLOW_COPY_AND_ASSIGN(PreferenceDataTypeController);
 };
diff --git a/chrome/browser/sync/glue/preference_data_type_controller_unittest.cc b/chrome/browser/sync/glue/preference_data_type_controller_unittest.cc
index 4df8b3f..42d563ad 100644
--- a/chrome/browser/sync/glue/preference_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/preference_data_type_controller_unittest.cc
@@ -11,16 +11,15 @@
 #include "base/tracked_objects.h"
 #include "chrome/browser/sync/glue/preference_data_type_controller.h"
 #include "chrome/browser/sync/glue/change_processor_mock.h"
-#include "chrome/browser/sync/glue/model_associator_mock.h"
 #include "chrome/browser/sync/profile_sync_factory_mock.h"
 #include "chrome/browser/sync/profile_sync_service_mock.h"
+#include "chrome/browser/sync/syncable_service_mock.h"
 #include "chrome/test/profile_mock.h"
 #include "content/browser/browser_thread.h"
 
 using browser_sync::PreferenceDataTypeController;
 using browser_sync::ChangeProcessorMock;
 using browser_sync::DataTypeController;
-using browser_sync::ModelAssociatorMock;
 using testing::_;
 using testing::DoAll;
 using testing::InvokeWithoutArgs;
@@ -48,11 +47,13 @@
 
  protected:
   void SetStartExpectations() {
-    model_associator_ = new ModelAssociatorMock();
+    model_associator_.reset(new SyncableServiceMock());
     change_processor_ = new ChangeProcessorMock();
     EXPECT_CALL(*profile_sync_factory_, CreatePreferenceSyncComponents(_, _)).
-        WillOnce(Return(ProfileSyncFactory::SyncComponents(model_associator_,
-                                                           change_processor_)));
+        WillOnce(Return(
+            ProfileSyncFactory::SyncComponents(model_associator_.get(),
+                                               change_processor_)));
+    EXPECT_CALL(*model_associator_, SetupSync(_,_)).Times(1);
   }
 
   void SetAssociateExpectations() {
@@ -79,7 +80,7 @@
   scoped_ptr<ProfileSyncFactoryMock> profile_sync_factory_;
   ProfileMock profile_;
   ProfileSyncServiceMock service_;
-  ModelAssociatorMock* model_associator_;
+  scoped_ptr<SyncableServiceMock> model_associator_;
   ChangeProcessorMock* change_processor_;
   StartCallback start_callback_;
 };
diff --git a/chrome/browser/sync/glue/preference_model_associator.cc b/chrome/browser/sync/glue/preference_model_associator.cc
deleted file mode 100644
index 7d75c38..0000000
--- a/chrome/browser/sync/glue/preference_model_associator.cc
+++ /dev/null
@@ -1,338 +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/sync/glue/preference_model_associator.h"
-
-#include "base/json/json_reader.h"
-#include "base/logging.h"
-#include "base/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/engine/syncapi.h"
-#include "chrome/browser/sync/glue/synchronized_preferences.h"
-#include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/browser/sync/protocol/preference_specifics.pb.h"
-#include "chrome/common/pref_names.h"
-#include "content/browser/browser_thread.h"
-#include "content/common/json_value_serializer.h"
-#include "content/common/notification_service.h"
-
-namespace browser_sync {
-
-PreferenceModelAssociator::PreferenceModelAssociator(
-    ProfileSyncService* sync_service)
-    : sync_service_(sync_service),
-      preferences_node_id_(sync_api::kInvalidId) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(sync_service_);
-
-  // Add the list of kSynchronizedPreferences to our local
-  // synced_preferences set, taking care to filter out any preferences
-  // that are not registered.
-  PrefService* pref_service = sync_service_->profile()->GetPrefs();
-  for (size_t i = 0; i < arraysize(kSynchronizedPreferences); ++i) {
-    if (pref_service->FindPreference(kSynchronizedPreferences[i]))
-      synced_preferences_.insert(kSynchronizedPreferences[i]);
-  }
-}
-
-PreferenceModelAssociator::~PreferenceModelAssociator() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-}
-
-bool PreferenceModelAssociator::InitPrefNodeAndAssociate(
-    sync_api::WriteTransaction* trans,
-    const sync_api::BaseNode& root,
-    const PrefService::Preference* pref) {
-  DCHECK(pref);
-
-  PrefService* pref_service = sync_service_->profile()->GetPrefs();
-  base::JSONReader reader;
-  std::string tag = pref->name();
-  sync_api::WriteNode node(trans);
-  if (node.InitByClientTagLookup(syncable::PREFERENCES, tag)) {
-    // The server has a value for the preference.
-    const sync_pb::PreferenceSpecifics& preference(
-        node.GetPreferenceSpecifics());
-    DCHECK_EQ(tag, preference.name());
-
-    if (pref->IsUserModifiable()) {
-      scoped_ptr<Value> value(
-          reader.JsonToValue(preference.value(), false, false));
-      std::string pref_name = preference.name();
-      if (!value.get()) {
-        LOG(ERROR) << "Failed to deserialize preference value: "
-                   << reader.GetErrorMessage();
-        return false;
-      }
-
-      // Merge the server value of this preference with the local value.
-      scoped_ptr<Value> new_value(MergePreference(*pref, *value));
-
-      // Update the local preference based on what we got from the
-      // sync server.
-      if (new_value->IsType(Value::TYPE_NULL)) {
-        pref_service->ClearPref(pref_name.c_str());
-      } else if (!new_value->IsType(pref->GetType())) {
-        LOG(WARNING) << "Synced value for " << preference.name()
-                     << " is of type " << new_value->GetType()
-                     << " which doesn't match pref type " << pref->GetType();
-      } else if (!pref->GetValue()->Equals(new_value.get())) {
-        pref_service->Set(pref_name.c_str(), *new_value);
-      }
-
-      AfterUpdateOperations(pref_name);
-
-      // If the merge resulted in an updated value, write it back to
-      // the sync node.
-      if (!value->Equals(new_value.get()) &&
-          !WritePreferenceToNode(pref->name(), *new_value, &node))
-        return false;
-    }
-    Associate(pref, node.GetId());
-  } else if (pref->IsUserControlled()) {
-    // The server doesn't have a value, but we have a user-controlled value,
-    // so we push it to the server.
-    sync_api::WriteNode write_node(trans);
-    if (!write_node.InitUniqueByCreation(syncable::PREFERENCES, root, tag)) {
-      LOG(ERROR) << "Failed to create preference sync node.";
-      return false;
-    }
-
-    // Update the sync node with the local value for this preference.
-    if (!WritePreferenceToNode(pref->name(), *pref->GetValue(), &write_node))
-      return false;
-
-    Associate(pref, write_node.GetId());
-  }
-
-  return true;
-}
-
-bool PreferenceModelAssociator::AssociateModels() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  PrefService* pref_service = sync_service_->profile()->GetPrefs();
-
-  int64 root_id;
-  if (!GetSyncIdForTaggedNode(kPreferencesTag, &root_id)) {
-    LOG(ERROR) << "Server did not create the top-level preferences node. We "
-               << "might be running against an out-of-date server.";
-    return false;
-  }
-
-  sync_api::WriteTransaction trans(sync_service_->GetUserShare());
-  sync_api::ReadNode root(&trans);
-  if (!root.InitByIdLookup(root_id)) {
-    LOG(ERROR) << "Server did not create the top-level preferences node. We "
-               << "might be running against an out-of-date server.";
-    return false;
-  }
-
-  for (std::set<std::string>::iterator it = synced_preferences_.begin();
-       it != synced_preferences_.end(); ++it) {
-    const PrefService::Preference* pref =
-        pref_service->FindPreference((*it).c_str());
-    DCHECK(pref);
-    InitPrefNodeAndAssociate(&trans, root, pref);
-  }
-  return true;
-}
-
-bool PreferenceModelAssociator::DisassociateModels() {
-  id_map_.clear();
-  id_map_inverse_.clear();
-  return true;
-}
-
-bool PreferenceModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) {
-  DCHECK(has_nodes);
-  *has_nodes = false;
-  int64 preferences_sync_id;
-  if (!GetSyncIdForTaggedNode(kPreferencesTag, &preferences_sync_id)) {
-    LOG(ERROR) << "Server did not create the top-level preferences node. We "
-               << "might be running against an out-of-date server.";
-    return false;
-  }
-  sync_api::ReadTransaction trans(sync_service_->GetUserShare());
-
-  sync_api::ReadNode preferences_node(&trans);
-  if (!preferences_node.InitByIdLookup(preferences_sync_id)) {
-    LOG(ERROR) << "Server did not create the top-level preferences node. We "
-               << "might be running against an out-of-date server.";
-    return false;
-  }
-
-  // The sync model has user created nodes if the preferences folder has any
-  // children.
-  *has_nodes = sync_api::kInvalidId != preferences_node.GetFirstChildId();
-  return true;
-}
-
-const PrefService::Preference*
-PreferenceModelAssociator::GetChromeNodeFromSyncId(int64 sync_id) {
-  return NULL;
-}
-
-bool PreferenceModelAssociator::InitSyncNodeFromChromeId(
-    const std::string& node_id,
-    sync_api::BaseNode* sync_node) {
-  return false;
-}
-
-int64 PreferenceModelAssociator::GetSyncIdFromChromeId(
-    const std::string& preference_name) {
-  PreferenceNameToSyncIdMap::const_iterator iter =
-      id_map_.find(preference_name);
-  return iter == id_map_.end() ? sync_api::kInvalidId : iter->second;
-}
-
-void PreferenceModelAssociator::Associate(
-    const PrefService::Preference* preference, int64 sync_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK_NE(sync_api::kInvalidId, sync_id);
-  DCHECK(id_map_.find(preference->name()) == id_map_.end());
-  DCHECK(id_map_inverse_.find(sync_id) == id_map_inverse_.end());
-  id_map_[preference->name()] = sync_id;
-  id_map_inverse_[sync_id] = preference->name();
-}
-
-void PreferenceModelAssociator::Disassociate(int64 sync_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  SyncIdToPreferenceNameMap::iterator iter = id_map_inverse_.find(sync_id);
-  if (iter == id_map_inverse_.end())
-    return;
-  id_map_.erase(iter->second);
-  id_map_inverse_.erase(iter);
-}
-
-bool PreferenceModelAssociator::GetSyncIdForTaggedNode(const std::string& tag,
-                                                       int64* sync_id) {
-  sync_api::ReadTransaction trans(sync_service_->GetUserShare());
-  sync_api::ReadNode sync_node(&trans);
-  if (!sync_node.InitByTagLookup(tag.c_str()))
-    return false;
-  *sync_id = sync_node.GetId();
-  return true;
-}
-
-Value* PreferenceModelAssociator::MergePreference(
-    const PrefService::Preference& local_pref,
-    const Value& server_value) {
-  const std::string& name(local_pref.name());
-  if (name == prefs::kURLsToRestoreOnStartup ||
-      name == prefs::kDesktopNotificationAllowedOrigins ||
-      name == prefs::kDesktopNotificationDeniedOrigins) {
-    return MergeListValues(*local_pref.GetValue(), server_value);
-  }
-
-  if (name == prefs::kContentSettingsPatterns ||
-      name == prefs::kGeolocationContentSettings) {
-    return MergeDictionaryValues(*local_pref.GetValue(), server_value);
-  }
-
-  // If this is not a specially handled preference, server wins.
-  return server_value.DeepCopy();
-}
-
-bool PreferenceModelAssociator::WritePreferenceToNode(
-    const std::string& name,
-    const Value& value,
-    sync_api::WriteNode* node) {
-  std::string serialized;
-  JSONStringValueSerializer json(&serialized);
-  if (!json.Serialize(value)) {
-    LOG(ERROR) << "Failed to serialize preference value.";
-    return false;
-  }
-
-  sync_pb::PreferenceSpecifics preference;
-  preference.set_name(name);
-  preference.set_value(serialized);
-  node->SetPreferenceSpecifics(preference);
-  // TODO(viettrungluu): eliminate conversion (it's temporary)
-  node->SetTitle(UTF8ToWide(name));
-  return true;
-}
-
-Value* PreferenceModelAssociator::MergeListValues(const Value& from_value,
-                                                  const Value& to_value) {
-  if (from_value.GetType() == Value::TYPE_NULL)
-    return to_value.DeepCopy();
-  if (to_value.GetType() == Value::TYPE_NULL)
-    return from_value.DeepCopy();
-
-  DCHECK(from_value.GetType() == Value::TYPE_LIST);
-  DCHECK(to_value.GetType() == Value::TYPE_LIST);
-  const ListValue& from_list_value = static_cast<const ListValue&>(from_value);
-  const ListValue& to_list_value = static_cast<const ListValue&>(to_value);
-  ListValue* result = to_list_value.DeepCopy();
-
-  for (ListValue::const_iterator i = from_list_value.begin();
-       i != from_list_value.end(); ++i) {
-    Value* value = (*i)->DeepCopy();
-    result->AppendIfNotPresent(value);
-  }
-  return result;
-}
-
-Value* PreferenceModelAssociator::MergeDictionaryValues(
-    const Value& from_value,
-    const Value& to_value) {
-  if (from_value.GetType() == Value::TYPE_NULL)
-    return to_value.DeepCopy();
-  if (to_value.GetType() == Value::TYPE_NULL)
-    return from_value.DeepCopy();
-
-  DCHECK(from_value.GetType() == Value::TYPE_DICTIONARY);
-  DCHECK(to_value.GetType() == Value::TYPE_DICTIONARY);
-  const DictionaryValue& from_dict_value =
-      static_cast<const DictionaryValue&>(from_value);
-  const DictionaryValue& to_dict_value =
-      static_cast<const DictionaryValue&>(to_value);
-  DictionaryValue* result = to_dict_value.DeepCopy();
-
-  for (DictionaryValue::key_iterator key = from_dict_value.begin_keys();
-       key != from_dict_value.end_keys(); ++key) {
-    Value* from_value;
-    bool success = from_dict_value.GetWithoutPathExpansion(*key, &from_value);
-    DCHECK(success);
-
-    Value* to_key_value;
-    if (result->GetWithoutPathExpansion(*key, &to_key_value)) {
-      if (to_key_value->GetType() == Value::TYPE_DICTIONARY) {
-        Value* merged_value = MergeDictionaryValues(*from_value, *to_key_value);
-        result->SetWithoutPathExpansion(*key, merged_value);
-      }
-      // Note that for all other types we want to preserve the "to"
-      // values so we do nothing here.
-    } else {
-      result->SetWithoutPathExpansion(*key, from_value->DeepCopy());
-    }
-  }
-  return result;
-}
-
-void PreferenceModelAssociator::AfterUpdateOperations(
-    const std::string& pref_name) {
-  // The bookmark bar visibility preference requires a special
-  // notification to update the UI.
-  if (0 == pref_name.compare(prefs::kShowBookmarkBar)) {
-    NotificationService::current()->Notify(
-        NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED,
-        Source<PreferenceModelAssociator>(this),
-        NotificationService::NoDetails());
-  }
-}
-
-bool PreferenceModelAssociator::CryptoReadyIfNecessary() {
-  // We only access the cryptographer while holding a transaction.
-  sync_api::ReadTransaction trans(sync_service_->GetUserShare());
-  syncable::ModelTypeSet encrypted_types;
-  sync_service_->GetEncryptedDataTypes(&encrypted_types);
-  return encrypted_types.count(syncable::PREFERENCES) == 0 ||
-         sync_service_->IsCryptographerReady(&trans);
-}
-
-}  // namespace browser_sync
diff --git a/chrome/browser/sync/glue/preference_model_associator.h b/chrome/browser/sync/glue/preference_model_associator.h
deleted file mode 100644
index 5c661b2..0000000
--- a/chrome/browser/sync/glue/preference_model_associator.h
+++ /dev/null
@@ -1,135 +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_SYNC_GLUE_PREFERENCE_MODEL_ASSOCIATOR_H_
-#define CHROME_BROWSER_SYNC_GLUE_PREFERENCE_MODEL_ASSOCIATOR_H_
-#pragma once
-
-#include <map>
-#include <set>
-#include <string>
-
-#include "base/basictypes.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/sync/glue/model_associator.h"
-#include "chrome/browser/sync/unrecoverable_error_handler.h"
-
-class ProfileSyncService;
-class Value;
-
-namespace sync_api {
-class WriteNode;
-class WriteTransaction;
-}
-
-namespace browser_sync {
-
-class PreferenceChangeProcessor;
-
-static const char kPreferencesTag[] = "google_chrome_preferences";
-
-// Contains all model association related logic:
-// * Algorithm to associate preferences model and sync model.
-class PreferenceModelAssociator
-    : public PerDataTypeAssociatorInterface<PrefService::Preference,
-                                            std::string> {
- public:
-  static syncable::ModelType model_type() { return syncable::PREFERENCES; }
-  explicit PreferenceModelAssociator(ProfileSyncService* sync_service);
-  virtual ~PreferenceModelAssociator();
-
-  // Returns the list of preference names that should be monitored for
-  // changes.  Only preferences that are registered will be in this
-  // list.
-  const std::set<std::string>& synced_preferences() {
-    return synced_preferences_;
-  }
-
-  // Create an association for a given preference. A sync node is created if
-  // necessary and the value is read from or written to the node as appropriate.
-  bool InitPrefNodeAndAssociate(sync_api::WriteTransaction* trans,
-                                const sync_api::BaseNode& root,
-                                const PrefService::Preference* pref);
-
-  // PerDataTypeAssociatorInterface implementation.
-  //
-  // Iterates through the sync model looking for matched pairs of items.
-  virtual bool AssociateModels();
-
-  // Clears all associations.
-  virtual bool DisassociateModels();
-
-  // Returns whether the sync model has nodes other than the permanent tagged
-  // nodes.
-  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
-
-  virtual void AbortAssociation() {
-    // No implementation needed, this associator runs on the main
-    // thread.
-  }
-
-  // See ModelAssociator interface.
-  virtual bool CryptoReadyIfNecessary();
-
-  // Not implemented.
-  virtual const PrefService::Preference* GetChromeNodeFromSyncId(int64 sync_id);
-
-  // Not implemented.
-  virtual bool InitSyncNodeFromChromeId(const std::string& node_id,
-                                        sync_api::BaseNode* sync_node);
-
-  // Returns the sync id for the given preference name, or sync_api::kInvalidId
-  // if the preference name is not associated to any sync id.
-  virtual int64 GetSyncIdFromChromeId(const std::string& node_id);
-
-  // Associates the given preference name with the given sync id.
-  virtual void Associate(const PrefService::Preference* node, int64 sync_id);
-
-  // Remove the association that corresponds to the given sync id.
-  virtual void Disassociate(int64 sync_id);
-
-  // Returns whether a node with the given permanent tag was found and update
-  // |sync_id| with that node's id.
-  virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
-
-  // Merges the value of local_pref into the supplied server_value and
-  // returns the result (caller takes ownership).  If there is a
-  // conflict, the server value always takes precedence.  Note that
-  // only certain preferences will actually be merged, all others will
-  // return a copy of the server value.  See the method's
-  // implementation for details.
-  static Value* MergePreference(const PrefService::Preference& local_pref,
-                                const Value& server_value);
-
-  // Writes the value of pref into the specified node.  Returns true
-  // upon success.
-  static bool WritePreferenceToNode(const std::string& name,
-                                    const Value& value,
-                                    sync_api::WriteNode* node);
-
-  // Perform any additional operations that need to happen after a preference
-  // has been updated.
-  void AfterUpdateOperations(const std::string& pref_name);
-
- private:
-  typedef std::map<std::string, int64> PreferenceNameToSyncIdMap;
-  typedef std::map<int64, std::string> SyncIdToPreferenceNameMap;
-
-  static Value* MergeListValues(const Value& from_value, const Value& to_value);
-  static Value* MergeDictionaryValues(const Value& from_value,
-                                      const Value& to_value);
-
-  ProfileSyncService* sync_service_;
-  std::set<std::string> synced_preferences_;
-  int64 preferences_node_id_;
-
-  PreferenceNameToSyncIdMap id_map_;
-  SyncIdToPreferenceNameMap id_map_inverse_;
-
-  DISALLOW_COPY_AND_ASSIGN(PreferenceModelAssociator);
-};
-
-}  // namespace browser_sync
-
-#endif  // CHROME_BROWSER_SYNC_GLUE_PREFERENCE_MODEL_ASSOCIATOR_H_
diff --git a/chrome/browser/sync/glue/session_data_type_controller.cc b/chrome/browser/sync/glue/session_data_type_controller.cc
index 68186cbd..5d84b299 100644
--- a/chrome/browser/sync/glue/session_data_type_controller.cc
+++ b/chrome/browser/sync/glue/session_data_type_controller.cc
@@ -31,8 +31,8 @@
 void SessionDataTypeController::CreateSyncComponents() {
   ProfileSyncFactory::SyncComponents sync_components = profile_sync_factory_->
       CreateSessionSyncComponents(sync_service_, this);
-  model_associator_.reset(sync_components.model_associator);
-  change_processor_.reset(sync_components.change_processor);
+  set_model_associator(sync_components.model_associator);
+  set_change_processor(sync_components.change_processor);
 }
 
 void SessionDataTypeController::RecordUnrecoverableError(
diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc
index d039471..c3a8bff 100644
--- a/chrome/browser/sync/glue/sync_backend_host.cc
+++ b/chrome/browser/sync/glue/sync_backend_host.cc
@@ -515,6 +515,9 @@
   // processors so it can receive updates.
   DCHECK_EQ(processors_.count(type), 0U);
   processors_[type] = change_processor;
+
+  // Start the change processor.
+  change_processor->Start(profile_, GetUserShare());
 }
 
 void SyncBackendHost::DeactivateDataType(
@@ -523,6 +526,8 @@
   base::AutoLock lock(registrar_lock_);
   registrar_.routing_info.erase(data_type_controller->type());
 
+  // Stop the change processor and remove it from the list of processors.
+  change_processor->Stop();
   std::map<syncable::ModelType, ChangeProcessor*>::size_type erased =
       processors_.erase(data_type_controller->type());
   DCHECK_EQ(erased, 1U);
diff --git a/chrome/browser/sync/glue/synchronized_preferences.h b/chrome/browser/sync/glue/synchronized_preferences.h
deleted file mode 100644
index beb8166..0000000
--- a/chrome/browser/sync/glue/synchronized_preferences.h
+++ /dev/null
@@ -1,205 +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.
-
-// Defines a list of the preferences that the
-// PreferencesChangeProcessor should process changes for.
-
-#ifndef CHROME_BROWSER_SYNC_GLUE_SYNCHRONIZED_PREFERENCES_H_
-#define CHROME_BROWSER_SYNC_GLUE_SYNCHRONIZED_PREFERENCES_H_
-#pragma once
-
-#include "chrome/browser/translate/translate_prefs.h"
-#include "chrome/common/pref_names.h"
-
-namespace browser_sync {
-
-static const char* kSynchronizedPreferences[] = {
-  // Options dialog: Basics tab.
-  prefs::kRestoreOnStartup,
-  prefs::kURLsToRestoreOnStartup,
-  prefs::kShowBookmarkBar,
-  prefs::kHomePageIsNewTabPage,
-  prefs::kHomePage,
-  prefs::kShowHomeButton,
-  // Default Search is not synced, needs a new data type.  See
-  // http://crbug.com/40482
-
-  // Options dialog: Personal Stuff tab.
-  prefs::kPasswordManagerEnabled,
-  prefs::kAutofillEnabled,
-  prefs::kUseCustomChromeFrame,
-
-  // Options dialog: Under the hood -> Content Settings -> Cookies.
-  //   Cookie settings and exceptions not working
-  prefs::kBlockThirdPartyCookies,
-  prefs::kClearSiteDataOnExit,
-
-  // Options dialog: Under the hood -> Content Settings ->
-  //     Images, JavaScript, Plug-ins, Pop-ups.
-  prefs::kDefaultContentSettings,
-  prefs::kContentSettingsPatterns,
-
-  // Options dialog: Under the hood -> Content Settings -> Location.
-  //   Exceptions not working (dialog not working either).
-  prefs::kGeolocationContentSettings,
-  prefs::kGeolocationDefaultContentSetting,
-
-  // Options dialog: under the hood -> Content Settings -> Notifications.
-  prefs::kDesktopNotificationDefaultContentSetting,
-
-  // Options dialog: Under the hood -> Clear browsing data.
-  //  All working but no live update.
-  prefs::kDeleteBrowsingHistory,
-  prefs::kDeleteDownloadHistory,
-  prefs::kDeleteCache,
-  prefs::kDeleteCookies,
-  prefs::kDeletePasswords,
-  prefs::kDeleteFormData,
-  prefs::kDeleteTimePeriod,
-
-  // Options dialog: Under the hood -> Change proxy settings.
-  //  Uses native OS dialog, not synced.
-
-  // Options dialog: Under the hood -> Change font and language settings.
-  //   Serif, San Serif, Fixed font settings not synced.
-  prefs::kDefaultCharset,
-  // There is no dialog to modify the kAcceptLanguages list on OSX, so
-  // don't sync it.
-#if !defined(OS_MACOSX)
-  prefs::kAcceptLanguages,
-#endif
-  prefs::kEnableSpellCheck,
-  // Spell checker language not synced.
-  prefs::kApplicationLocale,
-
-  // Options dialog: Under the hood.
-  prefs::kAlternateErrorPagesEnabled,
-  prefs::kSearchSuggestEnabled,
-  prefs::kNetworkPredictionEnabled,
-  prefs::kSafeBrowsingEnabled,
-  prefs::kEnableTranslate,
-  // Download directory not synced.
-  // Clear auto-opening settings not synced.
-  prefs::kPromptForDownload,
-
-  // Wrench menu -> Extensions.
-  prefs::kExtensionsUIDeveloperMode,  // no live update
-
-  // Document menu -> Zoom.
-  //   prefs::kPerHostZoomLevels creates bad UX when synced, see
-  //   http://crbug.com/47359.
-
-  // Document menu -> Encoding -> Auto Detect.
-  prefs::kWebKitUsesUniversalDetector,
-
-  // Autofill dialog.
-#if defined(OS_MACOSX)
-  prefs::kAutofillAuxiliaryProfilesEnabled,
-#endif
-
-  // Translate preferences.
-  TranslatePrefs::kPrefTranslateLanguageBlacklist,
-  TranslatePrefs::kPrefTranslateSiteBlacklist,
-  TranslatePrefs::kPrefTranslateWhitelists,
-  TranslatePrefs::kPrefTranslateDeniedCount,
-  TranslatePrefs::kPrefTranslateAcceptedCount,
-
-  // Desktop notification permissions.
-  prefs::kDesktopNotificationAllowedOrigins,
-  prefs::kDesktopNotificationDeniedOrigins,
-
-  // (Mac) Application menu.
-  prefs::kConfirmToQuitEnabled,
-
-#if defined(OS_CHROMEOS)
-  // IME prefs
-  prefs::kLanguageChewingAddPhraseDirection,
-  prefs::kLanguageChewingAutoShiftCur,
-  prefs::kLanguageChewingCandPerPage,
-  prefs::kLanguageChewingEasySymbolInput,
-  prefs::kLanguageChewingEscCleanAllBuf,
-  prefs::kLanguageChewingForceLowercaseEnglish,
-  prefs::kLanguageChewingHsuSelKeyType,
-  prefs::kLanguageChewingKeyboardType,
-  prefs::kLanguageChewingMaxChiSymbolLen,
-  prefs::kLanguageChewingPhraseChoiceRearward,
-  prefs::kLanguageChewingPlainZhuyin,
-  prefs::kLanguageChewingSelKeys,
-  prefs::kLanguageChewingSpaceAsSelection,
-  prefs::kLanguageHangulKeyboard,
-  prefs::kLanguageMozcHistoryLearningLevel,
-  prefs::kLanguageMozcIncognitoMode,
-  prefs::kLanguageMozcNumpadCharacterForm,
-  prefs::kLanguageMozcPreeditMethod,
-  prefs::kLanguageMozcPunctuationMethod,
-  prefs::kLanguageMozcSessionKeymap,
-  prefs::kLanguageMozcShiftKeyModeSwitch,
-  prefs::kLanguageMozcSpaceCharacterForm,
-  prefs::kLanguageMozcSuggestionsSize,
-  prefs::kLanguageMozcSymbolMethod,
-  prefs::kLanguageMozcUseAutoImeTurnOff,
-  prefs::kLanguageMozcUseDateConversion,
-  prefs::kLanguageMozcUseDictionarySuggest,
-  prefs::kLanguageMozcUseHistorySuggest,
-  prefs::kLanguageMozcUseNumberConversion,
-  prefs::kLanguageMozcUseSingleKanjiConversion,
-  prefs::kLanguageMozcUseSymbolConversion,
-  prefs::kLanguagePinyinAutoCommit,
-  prefs::kLanguagePinyinCommaPeriodPage,
-  prefs::kLanguagePinyinCorrectPinyin,
-  prefs::kLanguagePinyinDoublePinyin,
-  prefs::kLanguagePinyinDoublePinyinSchema,
-  prefs::kLanguagePinyinFuzzyPinyin,
-  prefs::kLanguagePinyinInitChinese,
-  prefs::kLanguagePinyinInitFull,
-  prefs::kLanguagePinyinInitFullPunct,
-  prefs::kLanguagePinyinInitSimplifiedChinese,
-  prefs::kLanguagePinyinMinusEqualPage,
-  prefs::kLanguagePinyinShiftSelectCandidate,
-  prefs::kLanguagePinyinTradCandidate,
-  prefs::kLanguagePreferredLanguages,
-  prefs::kLanguagePreloadEngines,
-
-  // We don't sync the following IME prefs since they are not user-configurable
-  // (yet):
-  //   prefs::kLanguageHangulHanjaKeys,
-  //   prefs::kLanguageHotkeyNextEngineInMenu,
-  //   prefs::kLanguageHotkeyPreviousEngine,
-  //   prefs::kLanguageMozcSelectionShortcut,
-  //   prefs::kLanguagePinyinLookupTablePageSize,
-  //
-  // We don't sync prefs::kLanguageCurrentInputMethod and PreviousInputMethod.
-
-  // Keyboard prefs
-  prefs::kLanguageXkbRemapAltKeyTo,
-  prefs::kLanguageXkbRemapControlKeyTo,
-  prefs::kLanguageXkbRemapSearchKeyTo,
-
-  // We don't sync the following keyboard prefs since they are not user-
-  // configurable:
-  //   prefs::kLanguageXkbAutoRepeatDelay,
-  //   prefs::kLanguageXkbAutoRepeatEnabled,
-  //   prefs::kLanguageXkbAutoRepeatInterval,
-
-  // Whether to show mobile plan notifications.
-  //   Settings -> Internet -> Mobile plan details
-  prefs::kShowPlanNotifications,
-
-  // Whether to require password to wake up from sleep
-  //   Settings -> Personal Stuff -> Account
-  prefs::kEnableScreenLock,
-
-  // Whether to enable tap-to-click
-  //   Settings -> System -> Touchpad
-  prefs::kTapToClickEnabled,
-
-  // Whether to use the 24-hour clock format.
-  //   Settings -> System -> Date and Time
-  prefs::kUse24HourClock,
-#endif
-};
-
-}  // namespace browser_sync
-
-#endif  // CHROME_BROWSER_SYNC_GLUE_SYNCHRONIZED_PREFERENCES_H_
diff --git a/chrome/browser/sync/glue/theme_data_type_controller.cc b/chrome/browser/sync/glue/theme_data_type_controller.cc
index efcbe11..3e30b84 100644
--- a/chrome/browser/sync/glue/theme_data_type_controller.cc
+++ b/chrome/browser/sync/glue/theme_data_type_controller.cc
@@ -35,8 +35,8 @@
   ProfileSyncFactory::SyncComponents sync_components =
       profile_sync_factory_->CreateThemeSyncComponents(sync_service_,
                                                      this);
-  model_associator_.reset(sync_components.model_associator);
-  change_processor_.reset(sync_components.change_processor);
+  set_model_associator(sync_components.model_associator);
+  set_change_processor(sync_components.change_processor);
 }
 
 void ThemeDataTypeController::RecordUnrecoverableError(
diff --git a/chrome/browser/sync/profile_sync_factory_impl.cc b/chrome/browser/sync/profile_sync_factory_impl.cc
index ef701fff..9ca4ede 100644
--- a/chrome/browser/sync/profile_sync_factory_impl.cc
+++ b/chrome/browser/sync/profile_sync_factory_impl.cc
@@ -22,12 +22,11 @@
 #include "chrome/browser/sync/glue/extension_data_type_controller.h"
 #include "chrome/browser/sync/glue/extension_model_associator.h"
 #include "chrome/browser/sync/glue/extension_sync_traits.h"
+#include "chrome/browser/sync/glue/generic_change_processor.h"
 #include "chrome/browser/sync/glue/password_change_processor.h"
 #include "chrome/browser/sync/glue/password_data_type_controller.h"
 #include "chrome/browser/sync/glue/password_model_associator.h"
-#include "chrome/browser/sync/glue/preference_change_processor.h"
 #include "chrome/browser/sync/glue/preference_data_type_controller.h"
-#include "chrome/browser/sync/glue/preference_model_associator.h"
 #include "chrome/browser/sync/glue/session_change_processor.h"
 #include "chrome/browser/sync/glue/session_data_type_controller.h"
 #include "chrome/browser/sync/glue/session_model_associator.h"
@@ -40,6 +39,7 @@
 #include "chrome/browser/sync/glue/typed_url_model_associator.h"
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_factory_impl.h"
+#include "chrome/browser/sync/syncable_service.h"
 #include "chrome/browser/webdata/web_data_service.h"
 #include "chrome/common/chrome_switches.h"
 
@@ -61,12 +61,11 @@
 using browser_sync::ExtensionChangeProcessor;
 using browser_sync::ExtensionDataTypeController;
 using browser_sync::ExtensionModelAssociator;
+using browser_sync::GenericChangeProcessor;
 using browser_sync::PasswordChangeProcessor;
 using browser_sync::PasswordDataTypeController;
 using browser_sync::PasswordModelAssociator;
-using browser_sync::PreferenceChangeProcessor;
 using browser_sync::PreferenceDataTypeController;
-using browser_sync::PreferenceModelAssociator;
 using browser_sync::SessionChangeProcessor;
 using browser_sync::SessionDataTypeController;
 using browser_sync::SessionModelAssociator;
@@ -273,12 +272,11 @@
 ProfileSyncFactoryImpl::CreatePreferenceSyncComponents(
     ProfileSyncService* profile_sync_service,
     UnrecoverableErrorHandler* error_handler) {
-  PreferenceModelAssociator* model_associator =
-      new PreferenceModelAssociator(profile_sync_service);
-  PreferenceChangeProcessor* change_processor =
-      new PreferenceChangeProcessor(model_associator,
-                                    error_handler);
-  return SyncComponents(model_associator, change_processor);
+  SyncableService* pref_sync_service =
+      profile_->GetPrefs()->GetSyncableService();
+  GenericChangeProcessor* change_processor =
+      new GenericChangeProcessor(pref_sync_service, error_handler);
+  return SyncComponents(pref_sync_service, change_processor);
 }
 
 ProfileSyncFactory::SyncComponents
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index f432b5c4..798d305 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -242,9 +242,15 @@
   PrefService* pref_service = profile_->GetPrefs();
   if (pref_service->FindPreference(prefs::kSyncLastSyncedTime))
     return;
-  pref_service->RegisterInt64Pref(prefs::kSyncLastSyncedTime, 0);
-  pref_service->RegisterBooleanPref(prefs::kSyncHasSetupCompleted, false);
-  pref_service->RegisterBooleanPref(prefs::kSyncSuppressStart, false);
+  pref_service->RegisterInt64Pref(prefs::kSyncLastSyncedTime,
+                                  0,
+                                  PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterBooleanPref(prefs::kSyncHasSetupCompleted,
+                                    false,
+                                    PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterBooleanPref(prefs::kSyncSuppressStart,
+                                    false,
+                                    PrefService::UNSYNCABLE_PREF);
 
   // If you've never synced before, or if you're using Chrome OS, all datatypes
   // are on by default.
@@ -257,22 +263,46 @@
       !pref_service->HasPrefPath(prefs::kSyncHasSetupCompleted);
 #endif
 
-  pref_service->RegisterBooleanPref(prefs::kSyncBookmarks, true);
-  pref_service->RegisterBooleanPref(prefs::kSyncPasswords, enable_by_default);
-  pref_service->RegisterBooleanPref(prefs::kSyncPreferences, enable_by_default);
-  pref_service->RegisterBooleanPref(prefs::kSyncAutofill, enable_by_default);
-  pref_service->RegisterBooleanPref(prefs::kSyncThemes, enable_by_default);
-  pref_service->RegisterBooleanPref(prefs::kSyncTypedUrls, enable_by_default);
-  pref_service->RegisterBooleanPref(prefs::kSyncExtensions, enable_by_default);
-  pref_service->RegisterBooleanPref(prefs::kSyncApps, enable_by_default);
-  pref_service->RegisterBooleanPref(prefs::kSyncSessions, enable_by_default);
+  pref_service->RegisterBooleanPref(prefs::kSyncBookmarks,
+                                    true,
+                                    PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterBooleanPref(prefs::kSyncPasswords,
+                                    enable_by_default,
+                                    PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterBooleanPref(prefs::kSyncPreferences,
+                                    enable_by_default,
+                                    PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterBooleanPref(prefs::kSyncAutofill,
+                                    enable_by_default,
+                                    PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterBooleanPref(prefs::kSyncThemes,
+                                    enable_by_default,
+                                    PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterBooleanPref(prefs::kSyncTypedUrls,
+                                    enable_by_default,
+                                    PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterBooleanPref(prefs::kSyncExtensions,
+                                    enable_by_default,
+                                    PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterBooleanPref(prefs::kSyncApps,
+                                    enable_by_default,
+                                    PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterBooleanPref(prefs::kSyncSessions,
+                                    enable_by_default,
+                                    PrefService::UNSYNCABLE_PREF);
   pref_service->RegisterBooleanPref(prefs::kKeepEverythingSynced,
-      enable_by_default);
-  pref_service->RegisterBooleanPref(prefs::kSyncManaged, false);
-  pref_service->RegisterStringPref(prefs::kEncryptionBootstrapToken, "");
+                                    enable_by_default,
+                                    PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterBooleanPref(prefs::kSyncManaged,
+                                    false,
+                                    PrefService::UNSYNCABLE_PREF);
+  pref_service->RegisterStringPref(prefs::kEncryptionBootstrapToken,
+                                   "",
+                                   PrefService::UNSYNCABLE_PREF);
 
   pref_service->RegisterBooleanPref(prefs::kSyncAutofillProfile,
-      enable_by_default);
+                                    enable_by_default,
+                                    PrefService::UNSYNCABLE_PREF);
 }
 
 void ProfileSyncService::ClearPreferences() {
@@ -1099,16 +1129,15 @@
     return;
   }
   DCHECK(backend_initialized_);
-  change_processor->Start(profile(), backend_->GetUserShare());
   backend_->ActivateDataType(data_type_controller, change_processor);
 }
 
 void ProfileSyncService::DeactivateDataType(
     DataTypeController* data_type_controller,
     ChangeProcessor* change_processor) {
-  change_processor->Stop();
-  if (backend_.get())
-    backend_->DeactivateDataType(data_type_controller, change_processor);
+  if (!backend_.get())
+    return;
+  backend_->DeactivateDataType(data_type_controller, change_processor);
 }
 
 void ProfileSyncService::SetPassphrase(const std::string& passphrase,
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index fa203a8..490d050a 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -396,6 +396,7 @@
       syncable::AutofillMigrationDebugInfo::PropertyToSet property_to_set,
       const syncable::AutofillMigrationDebugInfo& info);
 
+  // TODO(zea): Remove these and have the dtc's call directly into the SBH.
   virtual void ActivateDataType(
       browser_sync::DataTypeController* data_type_controller,
       browser_sync::ChangeProcessor* change_processor);
diff --git a/chrome/browser/sync/profile_sync_service_preference_unittest.cc b/chrome/browser/sync/profile_sync_service_preference_unittest.cc
index db010074..12488bc 100644
--- a/chrome/browser/sync/profile_sync_service_preference_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_preference_unittest.cc
@@ -9,12 +9,12 @@
 #include "base/stl_util-inl.h"
 #include "base/string_piece.h"
 #include "base/task.h"
+#include "chrome/browser/prefs/pref_model_associator.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/sync/abstract_profile_sync_service_test.h"
 #include "chrome/browser/sync/engine/syncapi.h"
-#include "chrome/browser/sync/glue/preference_change_processor.h"
+#include "chrome/browser/sync/glue/generic_change_processor.h"
 #include "chrome/browser/sync/glue/preference_data_type_controller.h"
-#include "chrome/browser/sync/glue/preference_model_associator.h"
 #include "chrome/browser/sync/glue/sync_backend_host.h"
 #include "chrome/browser/sync/profile_sync_test_util.h"
 #include "chrome/browser/sync/protocol/preference_specifics.pb.h"
@@ -29,9 +29,8 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 using base::JSONReader;
-using browser_sync::PreferenceChangeProcessor;
+using browser_sync::GenericChangeProcessor;
 using browser_sync::PreferenceDataTypeController;
-using browser_sync::PreferenceModelAssociator;
 using browser_sync::SyncBackendHost;
 using sync_api::SyncManager;
 using testing::_;
@@ -57,7 +56,8 @@
     prefs_ = profile_->GetTestingPrefService();
 
     prefs_->RegisterStringPref(not_synced_preference_name_.c_str(),
-                               not_synced_preference_default_value_);
+                               not_synced_preference_default_value_,
+                               PrefService::UNSYNCABLE_PREF);
   }
 
   virtual void TearDown() {
@@ -72,12 +72,10 @@
 
     service_.reset(new TestProfileSyncService(
         &factory_, profile_.get(), "test", false, task));
-
-    // Register the preference data type.
     model_associator_ =
-        new PreferenceModelAssociator(service_.get());
-    change_processor_ = new PreferenceChangeProcessor(model_associator_,
-                                                      service_.get());
+        reinterpret_cast<PrefModelAssociator*>(prefs_->GetSyncableService());
+    change_processor_ = new GenericChangeProcessor(model_associator_,
+                                                   service_.get());
     EXPECT_CALL(factory_, CreatePreferenceSyncComponents(_, _)).
         WillOnce(Return(ProfileSyncFactory::SyncComponents(
             model_associator_, change_processor_)));
@@ -85,12 +83,13 @@
     EXPECT_CALL(factory_, CreateDataTypeManager(_, _)).
         WillOnce(ReturnNewDataTypeManager());
 
-    service_->RegisterDataTypeController(
-        new PreferenceDataTypeController(&factory_,
-                                         profile_.get(),
-                                         service_.get()));
+    dtc_ = new PreferenceDataTypeController(&factory_,
+                                            profile_.get(),
+                                            service_.get());
+    service_->RegisterDataTypeController(dtc_);
     profile_->GetTokenService()->IssueAuthTokenForTest(
         GaiaConstants::kSyncService, "token");
+
     service_->Initialize();
     MessageLoop::current()->Run();
     return true;
@@ -123,7 +122,7 @@
   int64 WriteSyncedValue(const std::string& name,
                          const Value& value,
                          sync_api::WriteNode* node) {
-    if (!PreferenceModelAssociator::WritePreferenceToNode(name, value, node))
+    if (!PrefModelAssociator::WritePreferenceToNode(name, value, node))
       return sync_api::kInvalidId;
     return node->GetId();
   }
@@ -131,8 +130,10 @@
   int64 SetSyncedValue(const std::string& name, const Value& value) {
     sync_api::WriteTransaction trans(service_->GetUserShare());
     sync_api::ReadNode root(&trans);
-    if (!root.InitByTagLookup(browser_sync::kPreferencesTag))
+    if (!root.InitByTagLookup(
+        syncable::ModelTypeToRootTag(syncable::PREFERENCES))) {
       return sync_api::kInvalidId;
+    }
 
     sync_api::WriteNode tag_node(&trans);
     sync_api::WriteNode node(&trans);
@@ -174,8 +175,10 @@
   scoped_ptr<TestingProfile> profile_;
   TestingPrefService* prefs_;
 
-  PreferenceModelAssociator* model_associator_;
-  PreferenceChangeProcessor* change_processor_;
+  PreferenceDataTypeController* dtc_;
+  PrefModelAssociator* model_associator_;
+  GenericChangeProcessor* change_processor_;
+
   std::string example_url0_;
   std::string example_url1_;
   std::string example_url2_;
@@ -223,7 +226,7 @@
   EXPECT_TRUE(node.InitByClientTagLookup(syncable::PREFERENCES,
                                          prefs::kHomePage));
 
-  EXPECT_TRUE(PreferenceModelAssociator::WritePreferenceToNode(
+  EXPECT_TRUE(PrefModelAssociator::WritePreferenceToNode(
       pref->name(), *pref->GetValue(), &node));
   EXPECT_EQ(UTF8ToWide(prefs::kHomePage), node.GetTitle());
   const sync_pb::PreferenceSpecifics& specifics(node.GetPreferenceSpecifics());
diff --git a/chrome/browser/sync/signin_manager.cc b/chrome/browser/sync/signin_manager.cc
index b0521757..1ec73e2 100644
--- a/chrome/browser/sync/signin_manager.cc
+++ b/chrome/browser/sync/signin_manager.cc
@@ -21,7 +21,9 @@
 
 // static
 void SigninManager::RegisterUserPrefs(PrefService* user_prefs) {
-  user_prefs->RegisterStringPref(prefs::kGoogleServicesUsername, "");
+  user_prefs->RegisterStringPref(prefs::kGoogleServicesUsername,
+                                 "",
+                                 PrefService::UNSYNCABLE_PREF);
 }
 
 void SigninManager::Initialize(Profile* profile) {
diff --git a/chrome/browser/sync/syncable_service.cc b/chrome/browser/sync/syncable_service.cc
new file mode 100644
index 0000000..f8e7d515
--- /dev/null
+++ b/chrome/browser/sync/syncable_service.cc
@@ -0,0 +1,9 @@
+// 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/sync/syncable_service.h"
+
+SyncableService::SyncableService() {}
+
+SyncableService::~SyncableService() {}
diff --git a/chrome/browser/sync/syncable_service.h b/chrome/browser/sync/syncable_service.h
new file mode 100644
index 0000000..9b06ea8
--- /dev/null
+++ b/chrome/browser/sync/syncable_service.h
@@ -0,0 +1,55 @@
+// 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_SYNC_SYNCABLE_SERVICE_H_
+#define CHROME_BROWSER_SYNC_SYNCABLE_SERVICE_H_
+#pragma once
+
+#include "chrome/browser/sync/engine/syncapi.h"  // TODO(zea): remove this.
+#include "chrome/browser/sync/glue/model_associator.h"
+
+class ProfileSyncService;
+
+namespace browser_sync {
+class GenericChangeProcessor;
+}
+
+// TODO(sync): Define SyncData type for passing sync changes here.
+
+// TODO(sync): Have this become an independent class and deprecate
+// AssociatorInterface.
+class SyncableService : public browser_sync::AssociatorInterface {
+ public:
+  SyncableService();
+  virtual ~SyncableService();
+
+  // Future methods for SyncableService:
+  // StartSyncing
+  // StopSyncing
+  // GetAllSyncData
+  // ProcessNewSyncData (replaces ApplyChangeFromSync)
+
+  // TODO(sync): remove these once we switch to the real SyncableService
+  // interface. This just keeps us going while we use the model associator/
+  // change processor way of things.
+
+  // AssociatorInterface implementation.
+  virtual bool AssociateModels() = 0;
+  virtual bool DisassociateModels() = 0;
+  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes) = 0;
+  virtual void AbortAssociation() = 0;
+  virtual bool CryptoReadyIfNecessary() = 0;
+
+  // Receive changes from change processor (the ChangeRecord dependency is
+  // the reason we must include syncapi.h).
+  virtual void ApplyChangesFromSync(
+      const sync_api::BaseTransaction* trans,
+      const sync_api::SyncManager::ChangeRecord* changes,
+      int change_count) = 0;
+  virtual void SetupSync(
+      ProfileSyncService* sync_service,
+      browser_sync::GenericChangeProcessor* change_processor) = 0;
+};
+
+#endif  // CHROME_BROWSER_SYNC_SYNCABLE_SERVICE_H_
diff --git a/chrome/browser/sync/syncable_service_mock.cc b/chrome/browser/sync/syncable_service_mock.cc
new file mode 100644
index 0000000..3050fde
--- /dev/null
+++ b/chrome/browser/sync/syncable_service_mock.cc
@@ -0,0 +1,9 @@
+// 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/sync/syncable_service_mock.h"
+
+SyncableServiceMock::SyncableServiceMock() {}
+
+SyncableServiceMock::~SyncableServiceMock() {}
diff --git a/chrome/browser/sync/syncable_service_mock.h b/chrome/browser/sync/syncable_service_mock.h
new file mode 100644
index 0000000..b1ea235
--- /dev/null
+++ b/chrome/browser/sync/syncable_service_mock.h
@@ -0,0 +1,31 @@
+// 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_SYNC_SYNCABLE_SERVICE_MOCK_H_
+#define CHROME_BROWSER_SYNC_SYNCABLE_SERVICE_MOCK_H_
+#pragma once
+
+#include "chrome/browser/sync/syncable_service.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+class SyncableServiceMock : public SyncableService {
+ public:
+  SyncableServiceMock();
+  virtual ~SyncableServiceMock();
+
+  MOCK_METHOD0(AssociateModels, bool());
+  MOCK_METHOD0(DisassociateModels, bool());
+  MOCK_METHOD1(SyncModelHasUserCreatedNodes, bool(bool* has_nodes));
+  MOCK_METHOD0(AbortAssociation, void());
+  MOCK_METHOD0(CryptoReadyIfNecessary, bool());
+  MOCK_METHOD3(ApplyChangesFromSync, void(
+      const sync_api::BaseTransaction* trans,
+      const sync_api::SyncManager::ChangeRecord* changes,
+      int change_count));
+  MOCK_METHOD2(SetupSync, void(
+      ProfileSyncService* sync_service,
+      browser_sync::GenericChangeProcessor* change_processor));
+};
+
+#endif  // CHROME_BROWSER_SYNC_SYNCABLE_SERVICE_MOCK_H_
diff --git a/chrome/browser/tabs/pinned_tab_codec.cc b/chrome/browser/tabs/pinned_tab_codec.cc
index 91279e0..1dfc57e 100644
--- a/chrome/browser/tabs/pinned_tab_codec.cc
+++ b/chrome/browser/tabs/pinned_tab_codec.cc
@@ -89,7 +89,7 @@
 
 // static
 void PinnedTabCodec::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterListPref(prefs::kPinnedTabs);
+  prefs->RegisterListPref(prefs::kPinnedTabs, PrefService::UNSYNCABLE_PREF);
 }
 
 // static
diff --git a/chrome/browser/translate/translate_prefs.cc b/chrome/browser/translate/translate_prefs.cc
index cc04f42..3aca798 100644
--- a/chrome/browser/translate/translate_prefs.cc
+++ b/chrome/browser/translate/translate_prefs.cc
@@ -152,17 +152,22 @@
 
 void TranslatePrefs::RegisterUserPrefs(PrefService* user_prefs) {
   if (!user_prefs->FindPreference(kPrefTranslateLanguageBlacklist))
-    user_prefs->RegisterListPref(kPrefTranslateLanguageBlacklist);
+    user_prefs->RegisterListPref(kPrefTranslateLanguageBlacklist,
+                                 PrefService::SYNCABLE_PREF);
   if (!user_prefs->FindPreference(kPrefTranslateSiteBlacklist))
-    user_prefs->RegisterListPref(kPrefTranslateSiteBlacklist);
+    user_prefs->RegisterListPref(kPrefTranslateSiteBlacklist,
+                                 PrefService::SYNCABLE_PREF);
   if (!user_prefs->FindPreference(kPrefTranslateWhitelists)) {
-    user_prefs->RegisterDictionaryPref(kPrefTranslateWhitelists);
+    user_prefs->RegisterDictionaryPref(kPrefTranslateWhitelists,
+                                       PrefService::SYNCABLE_PREF);
     MigrateTranslateWhitelists(user_prefs);
   }
   if (!user_prefs->FindPreference(kPrefTranslateDeniedCount))
-    user_prefs->RegisterDictionaryPref(kPrefTranslateDeniedCount);
+    user_prefs->RegisterDictionaryPref(kPrefTranslateDeniedCount,
+                                       PrefService::SYNCABLE_PREF);
   if (!user_prefs->FindPreference(kPrefTranslateAcceptedCount))
-    user_prefs->RegisterDictionaryPref(kPrefTranslateAcceptedCount);
+    user_prefs->RegisterDictionaryPref(kPrefTranslateAcceptedCount,
+                                       PrefService::SYNCABLE_PREF);
 }
 
 // TranslatePrefs: private, static: --------------------------------------------
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 5cbc616..41716b5 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -2089,9 +2089,14 @@
 // static
 void Browser::RegisterUserPrefs(PrefService* prefs) {
   prefs->RegisterStringPref(prefs::kHomePage,
-                            chrome::kChromeUINewTabURL);
-  prefs->RegisterBooleanPref(prefs::kHomePageIsNewTabPage, true);
-  prefs->RegisterBooleanPref(prefs::kShowHomeButton, false);
+                            chrome::kChromeUINewTabURL,
+                            PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kHomePageIsNewTabPage,
+                             true,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kShowHomeButton,
+                             false,
+                             PrefService::SYNCABLE_PREF);
 #if defined(OS_MACOSX)
   // This really belongs in platform code, but there's no good place to
   // initialize it between the time when the AppController is created
@@ -2101,46 +2106,112 @@
   // pref to be already initialized. Doing it here also saves us from having
   // to hard-code pref registration in the several unit tests that use
   // this preference.
-  prefs->RegisterBooleanPref(prefs::kConfirmToQuitEnabled, false);
-  prefs->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar, true);
+  prefs->RegisterBooleanPref(prefs::kConfirmToQuitEnabled,
+                             false,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
 #endif
-  prefs->RegisterBooleanPref(prefs::kDeleteBrowsingHistory, true);
-  prefs->RegisterBooleanPref(prefs::kDeleteDownloadHistory, true);
-  prefs->RegisterBooleanPref(prefs::kDeleteCache, true);
-  prefs->RegisterBooleanPref(prefs::kDeleteCookies, true);
-  prefs->RegisterBooleanPref(prefs::kDeletePasswords, false);
-  prefs->RegisterBooleanPref(prefs::kDeleteFormData, false);
-  prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod, 0);
-  prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser, true);
-  prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint, true);
-  prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop, true);
-  prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu, true);
-  prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar, true);
-  prefs->RegisterBooleanPref(prefs::kUseVerticalTabs, false);
-  prefs->RegisterBooleanPref(prefs::kEnableTranslate, true);
-  prefs->RegisterBooleanPref(prefs::kEnableBookmarkBar, true);
-  prefs->RegisterBooleanPref(prefs::kRemotingHasSetupCompleted, false);
-  prefs->RegisterBooleanPref(prefs::kChromotingEnabled, false);
-  prefs->RegisterBooleanPref(prefs::kChromotingHostEnabled, false);
-  prefs->RegisterBooleanPref(prefs::kChromotingHostFirewallTraversal, false);
-  prefs->RegisterStringPref(prefs::kCloudPrintEmail, std::string());
-  prefs->RegisterBooleanPref(prefs::kCloudPrintProxyEnabled, true);
-  prefs->RegisterBooleanPref(prefs::kDevToolsDisabled, false);
-  prefs->RegisterBooleanPref(prefs::kIncognitoEnabled, true);
-  prefs->RegisterIntegerPref(prefs::kDevToolsSplitLocation, -1);
-  prefs->RegisterDictionaryPref(prefs::kBrowserWindowPlacement);
-  prefs->RegisterDictionaryPref(prefs::kPreferencesWindowPlacement);
+  prefs->RegisterBooleanPref(prefs::kDeleteBrowsingHistory,
+                             true,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kDeleteDownloadHistory,
+                             true,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kDeleteCache,
+                             true,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kDeleteCookies,
+                             true,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kDeletePasswords,
+                             false,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kDeleteFormData,
+                             false,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod,
+                             0,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kUseVerticalTabs,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kEnableTranslate,
+                             true,
+                             PrefService::SYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kEnableBookmarkBar,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kRemotingHasSetupCompleted,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kChromotingEnabled,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kChromotingHostEnabled,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kChromotingHostFirewallTraversal,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kCloudPrintEmail,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kCloudPrintProxyEnabled,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kDevToolsDisabled,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kIncognitoEnabled,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterIntegerPref(prefs::kDevToolsSplitLocation,
+                             -1,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kBrowserWindowPlacement,
+                                PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kPreferencesWindowPlacement,
+                                PrefService::UNSYNCABLE_PREF);
   // We need to register the type of these preferences in order to query
-  // them even though they're typically only controlled via policy or command
-  // line switches.
-  prefs->RegisterBooleanPref(prefs::kDisable3DAPIs, false);
-  prefs->RegisterBooleanPref(prefs::kPluginsAllowOutdated, false);
-  prefs->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize, false);
-  prefs->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing, true);
-  prefs->RegisterBooleanPref(prefs::kEnableReferrers, true);
-  prefs->RegisterBooleanPref(prefs::kWebKitAllowRunningInsecureContent, false);
+  // them even though they're only typically controlled via policy.
+  prefs->RegisterBooleanPref(prefs::kDisable3DAPIs,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kPluginsAllowOutdated,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kEnableReferrers,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kWebKitAllowRunningInsecureContent,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterBooleanPref(prefs::kWebKitAllowDisplayingInsecureContent,
-                             true);
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
 }
 
 // static
@@ -4363,8 +4434,10 @@
   window_pref.append("_");
   window_pref.append(app_name);
   PrefService* prefs = profile->GetPrefs();
-  if (!prefs->FindPreference(window_pref.c_str()))
-    prefs->RegisterDictionaryPref(window_pref.c_str());
+  if (!prefs->FindPreference(window_pref.c_str())) {
+    prefs->RegisterDictionaryPref(window_pref.c_str(),
+                                  PrefService::UNSYNCABLE_PREF);
+  }
 }
 
 void Browser::TabRestoreServiceChanged(TabRestoreService* service) {
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
index 4cb17741..279be6c 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
@@ -417,7 +417,9 @@
 }
 
 + (void)registerUserPrefs:(PrefService*)prefs {
-  prefs->RegisterDoublePref(prefs::kBrowserActionContainerWidth, 0);
+  prefs->RegisterDoublePref(prefs::kBrowserActionContainerWidth,
+                            0,
+                            PrefService::UNSYNCABLE_PREF);
 }
 
 #pragma mark -
diff --git a/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm b/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm
index 7b93717..70d0b093 100644
--- a/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm
+++ b/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm
@@ -26,7 +26,9 @@
                                               NSResizableWindowMask
                                       backing:NSBackingStoreBuffered
                                         defer:NO];
-    browser_helper_.profile()->GetPrefs()->RegisterDictionaryPref(path_);
+    browser_helper_.profile()->GetPrefs()->RegisterDictionaryPref(
+        path_,
+        PrefService::UNSYNCABLE_PREF);
   }
 
   virtual void TearDown() {
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc
index 67ed90bf..36bc6fa0 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.cc
+++ b/chrome/browser/ui/gtk/browser_window_gtk.cc
@@ -1512,8 +1512,9 @@
       !prefs->HasPrefPath(prefs::kUseCustomChromeFrame)) {
     custom_frame_default = GetCustomFramePrefDefault();
   }
-  prefs->RegisterBooleanPref(
-      prefs::kUseCustomChromeFrame, custom_frame_default);
+  prefs->RegisterBooleanPref(prefs::kUseCustomChromeFrame,
+                             custom_frame_default,
+                             PrefService::SYNCABLE_PREF);
 }
 
 void BrowserWindowGtk::BookmarkBarIsFloating(bool is_floating) {
diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
index 7437b8f..6e4a979 100644
--- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
+++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
@@ -109,60 +109,97 @@
 }
 
 void TabContentsWrapper::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kAlternateErrorPagesEnabled, true);
+  prefs->RegisterBooleanPref(prefs::kAlternateErrorPagesEnabled,
+                             true,
+                             PrefService::SYNCABLE_PREF);
 
   WebPreferences pref_defaults;
   prefs->RegisterBooleanPref(prefs::kWebKitJavascriptEnabled,
-                             pref_defaults.javascript_enabled);
+                             pref_defaults.javascript_enabled,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterBooleanPref(prefs::kWebKitWebSecurityEnabled,
-                             pref_defaults.web_security_enabled);
+                             pref_defaults.web_security_enabled,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterBooleanPref(
-      prefs::kWebKitJavascriptCanOpenWindowsAutomatically, true);
+      prefs::kWebKitJavascriptCanOpenWindowsAutomatically,
+      true,
+      PrefService::UNSYNCABLE_PREF);
   prefs->RegisterBooleanPref(prefs::kWebKitLoadsImagesAutomatically,
-                             pref_defaults.loads_images_automatically);
+                             pref_defaults.loads_images_automatically,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterBooleanPref(prefs::kWebKitPluginsEnabled,
-                             pref_defaults.plugins_enabled);
+                             pref_defaults.plugins_enabled,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterBooleanPref(prefs::kWebKitDomPasteEnabled,
-                             pref_defaults.dom_paste_enabled);
+                             pref_defaults.dom_paste_enabled,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterBooleanPref(prefs::kWebKitShrinksStandaloneImagesToFit,
-                             pref_defaults.shrinks_standalone_images_to_fit);
-  prefs->RegisterDictionaryPref(prefs::kWebKitInspectorSettings);
+                             pref_defaults.shrinks_standalone_images_to_fit,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kWebKitInspectorSettings,
+                                PrefService::UNSYNCABLE_PREF);
   prefs->RegisterBooleanPref(prefs::kWebKitTextAreasAreResizable,
-                             pref_defaults.text_areas_are_resizable);
+                             pref_defaults.text_areas_are_resizable,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterBooleanPref(prefs::kWebKitJavaEnabled,
-                             pref_defaults.java_enabled);
+                             pref_defaults.java_enabled,
+                             PrefService::UNSYNCABLE_PREF);
   prefs->RegisterBooleanPref(prefs::kWebkitTabsToLinks,
-                             pref_defaults.tabs_to_links);
+                             pref_defaults.tabs_to_links,
+                             PrefService::UNSYNCABLE_PREF);
 
+#if !defined(OS_MACOSX)
   prefs->RegisterLocalizedStringPref(prefs::kAcceptLanguages,
-                                     IDS_ACCEPT_LANGUAGES);
+                                     IDS_ACCEPT_LANGUAGES,
+                                     PrefService::SYNCABLE_PREF);
+#else
+  // Not used in OSX.
+  prefs->RegisterLocalizedStringPref(prefs::kAcceptLanguages,
+                                     IDS_ACCEPT_LANGUAGES,
+                                     PrefService::UNSYNCABLE_PREF);
+#endif
   prefs->RegisterLocalizedStringPref(prefs::kDefaultCharset,
-                                     IDS_DEFAULT_ENCODING);
+                                     IDS_DEFAULT_ENCODING,
+                                     PrefService::SYNCABLE_PREF);
   prefs->RegisterLocalizedStringPref(prefs::kWebKitStandardFontFamily,
-                                     IDS_STANDARD_FONT_FAMILY);
+                                     IDS_STANDARD_FONT_FAMILY,
+                                     PrefService::UNSYNCABLE_PREF);
   prefs->RegisterLocalizedStringPref(prefs::kWebKitFixedFontFamily,
-                                     IDS_FIXED_FONT_FAMILY);
+                                     IDS_FIXED_FONT_FAMILY,
+                                     PrefService::UNSYNCABLE_PREF);
   prefs->RegisterLocalizedStringPref(prefs::kWebKitSerifFontFamily,
-                                     IDS_SERIF_FONT_FAMILY);
+                                     IDS_SERIF_FONT_FAMILY,
+                                     PrefService::UNSYNCABLE_PREF);
   prefs->RegisterLocalizedStringPref(prefs::kWebKitSansSerifFontFamily,
-                                     IDS_SANS_SERIF_FONT_FAMILY);
+                                     IDS_SANS_SERIF_FONT_FAMILY,
+                                     PrefService::UNSYNCABLE_PREF);
   prefs->RegisterLocalizedStringPref(prefs::kWebKitCursiveFontFamily,
-                                     IDS_CURSIVE_FONT_FAMILY);
+                                     IDS_CURSIVE_FONT_FAMILY,
+                                     PrefService::UNSYNCABLE_PREF);
   prefs->RegisterLocalizedStringPref(prefs::kWebKitFantasyFontFamily,
-                                     IDS_FANTASY_FONT_FAMILY);
+                                     IDS_FANTASY_FONT_FAMILY,
+                                     PrefService::UNSYNCABLE_PREF);
   prefs->RegisterLocalizedIntegerPref(prefs::kWebKitDefaultFontSize,
-                                      IDS_DEFAULT_FONT_SIZE);
+                                      IDS_DEFAULT_FONT_SIZE,
+                                      PrefService::UNSYNCABLE_PREF);
   prefs->RegisterLocalizedIntegerPref(prefs::kWebKitDefaultFixedFontSize,
-                                      IDS_DEFAULT_FIXED_FONT_SIZE);
+                                      IDS_DEFAULT_FIXED_FONT_SIZE,
+                                      PrefService::UNSYNCABLE_PREF);
   prefs->RegisterLocalizedIntegerPref(prefs::kWebKitMinimumFontSize,
-                                      IDS_MINIMUM_FONT_SIZE);
+                                      IDS_MINIMUM_FONT_SIZE,
+                                      PrefService::UNSYNCABLE_PREF);
   prefs->RegisterLocalizedIntegerPref(prefs::kWebKitMinimumLogicalFontSize,
-                                      IDS_MINIMUM_LOGICAL_FONT_SIZE);
+                                      IDS_MINIMUM_LOGICAL_FONT_SIZE,
+                                      PrefService::UNSYNCABLE_PREF);
   prefs->RegisterLocalizedBooleanPref(prefs::kWebKitUsesUniversalDetector,
-                                      IDS_USES_UNIVERSAL_DETECTOR);
+                                      IDS_USES_UNIVERSAL_DETECTOR,
+                                      PrefService::SYNCABLE_PREF);
   prefs->RegisterLocalizedStringPref(prefs::kStaticEncodings,
-                                     IDS_STATIC_ENCODING_LIST);
-  prefs->RegisterStringPref(prefs::kRecentlySelectedEncoding, "");
+                                     IDS_STATIC_ENCODING_LIST,
+                                     PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kRecentlySelectedEncoding,
+                            "",
+                            PrefService::UNSYNCABLE_PREF);
 }
 
 string16 TabContentsWrapper::GetDefaultTitle() {
diff --git a/chrome/browser/ui/views/browser_actions_container.cc b/chrome/browser/ui/views/browser_actions_container.cc
index 942d92d..70b8df3 100644
--- a/chrome/browser/ui/views/browser_actions_container.cc
+++ b/chrome/browser/ui/views/browser_actions_container.cc
@@ -391,7 +391,9 @@
 
 // Static.
 void BrowserActionsContainer::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth, 0);
+  prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth,
+                             0,
+                             PrefService::UNSYNCABLE_PREF);
 }
 
 void BrowserActionsContainer::Init() {
diff --git a/chrome/browser/ui/webui/ntp/most_visited_handler.cc b/chrome/browser/ui/webui/ntp/most_visited_handler.cc
index 8b145f3..d6063a6 100644
--- a/chrome/browser/ui/webui/ntp/most_visited_handler.cc
+++ b/chrome/browser/ui/webui/ntp/most_visited_handler.cc
@@ -368,8 +368,10 @@
 
 // static
 void MostVisitedHandler::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterDictionaryPref(prefs::kNTPMostVisitedURLsBlacklist);
-  prefs->RegisterDictionaryPref(prefs::kNTPMostVisitedPinnedURLs);
+  prefs->RegisterDictionaryPref(prefs::kNTPMostVisitedURLsBlacklist,
+                                PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kNTPMostVisitedPinnedURLs,
+                                PrefService::UNSYNCABLE_PREF);
 }
 
 // static
diff --git a/chrome/browser/ui/webui/ntp/new_tab_ui.cc b/chrome/browser/ui/webui/ntp/new_tab_ui.cc
index ba1b8d0..1431437 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_ui.cc
+++ b/chrome/browser/ui/webui/ntp/new_tab_ui.cc
@@ -461,7 +461,9 @@
 
 // static
 void NewTabUI::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterIntegerPref(prefs::kNTPPrefVersion, 0);
+  prefs->RegisterIntegerPref(prefs::kNTPPrefVersion,
+                             0,
+                             PrefService::UNSYNCABLE_PREF);
 
   MostVisitedHandler::RegisterUserPrefs(prefs);
   ShownSectionsHandler::RegisterUserPrefs(prefs);
diff --git a/chrome/browser/ui/webui/ntp/shown_sections_handler.cc b/chrome/browser/ui/webui/ntp/shown_sections_handler.cc
index 003c34f..fdc42a8 100644
--- a/chrome/browser/ui/webui/ntp/shown_sections_handler.cc
+++ b/chrome/browser/ui/webui/ntp/shown_sections_handler.cc
@@ -105,9 +105,12 @@
 #if defined(OS_CHROMEOS)
   // Default to have expanded APPS and all other sections are minimized.
   pref_service->RegisterIntegerPref(prefs::kNTPShownSections,
-                                    APPS | MENU_THUMB | MENU_RECENT);
+                                    APPS | MENU_THUMB | MENU_RECENT,
+                                    PrefService::UNSYNCABLE_PREF);
 #else
-  pref_service->RegisterIntegerPref(prefs::kNTPShownSections, THUMB);
+  pref_service->RegisterIntegerPref(prefs::kNTPShownSections,
+                                    THUMB,
+                                    PrefService::UNSYNCABLE_PREF);
 #endif
 }
 
diff --git a/chrome/browser/ui/webui/options/extension_settings_handler.cc b/chrome/browser/ui/webui/options/extension_settings_handler.cc
index 5f47f7c..0aa8434 100644
--- a/chrome/browser/ui/webui/options/extension_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/extension_settings_handler.cc
@@ -919,5 +919,7 @@
 
 // static
 void ExtensionsUI::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kExtensionsUIDeveloperMode, false);
+  prefs->RegisterBooleanPref(prefs::kExtensionsUIDeveloperMode,
+                             false,
+                             PrefService::SYNCABLE_PREF);
 }
diff --git a/chrome/browser/ui/webui/plugins_ui.cc b/chrome/browser/ui/webui/plugins_ui.cc
index af93b93..7672fd4 100644
--- a/chrome/browser/ui/webui/plugins_ui.cc
+++ b/chrome/browser/ui/webui/plugins_ui.cc
@@ -368,8 +368,15 @@
 
 // static
 void PluginsUI::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterListPref(prefs::kPluginsPluginsList);
-  prefs->RegisterBooleanPref(prefs::kPluginsEnabledInternalPDF, false);
-  prefs->RegisterBooleanPref(prefs::kPluginsShowDetails, false);
-  prefs->RegisterBooleanPref(prefs::kPluginsShowSetReaderDefaultInfobar, true);
+  prefs->RegisterListPref(prefs::kPluginsPluginsList,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kPluginsEnabledInternalPDF,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kPluginsShowDetails,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kPluginsShowSetReaderDefaultInfobar,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
 }
diff --git a/chrome/browser/web_resource/promo_resource_service.cc b/chrome/browser/web_resource/promo_resource_service.cc
index d9f526f..8d9d145 100644
--- a/chrome/browser/web_resource/promo_resource_service.cc
+++ b/chrome/browser/web_resource/promo_resource_service.cc
@@ -62,16 +62,34 @@
 
 // static
 void PromoResourceService::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterDoublePref(prefs::kNTPCustomLogoStart, 0);
-  prefs->RegisterDoublePref(prefs::kNTPCustomLogoEnd, 0);
-  prefs->RegisterDoublePref(prefs::kNTPPromoStart, 0);
-  prefs->RegisterDoublePref(prefs::kNTPPromoEnd, 0);
-  prefs->RegisterStringPref(prefs::kNTPPromoLine, std::string());
-  prefs->RegisterBooleanPref(prefs::kNTPPromoClosed, false);
-  prefs->RegisterIntegerPref(prefs::kNTPPromoGroup, -1);
-  prefs->RegisterIntegerPref(prefs::kNTPPromoBuild,
-       CANARY_BUILD | DEV_BUILD | BETA_BUILD | STABLE_BUILD);
-  prefs->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice, 0);
+  prefs->RegisterDoublePref(prefs::kNTPCustomLogoStart,
+                            0,
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDoublePref(prefs::kNTPCustomLogoEnd,
+                            0,
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDoublePref(prefs::kNTPPromoStart,
+                            0,
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDoublePref(prefs::kNTPPromoEnd,
+                            0,
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kNTPPromoLine,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kNTPPromoClosed,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterIntegerPref(prefs::kNTPPromoGroup,
+                             -1,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterIntegerPref(
+      prefs::kNTPPromoBuild,
+      CANARY_BUILD | DEV_BUILD | BETA_BUILD | STABLE_BUILD,
+      PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice,
+                             0,
+                             PrefService::UNSYNCABLE_PREF);
 }
 
 // static
diff --git a/chrome/browser/web_resource/web_resource_service.cc b/chrome/browser/web_resource/web_resource_service.cc
index 83c4b40..47496eac 100644
--- a/chrome/browser/web_resource/web_resource_service.cc
+++ b/chrome/browser/web_resource/web_resource_service.cc
@@ -218,7 +218,9 @@
       web_resource_update_scheduled_(false) {
   DCHECK(prefs);
   DCHECK(profile);
-  prefs_->RegisterStringPref(last_update_time_pref_name, "0");
+  prefs_->RegisterStringPref(last_update_time_pref_name,
+                             "0",
+                             PrefService::UNSYNCABLE_PREF);
   resource_dispatcher_host_ = g_browser_process->resource_dispatcher_host();
   web_resource_fetcher_.reset(new WebResourceFetcher(this));
 }
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 6b5f1fa..556d94a 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1595,6 +1595,8 @@
         'browser/prefs/pref_change_registrar.h',
         'browser/prefs/pref_member.cc',
         'browser/prefs/pref_member.h',
+        'browser/prefs/pref_model_associator.cc',
+        'browser/prefs/pref_model_associator.h',
         'browser/prefs/pref_notifier.h',
         'browser/prefs/pref_notifier_impl.cc',
         'browser/prefs/pref_notifier_impl.h',
@@ -1939,6 +1941,8 @@
         'browser/sync/glue/foreign_session_tracker.h',
         'browser/sync/glue/frontend_data_type_controller.cc',
         'browser/sync/glue/frontend_data_type_controller.h',
+        'browser/sync/glue/generic_change_processor.cc',
+        'browser/sync/glue/generic_change_processor.h',
         'browser/sync/glue/history_model_worker.cc',
         'browser/sync/glue/history_model_worker.h',
         'browser/sync/glue/http_bridge.cc',
@@ -1954,12 +1958,8 @@
         'browser/sync/glue/password_model_associator.h',
         'browser/sync/glue/password_model_worker.cc',
         'browser/sync/glue/password_model_worker.h',
-        'browser/sync/glue/preference_change_processor.cc',
-        'browser/sync/glue/preference_change_processor.h',
         'browser/sync/glue/preference_data_type_controller.cc',
         'browser/sync/glue/preference_data_type_controller.h',
-        'browser/sync/glue/preference_model_associator.cc',
-        'browser/sync/glue/preference_model_associator.h',
         'browser/sync/glue/session_change_processor.cc',
         'browser/sync/glue/session_change_processor.h',
         'browser/sync/glue/session_data_type_controller.cc',
@@ -1968,7 +1968,6 @@
         'browser/sync/glue/session_model_associator.h',
         'browser/sync/glue/sync_backend_host.cc',
         'browser/sync/glue/sync_backend_host.h',
-        'browser/sync/glue/synchronized_preferences.h',
         'browser/sync/glue/theme_change_processor.cc',
         'browser/sync/glue/theme_change_processor.h',
         'browser/sync/glue/theme_data_type_controller.cc',
@@ -1997,6 +1996,8 @@
         'browser/sync/profile_sync_service_observer.h',
         'browser/sync/signin_manager.cc',
         'browser/sync/signin_manager.h',
+        'browser/sync/syncable_service.cc',
+        'browser/sync/syncable_service.h',
         'browser/sync/sync_setup_flow.cc',
         'browser/sync/sync_setup_flow.h',
         'browser/sync/sync_setup_flow_handler.h',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 56d4aef..1aa37a03 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1460,6 +1460,7 @@
         'browser/prefs/overlay_persistent_pref_store_unittest.cc',
         'browser/prefs/pref_change_registrar_unittest.cc',
         'browser/prefs/pref_member_unittest.cc',
+        'browser/prefs/pref_model_associator_unittest.cc',
         'browser/prefs/pref_notifier_impl_unittest.cc',
         'browser/prefs/pref_service_unittest.cc',
         'browser/prefs/pref_set_observer_unittest.cc',
@@ -1547,7 +1548,6 @@
         'browser/sync/glue/non_frontend_data_type_controller_mock.h',
         'browser/sync/glue/non_frontend_data_type_controller_unittest.cc',
         'browser/sync/glue/preference_data_type_controller_unittest.cc',
-        'browser/sync/glue/preference_model_associator_unittest.cc',
         'browser/sync/glue/session_model_associator_unittest.cc',
         'browser/sync/glue/sync_backend_host_mock.cc',
         'browser/sync/glue/sync_backend_host_mock.h',
@@ -1573,6 +1573,8 @@
         'browser/sync/sync_setup_wizard_unittest.cc',
         'browser/sync/sync_ui_util_mac_unittest.mm',
         'browser/sync/sync_ui_util_unittest.cc',
+        'browser/sync/syncable_service_mock.cc',
+        'browser/sync/syncable_service_mock.h',
         'browser/sync/test_profile_sync_service.cc',
         'browser/sync/test_profile_sync_service.h',
         'browser/sync/util/cryptographer_unittest.cc',
diff --git a/content/browser/host_zoom_map.cc b/content/browser/host_zoom_map.cc
index 98ebc1c..441473c6 100644
--- a/content/browser/host_zoom_map.cc
+++ b/content/browser/host_zoom_map.cc
@@ -72,8 +72,11 @@
 
 // static
 void HostZoomMap::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterDoublePref(prefs::kDefaultZoomLevel, 0.0);
-  prefs->RegisterDictionaryPref(prefs::kPerHostZoomLevels);
+  prefs->RegisterDoublePref(prefs::kDefaultZoomLevel,
+                            0.0,
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterDictionaryPref(prefs::kPerHostZoomLevels,
+                                PrefService::UNSYNCABLE_PREF);
 }
 
 double HostZoomMap::GetZoomLevel(const GURL& url) const {