Create a TabHandler object to decouple Browser from TabStripModel API.

Currently it's just a pass-through so everything still works while I begin to move stuff out of Browser down into it.

BUG=none
TEST=existing unittests.
Review URL: http://codereview.chromium.org/3412041

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60860 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 783ff7e5..1d2c82f1 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -182,7 +182,8 @@
     : type_(type),
       profile_(profile),
       window_(NULL),
-      tabstrip_model_(new TabStripModel(this, profile)),
+      ALLOW_THIS_IN_INITIALIZER_LIST(
+          tab_handler_(TabHandler::CreateTabHandler(this))),
       command_updater_(this),
       toolbar_model_(this),
       chrome_updater_factory_(this),
@@ -195,8 +196,6 @@
       last_blocked_command_disposition_(CURRENT_TAB),
       pending_web_app_action_(NONE),
       extension_app_(NULL) {
-  tabstrip_model_->AddObserver(this);
-
   registrar_.Add(this, NotificationType::SSL_VISIBLE_STATE_CHANGED,
                  NotificationService::AllSources());
   registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
@@ -247,10 +246,6 @@
 }
 
 Browser::~Browser() {
-  // The tab strip should not have any significant tabs at this point.
-  DCHECK(!tabstrip_model_->HasNonPhantomTabs());
-  tabstrip_model_->RemoveObserver(this);
-
   if (profile_->GetProfileSyncService())
     profile_->GetProfileSyncService()->RemoveObserver(this);
 
@@ -693,7 +688,8 @@
 }
 
 string16 Browser::GetWindowTitleForCurrentTab() const {
-  TabContents* contents = tabstrip_model_->GetSelectedTabContents();
+  TabContents* contents =
+      tab_handler_->GetTabStripModel()->GetSelectedTabContents();
   string16 title;
 
   // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
@@ -816,40 +812,40 @@
 // Browser, TabStripModel pass-thrus:
 
 int Browser::tab_count() const {
-  return tabstrip_model_->count();
+  return tab_handler_->GetTabStripModel()->count();
 }
 
 int Browser::selected_index() const {
-  return tabstrip_model_->selected_index();
+  return tab_handler_->GetTabStripModel()->selected_index();
 }
 
 int Browser::GetIndexOfController(
     const NavigationController* controller) const {
-  return tabstrip_model_->GetIndexOfController(controller);
+  return tab_handler_->GetTabStripModel()->GetIndexOfController(controller);
 }
 
 TabContents* Browser::GetTabContentsAt(int index) const {
-  return tabstrip_model_->GetTabContentsAt(index);
+  return tab_handler_->GetTabStripModel()->GetTabContentsAt(index);
 }
 
 TabContents* Browser::GetSelectedTabContents() const {
-  return tabstrip_model_->GetSelectedTabContents();
+  return tab_handler_->GetTabStripModel()->GetSelectedTabContents();
 }
 
 void Browser::SelectTabContentsAt(int index, bool user_gesture) {
-  tabstrip_model_->SelectTabContentsAt(index, user_gesture);
+  tab_handler_->GetTabStripModel()->SelectTabContentsAt(index, user_gesture);
 }
 
 void Browser::CloseAllTabs() {
-  tabstrip_model_->CloseAllTabs();
+  tab_handler_->GetTabStripModel()->CloseAllTabs();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Browser, Tab adding/showing functions:
 
 int Browser::GetIndexForInsertionDuringRestore(int relative_index) {
-  return (tabstrip_model_->insertion_policy() == TabStripModel::INSERT_AFTER) ?
-      tab_count() : relative_index;
+  return (tab_handler_->GetTabStripModel()->insertion_policy() ==
+      TabStripModel::INSERT_AFTER) ? tab_count() : relative_index;
 }
 
 TabContents* Browser::AddTabWithURL(const GURL& url,
@@ -868,7 +864,8 @@
     contents = CreateTabContentsForURL(url_to_load, referrer, profile_,
                                        transition, false, instance);
     contents->SetExtensionAppById(extension_app_id);
-    tabstrip_model_->AddTabContents(contents, index, transition, add_types);
+    tab_handler_->GetTabStripModel()->AddTabContents(contents, index,
+                                                     transition, add_types);
     // TODO(sky): figure out why this is needed. Without it we seem to get
     // failures in startup tests.
     // By default, content believes it is not hidden.  When adding contents
@@ -899,7 +896,7 @@
 
 TabContents* Browser::AddTab(TabContents* tab_contents,
                              PageTransition::Type type) {
-  tabstrip_model_->AddTabContents(
+  tab_handler_->GetTabStripModel()->AddTabContents(
       tab_contents, -1, type, TabStripModel::ADD_SELECTED);
   return tab_contents;
 }
@@ -939,18 +936,19 @@
     SessionStorageNamespace* session_storage_namespace) {
   TabContents* new_tab = new TabContents(
       profile(), NULL, MSG_ROUTING_NONE,
-      tabstrip_model_->GetSelectedTabContents(), session_storage_namespace);
+      tab_handler_->GetTabStripModel()->GetSelectedTabContents(),
+      session_storage_namespace);
   new_tab->SetExtensionAppById(extension_app_id);
   new_tab->controller().RestoreFromState(navigations, selected_navigation,
                                          from_last_session);
 
   bool really_pin =
       (pin && tab_index == tabstrip_model()->IndexOfFirstNonMiniTab());
-  tabstrip_model_->InsertTabContentsAt(
+  tab_handler_->GetTabStripModel()->InsertTabContentsAt(
       tab_index, new_tab,
       select ? TabStripModel::ADD_SELECTED : TabStripModel::ADD_NONE);
   if (really_pin)
-    tabstrip_model_->SetTabPinned(tab_index, true);
+    tab_handler_->GetTabStripModel()->SetTabPinned(tab_index, true);
   if (select) {
     window_->Activate();
   } else {
@@ -978,14 +976,15 @@
     const std::string& extension_app_id,
     SessionStorageNamespace* session_storage_namespace) {
   TabContents* replacement = new TabContents(profile(), NULL,
-      MSG_ROUTING_NONE, tabstrip_model_->GetSelectedTabContents(),
+      MSG_ROUTING_NONE,
+      tab_handler_->GetTabStripModel()->GetSelectedTabContents(),
       session_storage_namespace);
   replacement->SetExtensionAppById(extension_app_id);
   replacement->controller().RestoreFromState(navigations, selected_navigation,
                                              from_last_session);
 
-  tabstrip_model_->ReplaceNavigationControllerAt(
-      tabstrip_model_->selected_index(),
+  tab_handler_->GetTabStripModel()->ReplaceNavigationControllerAt(
+      tab_handler_->GetTabStripModel()->selected_index(),
       &replacement->controller());
 }
 
@@ -1013,11 +1012,12 @@
                                            &reverse_on_redirect);
 
   // See if we already have a tab with the given URL and select it if so.
-  for (int i = 0; i < tabstrip_model_->count(); i++) {
-    TabContents* tc = tabstrip_model_->GetTabContentsAt(i);
+  TabStripModel* model = tab_handler_->GetTabStripModel();
+  for (int i = 0; i < model->count(); i++) {
+    TabContents* tc = model->GetTabContentsAt(i);
     if (CompareURLsIgnoreRef(tc->GetURL(), url) ||
         CompareURLsIgnoreRef(tc->GetURL(), rewritten_url)) {
-      tabstrip_model_->SelectTabContentsAt(i, false);
+      model->SelectTabContentsAt(i, false);
       return;
     }
   }
@@ -1107,7 +1107,7 @@
   TabContents* current_tab = GetSelectedTabContents();
   if (ShouldOpenNewTabForWindowDisposition(disposition)) {
     current_tab = current_tab->Clone();
-    tabstrip_model_->AddTabContents(
+    tab_handler_->GetTabStripModel()->AddTabContents(
         current_tab, -1, PageTransition::LINK,
         disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_SELECTED :
                                             TabStripModel::ADD_NONE);
@@ -1116,7 +1116,7 @@
 }
 
 void Browser::UpdateTabStripModelInsertionPolicy() {
-  tabstrip_model_->SetInsertionPolicy(UseVerticalTabs() ?
+  tab_handler_->GetTabStripModel()->SetInsertionPolicy(UseVerticalTabs() ?
       TabStripModel::INSERT_BEFORE : TabStripModel::INSERT_AFTER);
 }
 
@@ -1301,8 +1301,8 @@
   UserMetrics::RecordAction(UserMetricsAction("CloseTab_Accelerator"),
                             profile_);
   if (CanCloseTab()) {
-    tabstrip_model_->CloseTabContentsAt(
-        tabstrip_model_->selected_index(),
+    tab_handler_->GetTabStripModel()->CloseTabContentsAt(
+        tab_handler_->GetTabStripModel()->selected_index(),
         TabStripModel::CLOSE_USER_GESTURE |
         TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
   }
@@ -1310,12 +1310,12 @@
 
 void Browser::SelectNextTab() {
   UserMetrics::RecordAction(UserMetricsAction("SelectNextTab"), profile_);
-  tabstrip_model_->SelectNextTab();
+  tab_handler_->GetTabStripModel()->SelectNextTab();
 }
 
 void Browser::SelectPreviousTab() {
   UserMetrics::RecordAction(UserMetricsAction("SelectPrevTab"), profile_);
-  tabstrip_model_->SelectPreviousTab();
+  tab_handler_->GetTabStripModel()->SelectPreviousTab();
 }
 
 void Browser::OpenTabpose() {
@@ -1334,25 +1334,25 @@
 
 void Browser::MoveTabNext() {
   UserMetrics::RecordAction(UserMetricsAction("MoveTabNext"), profile_);
-  tabstrip_model_->MoveTabNext();
+  tab_handler_->GetTabStripModel()->MoveTabNext();
 }
 
 void Browser::MoveTabPrevious() {
   UserMetrics::RecordAction(UserMetricsAction("MoveTabPrevious"), profile_);
-  tabstrip_model_->MoveTabPrevious();
+  tab_handler_->GetTabStripModel()->MoveTabPrevious();
 }
 
 void Browser::SelectNumberedTab(int index) {
   if (index < tab_count()) {
     UserMetrics::RecordAction(UserMetricsAction("SelectNumberedTab"),
                               profile_);
-    tabstrip_model_->SelectTabContentsAt(index, true);
+    tab_handler_->GetTabStripModel()->SelectTabContentsAt(index, true);
   }
 }
 
 void Browser::SelectLastTab() {
   UserMetrics::RecordAction(UserMetricsAction("SelectLastTab"), profile_);
-  tabstrip_model_->SelectLastTab();
+  tab_handler_->GetTabStripModel()->SelectLastTab();
 }
 
 void Browser::DuplicateTab() {
@@ -1386,8 +1386,9 @@
 
 void Browser::ConvertPopupToTabbedBrowser() {
   UserMetrics::RecordAction(UserMetricsAction("ShowAsTab"), profile_);
-  int tab_strip_index = tabstrip_model_->selected_index();
-  TabContents* contents = tabstrip_model_->DetachTabContentsAt(tab_strip_index);
+  int tab_strip_index = tab_handler_->GetTabStripModel()->selected_index();
+  TabContents* contents =
+      tab_handler_->GetTabStripModel()->DetachTabContentsAt(tab_strip_index);
   Browser* browser = Browser::Create(profile_);
   browser->tabstrip_model()->AppendTabContents(contents, true);
   browser->window()->Show();
@@ -1760,8 +1761,9 @@
   GURL url(chrome::kChromeUISettingsURL + sub_page);
 
   // See if there is already an options tab open that we can use.
-  for (int i = 0; i < tabstrip_model_->count(); i++) {
-    TabContents* tc = tabstrip_model_->GetTabContentsAt(i);
+  TabStripModel* model = tab_handler_->GetTabStripModel();
+  for (int i = 0; i < model->count(); i++) {
+    TabContents* tc = model->GetTabContentsAt(i);
     const GURL& tab_url = tc->GetURL();
 
     if (tab_url.scheme() == url.scheme() && tab_url.host() == url.host()) {
@@ -1771,7 +1773,7 @@
       // URL in the address bar, but security policy doesn't allow that.
       OpenURLAtIndex(tc, url, GURL(), CURRENT_TAB, PageTransition::GENERATED,
                      -1, -1);
-      tabstrip_model_->SelectTabContentsAt(i, false);
+      model->SelectTabContentsAt(i, false);
       return;
     }
   }
@@ -1996,11 +1998,29 @@
 }
 
 // static
+bool Browser::RunUnloadEventsHelper(TabContents* contents) {
+  // If the TabContents is not connected yet, then there's no unload
+  // handler we can fire even if the TabContents has an unload listener.
+  // One case where we hit this is in a tab that has an infinite loop
+  // before load.
+  if (TabHasUnloadListener(contents)) {
+    // If the page has unload listeners, then we tell the renderer to fire
+    // them. Once they have fired, we'll get a message back saying whether
+    // to proceed closing the page or not, which sends us back to this method
+    // with the HasUnloadListener bit cleared.
+    contents->render_view_host()->FirePageBeforeUnload(false);
+    return true;
+  }
+  return false;
+}
+
+// static
 Browser* Browser::GetBrowserForController(
     const NavigationController* controller, int* index_result) {
   BrowserList::const_iterator it;
   for (it = BrowserList::begin(); it != BrowserList::end(); ++it) {
-    int index = (*it)->tabstrip_model_->GetIndexOfController(controller);
+    int index = (*it)->tab_handler_->GetTabStripModel()->GetIndexOfController(
+        controller);
     if (index != TabStripModel::kNoTab) {
       if (index_result)
         *index_result = index;
@@ -2225,6 +2245,14 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// Browser, PageNavigator implementation:
+void Browser::OpenURL(const GURL& url, const GURL& referrer,
+                      WindowOpenDisposition disposition,
+                      PageTransition::Type transition) {
+  OpenURLFromTab(NULL, url, referrer, disposition, transition);
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // Browser, CommandUpdater::CommandUpdaterDelegate implementation:
 
 void Browser::ExecuteCommand(int id) {
@@ -2232,6 +2260,17 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// Browser, TabHandlerDelegate implementation:
+
+Profile* Browser::GetProfile() const {
+  return profile();
+}
+
+Browser* Browser::AsBrowser() {
+  return this;
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // Browser, TabStripModelDelegate implementation:
 
 TabContents* Browser::AddBlankTab(bool foreground) {
@@ -2287,7 +2326,8 @@
 }
 
 int Browser::GetDragActions() const {
-  return TAB_TEAROFF_ACTION | (tab_count() > 1 ? TAB_MOVE_ACTION : 0);
+  return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ?
+      TabStripModelDelegate::TAB_MOVE_ACTION : 0);
 }
 
 TabContents* Browser::CreateTabContentsForURL(
@@ -2295,7 +2335,8 @@
     PageTransition::Type transition, bool defer_load,
     SiteInstance* instance) const {
   TabContents* contents = new TabContents(profile, instance,
-      MSG_ROUTING_NONE, tabstrip_model_->GetSelectedTabContents(), NULL);
+      MSG_ROUTING_NONE,
+      tab_handler_->GetTabStripModel()->GetSelectedTabContents(), NULL);
 
   if (!defer_load) {
     // Load the initial URL before adding the new tab contents to the tab strip
@@ -2321,11 +2362,13 @@
     // If this is a tabbed browser, just create a duplicate tab inside the same
     // window next to the tab being duplicated.
     new_contents = contents->Clone();
-    pinned = tabstrip_model_->IsTabPinned(index);
+    pinned = tab_handler_->GetTabStripModel()->IsTabPinned(index);
     int add_types = TabStripModel::ADD_SELECTED |
         TabStripModel::ADD_INHERIT_GROUP |
         (pinned ? TabStripModel::ADD_PINNED : 0);
-    tabstrip_model_->InsertTabContentsAt(index + 1, new_contents, add_types);
+    tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
+                                                          new_contents,
+                                                          add_types);
   } else {
     Browser* browser = NULL;
     if (type_ & TYPE_APP) {
@@ -2397,7 +2440,7 @@
 bool Browser::CanCloseContentsAt(int index) {
   if (!CanCloseTab())
     return false;
-  if (tabstrip_model_->count() > 1)
+  if (tab_handler_->GetTabStripModel()->count() > 1)
     return true;
   // We are closing the last tab for this browser. Make sure to check for
   // in-progress downloads.
@@ -2525,9 +2568,9 @@
   // exist, the change will be picked up by sessions when created.
   if (profile_->HasSessionService()) {
     SessionService* session_service = profile_->GetSessionService();
-    if (session_service && !tabstrip_model_->closing_all()) {
+    if (session_service && !tab_handler_->GetTabStripModel()->closing_all()) {
       session_service->SetSelectedTabInWindow(
-          session_id(), tabstrip_model_->selected_index());
+          session_id(), tab_handler_->GetTabStripModel()->selected_index());
     }
   }
 }
@@ -2544,7 +2587,7 @@
                             TabContents* new_contents, int index) {
   TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
   TabInsertedAt(new_contents, index,
-                (index == tabstrip_model_->selected_index()));
+                (index == tab_handler_->GetTabStripModel()->selected_index()));
 
   int entry_count = new_contents->controller().entry_count();
   if (entry_count > 0) {
@@ -2563,7 +2606,7 @@
     session_service->SetPinnedState(
         session_id(),
         GetTabContentsAt(index)->controller().session_id(),
-        tabstrip_model_->IsTabPinned(index));
+        tab_handler_->GetTabStripModel()->IsTabPinned(index));
   }
 }
 
@@ -2581,14 +2624,6 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// Browser, PageNavigator implementation:
-void Browser::OpenURL(const GURL& url, const GURL& referrer,
-                      WindowOpenDisposition disposition,
-                      PageTransition::Type transition) {
-  OpenURLFromTab(NULL, url, referrer, disposition, transition);
-}
-
-///////////////////////////////////////////////////////////////////////////////
 // Browser, TabContentsDelegate implementation:
 
 void Browser::OpenURLFromTab(TabContents* source,
@@ -2624,7 +2659,8 @@
   // If this is a window with no tabstrip, we can only have one tab so we need
   // to process this in tabbed browser window.
   if (!CanSupportWindowFeature(FEATURE_TABSTRIP) &&
-      tabstrip_model_->count() > 0 && disposition != NEW_WINDOW &&
+      tab_handler_->GetTabStripModel()->count() > 0 &&
+      disposition != NEW_WINDOW &&
       disposition != NEW_POPUP) {
     Browser* b = GetOrCreateTabbedBrowser(profile_);
     DCHECK(b);
@@ -2650,7 +2686,7 @@
                             initial_pos, user_gesture);
     browser->window()->Show();
   } else if (disposition != SUPPRESS_OPEN) {
-    tabstrip_model_->AddTabContents(
+    tab_handler_->GetTabStripModel()->AddTabContents(
         new_contents, -1, PageTransition::LINK,
         disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_SELECTED :
                                             TabStripModel::ADD_NONE);
@@ -2658,8 +2694,8 @@
 }
 
 void Browser::ActivateContents(TabContents* contents) {
-  tabstrip_model_->SelectTabContentsAt(
-      tabstrip_model_->GetIndexOfTabContents(contents), false);
+  tab_handler_->GetTabStripModel()->SelectTabContentsAt(
+      tab_handler_->GetTabStripModel()->GetIndexOfTabContents(contents), false);
   window_->Activate();
 }
 
@@ -2668,7 +2704,8 @@
 }
 
 void Browser::LoadingStateChanged(TabContents* source) {
-  window_->UpdateLoadingAnimations(tabstrip_model_->TabsAreLoading());
+  window_->UpdateLoadingAnimations(
+      tab_handler_->GetTabStripModel()->TabsAreLoading());
   window_->UpdateTitleBar();
 
   if (source == GetSelectedTabContents()) {
@@ -2707,12 +2744,12 @@
     return;
   }
 
-  int index = tabstrip_model_->GetIndexOfTabContents(source);
+  int index = tab_handler_->GetTabStripModel()->GetIndexOfTabContents(source);
   if (index == TabStripModel::kNoTab) {
     NOTREACHED() << "CloseContents called for tab not in our strip";
     return;
   }
-  tabstrip_model_->CloseTabContentsAt(
+  tab_handler_->GetTabStripModel()->CloseTabContentsAt(
       index,
       TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
 }
@@ -2726,9 +2763,9 @@
 }
 
 void Browser::DetachContents(TabContents* source) {
-  int index = tabstrip_model_->GetIndexOfTabContents(source);
+  int index = tab_handler_->GetTabStripModel()->GetIndexOfTabContents(source);
   if (index >= 0)
-    tabstrip_model_->DetachTabContentsAt(index);
+    tab_handler_->GetTabStripModel()->DetachTabContentsAt(index);
 }
 
 bool Browser::IsPopup(const TabContents* source) const {
@@ -3082,8 +3119,9 @@
 
       // Close any tabs from the unloaded extension.
       Extension* extension = Details<Extension>(details).ptr();
-      for (int i = tabstrip_model_->count() - 1; i >= 0; --i) {
-        TabContents* tc = tabstrip_model_->GetTabContentsAt(i);
+      TabStripModel* model = tab_handler_->GetTabStripModel();
+      for (int i = model->count() - 1; i >= 0; --i) {
+        TabContents* tc = model->GetTabContentsAt(i);
         if (tc->GetURL().SchemeIs(chrome::kExtensionScheme) &&
             tc->GetURL().host() == extension->id()) {
           CloseTabContents(tc);
@@ -3203,12 +3241,13 @@
 
 void Browser::CommitMatchPreview(TabContents* preview_contents) {
   TabContents* tab_contents = match_preview_->tab_contents();
-  int index = tabstrip_model_->GetIndexOfTabContents(tab_contents);
+  int index = tab_handler_->GetTabStripModel()->GetIndexOfTabContents(
+      tab_contents);
   DCHECK_NE(-1, index);
   preview_contents->controller().CopyStateFromAndPrune(
       tab_contents->controller());
   // TabStripModel takes ownership of preview_contents.
-  tabstrip_model_->ReplaceTabContentsAt(
+  tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(
       index,
       preview_contents,
       TabStripModelObserver::REPLACE_MATCH_PREVIEW);
@@ -3474,8 +3513,9 @@
     // Update the loading state synchronously. This is so the throbber will
     // immediately start/stop, which gives a more snappy feel. We want to do
     // this for any tab so they start & stop quickly.
-    tabstrip_model_->UpdateTabContentsStateAt(
-        tabstrip_model_->GetIndexOfController(&source->controller()),
+    tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
+        tab_handler_->GetTabStripModel()->GetIndexOfController(
+            &source->controller()),
         TabStripModelObserver::LOADING_ONLY);
     // The status bubble needs to be updated during INVALIDATE_LOAD too, but
     // we do that asynchronously by not stripping INVALIDATE_LOAD from
@@ -3487,8 +3527,9 @@
     // we need to process the update synchronously. This state only matters for
     // the TabStripModel, so we notify the TabStripModel now and notify others
     // asynchronously.
-    tabstrip_model_->UpdateTabContentsStateAt(
-        tabstrip_model_->GetIndexOfController(&source->controller()),
+    tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
+        tab_handler_->GetTabStripModel()->GetIndexOfController(
+            &source->controller()),
         TabStripModelObserver::TITLE_NOT_LOADING);
   }
 
@@ -3564,8 +3605,8 @@
 
     // Updates that don't depend upon the selected state go here.
     if (flags & (TabContents::INVALIDATE_TAB | TabContents::INVALIDATE_TITLE)) {
-      tabstrip_model_->UpdateTabContentsStateAt(
-          tabstrip_model_->GetIndexOfTabContents(contents),
+      tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
+          tab_handler_->GetTabStripModel()->GetIndexOfTabContents(contents),
           TabStripModelObserver::ALL);
     }
 
@@ -3610,9 +3651,10 @@
       if (contents) {
         session_service->SetTabIndexInWindow(
             session_id(), contents->controller().session_id(), i);
-        session_service->SetPinnedState(session_id(),
-                                        contents->controller().session_id(),
-                                        tabstrip_model_->IsTabPinned(i));
+        session_service->SetPinnedState(
+            session_id(),
+            contents->controller().session_id(),
+            tab_handler_->GetTabStripModel()->IsTabPinned(i));
       }
     }
   }
@@ -3897,7 +3939,7 @@
         &browser);
     browser->window()->Show();
   } else if ((disposition == CURRENT_TAB) && current_tab) {
-    tabstrip_model_->TabNavigating(current_tab, transition);
+    tab_handler_->GetTabStripModel()->TabNavigating(current_tab, transition);
 
     bool user_initiated = (PageTransition::StripQualifier(transition) ==
                            PageTransition::AUTO_BOOKMARK);
@@ -4017,15 +4059,17 @@
     // Save what the user's currently typed.
     window_->GetLocationBar()->SaveStateToContents(contents);
 
-    if (!tabstrip_model_->closing_all())
+    if (!tab_handler_->GetTabStripModel()->closing_all())
       SyncHistoryWithTabs(0);
   }
 
   contents->set_delegate(NULL);
   RemoveScheduledUpdatesFor(contents);
 
-  if (find_bar_controller_.get() && index == tabstrip_model_->selected_index())
+  if (find_bar_controller_.get() &&
+      index == tab_handler_->GetTabStripModel()->selected_index()) {
     find_bar_controller_->ChangeTabContents(NULL);
+  }
 
   registrar_.Remove(this, NotificationType::TAB_CONTENTS_DISCONNECTED,
                     Source<TabContents>(contents));
@@ -4054,23 +4098,6 @@
   prefs->RegisterDictionaryPref(window_pref.c_str());
 }
 
-// static
-bool Browser::RunUnloadEventsHelper(TabContents* contents) {
-  // If the TabContents is not connected yet, then there's no unload
-  // handler we can fire even if the TabContents has an unload listener.
-  // One case where we hit this is in a tab that has an infinite loop
-  // before load.
-  if (TabHasUnloadListener(contents)) {
-    // If the page has unload listeners, then we tell the renderer to fire
-    // them. Once they have fired, we'll get a message back saying whether
-    // to proceed closing the page or not, which sends us back to this method
-    // with the HasUnloadListener bit cleared.
-    contents->render_view_host()->FirePageBeforeUnload(false);
-    return true;
-  }
-  return false;
-}
-
 void Browser::TabRestoreServiceChanged(TabRestoreService* service) {
   command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
                                         !service->entries().empty());
@@ -4098,7 +4125,7 @@
     TabContents* preview_contents = match_preview()->ReleasePreviewContents(
         MatchPreview::COMMIT_PRESSED_ENTER);
     preview_contents->controller().PruneAllButActive();
-    tabstrip_model_->AddTabContents(
+    tab_handler_->GetTabStripModel()->AddTabContents(
         preview_contents,
         -1,
         match_preview()->last_transition_type(),