extensions: Create AppSorting interface.

Create an AppSorting interface in extensions/browser/ and
make ChromeAppSorting (formerly ExtensionSorting) implement
it.

BUG=313284

Review URL: https://codereview.chromium.org/74613003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@236500 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/app_sync_bundle.cc b/chrome/browser/extensions/app_sync_bundle.cc
index d14665e..d8e2cdd 100644
--- a/chrome/browser/extensions/app_sync_bundle.cc
+++ b/chrome/browser/extensions/app_sync_bundle.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/extensions/app_sync_bundle.h"
 
 #include "base/location.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/extensions/extension_sync_service.h"
 #include "chrome/common/extensions/extension_set.h"
 #include "chrome/common/extensions/sync_helper.h"
+#include "extensions/browser/app_sorting.h"
 #include "extensions/common/extension.h"
 #include "sync/api/sync_change_processor.h"
 #include "sync/api/sync_error_factory.h"
@@ -92,7 +92,7 @@
 void AppSyncBundle::ProcessSyncChangeList(
     syncer::SyncChangeList sync_change_list) {
   sync_processor_->ProcessSyncChanges(FROM_HERE, sync_change_list);
-  extension_sync_service_->extension_prefs().extension_sorting()->
+  extension_sync_service_->extension_prefs().app_sorting()->
       FixNTPOrdinalCollisions();
 }
 
diff --git a/chrome/browser/extensions/extension_sorting.cc b/chrome/browser/extensions/chrome_app_sorting.cc
similarity index 89%
rename from chrome/browser/extensions/extension_sorting.cc
rename to chrome/browser/extensions/chrome_app_sorting.cc
index 1d5edcb..fa6967eb 100644
--- a/chrome/browser/extensions/extension_sorting.cc
+++ b/chrome/browser/extensions/chrome_app_sorting.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/extensions/extension_sorting.h"
+#include "chrome/browser/extensions/chrome_app_sorting.h"
 
 #include <algorithm>
 #include <vector>
@@ -18,7 +18,7 @@
 #include "chrome/browser/chromeos/extensions/default_app_order.h"
 #endif
 
-using extensions::ExtensionPrefs;
+namespace extensions {
 
 namespace {
 
@@ -37,37 +37,37 @@
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
-// ExtensionSorting::AppOrdinals
+// ChromeAppSorting::AppOrdinals
 
-ExtensionSorting::AppOrdinals::AppOrdinals() {}
+ChromeAppSorting::AppOrdinals::AppOrdinals() {}
 
-ExtensionSorting::AppOrdinals::~AppOrdinals() {}
+ChromeAppSorting::AppOrdinals::~AppOrdinals() {}
 
 ////////////////////////////////////////////////////////////////////////////////
-// ExtensionSorting
+// ChromeAppSorting
 
-ExtensionSorting::ExtensionSorting(ExtensionScopedPrefs* extension_scoped_prefs)
+ChromeAppSorting::ChromeAppSorting(ExtensionScopedPrefs* extension_scoped_prefs)
     : extension_scoped_prefs_(extension_scoped_prefs),
       extension_sync_service_(NULL),
       default_ordinals_created_(false) {
 }
 
-ExtensionSorting::~ExtensionSorting() {
+ChromeAppSorting::~ChromeAppSorting() {
 }
 
-void ExtensionSorting::SetExtensionSyncService(
+void ChromeAppSorting::SetExtensionSyncService(
     ExtensionSyncService* extension_sync_service) {
   extension_sync_service_ = extension_sync_service;
 }
 
-void ExtensionSorting::Initialize(
+void ChromeAppSorting::Initialize(
     const extensions::ExtensionIdList& extension_ids) {
   InitializePageOrdinalMap(extension_ids);
 
   MigrateAppIndex(extension_ids);
 }
 
-void ExtensionSorting::CreateOrdinalsIfNecessary(size_t minimum_size) {
+void ChromeAppSorting::CreateOrdinalsIfNecessary(size_t minimum_size) {
   // Create StringOrdinal values as required to ensure |ntp_ordinal_map_| has at
   // least |minimum_size| entries.
   if (ntp_ordinal_map_.empty() && minimum_size > 0)
@@ -81,7 +81,7 @@
   }
 }
 
-void ExtensionSorting::MigrateAppIndex(
+void ChromeAppSorting::MigrateAppIndex(
     const extensions::ExtensionIdList& extension_ids) {
   if (extension_ids.empty())
     return;
@@ -169,7 +169,7 @@
   }
 }
 
-void ExtensionSorting::FixNTPOrdinalCollisions() {
+void ChromeAppSorting::FixNTPOrdinalCollisions() {
   for (PageOrdinalMap::iterator page_it = ntp_ordinal_map_.begin();
        page_it != ntp_ordinal_map_.end(); ++page_it) {
     AppLaunchOrdinalMap& page = page_it->second;
@@ -215,11 +215,11 @@
 
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED,
-      content::Source<ExtensionSorting>(this),
+      content::Source<ChromeAppSorting>(this),
       content::NotificationService::NoDetails());
 }
 
-void ExtensionSorting::EnsureValidOrdinals(
+void ChromeAppSorting::EnsureValidOrdinals(
     const std::string& extension_id,
     const syncer::StringOrdinal& suggested_page) {
   syncer::StringOrdinal page_ordinal = GetPageOrdinal(extension_id);
@@ -247,7 +247,7 @@
   }
 }
 
-void ExtensionSorting::OnExtensionMoved(
+void ChromeAppSorting::OnExtensionMoved(
     const std::string& moved_extension_id,
     const std::string& predecessor_extension_id,
     const std::string& successor_extension_id) {
@@ -276,12 +276,12 @@
 
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED,
-      content::Source<ExtensionSorting>(this),
+      content::Source<ChromeAppSorting>(this),
       content::Details<const std::string>(&moved_extension_id));
 }
 
 
-syncer::StringOrdinal ExtensionSorting::GetAppLaunchOrdinal(
+syncer::StringOrdinal ChromeAppSorting::GetAppLaunchOrdinal(
     const std::string& extension_id) const {
   std::string raw_value;
   // If the preference read fails then raw_value will still be unset and we
@@ -292,7 +292,7 @@
   return syncer::StringOrdinal(raw_value);
 }
 
-void ExtensionSorting::SetAppLaunchOrdinal(
+void ChromeAppSorting::SetAppLaunchOrdinal(
     const std::string& extension_id,
     const syncer::StringOrdinal& new_app_launch_ordinal) {
   // No work is required if the old and new values are the same.
@@ -317,11 +317,11 @@
   SyncIfNeeded(extension_id);
 }
 
-syncer::StringOrdinal ExtensionSorting::CreateFirstAppLaunchOrdinal(
+syncer::StringOrdinal ChromeAppSorting::CreateFirstAppLaunchOrdinal(
     const syncer::StringOrdinal& page_ordinal) const {
   const syncer::StringOrdinal& min_ordinal =
       GetMinOrMaxAppLaunchOrdinalsOnPage(page_ordinal,
-                                         ExtensionSorting::MIN_ORDINAL);
+                                         ChromeAppSorting::MIN_ORDINAL);
 
   if (min_ordinal.IsValid())
     return min_ordinal.CreateBefore();
@@ -329,11 +329,11 @@
     return syncer::StringOrdinal::CreateInitialOrdinal();
 }
 
-syncer::StringOrdinal ExtensionSorting::CreateNextAppLaunchOrdinal(
+syncer::StringOrdinal ChromeAppSorting::CreateNextAppLaunchOrdinal(
     const syncer::StringOrdinal& page_ordinal) const {
   const syncer::StringOrdinal& max_ordinal =
       GetMinOrMaxAppLaunchOrdinalsOnPage(page_ordinal,
-                                         ExtensionSorting::MAX_ORDINAL);
+                                         ChromeAppSorting::MAX_ORDINAL);
 
   if (max_ordinal.IsValid())
     return max_ordinal.CreateAfter();
@@ -341,14 +341,14 @@
     return syncer::StringOrdinal::CreateInitialOrdinal();
 }
 
-syncer::StringOrdinal ExtensionSorting::CreateFirstAppPageOrdinal() const {
+syncer::StringOrdinal ChromeAppSorting::CreateFirstAppPageOrdinal() const {
   if (ntp_ordinal_map_.empty())
     return syncer::StringOrdinal::CreateInitialOrdinal();
 
   return ntp_ordinal_map_.begin()->first;
 }
 
-syncer::StringOrdinal ExtensionSorting::GetNaturalAppPageOrdinal() const {
+syncer::StringOrdinal ChromeAppSorting::GetNaturalAppPageOrdinal() const {
   if (ntp_ordinal_map_.empty())
     return syncer::StringOrdinal::CreateInitialOrdinal();
 
@@ -363,7 +363,7 @@
   return last_element.CreateAfter();
 }
 
-syncer::StringOrdinal ExtensionSorting::GetPageOrdinal(
+syncer::StringOrdinal ChromeAppSorting::GetPageOrdinal(
     const std::string& extension_id) const {
   std::string raw_data;
   // If the preference read fails then raw_data will still be unset and we will
@@ -373,7 +373,7 @@
   return syncer::StringOrdinal(raw_data);
 }
 
-void ExtensionSorting::SetPageOrdinal(
+void ChromeAppSorting::SetPageOrdinal(
     const std::string& extension_id,
     const syncer::StringOrdinal& new_page_ordinal) {
   // No work is required if the old and new values are the same.
@@ -396,7 +396,7 @@
   SyncIfNeeded(extension_id);
 }
 
-void ExtensionSorting::ClearOrdinals(const std::string& extension_id) {
+void ChromeAppSorting::ClearOrdinals(const std::string& extension_id) {
   RemoveOrdinalMapping(extension_id,
                        GetPageOrdinal(extension_id),
                        GetAppLaunchOrdinal(extension_id));
@@ -407,7 +407,7 @@
       extension_id, kPrefAppLaunchOrdinal, NULL);
 }
 
-int ExtensionSorting::PageStringOrdinalAsInteger(
+int ChromeAppSorting::PageStringOrdinalAsInteger(
     const syncer::StringOrdinal& page_ordinal) const {
   if (!page_ordinal.IsValid())
     return -1;
@@ -417,7 +417,7 @@
       std::distance(ntp_ordinal_map_.begin(), it) : -1;
 }
 
-syncer::StringOrdinal ExtensionSorting::PageIntegerAsStringOrdinal(
+syncer::StringOrdinal ChromeAppSorting::PageIntegerAsStringOrdinal(
     size_t page_index) {
   if (page_index < ntp_ordinal_map_.size()) {
     PageOrdinalMap::const_iterator it = ntp_ordinal_map_.begin();
@@ -429,11 +429,11 @@
   return ntp_ordinal_map_.rbegin()->first;
 }
 
-void ExtensionSorting::MarkExtensionAsHidden(const std::string& extension_id) {
+void ChromeAppSorting::MarkExtensionAsHidden(const std::string& extension_id) {
   ntp_hidden_extensions_.insert(extension_id);
 }
 
-syncer::StringOrdinal ExtensionSorting::GetMinOrMaxAppLaunchOrdinalsOnPage(
+syncer::StringOrdinal ChromeAppSorting::GetMinOrMaxAppLaunchOrdinalsOnPage(
     const syncer::StringOrdinal& target_page_ordinal,
     AppLaunchOrdinalReturn return_type) const {
   CHECK(target_page_ordinal.IsValid());
@@ -448,16 +448,16 @@
     if (app_list.empty())
       return syncer::StringOrdinal();
 
-    if (return_type == ExtensionSorting::MAX_ORDINAL)
+    if (return_type == ChromeAppSorting::MAX_ORDINAL)
       return_value = app_list.rbegin()->first;
-    else if (return_type == ExtensionSorting::MIN_ORDINAL)
+    else if (return_type == ChromeAppSorting::MIN_ORDINAL)
       return_value = app_list.begin()->first;
   }
 
   return return_value;
 }
 
-void ExtensionSorting::InitializePageOrdinalMap(
+void ChromeAppSorting::InitializePageOrdinalMap(
     const extensions::ExtensionIdList& extension_ids) {
   for (extensions::ExtensionIdList::const_iterator ext_it =
            extension_ids.begin(); ext_it != extension_ids.end(); ++ext_it) {
@@ -489,7 +489,7 @@
   }
 }
 
-void ExtensionSorting::AddOrdinalMapping(
+void ChromeAppSorting::AddOrdinalMapping(
     const std::string& extension_id,
     const syncer::StringOrdinal& page_ordinal,
     const syncer::StringOrdinal& app_launch_ordinal) {
@@ -500,7 +500,7 @@
       std::make_pair(app_launch_ordinal, extension_id));
 }
 
-void ExtensionSorting::RemoveOrdinalMapping(
+void ChromeAppSorting::RemoveOrdinalMapping(
     const std::string& extension_id,
     const syncer::StringOrdinal& page_ordinal,
     const syncer::StringOrdinal& app_launch_ordinal) {
@@ -523,12 +523,12 @@
   }
 }
 
-void ExtensionSorting::SyncIfNeeded(const std::string& extension_id) {
+void ChromeAppSorting::SyncIfNeeded(const std::string& extension_id) {
   if (extension_sync_service_)
     extension_sync_service_->SyncOrderingChange(extension_id);
 }
 
-void ExtensionSorting::CreateDefaultOrdinals() {
+void ChromeAppSorting::CreateDefaultOrdinals() {
   if (default_ordinals_created_)
     return;
   default_ordinals_created_ = true;
@@ -557,7 +557,7 @@
   }
 }
 
-bool ExtensionSorting::GetDefaultOrdinals(
+bool ChromeAppSorting::GetDefaultOrdinals(
     const std::string& extension_id,
     syncer::StringOrdinal* page_ordinal,
     syncer::StringOrdinal* app_launch_ordinal) {
@@ -573,7 +573,7 @@
   return true;
 }
 
-syncer::StringOrdinal ExtensionSorting::ResolveCollision(
+syncer::StringOrdinal ChromeAppSorting::ResolveCollision(
     const syncer::StringOrdinal& page_ordinal,
     const syncer::StringOrdinal& app_launch_ordinal) const {
   DCHECK(page_ordinal.IsValid() && app_launch_ordinal.IsValid());
@@ -602,7 +602,7 @@
   return app_launch_ordinal.CreateBetween(app_it->first);
 }
 
-size_t ExtensionSorting::CountItemsVisibleOnNtp(
+size_t ChromeAppSorting::CountItemsVisibleOnNtp(
     const AppLaunchOrdinalMap& m) const {
   size_t result = 0;
   for (AppLaunchOrdinalMap::const_iterator it = m.begin(); it != m.end();
@@ -613,3 +613,5 @@
   }
   return result;
 }
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/chrome_app_sorting.h b/chrome/browser/extensions/chrome_app_sorting.h
new file mode 100644
index 0000000..5d16ed3
--- /dev/null
+++ b/chrome/browser/extensions/chrome_app_sorting.h
@@ -0,0 +1,185 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_CHROME_APP_SORTING_H_
+#define CHROME_BROWSER_EXTENSIONS_CHROME_APP_SORTING_H_
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "base/basictypes.h"
+#include "chrome/browser/extensions/extension_prefs.h"
+#include "extensions/browser/app_sorting.h"
+#include "extensions/common/extension.h"
+#include "sync/api/string_ordinal.h"
+
+class ExtensionSyncService;
+class PrefService;
+
+namespace extensions {
+
+class ExtensionScopedPrefs;
+
+class ChromeAppSorting : public AppSorting {
+ public:
+  explicit ChromeAppSorting(ExtensionScopedPrefs* extension_scoped_prefs);
+  virtual ~ChromeAppSorting();
+
+  // AppSorting implementation:
+  virtual void SetExtensionSyncService(
+      ExtensionSyncService* extension_sync_service) OVERRIDE;
+  virtual void Initialize(
+      const extensions::ExtensionIdList& extension_ids) OVERRIDE;
+  virtual void FixNTPOrdinalCollisions() OVERRIDE;
+  virtual void EnsureValidOrdinals(
+      const std::string& extension_id,
+      const syncer::StringOrdinal& suggested_page) OVERRIDE;
+  virtual void OnExtensionMoved(
+      const std::string& moved_extension_id,
+      const std::string& predecessor_extension_id,
+      const std::string& successor_extension_id) OVERRIDE;
+  virtual syncer::StringOrdinal GetAppLaunchOrdinal(
+      const std::string& extension_id) const OVERRIDE;
+  virtual void SetAppLaunchOrdinal(
+      const std::string& extension_id,
+      const syncer::StringOrdinal& new_app_launch_ordinal) OVERRIDE;
+  virtual syncer::StringOrdinal CreateFirstAppLaunchOrdinal(
+      const syncer::StringOrdinal& page_ordinal) const OVERRIDE;
+  virtual syncer::StringOrdinal CreateNextAppLaunchOrdinal(
+      const syncer::StringOrdinal& page_ordinal) const OVERRIDE;
+  virtual syncer::StringOrdinal CreateFirstAppPageOrdinal() const OVERRIDE;
+  virtual syncer::StringOrdinal GetNaturalAppPageOrdinal() const OVERRIDE;
+  virtual syncer::StringOrdinal GetPageOrdinal(
+      const std::string& extension_id) const OVERRIDE;
+  virtual void SetPageOrdinal(
+      const std::string& extension_id,
+      const syncer::StringOrdinal& new_page_ordinal) OVERRIDE;
+  virtual void ClearOrdinals(const std::string& extension_id) OVERRIDE;
+  virtual int PageStringOrdinalAsInteger(
+      const syncer::StringOrdinal& page_ordinal) const OVERRIDE;
+  virtual syncer::StringOrdinal PageIntegerAsStringOrdinal(
+      size_t page_index) OVERRIDE;
+  virtual void MarkExtensionAsHidden(const std::string& extension_id) OVERRIDE;
+
+ private:
+  // The StringOrdinal is the app launch ordinal and the string is the extension
+  // id.
+  typedef std::multimap<
+      syncer::StringOrdinal, std::string,
+    syncer::StringOrdinal::LessThanFn> AppLaunchOrdinalMap;
+  // The StringOrdinal is the page ordinal and the AppLaunchOrdinalMap is the
+  // contents of that page.
+  typedef std::map<
+      syncer::StringOrdinal, AppLaunchOrdinalMap,
+    syncer::StringOrdinal::LessThanFn> PageOrdinalMap;
+
+  // Unit tests.
+  friend class ChromeAppSortingDefaultOrdinalsBase;
+  friend class ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage;
+  friend class ChromeAppSortingInitializeWithNoApps;
+  friend class ChromeAppSortingPageOrdinalMapping;
+
+  // An enum used by GetMinOrMaxAppLaunchOrdinalsOnPage to specify which
+  // value should be returned.
+  enum AppLaunchOrdinalReturn {MIN_ORDINAL, MAX_ORDINAL};
+
+  // Maps an app id to its ordinals.
+  struct AppOrdinals {
+    AppOrdinals();
+    ~AppOrdinals();
+
+    syncer::StringOrdinal page_ordinal;
+    syncer::StringOrdinal app_launch_ordinal;
+  };
+  typedef std::map<std::string, AppOrdinals> AppOrdinalsMap;
+
+  // This function returns the lowest ordinal on |page_ordinal| if
+  // |return_value| == AppLaunchOrdinalReturn::MIN_ORDINAL, otherwise it returns
+  // the largest ordinal on |page_ordinal|. If there are no apps on the page
+  // then an invalid StringOrdinal is returned. It is an error to call this
+  // function with an invalid |page_ordinal|.
+  syncer::StringOrdinal GetMinOrMaxAppLaunchOrdinalsOnPage(
+      const syncer::StringOrdinal& page_ordinal,
+      AppLaunchOrdinalReturn return_type) const;
+
+  // Initialize the |page_ordinal_map_| with the page ordinals used by the
+  // given extensions.
+  void InitializePageOrdinalMap(
+      const extensions::ExtensionIdList& extension_ids);
+
+  // Migrates the app launcher and page index values.
+  void MigrateAppIndex(
+      const extensions::ExtensionIdList& extension_ids);
+
+  // Called to add a new mapping value for |extension_id| with a page ordinal
+  // of |page_ordinal| and a app launch ordinal of |app_launch_ordinal|. This
+  // works with valid and invalid StringOrdinals.
+  void AddOrdinalMapping(const std::string& extension_id,
+                         const syncer::StringOrdinal& page_ordinal,
+                         const syncer::StringOrdinal& app_launch_ordinal);
+
+  // Ensures |ntp_ordinal_map_| is of |minimum_size| number of entries.
+  void CreateOrdinalsIfNecessary(size_t minimum_size);
+
+  // Removes the mapping for |extension_id| with a page ordinal of
+  // |page_ordinal| and a app launch ordinal of |app_launch_ordinal|. If there
+  // is not matching map, nothing happens. This works with valid and invalid
+  // StringOrdinals.
+  void RemoveOrdinalMapping(const std::string& extension_id,
+                            const syncer::StringOrdinal& page_ordinal,
+                            const syncer::StringOrdinal& app_launch_ordinal);
+
+  // Syncs the extension if needed. It is an error to call this if the
+  // extension is not an application.
+  void SyncIfNeeded(const std::string& extension_id);
+
+  // Creates the default ordinals.
+  void CreateDefaultOrdinals();
+
+  // Gets the default ordinals for |extension_id|. Returns false if no default
+  // ordinals for |extension_id| is defined. Otherwise, returns true and
+  // ordinals is updated with corresponding ordinals.
+  bool GetDefaultOrdinals(const std::string& extension_id,
+                          syncer::StringOrdinal* page_ordinal,
+                          syncer::StringOrdinal* app_launch_ordinal);
+
+  // Returns |app_launch_ordinal| if it has no collision in the page specified
+  // by |page_ordinal|. Otherwise, returns an ordinal after |app_launch_ordinal|
+  // that has no conflict.
+  syncer::StringOrdinal ResolveCollision(
+      const syncer::StringOrdinal& page_ordinal,
+      const syncer::StringOrdinal& app_launch_ordinal) const;
+
+  // Returns the number of items in |m| visible on the new tab page.
+  size_t CountItemsVisibleOnNtp(const AppLaunchOrdinalMap& m) const;
+
+  ExtensionScopedPrefs* extension_scoped_prefs_;  // Weak, owns this instance.
+  ExtensionSyncService* extension_sync_service_;  // Weak.
+
+  // A map of all the StringOrdinal page ordinals mapping to the collections of
+  // app launch ordinals that exist on that page. This is used for mapping
+  // StringOrdinals to their Integer equivalent as well as quick lookup of the
+  // any collision of on the NTP (icons with the same page and same app launch
+  // ordinals). The possiblity of collisions means that a multimap must be used
+  // (although the collisions must all be resolved once all the syncing is
+  // done).
+  PageOrdinalMap ntp_ordinal_map_;
+
+  // Defines the default ordinals.
+  AppOrdinalsMap default_ordinals_;
+
+  // Used to construct the default ordinals once when needed instead of on
+  // construction when the app order may not have been determined.
+  bool default_ordinals_created_;
+
+  // The set of extensions that don't appear in the new tab page.
+  std::set<std::string> ntp_hidden_extensions_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeAppSorting);
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_CHROME_APP_SORTING_H_
diff --git a/chrome/browser/extensions/chrome_app_sorting_unittest.cc b/chrome/browser/extensions/chrome_app_sorting_unittest.cc
new file mode 100644
index 0000000..d5737f80
--- /dev/null
+++ b/chrome/browser/extensions/chrome_app_sorting_unittest.cc
@@ -0,0 +1,962 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/chrome_app_sorting.h"
+
+#include <map>
+
+#include "chrome/browser/extensions/extension_prefs_unittest.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "extensions/common/manifest_constants.h"
+#include "sync/api/string_ordinal.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+namespace keys = manifest_keys;
+
+class ChromeAppSortingTest : public ExtensionPrefsTest {
+ protected:
+  ChromeAppSorting* app_sorting() {
+    return static_cast<ChromeAppSorting*>(prefs()->app_sorting());
+  }
+};
+
+class ChromeAppSortingAppLocation : public ChromeAppSortingTest {
+ public:
+  virtual void Initialize() OVERRIDE {
+    extension_ = prefs_.AddExtension("not_an_app");
+    // Non-apps should not have any app launch ordinal or page ordinal.
+    prefs()->OnExtensionInstalled(extension_.get(),
+                                  Extension::ENABLED,
+                                  false,
+                                  syncer::StringOrdinal());
+  }
+
+  virtual void Verify() OVERRIDE {
+    EXPECT_FALSE(
+        app_sorting()->GetAppLaunchOrdinal(extension_->id()).IsValid());
+    EXPECT_FALSE(
+        app_sorting()->GetPageOrdinal(extension_->id()).IsValid());
+  }
+
+ private:
+  scoped_refptr<Extension> extension_;
+};
+TEST_F(ChromeAppSortingAppLocation, ChromeAppSortingAppLocation) {}
+
+class ChromeAppSortingAppLaunchOrdinal : public ChromeAppSortingTest {
+ public:
+  virtual void Initialize() OVERRIDE {
+    // No extensions yet.
+    syncer::StringOrdinal page = syncer::StringOrdinal::CreateInitialOrdinal();
+    EXPECT_TRUE(syncer::StringOrdinal::CreateInitialOrdinal().Equals(
+        app_sorting()->CreateNextAppLaunchOrdinal(page)));
+
+    extension_ = prefs_.AddApp("on_extension_installed");
+    EXPECT_FALSE(prefs()->IsExtensionDisabled(extension_->id()));
+    prefs()->OnExtensionInstalled(extension_.get(),
+                                  Extension::ENABLED,
+                                  false,
+                                  syncer::StringOrdinal());
+  }
+
+  virtual void Verify() OVERRIDE {
+    syncer::StringOrdinal launch_ordinal =
+        app_sorting()->GetAppLaunchOrdinal(extension_->id());
+    syncer::StringOrdinal page_ordinal =
+        syncer::StringOrdinal::CreateInitialOrdinal();
+
+    // Extension should have been assigned a valid StringOrdinal.
+    EXPECT_TRUE(launch_ordinal.IsValid());
+    EXPECT_TRUE(launch_ordinal.LessThan(
+        app_sorting()->CreateNextAppLaunchOrdinal(page_ordinal)));
+    // Set a new launch ordinal of and verify it comes after.
+    app_sorting()->SetAppLaunchOrdinal(
+        extension_->id(),
+        app_sorting()->CreateNextAppLaunchOrdinal(page_ordinal));
+    syncer::StringOrdinal new_launch_ordinal =
+        app_sorting()->GetAppLaunchOrdinal(extension_->id());
+    EXPECT_TRUE(launch_ordinal.LessThan(new_launch_ordinal));
+
+    // This extension doesn't exist, so it should return an invalid
+    // StringOrdinal.
+    syncer::StringOrdinal invalid_app_launch_ordinal =
+        app_sorting()->GetAppLaunchOrdinal("foo");
+    EXPECT_FALSE(invalid_app_launch_ordinal.IsValid());
+    EXPECT_EQ(-1, app_sorting()->PageStringOrdinalAsInteger(
+        invalid_app_launch_ordinal));
+
+    // The second page doesn't have any apps so its next launch ordinal should
+    // be the first launch ordinal.
+    syncer::StringOrdinal next_page = page_ordinal.CreateAfter();
+    syncer::StringOrdinal next_page_app_launch_ordinal =
+        app_sorting()->CreateNextAppLaunchOrdinal(next_page);
+    EXPECT_TRUE(next_page_app_launch_ordinal.Equals(
+        app_sorting()->CreateFirstAppLaunchOrdinal(next_page)));
+  }
+
+ private:
+  scoped_refptr<Extension> extension_;
+};
+TEST_F(ChromeAppSortingAppLaunchOrdinal, ChromeAppSortingAppLaunchOrdinal) {}
+
+class ChromeAppSortingPageOrdinal : public ChromeAppSortingTest {
+ public:
+  virtual void Initialize() OVERRIDE {
+    extension_ = prefs_.AddApp("page_ordinal");
+    // Install with a page preference.
+    first_page_ = syncer::StringOrdinal::CreateInitialOrdinal();
+    prefs()->OnExtensionInstalled(extension_.get(),
+                                  Extension::ENABLED,
+                                  false,
+                                  first_page_);
+    EXPECT_TRUE(first_page_.Equals(
+        app_sorting()->GetPageOrdinal(extension_->id())));
+    EXPECT_EQ(0, app_sorting()->PageStringOrdinalAsInteger(first_page_));
+
+    scoped_refptr<Extension> extension2 = prefs_.AddApp("page_ordinal_2");
+    // Install without any page preference.
+    prefs()->OnExtensionInstalled(extension2.get(),
+                                  Extension::ENABLED,
+                                  false,
+                                  syncer::StringOrdinal());
+    EXPECT_TRUE(first_page_.Equals(
+        app_sorting()->GetPageOrdinal(extension2->id())));
+  }
+  virtual void Verify() OVERRIDE {
+    // Set the page ordinal.
+    syncer::StringOrdinal new_page = first_page_.CreateAfter();
+    app_sorting()->SetPageOrdinal(extension_->id(), new_page);
+    // Verify the page ordinal.
+    EXPECT_TRUE(
+        new_page.Equals(app_sorting()->GetPageOrdinal(extension_->id())));
+    EXPECT_EQ(1, app_sorting()->PageStringOrdinalAsInteger(new_page));
+
+    // This extension doesn't exist, so it should return an invalid
+    // StringOrdinal.
+    EXPECT_FALSE(app_sorting()->GetPageOrdinal("foo").IsValid());
+  }
+
+ private:
+  syncer::StringOrdinal first_page_;
+  scoped_refptr<Extension> extension_;
+};
+TEST_F(ChromeAppSortingPageOrdinal, ChromeAppSortingPageOrdinal) {}
+
+// Ensure that ChromeAppSorting is able to properly initialize off a set
+// of old page and app launch indices and properly convert them.
+class ChromeAppSortingInitialize : public PrefsPrepopulatedTestBase {
+ public:
+  ChromeAppSortingInitialize() {}
+  virtual ~ChromeAppSortingInitialize() {}
+
+  virtual void Initialize() OVERRIDE {
+    // A preference determining the order of which the apps appear on the NTP.
+    const char kPrefAppLaunchIndexDeprecated[] = "app_launcher_index";
+    // A preference determining the page on which an app appears in the NTP.
+    const char kPrefPageIndexDeprecated[] = "page_index";
+
+    // Setup the deprecated preferences.
+    ExtensionScopedPrefs* scoped_prefs =
+        static_cast<ExtensionScopedPrefs*>(prefs());
+    scoped_prefs->UpdateExtensionPref(extension1()->id(),
+                                      kPrefAppLaunchIndexDeprecated,
+                                      new base::FundamentalValue(0));
+    scoped_prefs->UpdateExtensionPref(extension1()->id(),
+                                      kPrefPageIndexDeprecated,
+                                      new base::FundamentalValue(0));
+
+    scoped_prefs->UpdateExtensionPref(extension2()->id(),
+                                      kPrefAppLaunchIndexDeprecated,
+                                      new base::FundamentalValue(1));
+    scoped_prefs->UpdateExtensionPref(extension2()->id(),
+                                      kPrefPageIndexDeprecated,
+                                      new base::FundamentalValue(0));
+
+    scoped_prefs->UpdateExtensionPref(extension3()->id(),
+                                      kPrefAppLaunchIndexDeprecated,
+                                      new base::FundamentalValue(0));
+    scoped_prefs->UpdateExtensionPref(extension3()->id(),
+                                      kPrefPageIndexDeprecated,
+                                      new base::FundamentalValue(1));
+
+    // We insert the ids in reserve order so that we have to deal with the
+    // element on the 2nd page before the 1st page is seen.
+    ExtensionIdList ids;
+    ids.push_back(extension3()->id());
+    ids.push_back(extension2()->id());
+    ids.push_back(extension1()->id());
+
+    prefs()->app_sorting()->Initialize(ids);
+  }
+  virtual void Verify() OVERRIDE {
+    syncer::StringOrdinal first_ordinal =
+        syncer::StringOrdinal::CreateInitialOrdinal();
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    EXPECT_TRUE(first_ordinal.Equals(
+        app_sorting->GetAppLaunchOrdinal(extension1()->id())));
+    EXPECT_TRUE(first_ordinal.LessThan(
+        app_sorting->GetAppLaunchOrdinal(extension2()->id())));
+    EXPECT_TRUE(first_ordinal.Equals(
+        app_sorting->GetAppLaunchOrdinal(extension3()->id())));
+
+    EXPECT_TRUE(first_ordinal.Equals(
+        app_sorting->GetPageOrdinal(extension1()->id())));
+    EXPECT_TRUE(first_ordinal.Equals(
+        app_sorting->GetPageOrdinal(extension2()->id())));
+    EXPECT_TRUE(first_ordinal.LessThan(
+        app_sorting->GetPageOrdinal(extension3()->id())));
+  }
+};
+TEST_F(ChromeAppSortingInitialize, ChromeAppSortingInitialize) {}
+
+// Make sure that initialization still works when no extensions are present
+// (i.e. make sure that the web store icon is still loaded into the map).
+class ChromeAppSortingInitializeWithNoApps : public PrefsPrepopulatedTestBase {
+ public:
+  ChromeAppSortingInitializeWithNoApps() {}
+  virtual ~ChromeAppSortingInitializeWithNoApps() {}
+
+  virtual void Initialize() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    // Make sure that the web store has valid ordinals.
+    syncer::StringOrdinal initial_ordinal =
+        syncer::StringOrdinal::CreateInitialOrdinal();
+    app_sorting->SetPageOrdinal(extension_misc::kWebStoreAppId,
+                                initial_ordinal);
+    app_sorting->SetAppLaunchOrdinal(extension_misc::kWebStoreAppId,
+                                     initial_ordinal);
+
+    ExtensionIdList ids;
+    app_sorting->Initialize(ids);
+  }
+  virtual void Verify() OVERRIDE {
+    ChromeAppSorting* app_sorting =
+        static_cast<ChromeAppSorting*>(prefs()->app_sorting());
+
+    syncer::StringOrdinal page =
+        app_sorting->GetPageOrdinal(extension_misc::kWebStoreAppId);
+    EXPECT_TRUE(page.IsValid());
+
+    ChromeAppSorting::PageOrdinalMap::iterator page_it =
+        app_sorting->ntp_ordinal_map_.find(page);
+    EXPECT_TRUE(page_it != app_sorting->ntp_ordinal_map_.end());
+
+    syncer::StringOrdinal app_launch =
+        app_sorting->GetPageOrdinal(extension_misc::kWebStoreAppId);
+    EXPECT_TRUE(app_launch.IsValid());
+
+    ChromeAppSorting::AppLaunchOrdinalMap::iterator app_launch_it =
+        page_it->second.find(app_launch);
+    EXPECT_TRUE(app_launch_it != page_it->second.end());
+  }
+};
+TEST_F(ChromeAppSortingInitializeWithNoApps,
+       ChromeAppSortingInitializeWithNoApps) {}
+
+// Tests the application index to ordinal migration code for values that
+// shouldn't be converted. This should be removed when the migrate code
+// is taken out.
+// http://crbug.com/107376
+class ChromeAppSortingMigrateAppIndexInvalid
+    : public PrefsPrepopulatedTestBase {
+ public:
+  ChromeAppSortingMigrateAppIndexInvalid() {}
+  virtual ~ChromeAppSortingMigrateAppIndexInvalid() {}
+
+  virtual void Initialize() OVERRIDE {
+    // A preference determining the order of which the apps appear on the NTP.
+    const char kPrefAppLaunchIndexDeprecated[] = "app_launcher_index";
+    // A preference determining the page on which an app appears in the NTP.
+    const char kPrefPageIndexDeprecated[] = "page_index";
+
+    // Setup the deprecated preference.
+    ExtensionScopedPrefs* scoped_prefs =
+        static_cast<ExtensionScopedPrefs*>(prefs());
+    scoped_prefs->UpdateExtensionPref(extension1()->id(),
+                                      kPrefAppLaunchIndexDeprecated,
+                                      new base::FundamentalValue(0));
+    scoped_prefs->UpdateExtensionPref(extension1()->id(),
+                                      kPrefPageIndexDeprecated,
+                                      new base::FundamentalValue(-1));
+
+    ExtensionIdList ids;
+    ids.push_back(extension1()->id());
+
+    prefs()->app_sorting()->Initialize(ids);
+  }
+  virtual void Verify() OVERRIDE {
+    // Make sure that the invalid page_index wasn't converted over.
+    EXPECT_FALSE(prefs()->app_sorting()->GetAppLaunchOrdinal(
+        extension1()->id()).IsValid());
+  }
+};
+TEST_F(ChromeAppSortingMigrateAppIndexInvalid,
+       ChromeAppSortingMigrateAppIndexInvalid) {}
+
+class ChromeAppSortingFixNTPCollisionsAllCollide
+    : public PrefsPrepopulatedTestBase {
+ public:
+  ChromeAppSortingFixNTPCollisionsAllCollide() {}
+  virtual ~ChromeAppSortingFixNTPCollisionsAllCollide() {}
+
+  virtual void Initialize() OVERRIDE {
+    repeated_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();
+
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    app_sorting->SetAppLaunchOrdinal(extension1()->id(),
+                                     repeated_ordinal_);
+    app_sorting->SetPageOrdinal(extension1()->id(), repeated_ordinal_);
+
+    app_sorting->SetAppLaunchOrdinal(extension2()->id(), repeated_ordinal_);
+    app_sorting->SetPageOrdinal(extension2()->id(), repeated_ordinal_);
+
+    app_sorting->SetAppLaunchOrdinal(extension3()->id(), repeated_ordinal_);
+    app_sorting->SetPageOrdinal(extension3()->id(), repeated_ordinal_);
+
+    app_sorting->FixNTPOrdinalCollisions();
+  }
+  virtual void Verify() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+    syncer::StringOrdinal extension1_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension1()->id());
+    syncer::StringOrdinal extension2_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension2()->id());
+    syncer::StringOrdinal extension3_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension3()->id());
+
+    // The overlapping extensions should have be adjusted so that they are
+    // sorted by their id.
+    EXPECT_EQ(extension1()->id() < extension2()->id(),
+              extension1_app_launch.LessThan(extension2_app_launch));
+    EXPECT_EQ(extension1()->id() < extension3()->id(),
+              extension1_app_launch.LessThan(extension3_app_launch));
+    EXPECT_EQ(extension2()->id() < extension3()->id(),
+              extension2_app_launch.LessThan(extension3_app_launch));
+
+    // The page ordinal should be unchanged.
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension1()->id()).Equals(
+        repeated_ordinal_));
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension2()->id()).Equals(
+        repeated_ordinal_));
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension3()->id()).Equals(
+        repeated_ordinal_));
+  }
+
+ private:
+  syncer::StringOrdinal repeated_ordinal_;
+};
+TEST_F(ChromeAppSortingFixNTPCollisionsAllCollide,
+       ChromeAppSortingFixNTPCollisionsAllCollide) {}
+
+class ChromeAppSortingFixNTPCollisionsSomeCollideAtStart
+    : public PrefsPrepopulatedTestBase {
+ public:
+  ChromeAppSortingFixNTPCollisionsSomeCollideAtStart() {}
+  virtual ~ChromeAppSortingFixNTPCollisionsSomeCollideAtStart() {}
+
+  virtual void Initialize() OVERRIDE {
+    first_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();
+    syncer::StringOrdinal second_ordinal = first_ordinal_.CreateAfter();
+
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    // Have the first two extension in the same position, with a third
+    // (non-colliding) extension after.
+
+    app_sorting->SetAppLaunchOrdinal(extension1()->id(), first_ordinal_);
+    app_sorting->SetPageOrdinal(extension1()->id(), first_ordinal_);
+
+    app_sorting->SetAppLaunchOrdinal(extension2()->id(), first_ordinal_);
+    app_sorting->SetPageOrdinal(extension2()->id(), first_ordinal_);
+
+    app_sorting->SetAppLaunchOrdinal(extension3()->id(), second_ordinal);
+    app_sorting->SetPageOrdinal(extension3()->id(), first_ordinal_);
+
+    app_sorting->FixNTPOrdinalCollisions();
+  }
+  virtual void Verify() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+    syncer::StringOrdinal extension1_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension1()->id());
+    syncer::StringOrdinal extension2_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension2()->id());
+    syncer::StringOrdinal extension3_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension3()->id());
+
+    // The overlapping extensions should have be adjusted so that they are
+    // sorted by their id, but they both should be before ext3, which wasn't
+    // overlapping.
+    EXPECT_EQ(extension1()->id() < extension2()->id(),
+              extension1_app_launch.LessThan(extension2_app_launch));
+    EXPECT_TRUE(extension1_app_launch.LessThan(extension3_app_launch));
+    EXPECT_TRUE(extension2_app_launch.LessThan(extension3_app_launch));
+
+    // The page ordinal should be unchanged.
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension1()->id()).Equals(
+        first_ordinal_));
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension2()->id()).Equals(
+        first_ordinal_));
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension3()->id()).Equals(
+        first_ordinal_));
+  }
+
+ private:
+  syncer::StringOrdinal first_ordinal_;
+};
+TEST_F(ChromeAppSortingFixNTPCollisionsSomeCollideAtStart,
+       ChromeAppSortingFixNTPCollisionsSomeCollideAtStart) {}
+
+class ChromeAppSortingFixNTPCollisionsSomeCollideAtEnd
+    : public PrefsPrepopulatedTestBase {
+ public:
+  ChromeAppSortingFixNTPCollisionsSomeCollideAtEnd() {}
+  virtual ~ChromeAppSortingFixNTPCollisionsSomeCollideAtEnd() {}
+
+  virtual void Initialize() OVERRIDE {
+    first_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();
+    syncer::StringOrdinal second_ordinal = first_ordinal_.CreateAfter();
+
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    // Have the first extension in a non-colliding position, followed by two
+    // two extension in the same position.
+
+    app_sorting->SetAppLaunchOrdinal(extension1()->id(), first_ordinal_);
+    app_sorting->SetPageOrdinal(extension1()->id(), first_ordinal_);
+
+    app_sorting->SetAppLaunchOrdinal(extension2()->id(), second_ordinal);
+    app_sorting->SetPageOrdinal(extension2()->id(), first_ordinal_);
+
+    app_sorting->SetAppLaunchOrdinal(extension3()->id(), second_ordinal);
+    app_sorting->SetPageOrdinal(extension3()->id(), first_ordinal_);
+
+    app_sorting->FixNTPOrdinalCollisions();
+  }
+  virtual void Verify() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+    syncer::StringOrdinal extension1_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension1()->id());
+    syncer::StringOrdinal extension2_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension2()->id());
+    syncer::StringOrdinal extension3_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension3()->id());
+
+    // The overlapping extensions should have be adjusted so that they are
+    // sorted by their id, but they both should be after ext1, which wasn't
+    // overlapping.
+    EXPECT_TRUE(extension1_app_launch.LessThan(extension2_app_launch));
+    EXPECT_TRUE(extension1_app_launch.LessThan(extension3_app_launch));
+    EXPECT_EQ(extension2()->id() < extension3()->id(),
+              extension2_app_launch.LessThan(extension3_app_launch));
+
+    // The page ordinal should be unchanged.
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension1()->id()).Equals(
+        first_ordinal_));
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension2()->id()).Equals(
+        first_ordinal_));
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension3()->id()).Equals(
+        first_ordinal_));
+  }
+
+ private:
+  syncer::StringOrdinal first_ordinal_;
+};
+TEST_F(ChromeAppSortingFixNTPCollisionsSomeCollideAtEnd,
+       ChromeAppSortingFixNTPCollisionsSomeCollideAtEnd) {}
+
+class ChromeAppSortingFixNTPCollisionsTwoCollisions
+    : public PrefsPrepopulatedTestBase {
+ public:
+  ChromeAppSortingFixNTPCollisionsTwoCollisions() {}
+  virtual ~ChromeAppSortingFixNTPCollisionsTwoCollisions() {}
+
+  virtual void Initialize() OVERRIDE {
+    first_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();
+    syncer::StringOrdinal second_ordinal = first_ordinal_.CreateAfter();
+
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    // Have two extensions colliding, followed by two more colliding extensions.
+    app_sorting->SetAppLaunchOrdinal(extension1()->id(), first_ordinal_);
+    app_sorting->SetPageOrdinal(extension1()->id(), first_ordinal_);
+
+    app_sorting->SetAppLaunchOrdinal(extension2()->id(), first_ordinal_);
+    app_sorting->SetPageOrdinal(extension2()->id(), first_ordinal_);
+
+    app_sorting->SetAppLaunchOrdinal(extension3()->id(), second_ordinal);
+    app_sorting->SetPageOrdinal(extension3()->id(), first_ordinal_);
+
+    app_sorting->SetAppLaunchOrdinal(extension4()->id(), second_ordinal);
+    app_sorting->SetPageOrdinal(extension4()->id(), first_ordinal_);
+
+    app_sorting->FixNTPOrdinalCollisions();
+  }
+  virtual void Verify() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+    syncer::StringOrdinal extension1_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension1()->id());
+    syncer::StringOrdinal extension2_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension2()->id());
+    syncer::StringOrdinal extension3_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension3()->id());
+    syncer::StringOrdinal extension4_app_launch =
+        app_sorting->GetAppLaunchOrdinal(extension4()->id());
+
+    // The overlapping extensions should have be adjusted so that they are
+    // sorted by their id, with |ext1| and |ext2| appearing before |ext3| and
+    // |ext4|.
+    EXPECT_TRUE(extension1_app_launch.LessThan(extension3_app_launch));
+    EXPECT_TRUE(extension1_app_launch.LessThan(extension4_app_launch));
+    EXPECT_TRUE(extension2_app_launch.LessThan(extension3_app_launch));
+    EXPECT_TRUE(extension2_app_launch.LessThan(extension4_app_launch));
+
+    EXPECT_EQ(extension1()->id() < extension2()->id(),
+              extension1_app_launch.LessThan(extension2_app_launch));
+    EXPECT_EQ(extension3()->id() < extension4()->id(),
+              extension3_app_launch.LessThan(extension4_app_launch));
+
+    // The page ordinal should be unchanged.
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension1()->id()).Equals(
+        first_ordinal_));
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension2()->id()).Equals(
+        first_ordinal_));
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension3()->id()).Equals(
+        first_ordinal_));
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension4()->id()).Equals(
+        first_ordinal_));
+  }
+
+ private:
+  syncer::StringOrdinal first_ordinal_;
+};
+TEST_F(ChromeAppSortingFixNTPCollisionsTwoCollisions,
+       ChromeAppSortingFixNTPCollisionsTwoCollisions) {}
+
+class ChromeAppSortingEnsureValidOrdinals
+    : public PrefsPrepopulatedTestBase {
+ public :
+  ChromeAppSortingEnsureValidOrdinals() {}
+  virtual ~ChromeAppSortingEnsureValidOrdinals() {}
+
+  virtual void Initialize() OVERRIDE {}
+  virtual void Verify() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    // Give ext1 invalid ordinals and then check that EnsureValidOrdinals fixes
+    // them.
+    app_sorting->SetAppLaunchOrdinal(extension1()->id(),
+                                     syncer::StringOrdinal());
+    app_sorting->SetPageOrdinal(extension1()->id(), syncer::StringOrdinal());
+
+    app_sorting->EnsureValidOrdinals(extension1()->id(),
+                                     syncer::StringOrdinal());
+
+    EXPECT_TRUE(app_sorting->GetAppLaunchOrdinal(extension1()->id()).IsValid());
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(extension1()->id()).IsValid());
+  }
+};
+TEST_F(ChromeAppSortingEnsureValidOrdinals,
+       ChromeAppSortingEnsureValidOrdinals) {}
+
+class ChromeAppSortingPageOrdinalMapping : public PrefsPrepopulatedTestBase {
+ public:
+  ChromeAppSortingPageOrdinalMapping() {}
+  virtual ~ChromeAppSortingPageOrdinalMapping() {}
+
+  virtual void Initialize() OVERRIDE {}
+  virtual void Verify() OVERRIDE {
+    std::string ext_1 = "ext_1";
+    std::string ext_2 = "ext_2";
+
+    ChromeAppSorting* app_sorting =
+        static_cast<ChromeAppSorting*>(prefs()->app_sorting());
+    syncer::StringOrdinal first_ordinal =
+        syncer::StringOrdinal::CreateInitialOrdinal();
+
+    // Ensure attempting to removing a mapping with an invalid page doesn't
+    // modify the map.
+    EXPECT_TRUE(app_sorting->ntp_ordinal_map_.empty());
+    app_sorting->RemoveOrdinalMapping(
+        ext_1, first_ordinal, first_ordinal);
+    EXPECT_TRUE(app_sorting->ntp_ordinal_map_.empty());
+
+    // Add new mappings.
+    app_sorting->AddOrdinalMapping(ext_1, first_ordinal, first_ordinal);
+    app_sorting->AddOrdinalMapping(ext_2, first_ordinal, first_ordinal);
+
+    EXPECT_EQ(1U, app_sorting->ntp_ordinal_map_.size());
+    EXPECT_EQ(2U, app_sorting->ntp_ordinal_map_[first_ordinal].size());
+
+    ChromeAppSorting::AppLaunchOrdinalMap::iterator it =
+        app_sorting->ntp_ordinal_map_[first_ordinal].find(first_ordinal);
+    EXPECT_EQ(ext_1, it->second);
+    ++it;
+    EXPECT_EQ(ext_2, it->second);
+
+    app_sorting->RemoveOrdinalMapping(ext_1, first_ordinal, first_ordinal);
+    EXPECT_EQ(1U, app_sorting->ntp_ordinal_map_.size());
+    EXPECT_EQ(1U, app_sorting->ntp_ordinal_map_[first_ordinal].size());
+
+    it = app_sorting->ntp_ordinal_map_[first_ordinal].find(first_ordinal);
+    EXPECT_EQ(ext_2, it->second);
+
+    // Ensure that attempting to remove an extension with a valid page and app
+    // launch ordinals, but a unused id has no effect.
+    app_sorting->RemoveOrdinalMapping(
+        "invalid_ext", first_ordinal, first_ordinal);
+    EXPECT_EQ(1U, app_sorting->ntp_ordinal_map_.size());
+    EXPECT_EQ(1U, app_sorting->ntp_ordinal_map_[first_ordinal].size());
+
+    it = app_sorting->ntp_ordinal_map_[first_ordinal].find(first_ordinal);
+    EXPECT_EQ(ext_2, it->second);
+  }
+};
+TEST_F(ChromeAppSortingPageOrdinalMapping,
+       ChromeAppSortingPageOrdinalMapping) {}
+
+class ChromeAppSortingPreinstalledAppsBase : public PrefsPrepopulatedTestBase {
+ public:
+  ChromeAppSortingPreinstalledAppsBase() {
+    DictionaryValue simple_dict;
+    simple_dict.SetString(keys::kVersion, "1.0.0.0");
+    simple_dict.SetString(keys::kName, "unused");
+    simple_dict.SetString(keys::kApp, "true");
+    simple_dict.SetString(keys::kLaunchLocalPath, "fake.html");
+
+    std::string error;
+    app1_scoped_ = Extension::Create(
+        prefs_.temp_dir().AppendASCII("app1_"), Manifest::EXTERNAL_PREF,
+        simple_dict, Extension::NO_FLAGS, &error);
+    prefs()->OnExtensionInstalled(app1_scoped_.get(),
+                                  Extension::ENABLED,
+                                  false,
+                                  syncer::StringOrdinal());
+
+    app2_scoped_ = Extension::Create(
+        prefs_.temp_dir().AppendASCII("app2_"), Manifest::EXTERNAL_PREF,
+        simple_dict, Extension::NO_FLAGS, &error);
+    prefs()->OnExtensionInstalled(app2_scoped_.get(),
+                                  Extension::ENABLED,
+                                  false,
+                                  syncer::StringOrdinal());
+
+    app1_ = app1_scoped_.get();
+    app2_ = app2_scoped_.get();
+  }
+  virtual ~ChromeAppSortingPreinstalledAppsBase() {}
+
+ protected:
+  // Weak references, for convenience.
+  Extension* app1_;
+  Extension* app2_;
+
+ private:
+  scoped_refptr<Extension> app1_scoped_;
+  scoped_refptr<Extension> app2_scoped_;
+};
+
+class ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage
+    : public ChromeAppSortingPreinstalledAppsBase {
+ public:
+  ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage() {}
+  virtual ~ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage() {}
+
+  virtual void Initialize() OVERRIDE {}
+  virtual void Verify() OVERRIDE {
+    syncer::StringOrdinal page = syncer::StringOrdinal::CreateInitialOrdinal();
+    ChromeAppSorting* app_sorting =
+        static_cast<ChromeAppSorting*>(prefs()->app_sorting());
+
+    syncer::StringOrdinal min =
+        app_sorting->GetMinOrMaxAppLaunchOrdinalsOnPage(
+            page,
+            ChromeAppSorting::MIN_ORDINAL);
+    syncer::StringOrdinal max =
+        app_sorting->GetMinOrMaxAppLaunchOrdinalsOnPage(
+            page,
+            ChromeAppSorting::MAX_ORDINAL);
+    EXPECT_TRUE(min.IsValid());
+    EXPECT_TRUE(max.IsValid());
+    EXPECT_TRUE(min.LessThan(max));
+
+    // Ensure that the min and max values aren't set for empty pages.
+    min = syncer::StringOrdinal();
+    max = syncer::StringOrdinal();
+    syncer::StringOrdinal empty_page = page.CreateAfter();
+    EXPECT_FALSE(min.IsValid());
+    EXPECT_FALSE(max.IsValid());
+    min = app_sorting->GetMinOrMaxAppLaunchOrdinalsOnPage(
+        empty_page,
+        ChromeAppSorting::MIN_ORDINAL);
+    max = app_sorting->GetMinOrMaxAppLaunchOrdinalsOnPage(
+        empty_page,
+        ChromeAppSorting::MAX_ORDINAL);
+    EXPECT_FALSE(min.IsValid());
+    EXPECT_FALSE(max.IsValid());
+  }
+};
+TEST_F(ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage,
+       ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage) {}
+
+// Make sure that empty pages aren't removed from the integer to ordinal
+// mapping. See http://crbug.com/109802 for details.
+class ChromeAppSortingKeepEmptyStringOrdinalPages
+    : public ChromeAppSortingPreinstalledAppsBase {
+ public:
+  ChromeAppSortingKeepEmptyStringOrdinalPages() {}
+  virtual ~ChromeAppSortingKeepEmptyStringOrdinalPages() {}
+
+  virtual void Initialize() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    syncer::StringOrdinal first_page =
+        syncer::StringOrdinal::CreateInitialOrdinal();
+    app_sorting->SetPageOrdinal(app1_->id(), first_page);
+    EXPECT_EQ(0, app_sorting->PageStringOrdinalAsInteger(first_page));
+
+    last_page_ = first_page.CreateAfter();
+    app_sorting->SetPageOrdinal(app2_->id(), last_page_);
+    EXPECT_EQ(1, app_sorting->PageStringOrdinalAsInteger(last_page_));
+
+    // Move the second app to create an empty page.
+    app_sorting->SetPageOrdinal(app2_->id(), first_page);
+    EXPECT_EQ(0, app_sorting->PageStringOrdinalAsInteger(first_page));
+  }
+  virtual void Verify() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    // Move the second app to a new empty page at the end, skipping over
+    // the current empty page.
+    last_page_ = last_page_.CreateAfter();
+    app_sorting->SetPageOrdinal(app2_->id(), last_page_);
+    EXPECT_EQ(2, app_sorting->PageStringOrdinalAsInteger(last_page_));
+    EXPECT_TRUE(last_page_.Equals(app_sorting->PageIntegerAsStringOrdinal(2)));
+  }
+
+ private:
+  syncer::StringOrdinal last_page_;
+};
+TEST_F(ChromeAppSortingKeepEmptyStringOrdinalPages,
+       ChromeAppSortingKeepEmptyStringOrdinalPages) {}
+
+class ChromeAppSortingMakesFillerOrdinals
+    : public ChromeAppSortingPreinstalledAppsBase {
+ public:
+  ChromeAppSortingMakesFillerOrdinals() {}
+  virtual ~ChromeAppSortingMakesFillerOrdinals() {}
+
+  virtual void Initialize() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    syncer::StringOrdinal first_page =
+        syncer::StringOrdinal::CreateInitialOrdinal();
+    app_sorting->SetPageOrdinal(app1_->id(), first_page);
+    EXPECT_EQ(0, app_sorting->PageStringOrdinalAsInteger(first_page));
+  }
+  virtual void Verify() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    // Because the UI can add an unlimited number of empty pages without an app
+    // on them, this test simulates dropping of an app on the 1st and 4th empty
+    // pages (3rd and 6th pages by index) to ensure we don't crash and that
+    // filler ordinals are created as needed. See: http://crbug.com/122214
+    syncer::StringOrdinal page_three =
+        app_sorting->PageIntegerAsStringOrdinal(2);
+    app_sorting->SetPageOrdinal(app1_->id(), page_three);
+    EXPECT_EQ(2, app_sorting->PageStringOrdinalAsInteger(page_three));
+
+    syncer::StringOrdinal page_six = app_sorting->PageIntegerAsStringOrdinal(5);
+    app_sorting->SetPageOrdinal(app1_->id(), page_six);
+    EXPECT_EQ(5, app_sorting->PageStringOrdinalAsInteger(page_six));
+  }
+};
+TEST_F(ChromeAppSortingMakesFillerOrdinals,
+       ChromeAppSortingMakesFillerOrdinals) {}
+
+class ChromeAppSortingDefaultOrdinalsBase : public ChromeAppSortingTest {
+ public:
+  ChromeAppSortingDefaultOrdinalsBase() {}
+  virtual ~ChromeAppSortingDefaultOrdinalsBase() {}
+
+  virtual void Initialize() OVERRIDE {
+    app_ = CreateApp("app");
+
+    InitDefaultOrdinals();
+    ChromeAppSorting* app_sorting =
+        static_cast<ChromeAppSorting*>(prefs()->app_sorting());
+    ChromeAppSorting::AppOrdinalsMap& sorting_defaults =
+        app_sorting->default_ordinals_;
+    sorting_defaults[app_->id()].page_ordinal = default_page_ordinal_;
+    sorting_defaults[app_->id()].app_launch_ordinal =
+        default_app_launch_ordinal_;
+
+    SetupUserOrdinals();
+    InstallApps();
+  }
+
+ protected:
+  scoped_refptr<Extension> CreateApp(const std::string& name) {
+    DictionaryValue simple_dict;
+    simple_dict.SetString(keys::kVersion, "1.0.0.0");
+    simple_dict.SetString(keys::kName, name);
+    simple_dict.SetString(keys::kApp, "true");
+    simple_dict.SetString(keys::kLaunchLocalPath, "fake.html");
+
+    std::string errors;
+    scoped_refptr<Extension> app = Extension::Create(
+        prefs_.temp_dir().AppendASCII(name), Manifest::EXTERNAL_PREF,
+        simple_dict, Extension::NO_FLAGS, &errors);
+    EXPECT_TRUE(app.get()) << errors;
+    EXPECT_TRUE(Extension::IdIsValid(app->id()));
+    return app;
+  }
+
+  void InitDefaultOrdinals() {
+    default_page_ordinal_ =
+        syncer::StringOrdinal::CreateInitialOrdinal().CreateAfter();
+    default_app_launch_ordinal_ =
+        syncer::StringOrdinal::CreateInitialOrdinal().CreateBefore();
+  }
+
+  virtual void SetupUserOrdinals() {}
+
+  virtual void InstallApps() {
+    prefs()->OnExtensionInstalled(app_.get(),
+                                  Extension::ENABLED,
+                                  false,
+                                  syncer::StringOrdinal());
+  }
+
+  scoped_refptr<Extension> app_;
+  syncer::StringOrdinal default_page_ordinal_;
+  syncer::StringOrdinal default_app_launch_ordinal_;
+};
+
+// Tests that the app gets its default ordinals.
+class ChromeAppSortingDefaultOrdinals
+    : public ChromeAppSortingDefaultOrdinalsBase {
+ public:
+  ChromeAppSortingDefaultOrdinals() {}
+  virtual ~ChromeAppSortingDefaultOrdinals() {}
+
+  virtual void Verify() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(app_->id()).Equals(
+        default_page_ordinal_));
+    EXPECT_TRUE(app_sorting->GetAppLaunchOrdinal(app_->id()).Equals(
+        default_app_launch_ordinal_));
+  }
+};
+TEST_F(ChromeAppSortingDefaultOrdinals,
+       ChromeAppSortingDefaultOrdinals) {}
+
+// Tests that the default page ordinal is overridden by install page ordinal.
+class ChromeAppSortingDefaultOrdinalOverriddenByInstallPage
+    : public ChromeAppSortingDefaultOrdinalsBase {
+ public:
+  ChromeAppSortingDefaultOrdinalOverriddenByInstallPage() {}
+  virtual ~ChromeAppSortingDefaultOrdinalOverriddenByInstallPage() {}
+
+  virtual void Verify() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    EXPECT_FALSE(app_sorting->GetPageOrdinal(app_->id()).Equals(
+        default_page_ordinal_));
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(app_->id()).Equals(install_page_));
+  }
+
+ protected:
+  virtual void InstallApps() OVERRIDE {
+    install_page_ = default_page_ordinal_.CreateAfter();
+    prefs()->OnExtensionInstalled(app_.get(),
+                                  Extension::ENABLED,
+                                  false,
+                                  install_page_);
+  }
+
+ private:
+  syncer::StringOrdinal install_page_;
+};
+TEST_F(ChromeAppSortingDefaultOrdinalOverriddenByInstallPage,
+       ChromeAppSortingDefaultOrdinalOverriddenByInstallPage) {}
+
+// Tests that the default ordinals are overridden by user values.
+class ChromeAppSortingDefaultOrdinalOverriddenByUserValue
+    : public ChromeAppSortingDefaultOrdinalsBase {
+ public:
+  ChromeAppSortingDefaultOrdinalOverriddenByUserValue() {}
+  virtual ~ChromeAppSortingDefaultOrdinalOverriddenByUserValue() {}
+
+  virtual void Verify() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(app_->id()).Equals(
+        user_page_ordinal_));
+    EXPECT_TRUE(app_sorting->GetAppLaunchOrdinal(app_->id()).Equals(
+        user_app_launch_ordinal_));
+  }
+
+ protected:
+  virtual void SetupUserOrdinals() OVERRIDE {
+    user_page_ordinal_ = default_page_ordinal_.CreateAfter();
+    user_app_launch_ordinal_ = default_app_launch_ordinal_.CreateBefore();
+
+    AppSorting* app_sorting = prefs()->app_sorting();
+    app_sorting->SetPageOrdinal(app_->id(), user_page_ordinal_);
+    app_sorting->SetAppLaunchOrdinal(app_->id(), user_app_launch_ordinal_);
+  }
+
+ private:
+  syncer::StringOrdinal user_page_ordinal_;
+  syncer::StringOrdinal user_app_launch_ordinal_;
+};
+TEST_F(ChromeAppSortingDefaultOrdinalOverriddenByUserValue,
+       ChromeAppSortingDefaultOrdinalOverriddenByUserValue) {}
+
+// Tests that the default app launch ordinal is changed to avoid collision.
+class ChromeAppSortingDefaultOrdinalNoCollision
+    : public ChromeAppSortingDefaultOrdinalsBase {
+ public:
+  ChromeAppSortingDefaultOrdinalNoCollision() {}
+  virtual ~ChromeAppSortingDefaultOrdinalNoCollision() {}
+
+  virtual void Verify() OVERRIDE {
+    AppSorting* app_sorting = prefs()->app_sorting();
+
+    // Use the default page.
+    EXPECT_TRUE(app_sorting->GetPageOrdinal(app_->id()).Equals(
+        default_page_ordinal_));
+    // Not using the default app launch ordinal because of the collision.
+    EXPECT_FALSE(app_sorting->GetAppLaunchOrdinal(app_->id()).Equals(
+        default_app_launch_ordinal_));
+  }
+
+ protected:
+  virtual void SetupUserOrdinals() OVERRIDE {
+    other_app_ = prefs_.AddApp("other_app");
+    // Creates a collision.
+    AppSorting* app_sorting = prefs()->app_sorting();
+    app_sorting->SetPageOrdinal(other_app_->id(), default_page_ordinal_);
+    app_sorting->SetAppLaunchOrdinal(other_app_->id(),
+                                     default_app_launch_ordinal_);
+
+    yet_another_app_ = prefs_.AddApp("yet_aother_app");
+    app_sorting->SetPageOrdinal(yet_another_app_->id(), default_page_ordinal_);
+    app_sorting->SetAppLaunchOrdinal(yet_another_app_->id(),
+                                     default_app_launch_ordinal_);
+  }
+
+ private:
+  scoped_refptr<Extension> other_app_;
+  scoped_refptr<Extension> yet_another_app_;
+};
+TEST_F(ChromeAppSortingDefaultOrdinalNoCollision,
+       ChromeAppSortingDefaultOrdinalNoCollision) {}
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/extension_install_ui_browsertest.cc b/chrome/browser/extensions/extension_install_ui_browsertest.cc
index dc93801..72d8069 100644
--- a/chrome/browser/extensions/extension_install_ui_browsertest.cc
+++ b/chrome/browser/extensions/extension_install_ui_browsertest.cc
@@ -8,7 +8,6 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
@@ -24,9 +23,11 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
+#include "extensions/browser/app_sorting.h"
 #include "extensions/common/id_util.h"
 
 using content::WebContents;
+using extensions::AppSorting;
 using extensions::Extension;
 
 class ExtensionInstallUIBrowserTest : public ExtensionBrowserTest {
@@ -225,11 +226,11 @@
   const extensions::Extension* webstore_extension =
       service->GetInstalledExtension(extension_misc::kWebStoreAppId);
   EXPECT_TRUE(webstore_extension);
-  ExtensionSorting* sorting = service->extension_prefs()->extension_sorting();
+  AppSorting* sorting = service->extension_prefs()->app_sorting();
 
   // Register for notifications in the same way as AppLauncherHandler.
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED,
-      content::Source<ExtensionSorting>(sorting));
+      content::Source<AppSorting>(sorting));
   // ExtensionAppItem calls this when an app install starts.
   sorting->EnsureValidOrdinals(app_id, syncer::StringOrdinal());
   // Vefify the app is not actually installed yet.
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index 7649f13..6b32db0 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -14,10 +14,10 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/content_settings/content_settings_store.h"
 #include "chrome/browser/extensions/api/preference/preference_api.h"
+#include "chrome/browser/extensions/chrome_app_sorting.h"
 #include "chrome/browser/extensions/event_router.h"
 #include "chrome/browser/extensions/extension_pref_store.h"
 #include "chrome/browser/extensions/extension_prefs_factory.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/common/chrome_switches.h"
@@ -1225,7 +1225,7 @@
 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id,
                                             const Manifest::Location& location,
                                             bool external_uninstall) {
-  extension_sorting_->ClearOrdinals(extension_id);
+  app_sorting_->ClearOrdinals(extension_id);
 
   // For external extensions, we save a preference reminding ourself not to try
   // and install the extension anymore (except when |external_uninstall| is
@@ -1702,7 +1702,7 @@
   FixMissingPrefs(extension_ids);
   MigratePermissions(extension_ids);
   MigrateDisableReasons(extension_ids);
-  extension_sorting_->Initialize(extension_ids);
+  app_sorting_->Initialize(extension_ids);
 
   PreferenceAPI::InitExtensionControlledPrefs(this, extension_pref_value_map_);
 
@@ -1781,7 +1781,7 @@
     : prefs_(prefs),
       install_directory_(root_dir),
       extension_pref_value_map_(extension_pref_value_map),
-      extension_sorting_(new ExtensionSorting(this)),
+      app_sorting_(new ChromeAppSorting(this)),
       content_settings_store_(new ContentSettingsStore()),
       time_provider_(time_provider.Pass()),
       extensions_disabled_(extensions_disabled) {
@@ -1963,15 +1963,12 @@
   // Clear state that may be registered from a previous install.
   extension_dict->Remove(EventRouter::kRegisteredEvents, NULL);
 
-  // FYI, all code below here races on sudden shutdown because
-  // |extension_dict|, |extension_sorting_|, |extension_pref_value_map_|,
-  // and |content_settings_store_| are updated non-transactionally. This is
-  // probably not fixable without nested transactional updates to pref
-  // dictionaries.
-  if (needs_sort_ordinal) {
-    extension_sorting_->EnsureValidOrdinals(extension_id,
-                                            suggested_page_ordinal);
-  }
+  // FYI, all code below here races on sudden shutdown because |extension_dict|,
+  // |app_sorting_|, |extension_pref_value_map_|, and |content_settings_store_|
+  // are updated non-transactionally. This is probably not fixable without
+  // nested transactional updates to pref dictionaries.
+  if (needs_sort_ordinal)
+    app_sorting_->EnsureValidOrdinals(extension_id, suggested_page_ordinal);
 
   bool is_enabled = false;
   int initial_state;
diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h
index ab895aab..f5e3bc2 100644
--- a/chrome/browser/extensions/extension_prefs.h
+++ b/chrome/browser/extensions/extension_prefs.h
@@ -16,13 +16,13 @@
 #include "base/values.h"
 #include "chrome/browser/extensions/extension_scoped_prefs.h"
 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
+#include "extensions/browser/app_sorting.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/url_pattern_set.h"
 #include "sync/api/string_ordinal.h"
 
 class ExtensionPrefValueMap;
-class ExtensionSorting;
 class PrefService;
 class Profile;
 
@@ -31,6 +31,7 @@
 }
 
 namespace extensions {
+class AppSorting;
 class ContentSettingsStore;
 class ExtensionPrefsUninstallExtension;
 class URLPatternSet;
@@ -493,10 +494,8 @@
   // The underlying PrefService.
   PrefService* pref_service() const { return prefs_; }
 
-  // The underlying ExtensionSorting.
-  ExtensionSorting* extension_sorting() const {
-    return extension_sorting_.get();
-  }
+  // The underlying AppSorting.
+  AppSorting* app_sorting() const { return app_sorting_.get(); }
 
   // Describes the URLs that are able to install extensions. See
   // prefs::kExtensionAllowedInstallSites for more information.
@@ -639,7 +638,7 @@
 
   // Contains all the logic for handling the order for various extension
   // properties.
-  scoped_ptr<ExtensionSorting> extension_sorting_;
+  scoped_ptr<AppSorting> app_sorting_;
 
   scoped_refptr<ContentSettingsStore> content_settings_store_;
 
diff --git a/chrome/browser/extensions/extension_scoped_prefs.h b/chrome/browser/extensions/extension_scoped_prefs.h
index 6917e5c..75b27cc 100644
--- a/chrome/browser/extensions/extension_scoped_prefs.h
+++ b/chrome/browser/extensions/extension_scoped_prefs.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SCOPED_PREFS_H_
 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_SCOPED_PREFS_H_
 
+namespace extensions {
+
 class ExtensionScopedPrefs {
  public:
   ExtensionScopedPrefs() {}
@@ -49,4 +51,6 @@
   virtual bool HasPrefForExtension(const std::string& extension_id) const = 0;
 };
 
+}  // namespace extensions
+
 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_SCOPED_PREFS_H_
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 2671bf9..f9dbb59 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -44,7 +44,6 @@
 #include "chrome/browser/extensions/extension_error_ui.h"
 #include "chrome/browser/extensions/extension_host.h"
 #include "chrome/browser/extensions/extension_install_ui.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/extensions/extension_special_storage_policy.h"
 #include "chrome/browser/extensions/extension_sync_service.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -88,6 +87,7 @@
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/url_data_source.h"
+#include "extensions/browser/app_sorting.h"
 #include "extensions/browser/process_manager.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/error_utils.h"
@@ -392,8 +392,8 @@
         this, profile_, &external_extension_providers_);
   }
 
-  // Set this as the ExtensionService for extension sorting to ensure it
-  // cause syncs if required.
+  // Set this as the ExtensionService for app sorting to ensure it causes syncs
+  // if required.
   is_first_run_ = !extension_prefs_->SetAlertSystemFirstRun();
 
 #if defined(ENABLE_EXTENSIONS)
@@ -1262,7 +1262,7 @@
     const std::string& moved_extension_id,
     const std::string& predecessor_extension_id,
     const std::string& successor_extension_id) {
-  extension_prefs_->extension_sorting()->OnExtensionMoved(
+  extension_prefs_->app_sorting()->OnExtensionMoved(
       moved_extension_id,
       predecessor_extension_id,
       successor_extension_id);
@@ -1755,10 +1755,9 @@
     // so we must ensure they have valid ordinals.
     if (extension->RequiresSortOrdinal()) {
       if (!extension->ShouldDisplayInNewTabPage()) {
-        extension_prefs_->extension_sorting()->MarkExtensionAsHidden(
-            extension->id());
+        extension_prefs_->app_sorting()->MarkExtensionAsHidden(extension->id());
       }
-      extension_prefs_->extension_sorting()->EnsureValidOrdinals(
+      extension_prefs_->app_sorting()->EnsureValidOrdinals(
           extension->id(), syncer::StringOrdinal());
     }
 
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 78fad9e..b947115 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -33,6 +33,7 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/app_sync_data.h"
 #include "chrome/browser/extensions/blacklist.h"
+#include "chrome/browser/extensions/chrome_app_sorting.h"
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/default_apps.h"
@@ -41,7 +42,6 @@
 #include "chrome/browser/extensions/extension_error_ui.h"
 #include "chrome/browser/extensions/extension_notification_observer.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/extensions/extension_special_storage_policy.h"
 #include "chrome/browser/extensions/extension_sync_data.h"
 #include "chrome/browser/extensions/extension_system.h"
@@ -145,6 +145,7 @@
 using content::PluginService;
 using extensions::APIPermission;
 using extensions::APIPermissionSet;
+using extensions::AppSorting;
 using extensions::Blacklist;
 using extensions::CrxInstaller;
 using extensions::Extension;
@@ -2657,7 +2658,7 @@
 // Verifies that the NTP page and launch ordinals are kept when updating apps.
 TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
   InitializeEmptyExtensionService();
-  ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
+  AppSorting* sorting = service_->extension_prefs()->app_sorting();
   base::FilePath extensions_path = data_dir_.AppendASCII("app_update");
 
   // First install v1 of a hosted app.
@@ -2693,7 +2694,7 @@
       IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
   service_->Init();
 
-  ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
+  AppSorting* sorting = service_->extension_prefs()->app_sorting();
   EXPECT_TRUE(
       sorting->GetPageOrdinal(extension_misc::kWebStoreAppId).IsValid());
   EXPECT_TRUE(
@@ -5591,7 +5592,7 @@
     EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
   }
 
-  ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
+  AppSorting* sorting = service_->extension_prefs()->app_sorting();
   sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
   {
     syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
diff --git a/chrome/browser/extensions/extension_sorting.h b/chrome/browser/extensions/extension_sorting.h
deleted file mode 100644
index 5c02d4aa..0000000
--- a/chrome/browser/extensions/extension_sorting.h
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SORTING_H_
-#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SORTING_H_
-
-#include <map>
-#include <set>
-#include <string>
-
-#include "base/basictypes.h"
-#include "chrome/browser/extensions/extension_prefs.h"
-#include "extensions/common/extension.h"
-#include "sync/api/string_ordinal.h"
-
-class ExtensionScopedPrefs;
-class ExtensionSyncService;
-class PrefService;
-
-class ExtensionSorting {
- public:
-  explicit ExtensionSorting(ExtensionScopedPrefs* extension_scoped_prefs);
-  ~ExtensionSorting();
-
-  // Set up the ExtensionSyncService to inform of changes that require syncing.
-  void SetExtensionSyncService(ExtensionSyncService* extension_sync_service);
-
-  // Properly initialize ExtensionSorting internal values that require
-  // |extension_ids|.
-  void Initialize(
-      const extensions::ExtensionIdList& extension_ids);
-
-  // Resolves any conflicts the might be created as a result of syncing that
-  // results in two icons having the same page and app launch ordinal. After
-  // this is called it is guaranteed that there are no collisions of NTP icons.
-  void FixNTPOrdinalCollisions();
-
-  // This ensures that the extension has valid ordinals, and if it doesn't then
-  // properly initialize them. |suggested_page| will be used if it is valid and
-  // the extension has no valid user-set page ordinal.
-  void EnsureValidOrdinals(const std::string& extension_id,
-                           const syncer::StringOrdinal& suggested_page);
-
-  // Updates the app launcher value for the moved extension so that it is now
-  // located after the given predecessor and before the successor.
-  // Empty strings are used to indicate no successor or predecessor.
-  void OnExtensionMoved(const std::string& moved_extension_id,
-                        const std::string& predecessor_extension_id,
-                        const std::string& successor_extension_id);
-
-  // Get the application launch ordinal for an app with |extension_id|. This
-  // determines the order in which the app appears on the page it's on in the
-  // New Tab Page (Note that you can compare app launch ordinals only if the
-  // apps are on the same page). A string value close to |a*| generally
-  // indicates top left. If the extension has no launch ordinal, an invalid
-  // StringOrdinal is returned.
-  syncer::StringOrdinal GetAppLaunchOrdinal(
-      const std::string& extension_id) const;
-
-  // Sets a specific launch ordinal for an app with |extension_id|.
-  void SetAppLaunchOrdinal(const std::string& extension_id,
-                           const syncer::StringOrdinal& new_app_launch_ordinal);
-
-  // Returns a StringOrdinal that is lower than any app launch ordinal for the
-  // given page.
-  syncer::StringOrdinal CreateFirstAppLaunchOrdinal(
-      const syncer::StringOrdinal& page_ordinal) const;
-
-  // Returns a StringOrdinal that is higher than any app launch ordinal for the
-  // given page.
-  syncer::StringOrdinal CreateNextAppLaunchOrdinal(
-      const syncer::StringOrdinal& page_ordinal) const;
-
-  // Returns a StringOrdinal that is lower than any existing page ordinal.
-  syncer::StringOrdinal CreateFirstAppPageOrdinal() const;
-
-  // Gets the page a new app should install to, which is the earliest non-full
-  // page.  The returned ordinal may correspond to a page that doesn't yet exist
-  // if all pages are full.
-  syncer::StringOrdinal GetNaturalAppPageOrdinal() const;
-
-  // Get the page ordinal for an app with |extension_id|. This determines
-  // which page an app will appear on in page-based NTPs.  If the app has no
-  // page specified, an invalid StringOrdinal is returned.
-  syncer::StringOrdinal GetPageOrdinal(const std::string& extension_id) const;
-
-  // Sets a specific page ordinal for an app with |extension_id|.
-  void SetPageOrdinal(const std::string& extension_id,
-                      const syncer::StringOrdinal& new_page_ordinal);
-
-  // Removes the ordinal values for an app.
-  void ClearOrdinals(const std::string& extension_id);
-
-  // Convert the page StringOrdinal value to its integer equivalent. This takes
-  // O(# of apps) worst-case.
-  int PageStringOrdinalAsInteger(
-      const syncer::StringOrdinal& page_ordinal) const;
-
-  // Converts the page index integer to its StringOrdinal equivalent. This takes
-  // O(# of apps) worst-case.
-  syncer::StringOrdinal PageIntegerAsStringOrdinal(size_t page_index);
-
-  // Hidden extensions don't appear in the new tab page.
-  void MarkExtensionAsHidden(const std::string& extension_id);
-
- private:
-  // The StringOrdinal is the app launch ordinal and the string is the extension
-  // id.
-  typedef std::multimap<
-      syncer::StringOrdinal, std::string,
-    syncer::StringOrdinal::LessThanFn> AppLaunchOrdinalMap;
-  // The StringOrdinal is the page ordinal and the AppLaunchOrdinalMap is the
-  // contents of that page.
-  typedef std::map<
-      syncer::StringOrdinal, AppLaunchOrdinalMap,
-    syncer::StringOrdinal::LessThanFn> PageOrdinalMap;
-
-  // Unit tests.
-  friend class ExtensionSortingDefaultOrdinalsBase;
-  friend class ExtensionSortingGetMinOrMaxAppLaunchOrdinalsOnPage;
-  friend class ExtensionSortingInitializeWithNoApps;
-  friend class ExtensionSortingPageOrdinalMapping;
-
-  // An enum used by GetMinOrMaxAppLaunchOrdinalsOnPage to specify which
-  // value should be returned.
-  enum AppLaunchOrdinalReturn {MIN_ORDINAL, MAX_ORDINAL};
-
-  // Maps an app id to its ordinals.
-  struct AppOrdinals {
-    AppOrdinals();
-    ~AppOrdinals();
-
-    syncer::StringOrdinal page_ordinal;
-    syncer::StringOrdinal app_launch_ordinal;
-  };
-  typedef std::map<std::string, AppOrdinals> AppOrdinalsMap;
-
-  // This function returns the lowest ordinal on |page_ordinal| if
-  // |return_value| == AppLaunchOrdinalReturn::MIN_ORDINAL, otherwise it returns
-  // the largest ordinal on |page_ordinal|. If there are no apps on the page
-  // then an invalid StringOrdinal is returned. It is an error to call this
-  // function with an invalid |page_ordinal|.
-  syncer::StringOrdinal GetMinOrMaxAppLaunchOrdinalsOnPage(
-      const syncer::StringOrdinal& page_ordinal,
-      AppLaunchOrdinalReturn return_type) const;
-
-  // Initialize the |page_ordinal_map_| with the page ordinals used by the
-  // given extensions.
-  void InitializePageOrdinalMap(
-      const extensions::ExtensionIdList& extension_ids);
-
-  // Migrates the app launcher and page index values.
-  void MigrateAppIndex(
-      const extensions::ExtensionIdList& extension_ids);
-
-  // Called to add a new mapping value for |extension_id| with a page ordinal
-  // of |page_ordinal| and a app launch ordinal of |app_launch_ordinal|. This
-  // works with valid and invalid StringOrdinals.
-  void AddOrdinalMapping(const std::string& extension_id,
-                         const syncer::StringOrdinal& page_ordinal,
-                         const syncer::StringOrdinal& app_launch_ordinal);
-
-  // Ensures |ntp_ordinal_map_| is of |minimum_size| number of entries.
-  void CreateOrdinalsIfNecessary(size_t minimum_size);
-
-  // Removes the mapping for |extension_id| with a page ordinal of
-  // |page_ordinal| and a app launch ordinal of |app_launch_ordinal|. If there
-  // is not matching map, nothing happens. This works with valid and invalid
-  // StringOrdinals.
-  void RemoveOrdinalMapping(const std::string& extension_id,
-                            const syncer::StringOrdinal& page_ordinal,
-                            const syncer::StringOrdinal& app_launch_ordinal);
-
-  // Syncs the extension if needed. It is an error to call this if the
-  // extension is not an application.
-  void SyncIfNeeded(const std::string& extension_id);
-
-  // Creates the default ordinals.
-  void CreateDefaultOrdinals();
-
-  // Gets the default ordinals for |extension_id|. Returns false if no default
-  // ordinals for |extension_id| is defined. Otherwise, returns true and
-  // ordinals is updated with corresponding ordinals.
-  bool GetDefaultOrdinals(const std::string& extension_id,
-                          syncer::StringOrdinal* page_ordinal,
-                          syncer::StringOrdinal* app_launch_ordinal);
-
-  // Returns |app_launch_ordinal| if it has no collision in the page specified
-  // by |page_ordinal|. Otherwise, returns an ordinal after |app_launch_ordinal|
-  // that has no conflict.
-  syncer::StringOrdinal ResolveCollision(
-      const syncer::StringOrdinal& page_ordinal,
-      const syncer::StringOrdinal& app_launch_ordinal) const;
-
-  // Returns the number of items in |m| visible on the new tab page.
-  size_t CountItemsVisibleOnNtp(const AppLaunchOrdinalMap& m) const;
-
-  ExtensionScopedPrefs* extension_scoped_prefs_;  // Weak, owns this instance.
-  ExtensionSyncService* extension_sync_service_;  // Weak.
-
-  // A map of all the StringOrdinal page ordinals mapping to the collections of
-  // app launch ordinals that exist on that page. This is used for mapping
-  // StringOrdinals to their Integer equivalent as well as quick lookup of the
-  // any collision of on the NTP (icons with the same page and same app launch
-  // ordinals). The possiblity of collisions means that a multimap must be used
-  // (although the collisions must all be resolved once all the syncing is
-  // done).
-  PageOrdinalMap ntp_ordinal_map_;
-
-  // Defines the default ordinals.
-  AppOrdinalsMap default_ordinals_;
-
-  // Used to construct the default ordinals once when needed instead of on
-  // construction when the app order may not have been determined.
-  bool default_ordinals_created_;
-
-  // The set of extensions that don't appear in the new tab page.
-  std::set<std::string> ntp_hidden_extensions_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExtensionSorting);
-};
-
-#endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_SORTING_H_
diff --git a/chrome/browser/extensions/extension_sorting_unittest.cc b/chrome/browser/extensions/extension_sorting_unittest.cc
deleted file mode 100644
index 65886899..0000000
--- a/chrome/browser/extensions/extension_sorting_unittest.cc
+++ /dev/null
@@ -1,975 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/extension_sorting.h"
-
-#include <map>
-
-#include "chrome/browser/extensions/extension_prefs_unittest.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "extensions/common/manifest_constants.h"
-#include "sync/api/string_ordinal.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using extensions::Extension;
-using extensions::Manifest;
-
-namespace keys = extensions::manifest_keys;
-
-class ExtensionSortingTest : public extensions::ExtensionPrefsTest {
- protected:
-  ExtensionSorting* extension_sorting() {
-    return prefs()->extension_sorting();
-  }
-};
-
-class ExtensionSortingAppLocation : public ExtensionSortingTest {
- public:
-  virtual void Initialize() OVERRIDE {
-    extension_ = prefs_.AddExtension("not_an_app");
-    // Non-apps should not have any app launch ordinal or page ordinal.
-    prefs()->OnExtensionInstalled(extension_.get(),
-                                  Extension::ENABLED,
-                                  false,
-                                  syncer::StringOrdinal());
-  }
-
-  virtual void Verify() OVERRIDE {
-    EXPECT_FALSE(
-        extension_sorting()->GetAppLaunchOrdinal(extension_->id()).IsValid());
-    EXPECT_FALSE(
-        extension_sorting()->GetPageOrdinal(extension_->id()).IsValid());
-  }
-
- private:
-  scoped_refptr<Extension> extension_;
-};
-TEST_F(ExtensionSortingAppLocation, ExtensionSortingAppLocation) {}
-
-class ExtensionSortingAppLaunchOrdinal : public ExtensionSortingTest {
- public:
-  virtual void Initialize() OVERRIDE {
-    // No extensions yet.
-    syncer::StringOrdinal page = syncer::StringOrdinal::CreateInitialOrdinal();
-    EXPECT_TRUE(syncer::StringOrdinal::CreateInitialOrdinal().Equals(
-        extension_sorting()->CreateNextAppLaunchOrdinal(page)));
-
-    extension_ = prefs_.AddApp("on_extension_installed");
-    EXPECT_FALSE(prefs()->IsExtensionDisabled(extension_->id()));
-    prefs()->OnExtensionInstalled(extension_.get(),
-                                  Extension::ENABLED,
-                                  false,
-                                  syncer::StringOrdinal());
-  }
-
-  virtual void Verify() OVERRIDE {
-    syncer::StringOrdinal launch_ordinal =
-        extension_sorting()->GetAppLaunchOrdinal(extension_->id());
-    syncer::StringOrdinal page_ordinal =
-        syncer::StringOrdinal::CreateInitialOrdinal();
-
-    // Extension should have been assigned a valid StringOrdinal.
-    EXPECT_TRUE(launch_ordinal.IsValid());
-    EXPECT_TRUE(launch_ordinal.LessThan(
-        extension_sorting()->CreateNextAppLaunchOrdinal(page_ordinal)));
-    // Set a new launch ordinal of and verify it comes after.
-    extension_sorting()->SetAppLaunchOrdinal(
-        extension_->id(),
-        extension_sorting()->CreateNextAppLaunchOrdinal(page_ordinal));
-    syncer::StringOrdinal new_launch_ordinal =
-        extension_sorting()->GetAppLaunchOrdinal(extension_->id());
-    EXPECT_TRUE(launch_ordinal.LessThan(new_launch_ordinal));
-
-    // This extension doesn't exist, so it should return an invalid
-    // StringOrdinal.
-    syncer::StringOrdinal invalid_app_launch_ordinal =
-        extension_sorting()->GetAppLaunchOrdinal("foo");
-    EXPECT_FALSE(invalid_app_launch_ordinal.IsValid());
-    EXPECT_EQ(-1, extension_sorting()->PageStringOrdinalAsInteger(
-        invalid_app_launch_ordinal));
-
-    // The second page doesn't have any apps so its next launch ordinal should
-    // be the first launch ordinal.
-    syncer::StringOrdinal next_page = page_ordinal.CreateAfter();
-    syncer::StringOrdinal next_page_app_launch_ordinal =
-        extension_sorting()->CreateNextAppLaunchOrdinal(next_page);
-    EXPECT_TRUE(next_page_app_launch_ordinal.Equals(
-        extension_sorting()->CreateFirstAppLaunchOrdinal(next_page)));
-  }
-
- private:
-  scoped_refptr<Extension> extension_;
-};
-TEST_F(ExtensionSortingAppLaunchOrdinal, ExtensionSortingAppLaunchOrdinal) {}
-
-class ExtensionSortingPageOrdinal : public ExtensionSortingTest {
- public:
-  virtual void Initialize() OVERRIDE {
-    extension_ = prefs_.AddApp("page_ordinal");
-    // Install with a page preference.
-    first_page_ = syncer::StringOrdinal::CreateInitialOrdinal();
-    prefs()->OnExtensionInstalled(extension_.get(),
-                                  Extension::ENABLED,
-                                  false,
-                                  first_page_);
-    EXPECT_TRUE(first_page_.Equals(
-        extension_sorting()->GetPageOrdinal(extension_->id())));
-    EXPECT_EQ(0, extension_sorting()->PageStringOrdinalAsInteger(first_page_));
-
-    scoped_refptr<Extension> extension2 = prefs_.AddApp("page_ordinal_2");
-    // Install without any page preference.
-    prefs()->OnExtensionInstalled(extension2.get(),
-                                  Extension::ENABLED,
-                                  false,
-                                  syncer::StringOrdinal());
-    EXPECT_TRUE(first_page_.Equals(
-        extension_sorting()->GetPageOrdinal(extension2->id())));
-  }
-  virtual void Verify() OVERRIDE {
-    // Set the page ordinal.
-    syncer::StringOrdinal new_page = first_page_.CreateAfter();
-    extension_sorting()->SetPageOrdinal(extension_->id(), new_page);
-    // Verify the page ordinal.
-    EXPECT_TRUE(
-        new_page.Equals(extension_sorting()->GetPageOrdinal(extension_->id())));
-    EXPECT_EQ(1, extension_sorting()->PageStringOrdinalAsInteger(new_page));
-
-    // This extension doesn't exist, so it should return an invalid
-    // StringOrdinal.
-    EXPECT_FALSE(extension_sorting()->GetPageOrdinal("foo").IsValid());
-  }
-
- private:
-  syncer::StringOrdinal first_page_;
-  scoped_refptr<Extension> extension_;
-};
-TEST_F(ExtensionSortingPageOrdinal, ExtensionSortingPageOrdinal) {}
-
-// Ensure that ExtensionSorting is able to properly initialize off a set
-// of old page and app launch indices and properly convert them.
-class ExtensionSortingInitialize
-    : public extensions::PrefsPrepopulatedTestBase {
- public:
-  ExtensionSortingInitialize() {}
-  virtual ~ExtensionSortingInitialize() {}
-
-  virtual void Initialize() OVERRIDE {
-    // A preference determining the order of which the apps appear on the NTP.
-    const char kPrefAppLaunchIndexDeprecated[] = "app_launcher_index";
-    // A preference determining the page on which an app appears in the NTP.
-    const char kPrefPageIndexDeprecated[] = "page_index";
-
-    // Setup the deprecated preferences.
-    ExtensionScopedPrefs* scoped_prefs =
-        static_cast<ExtensionScopedPrefs*>(prefs());
-    scoped_prefs->UpdateExtensionPref(extension1()->id(),
-                                      kPrefAppLaunchIndexDeprecated,
-                                      new base::FundamentalValue(0));
-    scoped_prefs->UpdateExtensionPref(extension1()->id(),
-                                      kPrefPageIndexDeprecated,
-                                      new base::FundamentalValue(0));
-
-    scoped_prefs->UpdateExtensionPref(extension2()->id(),
-                                      kPrefAppLaunchIndexDeprecated,
-                                      new base::FundamentalValue(1));
-    scoped_prefs->UpdateExtensionPref(extension2()->id(),
-                                      kPrefPageIndexDeprecated,
-                                      new base::FundamentalValue(0));
-
-    scoped_prefs->UpdateExtensionPref(extension3()->id(),
-                                      kPrefAppLaunchIndexDeprecated,
-                                      new base::FundamentalValue(0));
-    scoped_prefs->UpdateExtensionPref(extension3()->id(),
-                                      kPrefPageIndexDeprecated,
-                                      new base::FundamentalValue(1));
-
-    // We insert the ids in reserve order so that we have to deal with the
-    // element on the 2nd page before the 1st page is seen.
-    extensions::ExtensionIdList ids;
-    ids.push_back(extension3()->id());
-    ids.push_back(extension2()->id());
-    ids.push_back(extension1()->id());
-
-    prefs()->extension_sorting()->Initialize(ids);
-  }
-  virtual void Verify() OVERRIDE {
-    syncer::StringOrdinal first_ordinal =
-        syncer::StringOrdinal::CreateInitialOrdinal();
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    EXPECT_TRUE(first_ordinal.Equals(
-        extension_sorting->GetAppLaunchOrdinal(extension1()->id())));
-    EXPECT_TRUE(first_ordinal.LessThan(
-        extension_sorting->GetAppLaunchOrdinal(extension2()->id())));
-    EXPECT_TRUE(first_ordinal.Equals(
-        extension_sorting->GetAppLaunchOrdinal(extension3()->id())));
-
-    EXPECT_TRUE(first_ordinal.Equals(
-        extension_sorting->GetPageOrdinal(extension1()->id())));
-    EXPECT_TRUE(first_ordinal.Equals(
-        extension_sorting->GetPageOrdinal(extension2()->id())));
-    EXPECT_TRUE(first_ordinal.LessThan(
-        extension_sorting->GetPageOrdinal(extension3()->id())));
-  }
-};
-TEST_F(ExtensionSortingInitialize, ExtensionSortingInitialize) {}
-
-// Make sure that initialization still works when no extensions are present
-// (i.e. make sure that the web store icon is still loaded into the map).
-class ExtensionSortingInitializeWithNoApps
-    : public extensions::PrefsPrepopulatedTestBase {
- public:
-  ExtensionSortingInitializeWithNoApps() {}
-  virtual ~ExtensionSortingInitializeWithNoApps() {}
-
-  virtual void Initialize() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    // Make sure that the web store has valid ordinals.
-    syncer::StringOrdinal initial_ordinal =
-        syncer::StringOrdinal::CreateInitialOrdinal();
-    extension_sorting->SetPageOrdinal(extension_misc::kWebStoreAppId,
-                                      initial_ordinal);
-    extension_sorting->SetAppLaunchOrdinal(extension_misc::kWebStoreAppId,
-                                           initial_ordinal);
-
-    extensions::ExtensionIdList ids;
-    extension_sorting->Initialize(ids);
-  }
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    syncer::StringOrdinal page =
-        extension_sorting->GetPageOrdinal(extension_misc::kWebStoreAppId);
-    EXPECT_TRUE(page.IsValid());
-
-    ExtensionSorting::PageOrdinalMap::iterator page_it =
-        extension_sorting->ntp_ordinal_map_.find(page);
-    EXPECT_TRUE(page_it != extension_sorting->ntp_ordinal_map_.end());
-
-    syncer::StringOrdinal app_launch =
-        extension_sorting->GetPageOrdinal(extension_misc::kWebStoreAppId);
-    EXPECT_TRUE(app_launch.IsValid());
-
-    ExtensionSorting::AppLaunchOrdinalMap::iterator app_launch_it =
-        page_it->second.find(app_launch);
-    EXPECT_TRUE(app_launch_it != page_it->second.end());
-  }
-};
-TEST_F(ExtensionSortingInitializeWithNoApps,
-       ExtensionSortingInitializeWithNoApps) {}
-
-// Tests the application index to ordinal migration code for values that
-// shouldn't be converted. This should be removed when the migrate code
-// is taken out.
-// http://crbug.com/107376
-class ExtensionSortingMigrateAppIndexInvalid
-    : public extensions::PrefsPrepopulatedTestBase {
- public:
-  ExtensionSortingMigrateAppIndexInvalid() {}
-  virtual ~ExtensionSortingMigrateAppIndexInvalid() {}
-
-  virtual void Initialize() OVERRIDE {
-    // A preference determining the order of which the apps appear on the NTP.
-    const char kPrefAppLaunchIndexDeprecated[] = "app_launcher_index";
-    // A preference determining the page on which an app appears in the NTP.
-    const char kPrefPageIndexDeprecated[] = "page_index";
-
-    // Setup the deprecated preference.
-    ExtensionScopedPrefs* scoped_prefs =
-        static_cast<ExtensionScopedPrefs*>(prefs());
-    scoped_prefs->UpdateExtensionPref(extension1()->id(),
-                                      kPrefAppLaunchIndexDeprecated,
-                                      new base::FundamentalValue(0));
-    scoped_prefs->UpdateExtensionPref(extension1()->id(),
-                                      kPrefPageIndexDeprecated,
-                                      new base::FundamentalValue(-1));
-
-    extensions::ExtensionIdList ids;
-    ids.push_back(extension1()->id());
-
-    prefs()->extension_sorting()->Initialize(ids);
-  }
-  virtual void Verify() OVERRIDE {
-    // Make sure that the invalid page_index wasn't converted over.
-    EXPECT_FALSE(prefs()->extension_sorting()->GetAppLaunchOrdinal(
-        extension1()->id()).IsValid());
-  }
-};
-TEST_F(ExtensionSortingMigrateAppIndexInvalid,
-       ExtensionSortingMigrateAppIndexInvalid) {}
-
-class ExtensionSortingFixNTPCollisionsAllCollide
-    : public extensions::PrefsPrepopulatedTestBase {
- public:
-  ExtensionSortingFixNTPCollisionsAllCollide() {}
-  virtual ~ExtensionSortingFixNTPCollisionsAllCollide() {}
-
-  virtual void Initialize() OVERRIDE {
-    repeated_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();
-
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    extension_sorting->SetAppLaunchOrdinal(extension1()->id(),
-                                           repeated_ordinal_);
-    extension_sorting->SetPageOrdinal(extension1()->id(), repeated_ordinal_);
-
-    extension_sorting->SetAppLaunchOrdinal(extension2()->id(),
-                                           repeated_ordinal_);
-    extension_sorting->SetPageOrdinal(extension2()->id(), repeated_ordinal_);
-
-    extension_sorting->SetAppLaunchOrdinal(extension3()->id(),
-                                           repeated_ordinal_);
-    extension_sorting->SetPageOrdinal(extension3()->id(), repeated_ordinal_);
-
-    extension_sorting->FixNTPOrdinalCollisions();
-  }
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-    syncer::StringOrdinal extension1_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension1()->id());
-    syncer::StringOrdinal extension2_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension2()->id());
-    syncer::StringOrdinal extension3_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension3()->id());
-
-    // The overlapping extensions should have be adjusted so that they are
-    // sorted by their id.
-    EXPECT_EQ(extension1()->id() < extension2()->id(),
-              extension1_app_launch.LessThan(extension2_app_launch));
-    EXPECT_EQ(extension1()->id() < extension3()->id(),
-              extension1_app_launch.LessThan(extension3_app_launch));
-    EXPECT_EQ(extension2()->id() < extension3()->id(),
-              extension2_app_launch.LessThan(extension3_app_launch));
-
-    // The page ordinal should be unchanged.
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension1()->id()).Equals(
-        repeated_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension2()->id()).Equals(
-        repeated_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension3()->id()).Equals(
-        repeated_ordinal_));
-  }
-
- private:
-  syncer::StringOrdinal repeated_ordinal_;
-};
-TEST_F(ExtensionSortingFixNTPCollisionsAllCollide,
-       ExtensionSortingFixNTPCollisionsAllCollide) {}
-
-class ExtensionSortingFixNTPCollisionsSomeCollideAtStart
-    : public extensions::PrefsPrepopulatedTestBase {
- public:
-  ExtensionSortingFixNTPCollisionsSomeCollideAtStart() {}
-  virtual ~ExtensionSortingFixNTPCollisionsSomeCollideAtStart() {}
-
-  virtual void Initialize() OVERRIDE {
-    first_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();
-    syncer::StringOrdinal second_ordinal = first_ordinal_.CreateAfter();
-
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    // Have the first two extension in the same position, with a third
-    // (non-colliding) extension after.
-
-    extension_sorting->SetAppLaunchOrdinal(extension1()->id(), first_ordinal_);
-    extension_sorting->SetPageOrdinal(extension1()->id(), first_ordinal_);
-
-    extension_sorting->SetAppLaunchOrdinal(extension2()->id(), first_ordinal_);
-    extension_sorting->SetPageOrdinal(extension2()->id(), first_ordinal_);
-
-    extension_sorting->SetAppLaunchOrdinal(extension3()->id(), second_ordinal);
-    extension_sorting->SetPageOrdinal(extension3()->id(), first_ordinal_);
-
-    extension_sorting->FixNTPOrdinalCollisions();
-  }
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-    syncer::StringOrdinal extension1_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension1()->id());
-    syncer::StringOrdinal extension2_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension2()->id());
-    syncer::StringOrdinal extension3_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension3()->id());
-
-    // The overlapping extensions should have be adjusted so that they are
-    // sorted by their id, but they both should be before ext3, which wasn't
-    // overlapping.
-    EXPECT_EQ(extension1()->id() < extension2()->id(),
-              extension1_app_launch.LessThan(extension2_app_launch));
-    EXPECT_TRUE(extension1_app_launch.LessThan(extension3_app_launch));
-    EXPECT_TRUE(extension2_app_launch.LessThan(extension3_app_launch));
-
-    // The page ordinal should be unchanged.
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension1()->id()).Equals(
-        first_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension2()->id()).Equals(
-        first_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension3()->id()).Equals(
-        first_ordinal_));
-  }
-
- private:
-  syncer::StringOrdinal first_ordinal_;
-};
-TEST_F(ExtensionSortingFixNTPCollisionsSomeCollideAtStart,
-       ExtensionSortingFixNTPCollisionsSomeCollideAtStart) {}
-
-class ExtensionSortingFixNTPCollisionsSomeCollideAtEnd
-    : public extensions::PrefsPrepopulatedTestBase {
- public:
-  ExtensionSortingFixNTPCollisionsSomeCollideAtEnd() {}
-  virtual ~ExtensionSortingFixNTPCollisionsSomeCollideAtEnd() {}
-
-  virtual void Initialize() OVERRIDE {
-    first_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();
-    syncer::StringOrdinal second_ordinal = first_ordinal_.CreateAfter();
-
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    // Have the first extension in a non-colliding position, followed by two
-    // two extension in the same position.
-
-    extension_sorting->SetAppLaunchOrdinal(extension1()->id(), first_ordinal_);
-    extension_sorting->SetPageOrdinal(extension1()->id(), first_ordinal_);
-
-    extension_sorting->SetAppLaunchOrdinal(extension2()->id(), second_ordinal);
-    extension_sorting->SetPageOrdinal(extension2()->id(), first_ordinal_);
-
-    extension_sorting->SetAppLaunchOrdinal(extension3()->id(), second_ordinal);
-    extension_sorting->SetPageOrdinal(extension3()->id(), first_ordinal_);
-
-    extension_sorting->FixNTPOrdinalCollisions();
-  }
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-    syncer::StringOrdinal extension1_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension1()->id());
-    syncer::StringOrdinal extension2_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension2()->id());
-    syncer::StringOrdinal extension3_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension3()->id());
-
-    // The overlapping extensions should have be adjusted so that they are
-    // sorted by their id, but they both should be after ext1, which wasn't
-    // overlapping.
-    EXPECT_TRUE(extension1_app_launch.LessThan(extension2_app_launch));
-    EXPECT_TRUE(extension1_app_launch.LessThan(extension3_app_launch));
-    EXPECT_EQ(extension2()->id() < extension3()->id(),
-              extension2_app_launch.LessThan(extension3_app_launch));
-
-    // The page ordinal should be unchanged.
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension1()->id()).Equals(
-        first_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension2()->id()).Equals(
-        first_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension3()->id()).Equals(
-        first_ordinal_));
-  }
-
- private:
-  syncer::StringOrdinal first_ordinal_;
-};
-TEST_F(ExtensionSortingFixNTPCollisionsSomeCollideAtEnd,
-       ExtensionSortingFixNTPCollisionsSomeCollideAtEnd) {}
-
-class ExtensionSortingFixNTPCollisionsTwoCollisions
-    : public extensions::PrefsPrepopulatedTestBase {
- public:
-  ExtensionSortingFixNTPCollisionsTwoCollisions() {}
-  virtual ~ExtensionSortingFixNTPCollisionsTwoCollisions() {}
-
-  virtual void Initialize() OVERRIDE {
-    first_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();
-    syncer::StringOrdinal second_ordinal = first_ordinal_.CreateAfter();
-
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    // Have two extensions colliding, followed by two more colliding extensions.
-    extension_sorting->SetAppLaunchOrdinal(extension1()->id(), first_ordinal_);
-    extension_sorting->SetPageOrdinal(extension1()->id(), first_ordinal_);
-
-    extension_sorting->SetAppLaunchOrdinal(extension2()->id(), first_ordinal_);
-    extension_sorting->SetPageOrdinal(extension2()->id(), first_ordinal_);
-
-    extension_sorting->SetAppLaunchOrdinal(extension3()->id(), second_ordinal);
-    extension_sorting->SetPageOrdinal(extension3()->id(), first_ordinal_);
-
-    extension_sorting->SetAppLaunchOrdinal(extension4()->id(), second_ordinal);
-    extension_sorting->SetPageOrdinal(extension4()->id(), first_ordinal_);
-
-    extension_sorting->FixNTPOrdinalCollisions();
-  }
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-    syncer::StringOrdinal extension1_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension1()->id());
-    syncer::StringOrdinal extension2_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension2()->id());
-    syncer::StringOrdinal extension3_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension3()->id());
-    syncer::StringOrdinal extension4_app_launch =
-        extension_sorting->GetAppLaunchOrdinal(extension4()->id());
-
-    // The overlapping extensions should have be adjusted so that they are
-    // sorted by their id, with |ext1| and |ext2| appearing before |ext3| and
-    // |ext4|.
-    EXPECT_TRUE(extension1_app_launch.LessThan(extension3_app_launch));
-    EXPECT_TRUE(extension1_app_launch.LessThan(extension4_app_launch));
-    EXPECT_TRUE(extension2_app_launch.LessThan(extension3_app_launch));
-    EXPECT_TRUE(extension2_app_launch.LessThan(extension4_app_launch));
-
-    EXPECT_EQ(extension1()->id() < extension2()->id(),
-              extension1_app_launch.LessThan(extension2_app_launch));
-    EXPECT_EQ(extension3()->id() < extension4()->id(),
-              extension3_app_launch.LessThan(extension4_app_launch));
-
-    // The page ordinal should be unchanged.
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension1()->id()).Equals(
-        first_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension2()->id()).Equals(
-        first_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension3()->id()).Equals(
-        first_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(extension4()->id()).Equals(
-        first_ordinal_));
-  }
-
- private:
-  syncer::StringOrdinal first_ordinal_;
-};
-TEST_F(ExtensionSortingFixNTPCollisionsTwoCollisions,
-       ExtensionSortingFixNTPCollisionsTwoCollisions) {}
-
-class ExtensionSortingEnsureValidOrdinals
-    : public extensions::PrefsPrepopulatedTestBase {
- public :
-  ExtensionSortingEnsureValidOrdinals() {}
-  virtual ~ExtensionSortingEnsureValidOrdinals() {}
-
-  virtual void Initialize() OVERRIDE {}
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    // Give ext1 invalid ordinals and then check that EnsureValidOrdinals fixes
-    // them.
-    extension_sorting->SetAppLaunchOrdinal(extension1()->id(),
-                                           syncer::StringOrdinal());
-    extension_sorting->SetPageOrdinal(extension1()->id(),
-                                      syncer::StringOrdinal());
-
-    extension_sorting->EnsureValidOrdinals(extension1()->id(),
-                                           syncer::StringOrdinal());
-
-    EXPECT_TRUE(
-        extension_sorting->GetAppLaunchOrdinal(extension1()->id()).IsValid());
-    EXPECT_TRUE(
-        extension_sorting->GetPageOrdinal(extension1()->id()).IsValid());
-  }
-};
-TEST_F(ExtensionSortingEnsureValidOrdinals,
-       ExtensionSortingEnsureValidOrdinals) {}
-
-class ExtensionSortingPageOrdinalMapping
-    : public extensions::PrefsPrepopulatedTestBase {
- public:
-  ExtensionSortingPageOrdinalMapping() {}
-  virtual ~ExtensionSortingPageOrdinalMapping() {}
-
-  virtual void Initialize() OVERRIDE {}
-  virtual void Verify() OVERRIDE {
-    std::string ext_1 = "ext_1";
-    std::string ext_2 = "ext_2";
-
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-    syncer::StringOrdinal first_ordinal =
-        syncer::StringOrdinal::CreateInitialOrdinal();
-
-    // Ensure attempting to removing a mapping with an invalid page doesn't
-    // modify the map.
-    EXPECT_TRUE(extension_sorting->ntp_ordinal_map_.empty());
-    extension_sorting->RemoveOrdinalMapping(
-        ext_1, first_ordinal, first_ordinal);
-    EXPECT_TRUE(extension_sorting->ntp_ordinal_map_.empty());
-
-    // Add new mappings.
-    extension_sorting->AddOrdinalMapping(ext_1, first_ordinal, first_ordinal);
-    extension_sorting->AddOrdinalMapping(ext_2, first_ordinal, first_ordinal);
-
-    EXPECT_EQ(1U, extension_sorting->ntp_ordinal_map_.size());
-    EXPECT_EQ(2U, extension_sorting->ntp_ordinal_map_[first_ordinal].size());
-
-    ExtensionSorting::AppLaunchOrdinalMap::iterator it =
-        extension_sorting->ntp_ordinal_map_[first_ordinal].find(first_ordinal);
-    EXPECT_EQ(ext_1, it->second);
-    ++it;
-    EXPECT_EQ(ext_2, it->second);
-
-    extension_sorting->RemoveOrdinalMapping(ext_1,
-                                            first_ordinal,
-                                            first_ordinal);
-    EXPECT_EQ(1U, extension_sorting->ntp_ordinal_map_.size());
-    EXPECT_EQ(1U, extension_sorting->ntp_ordinal_map_[first_ordinal].size());
-
-    it = extension_sorting->ntp_ordinal_map_[first_ordinal].find(
-        first_ordinal);
-    EXPECT_EQ(ext_2, it->second);
-
-    // Ensure that attempting to remove an extension with a valid page and app
-    // launch ordinals, but a unused id has no effect.
-    extension_sorting->RemoveOrdinalMapping(
-        "invalid_ext", first_ordinal, first_ordinal);
-    EXPECT_EQ(1U, extension_sorting->ntp_ordinal_map_.size());
-    EXPECT_EQ(1U, extension_sorting->ntp_ordinal_map_[first_ordinal].size());
-
-    it = extension_sorting->ntp_ordinal_map_[first_ordinal].find(
-        first_ordinal);
-    EXPECT_EQ(ext_2, it->second);
-  }
-};
-TEST_F(ExtensionSortingPageOrdinalMapping,
-       ExtensionSortingPageOrdinalMapping) {}
-
-class ExtensionSortingPreinstalledAppsBase
-    : public extensions::PrefsPrepopulatedTestBase {
- public:
-  ExtensionSortingPreinstalledAppsBase() {
-    DictionaryValue simple_dict;
-    simple_dict.SetString(keys::kVersion, "1.0.0.0");
-    simple_dict.SetString(keys::kName, "unused");
-    simple_dict.SetString(keys::kApp, "true");
-    simple_dict.SetString(keys::kLaunchLocalPath, "fake.html");
-
-    std::string error;
-    app1_scoped_ = Extension::Create(
-        prefs_.temp_dir().AppendASCII("app1_"), Manifest::EXTERNAL_PREF,
-        simple_dict, Extension::NO_FLAGS, &error);
-    prefs()->OnExtensionInstalled(app1_scoped_.get(),
-                                  Extension::ENABLED,
-                                  false,
-                                  syncer::StringOrdinal());
-
-    app2_scoped_ = Extension::Create(
-        prefs_.temp_dir().AppendASCII("app2_"), Manifest::EXTERNAL_PREF,
-        simple_dict, Extension::NO_FLAGS, &error);
-    prefs()->OnExtensionInstalled(app2_scoped_.get(),
-                                  Extension::ENABLED,
-                                  false,
-                                  syncer::StringOrdinal());
-
-    app1_ = app1_scoped_.get();
-    app2_ = app2_scoped_.get();
-  }
-  virtual ~ExtensionSortingPreinstalledAppsBase() {}
-
- protected:
-  // Weak references, for convenience.
-  Extension* app1_;
-  Extension* app2_;
-
- private:
-  scoped_refptr<Extension> app1_scoped_;
-  scoped_refptr<Extension> app2_scoped_;
-};
-
-class ExtensionSortingGetMinOrMaxAppLaunchOrdinalsOnPage
-    : public ExtensionSortingPreinstalledAppsBase {
- public:
-  ExtensionSortingGetMinOrMaxAppLaunchOrdinalsOnPage() {}
-  virtual ~ExtensionSortingGetMinOrMaxAppLaunchOrdinalsOnPage() {}
-
-  virtual void Initialize() OVERRIDE {}
-  virtual void Verify() OVERRIDE {
-    syncer::StringOrdinal page = syncer::StringOrdinal::CreateInitialOrdinal();
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    syncer::StringOrdinal min =
-        extension_sorting->GetMinOrMaxAppLaunchOrdinalsOnPage(
-            page,
-            ExtensionSorting::MIN_ORDINAL);
-    syncer::StringOrdinal max =
-        extension_sorting->GetMinOrMaxAppLaunchOrdinalsOnPage(
-            page,
-            ExtensionSorting::MAX_ORDINAL);
-    EXPECT_TRUE(min.IsValid());
-    EXPECT_TRUE(max.IsValid());
-    EXPECT_TRUE(min.LessThan(max));
-
-    // Ensure that the min and max values aren't set for empty pages.
-    min = syncer::StringOrdinal();
-    max = syncer::StringOrdinal();
-    syncer::StringOrdinal empty_page = page.CreateAfter();
-    EXPECT_FALSE(min.IsValid());
-    EXPECT_FALSE(max.IsValid());
-    min = extension_sorting->GetMinOrMaxAppLaunchOrdinalsOnPage(
-        empty_page,
-        ExtensionSorting::MIN_ORDINAL);
-    max = extension_sorting->GetMinOrMaxAppLaunchOrdinalsOnPage(
-        empty_page,
-        ExtensionSorting::MAX_ORDINAL);
-    EXPECT_FALSE(min.IsValid());
-    EXPECT_FALSE(max.IsValid());
-  }
-};
-TEST_F(ExtensionSortingGetMinOrMaxAppLaunchOrdinalsOnPage,
-       ExtensionSortingGetMinOrMaxAppLaunchOrdinalsOnPage) {}
-
-// Make sure that empty pages aren't removed from the integer to ordinal
-// mapping. See http://crbug.com/109802 for details.
-class ExtensionSortingKeepEmptyStringOrdinalPages
-    : public ExtensionSortingPreinstalledAppsBase {
- public:
-  ExtensionSortingKeepEmptyStringOrdinalPages() {}
-  virtual ~ExtensionSortingKeepEmptyStringOrdinalPages() {}
-
-  virtual void Initialize() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    syncer::StringOrdinal first_page =
-        syncer::StringOrdinal::CreateInitialOrdinal();
-    extension_sorting->SetPageOrdinal(app1_->id(), first_page);
-    EXPECT_EQ(0, extension_sorting->PageStringOrdinalAsInteger(first_page));
-
-    last_page_ = first_page.CreateAfter();
-    extension_sorting->SetPageOrdinal(app2_->id(), last_page_);
-    EXPECT_EQ(1, extension_sorting->PageStringOrdinalAsInteger(last_page_));
-
-    // Move the second app to create an empty page.
-    extension_sorting->SetPageOrdinal(app2_->id(), first_page);
-    EXPECT_EQ(0, extension_sorting->PageStringOrdinalAsInteger(first_page));
-  }
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    // Move the second app to a new empty page at the end, skipping over
-    // the current empty page.
-    last_page_ = last_page_.CreateAfter();
-    extension_sorting->SetPageOrdinal(app2_->id(), last_page_);
-    EXPECT_EQ(2, extension_sorting->PageStringOrdinalAsInteger(last_page_));
-    EXPECT_TRUE(
-        last_page_.Equals(extension_sorting->PageIntegerAsStringOrdinal(2)));
-  }
-
- private:
-  syncer::StringOrdinal last_page_;
-};
-TEST_F(ExtensionSortingKeepEmptyStringOrdinalPages,
-       ExtensionSortingKeepEmptyStringOrdinalPages) {}
-
-class ExtensionSortingMakesFillerOrdinals
-    : public ExtensionSortingPreinstalledAppsBase {
- public:
-  ExtensionSortingMakesFillerOrdinals() {}
-  virtual ~ExtensionSortingMakesFillerOrdinals() {}
-
-  virtual void Initialize() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    syncer::StringOrdinal first_page =
-        syncer::StringOrdinal::CreateInitialOrdinal();
-    extension_sorting->SetPageOrdinal(app1_->id(), first_page);
-    EXPECT_EQ(0, extension_sorting->PageStringOrdinalAsInteger(first_page));
-  }
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    // Because the UI can add an unlimited number of empty pages without an app
-    // on them, this test simulates dropping of an app on the 1st and 4th empty
-    // pages (3rd and 6th pages by index) to ensure we don't crash and that
-    // filler ordinals are created as needed. See: http://crbug.com/122214
-    syncer::StringOrdinal page_three =
-        extension_sorting->PageIntegerAsStringOrdinal(2);
-    extension_sorting->SetPageOrdinal(app1_->id(), page_three);
-    EXPECT_EQ(2, extension_sorting->PageStringOrdinalAsInteger(page_three));
-
-    syncer::StringOrdinal page_six =
-        extension_sorting->PageIntegerAsStringOrdinal(5);
-    extension_sorting->SetPageOrdinal(app1_->id(), page_six);
-    EXPECT_EQ(5, extension_sorting->PageStringOrdinalAsInteger(page_six));
-  }
-};
-TEST_F(ExtensionSortingMakesFillerOrdinals,
-       ExtensionSortingMakesFillerOrdinals) {}
-
-class ExtensionSortingDefaultOrdinalsBase : public ExtensionSortingTest {
- public:
-  ExtensionSortingDefaultOrdinalsBase() {}
-  virtual ~ExtensionSortingDefaultOrdinalsBase() {}
-
-  virtual void Initialize() OVERRIDE {
-    app_ = CreateApp("app");
-
-    InitDefaultOrdinals();
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-    ExtensionSorting::AppOrdinalsMap& sorting_defaults =
-        extension_sorting->default_ordinals_;
-    sorting_defaults[app_->id()].page_ordinal = default_page_ordinal_;
-    sorting_defaults[app_->id()].app_launch_ordinal =
-        default_app_launch_ordinal_;
-
-    SetupUserOrdinals();
-    InstallApps();
-  }
-
- protected:
-  scoped_refptr<Extension> CreateApp(const std::string& name) {
-    DictionaryValue simple_dict;
-    simple_dict.SetString(keys::kVersion, "1.0.0.0");
-    simple_dict.SetString(keys::kName, name);
-    simple_dict.SetString(keys::kApp, "true");
-    simple_dict.SetString(keys::kLaunchLocalPath, "fake.html");
-
-    std::string errors;
-    scoped_refptr<Extension> app = Extension::Create(
-        prefs_.temp_dir().AppendASCII(name), Manifest::EXTERNAL_PREF,
-        simple_dict, Extension::NO_FLAGS, &errors);
-    EXPECT_TRUE(app.get()) << errors;
-    EXPECT_TRUE(Extension::IdIsValid(app->id()));
-    return app;
-  }
-
-  void InitDefaultOrdinals() {
-    default_page_ordinal_ =
-        syncer::StringOrdinal::CreateInitialOrdinal().CreateAfter();
-    default_app_launch_ordinal_ =
-        syncer::StringOrdinal::CreateInitialOrdinal().CreateBefore();
-  }
-
-  virtual void SetupUserOrdinals() {}
-
-  virtual void InstallApps() {
-    prefs()->OnExtensionInstalled(app_.get(),
-                                  Extension::ENABLED,
-                                  false,
-                                  syncer::StringOrdinal());
-  }
-
-  scoped_refptr<Extension> app_;
-  syncer::StringOrdinal default_page_ordinal_;
-  syncer::StringOrdinal default_app_launch_ordinal_;
-};
-
-// Tests that the app gets its default ordinals.
-class ExtensionSortingDefaultOrdinals
-    : public ExtensionSortingDefaultOrdinalsBase {
- public:
-  ExtensionSortingDefaultOrdinals() {}
-  virtual ~ExtensionSortingDefaultOrdinals() {}
-
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(app_->id()).Equals(
-        default_page_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetAppLaunchOrdinal(app_->id()).Equals(
-        default_app_launch_ordinal_));
-  }
-};
-TEST_F(ExtensionSortingDefaultOrdinals,
-       ExtensionSortingDefaultOrdinals) {}
-
-// Tests that the default page ordinal is overridden by install page ordinal.
-class ExtensionSortingDefaultOrdinalOverriddenByInstallPage
-    : public ExtensionSortingDefaultOrdinalsBase {
- public:
-  ExtensionSortingDefaultOrdinalOverriddenByInstallPage() {}
-  virtual ~ExtensionSortingDefaultOrdinalOverriddenByInstallPage() {}
-
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    EXPECT_FALSE(extension_sorting->GetPageOrdinal(app_->id()).Equals(
-        default_page_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(app_->id()).Equals(
-        install_page_));
-  }
-
- protected:
-  virtual void InstallApps() OVERRIDE {
-    install_page_ = default_page_ordinal_.CreateAfter();
-    prefs()->OnExtensionInstalled(app_.get(),
-                                  Extension::ENABLED,
-                                  false,
-                                  install_page_);
-  }
-
- private:
-  syncer::StringOrdinal install_page_;
-};
-TEST_F(ExtensionSortingDefaultOrdinalOverriddenByInstallPage,
-       ExtensionSortingDefaultOrdinalOverriddenByInstallPage) {}
-
-// Tests that the default ordinals are overridden by user values.
-class ExtensionSortingDefaultOrdinalOverriddenByUserValue
-    : public ExtensionSortingDefaultOrdinalsBase {
- public:
-  ExtensionSortingDefaultOrdinalOverriddenByUserValue() {}
-  virtual ~ExtensionSortingDefaultOrdinalOverriddenByUserValue() {}
-
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(app_->id()).Equals(
-        user_page_ordinal_));
-    EXPECT_TRUE(extension_sorting->GetAppLaunchOrdinal(app_->id()).Equals(
-        user_app_launch_ordinal_));
-  }
-
- protected:
-  virtual void SetupUserOrdinals() OVERRIDE {
-    user_page_ordinal_ = default_page_ordinal_.CreateAfter();
-    user_app_launch_ordinal_ = default_app_launch_ordinal_.CreateBefore();
-
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-    extension_sorting->SetPageOrdinal(app_->id(), user_page_ordinal_);
-    extension_sorting->SetAppLaunchOrdinal(app_->id(),
-                                           user_app_launch_ordinal_);
-  }
-
- private:
-  syncer::StringOrdinal user_page_ordinal_;
-  syncer::StringOrdinal user_app_launch_ordinal_;
-};
-TEST_F(ExtensionSortingDefaultOrdinalOverriddenByUserValue,
-       ExtensionSortingDefaultOrdinalOverriddenByUserValue) {}
-
-// Tests that the default app launch ordinal is changed to avoid collision.
-class ExtensionSortingDefaultOrdinalNoCollision
-    : public ExtensionSortingDefaultOrdinalsBase {
- public:
-  ExtensionSortingDefaultOrdinalNoCollision() {}
-  virtual ~ExtensionSortingDefaultOrdinalNoCollision() {}
-
-  virtual void Verify() OVERRIDE {
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-
-    // Use the default page.
-    EXPECT_TRUE(extension_sorting->GetPageOrdinal(app_->id()).Equals(
-        default_page_ordinal_));
-    // Not using the default app launch ordinal because of the collision.
-    EXPECT_FALSE(extension_sorting->GetAppLaunchOrdinal(app_->id()).Equals(
-        default_app_launch_ordinal_));
-  }
-
- protected:
-  virtual void SetupUserOrdinals() OVERRIDE {
-    other_app_ = prefs_.AddApp("other_app");
-    // Creates a collision.
-    ExtensionSorting* extension_sorting = prefs()->extension_sorting();
-    extension_sorting->SetPageOrdinal(other_app_->id(), default_page_ordinal_);
-    extension_sorting->SetAppLaunchOrdinal(other_app_->id(),
-                                           default_app_launch_ordinal_);
-
-    yet_another_app_ = prefs_.AddApp("yet_aother_app");
-    extension_sorting->SetPageOrdinal(yet_another_app_->id(),
-                                      default_page_ordinal_);
-    extension_sorting->SetAppLaunchOrdinal(yet_another_app_->id(),
-                                           default_app_launch_ordinal_);
-  }
-
- private:
-  scoped_refptr<Extension> other_app_;
-  scoped_refptr<Extension> yet_another_app_;
-};
-TEST_F(ExtensionSortingDefaultOrdinalNoCollision,
-       ExtensionSortingDefaultOrdinalNoCollision) {}
diff --git a/chrome/browser/extensions/extension_sync_bundle.cc b/chrome/browser/extensions/extension_sync_bundle.cc
index ab133b5..4786091 100644
--- a/chrome/browser/extensions/extension_sync_bundle.cc
+++ b/chrome/browser/extensions/extension_sync_bundle.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/extensions/extension_sync_bundle.h"
 
 #include "base/location.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/extensions/extension_sync_service.h"
 #include "chrome/common/extensions/extension_set.h"
 #include "chrome/common/extensions/sync_helper.h"
diff --git a/chrome/browser/extensions/extension_sync_service.cc b/chrome/browser/extensions/extension_sync_service.cc
index 670c73d4..9aa0dd3 100644
--- a/chrome/browser/extensions/extension_sync_service.cc
+++ b/chrome/browser/extensions/extension_sync_service.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/extensions/extension_error_ui.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/extensions/extension_sync_data.h"
 #include "chrome/browser/extensions/extension_sync_service_factory.h"
 #include "chrome/browser/extensions/extension_util.h"
@@ -22,6 +21,7 @@
 #include "chrome/browser/sync/sync_prefs.h"
 #include "chrome/common/extensions/sync_helper.h"
 #include "content/public/browser/browser_thread.h"
+#include "extensions/browser/app_sorting.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/feature_switch.h"
 #include "extensions/common/manifest_constants.h"
@@ -54,7 +54,7 @@
       profile_->GetPath()));
 
   extension_service_->set_extension_sync_service(this);
-  extension_prefs_->extension_sorting()->SetExtensionSyncService(this);
+  extension_prefs_->app_sorting()->SetExtensionSyncService(this);
 }
 
 ExtensionSyncService::~ExtensionSyncService() {}
@@ -219,7 +219,7 @@
     }
   }
 
-  extension_prefs_->extension_sorting()->FixNTPOrdinalCollisions();
+  extension_prefs_->app_sorting()->FixNTPOrdinalCollisions();
 
   return syncer::SyncError();
 }
@@ -238,9 +238,8 @@
       extension,
       extension_service_->IsExtensionEnabled(extension.id()),
       extension_util::IsIncognitoEnabled(extension.id(), extension_service_),
-      extension_prefs_->extension_sorting()->GetAppLaunchOrdinal(
-          extension.id()),
-      extension_prefs_->extension_sorting()->GetPageOrdinal(extension.id()));
+      extension_prefs_->app_sorting()->GetAppLaunchOrdinal(extension.id()),
+      extension_prefs_->app_sorting()->GetPageOrdinal(extension.id()));
 }
 
 std::vector<extensions::ExtensionSyncData>
@@ -300,10 +299,10 @@
 
   if (app_sync_data.app_launch_ordinal().IsValid() &&
       app_sync_data.page_ordinal().IsValid()) {
-    extension_prefs_->extension_sorting()->SetAppLaunchOrdinal(
+    extension_prefs_->app_sorting()->SetAppLaunchOrdinal(
         id,
         app_sync_data.app_launch_ordinal());
-    extension_prefs_->extension_sorting()->SetPageOrdinal(
+    extension_prefs_->app_sorting()->SetPageOrdinal(
         id,
         app_sync_data.page_ordinal());
   }
diff --git a/chrome/browser/extensions/install_tracker.cc b/chrome/browser/extensions/install_tracker.cc
index 7f70cac8..b84af2b0 100644
--- a/chrome/browser/extensions/install_tracker.cc
+++ b/chrome/browser/extensions/install_tracker.cc
@@ -14,7 +14,7 @@
 
 InstallTracker::InstallTracker(Profile* profile,
                                extensions::ExtensionPrefs* prefs) {
-  ExtensionSorting* sorting = prefs->extension_sorting();
+  AppSorting* sorting = prefs->app_sorting();
 
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
       content::Source<Profile>(profile));
@@ -25,7 +25,7 @@
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
       content::Source<Profile>(profile));
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED,
-      content::Source<ExtensionSorting>(sorting));
+      content::Source<AppSorting>(sorting));
   registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST,
       content::Source<Profile>(profile));
 
diff --git a/chrome/browser/sync/test/integration/sync_app_helper.cc b/chrome/browser/sync/test/integration/sync_app_helper.cc
index 897764e..4ca8b63 100644
--- a/chrome/browser/sync/test/integration/sync_app_helper.cc
+++ b/chrome/browser/sync/test/integration/sync_app_helper.cc
@@ -5,13 +5,13 @@
 #include "chrome/browser/sync/test/integration/sync_app_helper.h"
 
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/test/integration/extensions_helper.h"
 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
 #include "chrome/browser/sync/test/integration/sync_extension_helper.h"
 #include "chrome/common/extensions/sync_helper.h"
+#include "extensions/browser/app_sorting.h"
 #include "extensions/common/id_util.h"
 
 namespace {
@@ -46,9 +46,9 @@
              const std::string& id,
              AppState* app_state) {
   app_state->app_launch_ordinal = extension_service->extension_prefs()->
-      extension_sorting()->GetAppLaunchOrdinal(id);
+      app_sorting()->GetAppLaunchOrdinal(id);
   app_state->page_ordinal = extension_service->extension_prefs()->
-      extension_sorting()->GetPageOrdinal(id);
+      app_sorting()->GetPageOrdinal(id);
 }
 
 // Returns a map from |profile|'s installed extensions to their state.
@@ -147,15 +147,14 @@
     Profile* profile,
     const std::string& name) {
   return profile->GetExtensionService()->extension_prefs()->
-      extension_sorting()->GetPageOrdinal(
-          extensions::id_util::GenerateId(name));
+      app_sorting()->GetPageOrdinal(extensions::id_util::GenerateId(name));
 }
 
 void SyncAppHelper::SetPageOrdinalForApp(
     Profile* profile,
     const std::string& name,
     const syncer::StringOrdinal& page_ordinal) {
-  profile->GetExtensionService()->extension_prefs()->extension_sorting()->
+  profile->GetExtensionService()->extension_prefs()->app_sorting()->
       SetPageOrdinal(extensions::id_util::GenerateId(name), page_ordinal);
 }
 
@@ -163,21 +162,20 @@
     Profile* profile,
     const std::string& name) {
   return profile->GetExtensionService()->extension_prefs()->
-      extension_sorting()->GetAppLaunchOrdinal(
-          extensions::id_util::GenerateId(name));
+      app_sorting()->GetAppLaunchOrdinal(extensions::id_util::GenerateId(name));
 }
 
 void SyncAppHelper::SetAppLaunchOrdinalForApp(
     Profile* profile,
     const std::string& name,
     const syncer::StringOrdinal& app_launch_ordinal) {
-  profile->GetExtensionService()->extension_prefs()->extension_sorting()->
+  profile->GetExtensionService()->extension_prefs()->app_sorting()->
       SetAppLaunchOrdinal(extensions::id_util::GenerateId(name),
                           app_launch_ordinal);
 }
 
 void SyncAppHelper::FixNTPOrdinalCollisions(Profile* profile) {
-  profile->GetExtensionService()->extension_prefs()->extension_sorting()->
+  profile->GetExtensionService()->extension_prefs()->app_sorting()->
       FixNTPOrdinalCollisions();
 }
 
diff --git a/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc b/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc
index 475759a..9087961 100644
--- a/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc
@@ -4,13 +4,13 @@
 
 #include "base/basictypes.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/apps_helper.h"
 #include "chrome/browser/sync/test/integration/sync_app_helper.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chrome/common/extensions/extension_constants.h"
+#include "extensions/browser/app_sorting.h"
 #include "sync/api/string_ordinal.h"
 
 using apps_helper::AllProfilesHaveSameAppsAsVerifier;
@@ -395,12 +395,12 @@
   // Change the app launch ordinal.
   syncer::StringOrdinal cws_app_launch_ordinal =
       GetProfile(0)->GetExtensionService()->
-      extension_prefs()->extension_sorting()->GetAppLaunchOrdinal(
+      extension_prefs()->app_sorting()->GetAppLaunchOrdinal(
           extension_misc::kWebStoreAppId);
-  GetProfile(0)->GetExtensionService()->extension_prefs()->extension_sorting()->
+  GetProfile(0)->GetExtensionService()->extension_prefs()->app_sorting()->
       SetAppLaunchOrdinal(
           extension_misc::kWebStoreAppId, cws_app_launch_ordinal.CreateAfter());
-  verifier()->GetExtensionService()->extension_prefs()->extension_sorting()->
+  verifier()->GetExtensionService()->extension_prefs()->app_sorting()->
       SetAppLaunchOrdinal(
           extension_misc::kWebStoreAppId, cws_app_launch_ordinal.CreateAfter());
   ASSERT_TRUE(AwaitQuiescence());
@@ -409,14 +409,14 @@
   // Change the page ordinal.
   syncer::StringOrdinal cws_page_ordinal =
       GetProfile(1)->GetExtensionService()->
-      extension_prefs()->extension_sorting()->GetPageOrdinal(
+      extension_prefs()->app_sorting()->GetPageOrdinal(
           extension_misc::kWebStoreAppId);
   GetProfile(1)->GetExtensionService()->extension_prefs()->
-      extension_sorting()->SetPageOrdinal(extension_misc::kWebStoreAppId,
-                                          cws_page_ordinal.CreateAfter());
+      app_sorting()->SetPageOrdinal(extension_misc::kWebStoreAppId,
+                                    cws_page_ordinal.CreateAfter());
   verifier()->GetExtensionService()->extension_prefs()->
-      extension_sorting()->SetPageOrdinal(extension_misc::kWebStoreAppId,
-                                          cws_page_ordinal.CreateAfter());
+      app_sorting()->SetPageOrdinal(extension_misc::kWebStoreAppId,
+                                    cws_page_ordinal.CreateAfter());
   ASSERT_TRUE(AwaitQuiescence());
   ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
 }
diff --git a/chrome/browser/ui/app_list/extension_app_item.cc b/chrome/browser/ui/app_list/extension_app_item.cc
index f8a32400..94ae775 100644
--- a/chrome/browser/ui/app_list/extension_app_item.cc
+++ b/chrome/browser/ui/app_list/extension_app_item.cc
@@ -7,7 +7,6 @@
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/extensions/extension_prefs.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/app_context_menu.h"
@@ -21,6 +20,7 @@
 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
 #include "chrome/common/extensions/manifest_url_handler.h"
 #include "content/public/browser/user_metrics.h"
+#include "extensions/browser/app_sorting.h"
 #include "extensions/common/extension.h"
 #include "grit/theme_resources.h"
 #include "sync/api/string_ordinal.h"
@@ -59,10 +59,10 @@
   DISALLOW_COPY_AND_ASSIGN(ShortcutOverlayImageSource);
 };
 
-ExtensionSorting* GetExtensionSorting(Profile* profile) {
+extensions::AppSorting* GetAppSorting(Profile* profile) {
   ExtensionService* service =
       extensions::ExtensionSystem::Get(profile)->extension_service();
-  return service->extension_prefs()->extension_sorting();
+  return service->extension_prefs()->app_sorting();
 }
 
 const color_utils::HSL shift = {-1, 0, 0.6};
@@ -84,8 +84,8 @@
                                                           shift)),
       is_platform_app_(is_platform_app) {
   Reload();
-  GetExtensionSorting(profile_)->EnsureValidOrdinals(extension_id_,
-                                                     syncer::StringOrdinal());
+  GetAppSorting(profile_)->EnsureValidOrdinals(extension_id_,
+                                               syncer::StringOrdinal());
   UpdatePositionFromExtensionOrdering();
 }
 
@@ -144,7 +144,7 @@
 
   ExtensionService* service =
       extensions::ExtensionSystem::Get(profile_)->extension_service();
-  ExtensionSorting* sorting = service->extension_prefs()->extension_sorting();
+  extensions::AppSorting* sorting = service->extension_prefs()->app_sorting();
 
   syncer::StringOrdinal page;
   std::string prev_id, next_id;
@@ -279,9 +279,9 @@
 
 void ExtensionAppItem::UpdatePositionFromExtensionOrdering() {
   const syncer::StringOrdinal& page =
-      GetExtensionSorting(profile_)->GetPageOrdinal(extension_id_);
+      GetAppSorting(profile_)->GetPageOrdinal(extension_id_);
   const syncer::StringOrdinal& launch =
-     GetExtensionSorting(profile_)->GetAppLaunchOrdinal(extension_id_);
+     GetAppSorting(profile_)->GetAppLaunchOrdinal(extension_id_);
   set_position(syncer::StringOrdinal(
       page.ToInternalValue() + launch.ToInternalValue()));
 }
diff --git a/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc b/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc
index 53c9200..be9fb94a 100644
--- a/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc
+++ b/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc
@@ -13,13 +13,13 @@
 #include "base/values.h"
 #include "chrome/browser/extensions/extension_function_test_utils.h"
 #include "chrome/browser/extensions/extension_service_unittest.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/extensions/install_tracker.h"
 #include "chrome/browser/extensions/install_tracker_factory.h"
 #include "chrome/browser/ui/app_list/app_list_controller_delegate_impl.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
+#include "extensions/browser/app_sorting.h"
 #include "extensions/common/manifest.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/app_list/app_list_item_model.h"
@@ -230,7 +230,7 @@
 }
 
 TEST_F(ExtensionAppModelBuilderTest, OrdinalPrefsChange) {
-  ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
+  extensions::AppSorting* sorting = service_->extension_prefs()->app_sorting();
 
   syncer::StringOrdinal package_app_page =
       sorting->GetPageOrdinal(kPackagedApp1Id);
@@ -252,7 +252,7 @@
 }
 
 TEST_F(ExtensionAppModelBuilderTest, OnExtensionMoved) {
-  ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
+  extensions::AppSorting* sorting = service_->extension_prefs()->app_sorting();
   sorting->SetPageOrdinal(kHostedAppId,
                           sorting->GetPageOrdinal(kPackagedApp1Id));
 
@@ -274,11 +274,11 @@
 
 TEST_F(ExtensionAppModelBuilderTest, InvalidOrdinal) {
   // Creates a no-ordinal case.
-  ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
+  extensions::AppSorting* sorting = service_->extension_prefs()->app_sorting();
   sorting->ClearOrdinals(kPackagedApp1Id);
 
   // Creates an corrupted ordinal case.
-  ExtensionScopedPrefs* scoped_prefs = service_->extension_prefs();
+  extensions::ExtensionScopedPrefs* scoped_prefs = service_->extension_prefs();
   scoped_prefs->UpdateExtensionPref(
       kHostedAppId,
       "page_ordinal",
@@ -294,7 +294,7 @@
   syncer::StringOrdinal conflict_ordinal =
       syncer::StringOrdinal::CreateInitialOrdinal();
 
-  ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
+  extensions::AppSorting* sorting = service_->extension_prefs()->app_sorting();
   sorting->SetPageOrdinal(kHostedAppId, conflict_ordinal);
   sorting->SetAppLaunchOrdinal(kHostedAppId, conflict_ordinal);
 
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
index aa33c087..b867e5c7 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_sorting.h"
 #include "chrome/browser/extensions/extension_system.h"
 #include "chrome/browser/extensions/management_policy.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
@@ -48,6 +47,7 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/common/favicon_url.h"
+#include "extensions/browser/app_sorting.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "grit/browser_resources.h"
@@ -58,6 +58,7 @@
 #include "url/gurl.h"
 
 using content::WebContents;
+using extensions::AppSorting;
 using extensions::CrxInstaller;
 using extensions::Extension;
 using extensions::ExtensionPrefs;
@@ -161,7 +162,7 @@
   value->SetBoolean("is_webstore",
       extension->id() == extension_misc::kWebStoreAppId);
 
-  ExtensionSorting* sorting = prefs->extension_sorting();
+  AppSorting* sorting = prefs->app_sorting();
   syncer::StringOrdinal page_ordinal = sorting->GetPageOrdinal(extension->id());
   if (!page_ordinal.IsValid()) {
     // Make sure every app has a page ordinal (some predate the page ordinal).
@@ -466,8 +467,8 @@
     registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
         content::Source<Profile>(profile));
     registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED,
-        content::Source<ExtensionSorting>(
-            extension_service_->extension_prefs()->extension_sorting()));
+        content::Source<AppSorting>(
+            extension_service_->extension_prefs()->app_sorting()));
     registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR,
         content::Source<CrxInstaller>(NULL));
     registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOAD_ERROR,
@@ -640,20 +641,19 @@
 }
 
 void AppLauncherHandler::HandleSetPageIndex(const ListValue* args) {
-  ExtensionSorting* extension_sorting =
-      extension_service_->extension_prefs()->extension_sorting();
+  AppSorting* app_sorting =
+      extension_service_->extension_prefs()->app_sorting();
 
   std::string extension_id;
   double page_index;
   CHECK(args->GetString(0, &extension_id));
   CHECK(args->GetDouble(1, &page_index));
   const syncer::StringOrdinal& page_ordinal =
-      extension_sorting->PageIntegerAsStringOrdinal(
-          static_cast<size_t>(page_index));
+      app_sorting->PageIntegerAsStringOrdinal(static_cast<size_t>(page_index));
 
   // Don't update the page; it already knows the apps have been reordered.
   base::AutoReset<bool> auto_reset(&ignore_changes_, true);
-  extension_sorting->SetPageOrdinal(extension_id, page_ordinal);
+  app_sorting->SetPageOrdinal(extension_id, page_ordinal);
 }
 
 void AppLauncherHandler::HandleSaveAppPageName(const ListValue* args) {
@@ -680,11 +680,10 @@
 
   double page_index;
   CHECK(args->GetDouble(2, &page_index));
-  ExtensionSorting* extension_sorting =
-      extension_service_->extension_prefs()->extension_sorting();
+  AppSorting* app_sorting =
+      extension_service_->extension_prefs()->app_sorting();
   const syncer::StringOrdinal& page_ordinal =
-      extension_sorting->PageIntegerAsStringOrdinal(
-          static_cast<size_t>(page_index));
+      app_sorting->PageIntegerAsStringOrdinal(static_cast<size_t>(page_index));
 
   Profile* profile = Profile::FromWebUI(web_ui());
   FaviconService* favicon_service =