Switch BookmarkTabHelper to use WebContentsUserData.

BUG=107201
TEST=no visible change


Review URL: https://chromiumcodereview.appspot.com/10945010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157456 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/bookmarks/bookmark_manager_extension_api.cc b/chrome/browser/bookmarks/bookmark_manager_extension_api.cc
index 43e3b4d9..85f9b40a 100644
--- a/chrome/browser/bookmarks/bookmark_manager_extension_api.cc
+++ b/chrome/browser/bookmarks/bookmark_manager_extension_api.cc
@@ -158,12 +158,16 @@
     Profile* profile, TabContents* tab)
     : profile_(profile),
     tab_(tab) {
-  tab_->bookmark_tab_helper()->SetBookmarkDragDelegate(this);
+  BookmarkTabHelper* bookmark_tab_helper =
+      BookmarkTabHelper::FromWebContents(tab_->web_contents());
+  bookmark_tab_helper->SetBookmarkDragDelegate(this);
 }
 
 BookmarkManagerExtensionEventRouter::~BookmarkManagerExtensionEventRouter() {
-  if (tab_->bookmark_tab_helper()->GetBookmarkDragDelegate() == this)
-    tab_->bookmark_tab_helper()->SetBookmarkDragDelegate(NULL);
+  BookmarkTabHelper* bookmark_tab_helper =
+      BookmarkTabHelper::FromWebContents(tab_->web_contents());
+  if (bookmark_tab_helper->GetBookmarkDragDelegate() == this)
+    bookmark_tab_helper->SetBookmarkDragDelegate(NULL);
 }
 
 void BookmarkManagerExtensionEventRouter::DispatchEvent(
diff --git a/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.cc b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.cc
index a7e44f25..049fe5f 100644
--- a/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.cc
+++ b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.cc
@@ -245,7 +245,7 @@
 }
 
 // TODO(merge): WARNING! method no longer available on the base class.
-// See http://b/issue?id=5862108
+// See http://crbug.com/149477
 void WebContentsDelegateAndroid::URLStarredChanged(WebContents* source,
                                                    bool starred) {
   JNIEnv* env = AttachCurrentThread();
diff --git a/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h
index fb7aef6..84c75de5 100644
--- a/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h
+++ b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h
@@ -89,7 +89,7 @@
                                    int32 line_no,
                                    const string16& source_id) OVERRIDE;
   // TODO(merge): WARNING! method no longer available on the base class.
-  // See http://b/issue?id=5862108
+  // See http://crbug.com/149477
   virtual void URLStarredChanged(content::WebContents* source, bool starred);
   virtual void UpdateTargetURL(content::WebContents* source,
                                int32 page_id,
diff --git a/chrome/browser/tab_contents/web_drag_bookmark_handler_aura.cc b/chrome/browser/tab_contents/web_drag_bookmark_handler_aura.cc
index 90c4665c..7bd23b57 100644
--- a/chrome/browser/tab_contents/web_drag_bookmark_handler_aura.cc
+++ b/chrome/browser/tab_contents/web_drag_bookmark_handler_aura.cc
@@ -9,7 +9,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
-#include "chrome/browser/ui/tab_contents/tab_contents.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/dragdrop/os_exchange_data.h"
 #include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
@@ -18,33 +17,34 @@
 using content::WebContents;
 
 WebDragBookmarkHandlerAura::WebDragBookmarkHandlerAura()
-    : tab_(NULL) {
+    : bookmark_tab_helper_(NULL),
+      web_contents_(NULL) {
 }
 
 WebDragBookmarkHandlerAura::~WebDragBookmarkHandlerAura() {
 }
 
 void WebDragBookmarkHandlerAura::DragInitialize(WebContents* contents) {
-  // Ideally we would want to initialize the the TabContents member in
+  // Ideally we would want to initialize the the BookmarkTabHelper member in
   // the constructor. We cannot do that as the WebDragDest object is
   // created during the construction of the WebContents object.  The
-  // TabContents is created much later.
-  DCHECK(tab_ ? (tab_->web_contents() == contents) : true);
-  if (!tab_)
-    tab_ = TabContents::FromWebContents(contents);
+  // BookmarkTabHelper is created much later.
+  web_contents_ = contents;
+  if (!bookmark_tab_helper_)
+    bookmark_tab_helper_ = BookmarkTabHelper::FromWebContents(contents);
 }
 
 void WebDragBookmarkHandlerAura::OnDragOver() {
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
     if (bookmark_drag_data_.is_valid())
-      tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragOver(
+      bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragOver(
           bookmark_drag_data_);
   }
 }
 
 void WebDragBookmarkHandlerAura::OnReceiveDragData(
     const ui::OSExchangeData& data) {
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
     // Read the bookmark drag data and save it for use in later events in this
     // drag.
     bookmark_drag_data_.Read(data);
@@ -52,25 +52,24 @@
 }
 
 void WebDragBookmarkHandlerAura::OnDragEnter() {
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
     if (bookmark_drag_data_.is_valid())
-      tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragEnter(
+      bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragEnter(
           bookmark_drag_data_);
   }
 }
 
 void WebDragBookmarkHandlerAura::OnDrop() {
-  if (tab_) {
-    if (tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
+  if (bookmark_tab_helper_) {
+    if (bookmark_tab_helper_->GetBookmarkDragDelegate()) {
       if (bookmark_drag_data_.is_valid()) {
-        tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDrop(
+        bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDrop(
             bookmark_drag_data_);
       }
     }
 
     // Focus the target browser.
-    Browser* browser = browser::FindBrowserWithWebContents(
-        tab_->web_contents());
+    Browser* browser = browser::FindBrowserWithWebContents(web_contents_);
     if (browser)
       browser->window()->Show();
   }
@@ -79,9 +78,9 @@
 }
 
 void WebDragBookmarkHandlerAura::OnDragLeave() {
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
     if (bookmark_drag_data_.is_valid())
-      tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragLeave(
+      bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragLeave(
           bookmark_drag_data_);
   }
 
diff --git a/chrome/browser/tab_contents/web_drag_bookmark_handler_aura.h b/chrome/browser/tab_contents/web_drag_bookmark_handler_aura.h
index 835eef0b..e628e51 100644
--- a/chrome/browser/tab_contents/web_drag_bookmark_handler_aura.h
+++ b/chrome/browser/tab_contents/web_drag_bookmark_handler_aura.h
@@ -9,7 +9,11 @@
 #include "content/public/browser/web_drag_dest_delegate.h"
 #include "chrome/browser/bookmarks/bookmark_node_data.h"
 
-class TabContents;
+class BookmarkTabHelper;
+
+namespace content {
+class WebContents;
+}
 
 // Chrome needs to intercept content drag events so it can dispatch them to the
 // bookmarks and extensions system.
@@ -30,10 +34,12 @@
   virtual void OnReceiveDragData(const ui::OSExchangeData& data) OVERRIDE;
 
  private:
-  // The TabContents.
-  // Weak reference; may be NULL if the contents aren't contained in a
-  // TabContents (e.g. WebUI dialogs).
-  TabContents* tab_;
+  // The BookmarkTabHelper.
+  // Weak reference; may be NULL if the contents don't have a
+  // BookmarkTabHelper (e.g. WebUI dialogs).
+  BookmarkTabHelper* bookmark_tab_helper_;
+
+  content::WebContents* web_contents_;
 
   // The bookmark data for the active drag.  Empty when there is no active drag.
   BookmarkNodeData bookmark_drag_data_;
diff --git a/chrome/browser/tab_contents/web_drag_bookmark_handler_gtk.cc b/chrome/browser/tab_contents/web_drag_bookmark_handler_gtk.cc
index 83ab25e..f26d502e 100644
--- a/chrome/browser/tab_contents/web_drag_bookmark_handler_gtk.cc
+++ b/chrome/browser/tab_contents/web_drag_bookmark_handler_gtk.cc
@@ -9,7 +9,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h"
 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
-#include "chrome/browser/ui/tab_contents/tab_contents.h"
 #include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/dragdrop/gtk_dnd_util.h"
@@ -17,7 +16,8 @@
 using content::WebContents;
 
 WebDragBookmarkHandlerGtk::WebDragBookmarkHandlerGtk()
-    : tab_(NULL) {
+    : bookmark_tab_helper_(NULL),
+      web_contents_(NULL) {
 }
 
 WebDragBookmarkHandlerGtk::~WebDragBookmarkHandlerGtk() {}
@@ -25,13 +25,13 @@
 void WebDragBookmarkHandlerGtk::DragInitialize(WebContents* contents) {
   bookmark_drag_data_.Clear();
 
-  // Ideally we would want to initialize the the TabContents member in
+  // Ideally we would want to initialize the the BookmarkTabHelper member in
   // the constructor. We cannot do that as the WebDragDestGtk object is
   // created during the construction of the WebContents object.  The
-  // TabContents is created much later.
-  DCHECK(tab_ ? (tab_->web_contents() == contents) : true);
-  if (!tab_)
-    tab_ = TabContents::FromWebContents(contents);
+  // BookmarkTabHelper is created much later.
+  web_contents_ = contents;
+  if (!bookmark_tab_helper_)
+    bookmark_tab_helper_ = BookmarkTabHelper::FromWebContents(contents);
 }
 
 GdkAtom WebDragBookmarkHandlerGtk::GetBookmarkTargetAtom() const {
@@ -42,15 +42,14 @@
 }
 
 void WebDragBookmarkHandlerGtk::OnReceiveDataFromGtk(GtkSelectionData* data) {
-  if (tab_) {
-    Profile* profile = tab_->profile();
-    bookmark_drag_data_.ReadFromVector(
-        bookmark_utils::GetNodesFromSelection(
-            NULL, data,
-            ui::CHROME_BOOKMARK_ITEM,
-            profile, NULL, NULL));
-    bookmark_drag_data_.SetOriginatingProfile(profile);
-  }
+  Profile* profile =
+      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
+  bookmark_drag_data_.ReadFromVector(
+      bookmark_utils::GetNodesFromSelection(
+          NULL, data,
+          ui::CHROME_BOOKMARK_ITEM,
+          profile, NULL, NULL));
+  bookmark_drag_data_.SetOriginatingProfile(profile);
 }
 
 void WebDragBookmarkHandlerGtk::OnReceiveProcessedData(const GURL& url,
@@ -59,17 +58,17 @@
 }
 
 void WebDragBookmarkHandlerGtk::OnDragOver() {
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
-    tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragOver(
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
+    bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragOver(
         bookmark_drag_data_);
   }
 }
 
 void WebDragBookmarkHandlerGtk::OnDragEnter() {
-  // This is non-null if tab_contents_ is showing an ExtensionWebUI with
+  // This is non-null if the web_contents_ is showing an ExtensionWebUI with
   // support for (at the moment experimental) drag and drop extensions.
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
-    tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragEnter(
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
+    bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragEnter(
         bookmark_drag_data_);
   }
 }
@@ -77,23 +76,22 @@
 void WebDragBookmarkHandlerGtk::OnDrop() {
   // This is non-null if tab_contents_ is showing an ExtensionWebUI with
   // support for (at the moment experimental) drag and drop extensions.
-  if (tab_) {
-    if (tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
-      tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDrop(
+  if (bookmark_tab_helper_) {
+    if (bookmark_tab_helper_->GetBookmarkDragDelegate()) {
+      bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDrop(
           bookmark_drag_data_);
     }
 
     // Focus the target browser.
-    Browser* browser = browser::FindBrowserWithWebContents(
-        tab_->web_contents());
+    Browser* browser = browser::FindBrowserWithWebContents(web_contents_);
     if (browser)
       browser->window()->Show();
   }
 }
 
 void WebDragBookmarkHandlerGtk::OnDragLeave() {
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
-    tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragLeave(
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
+    bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragLeave(
         bookmark_drag_data_);
   }
 }
diff --git a/chrome/browser/tab_contents/web_drag_bookmark_handler_gtk.h b/chrome/browser/tab_contents/web_drag_bookmark_handler_gtk.h
index 72a052da..f144340d3 100644
--- a/chrome/browser/tab_contents/web_drag_bookmark_handler_gtk.h
+++ b/chrome/browser/tab_contents/web_drag_bookmark_handler_gtk.h
@@ -9,7 +9,11 @@
 #include "chrome/browser/bookmarks/bookmark_node_data.h"
 #include "content/public/browser/web_drag_dest_delegate.h"
 
-class TabContents;
+class BookmarkTabHelper;
+
+namespace content {
+class WebContents;
+}
 
 // Chrome needs to intercept content drag events so it can dispatch them to the
 // bookmarks and extensions system.
@@ -30,10 +34,12 @@
   virtual void OnDragLeave() OVERRIDE;
 
  private:
-  // The TabContents.
-  // Weak reference; may be NULL if the contents aren't contained in a
-  // TabContents (e.g. WebUI dialogs).
-  TabContents* tab_;
+  // The BookmarkTabHelper.
+  // Weak reference; may be NULL if the contents don't have a
+  // BookmarkTabHelper (e.g. WebUI dialogs).
+  BookmarkTabHelper* bookmark_tab_helper_;
+
+  content::WebContents* web_contents_;
 
   // The bookmark data for the current tab. This will be empty if there is not
   // a native bookmark drag (or we haven't gotten the data from the source yet).
diff --git a/chrome/browser/tab_contents/web_drag_bookmark_handler_mac.h b/chrome/browser/tab_contents/web_drag_bookmark_handler_mac.h
index a94bf4b..2dbd8a8d 100644
--- a/chrome/browser/tab_contents/web_drag_bookmark_handler_mac.h
+++ b/chrome/browser/tab_contents/web_drag_bookmark_handler_mac.h
@@ -9,7 +9,11 @@
 #include "chrome/browser/bookmarks/bookmark_node_data.h"
 #include "content/public/browser/web_drag_dest_delegate.h"
 
-class TabContents;
+class BookmarkTabHelper;
+
+namespace content {
+class WebContents;
+}
 
 // Chrome needs to intercept content drag events so it can dispatch them to the
 // bookmarks and extensions system.
@@ -26,10 +30,12 @@
   virtual void OnDragLeave() OVERRIDE;
 
  private:
-  // The TabContents.
-  // Weak reference; may be NULL if the contents aren't contained in a
-  // TabContents (e.g. WebUI dialogs).
-  TabContents* tab_;
+  // The BookmarkTabHelper.
+  // Weak reference; may be NULL if the contents don't have a
+  // BookmarkTabHelper (e.g. WebUI dialogs).
+  BookmarkTabHelper* bookmark_tab_helper_;
+
+  content::WebContents* web_contents_;
 
   // The bookmark data for the current tab. This will be empty if there is not
   // a native bookmark drag.
diff --git a/chrome/browser/tab_contents/web_drag_bookmark_handler_mac.mm b/chrome/browser/tab_contents/web_drag_bookmark_handler_mac.mm
index bf2bc5ac..a2ce829 100644
--- a/chrome/browser/tab_contents/web_drag_bookmark_handler_mac.mm
+++ b/chrome/browser/tab_contents/web_drag_bookmark_handler_mac.mm
@@ -8,59 +8,58 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
-#include "chrome/browser/ui/tab_contents/tab_contents.h"
 #include "content/public/browser/web_contents.h"
 
 using content::WebContents;
 
 WebDragBookmarkHandlerMac::WebDragBookmarkHandlerMac()
-    : tab_(NULL) {
+    : bookmark_tab_helper_(NULL),
+      web_contents_(NULL) {
 }
 
 WebDragBookmarkHandlerMac::~WebDragBookmarkHandlerMac() {}
 
 void WebDragBookmarkHandlerMac::DragInitialize(WebContents* contents) {
-  DCHECK(tab_ ? (tab_->web_contents() == contents) : true);
-  if (!tab_)
-    tab_ = TabContents::FromWebContents(contents);
+  web_contents_ = contents;
+  if (!bookmark_tab_helper_)
+    bookmark_tab_helper_ = BookmarkTabHelper::FromWebContents(contents);
 
   bookmark_drag_data_.ReadFromDragClipboard();
 }
 
 void WebDragBookmarkHandlerMac::OnDragOver() {
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
-    tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragOver(
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
+    bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragOver(
         bookmark_drag_data_);
   }
 }
 
 void WebDragBookmarkHandlerMac::OnDragEnter() {
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
-    tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragEnter(
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
+    bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragEnter(
         bookmark_drag_data_);
   }
 }
 
 void WebDragBookmarkHandlerMac::OnDrop() {
-  // This is non-null if tab_contents_ is showing an ExtensionWebUI with
+  // This is non-null if the web_contents_ is showing an ExtensionWebUI with
   // support for (at the moment experimental) drag and drop extensions.
-  if (tab_) {
-    if (tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
-      tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDrop(
+  if (bookmark_tab_helper_) {
+    if (bookmark_tab_helper_->GetBookmarkDragDelegate()) {
+      bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDrop(
           bookmark_drag_data_);
     }
 
     // Focus the target browser.
-    Browser* browser = browser::FindBrowserWithWebContents(
-        tab_->web_contents());
+    Browser* browser = browser::FindBrowserWithWebContents(web_contents_);
     if (browser)
       browser->window()->Show();
   }
 }
 
 void WebDragBookmarkHandlerMac::OnDragLeave() {
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
-    tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragLeave(
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
+    bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragLeave(
         bookmark_drag_data_);
   }
 }
diff --git a/chrome/browser/tab_contents/web_drag_bookmark_handler_win.cc b/chrome/browser/tab_contents/web_drag_bookmark_handler_win.cc
index 277d25a..827796e0 100644
--- a/chrome/browser/tab_contents/web_drag_bookmark_handler_win.cc
+++ b/chrome/browser/tab_contents/web_drag_bookmark_handler_win.cc
@@ -9,7 +9,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
-#include "chrome/browser/ui/tab_contents/tab_contents.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/web_contents.h"
@@ -20,75 +19,75 @@
 using content::WebContents;
 
 WebDragBookmarkHandlerWin::WebDragBookmarkHandlerWin()
-    : tab_(NULL) {
+    : bookmark_tab_helper_(NULL),
+      web_contents_(NULL) {
 }
 
 WebDragBookmarkHandlerWin::~WebDragBookmarkHandlerWin() {
 }
 
 void WebDragBookmarkHandlerWin::DragInitialize(WebContents* contents) {
-  // Ideally we would want to initialize the the TabContents member in
+  // Ideally we would want to initialize the the BookmarkTabHelper member in
   // the constructor. We cannot do that as the WebDragTargetWin object is
   // created during the construction of the WebContents object.  The
-  // TabContents is created much later.
-  DCHECK(tab_ ? (tab_->web_contents() == contents) : true);
-  if (!tab_)
-    tab_ = TabContents::FromWebContents(contents);
+  // BookmarkTabHelper is created much later.
+  web_contents_ = contents;
+  if (!bookmark_tab_helper_)
+    bookmark_tab_helper_ = BookmarkTabHelper::FromWebContents(contents);
 }
 
 void WebDragBookmarkHandlerWin::OnDragOver(IDataObject* data_object) {
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
     ui::OSExchangeData os_exchange_data(
         new ui::OSExchangeDataProviderWin(data_object));
     BookmarkNodeData bookmark_drag_data;
     if (bookmark_drag_data.Read(os_exchange_data))
-      tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragOver(
+      bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragOver(
           bookmark_drag_data);
   }
 }
 
 void WebDragBookmarkHandlerWin::OnDragEnter(IDataObject* data_object) {
-  // This is non-null if web_contents_ is showing an ExtensionWebUI with
+  // This is non-null if the web_contents_ is showing an ExtensionWebUI with
   // support for (at the moment experimental) drag and drop extensions.
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
     ui::OSExchangeData os_exchange_data(
         new ui::OSExchangeDataProviderWin(data_object));
     BookmarkNodeData bookmark_drag_data;
     if (bookmark_drag_data.Read(os_exchange_data))
-      tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragEnter(
+      bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragEnter(
           bookmark_drag_data);
   }
 }
 
 void WebDragBookmarkHandlerWin::OnDrop(IDataObject* data_object) {
-  // This is non-null if tab_contents_ is showing an ExtensionWebUI with
+  // This is non-null if the web_contents_ is showing an ExtensionWebUI with
   // support for (at the moment experimental) drag and drop extensions.
-  if (tab_) {
-    if (tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
+  if (bookmark_tab_helper_) {
+    if (bookmark_tab_helper_->GetBookmarkDragDelegate()) {
       ui::OSExchangeData os_exchange_data(
           new ui::OSExchangeDataProviderWin(data_object));
       BookmarkNodeData bookmark_drag_data;
       if (bookmark_drag_data.Read(os_exchange_data)) {
-        tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDrop(
+        bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDrop(
             bookmark_drag_data);
       }
     }
 
     // Focus the target browser.
-    Browser* browser = browser::FindBrowserWithWebContents(
-        tab_->web_contents());
+    Browser* browser = browser::FindBrowserWithWebContents(web_contents_);
     if (browser)
       browser->window()->Show();
   }
 }
 
 void WebDragBookmarkHandlerWin::OnDragLeave(IDataObject* data_object) {
-  if (tab_ && tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()) {
+  if (bookmark_tab_helper_ && bookmark_tab_helper_->GetBookmarkDragDelegate()) {
     ui::OSExchangeData os_exchange_data(
         new ui::OSExchangeDataProviderWin(data_object));
     BookmarkNodeData bookmark_drag_data;
     if (bookmark_drag_data.Read(os_exchange_data))
-      tab_->bookmark_tab_helper()->GetBookmarkDragDelegate()->OnDragLeave(
+      bookmark_tab_helper_->GetBookmarkDragDelegate()->OnDragLeave(
           bookmark_drag_data);
   }
 }
diff --git a/chrome/browser/tab_contents/web_drag_bookmark_handler_win.h b/chrome/browser/tab_contents/web_drag_bookmark_handler_win.h
index 51b356a..8b30188 100644
--- a/chrome/browser/tab_contents/web_drag_bookmark_handler_win.h
+++ b/chrome/browser/tab_contents/web_drag_bookmark_handler_win.h
@@ -9,7 +9,11 @@
 #include "chrome/browser/bookmarks/bookmark_node_data.h"
 #include "content/public/browser/web_drag_dest_delegate.h"
 
-class TabContents;
+class BookmarkTabHelper;
+
+namespace content {
+class WebContents;
+}
 
 // Chrome needs to intercept content drag events so it can dispatch them to the
 // bookmarks and extensions system.
@@ -28,10 +32,12 @@
                            ui::OSExchangeData* data) OVERRIDE;
 
  private:
-  // The TabContents.
-  // Weak reference; may be NULL if the contents aren't contained in a
-  // TabContents (e.g. WebUI dialogs).
-  TabContents* tab_;
+  // The BookmarkTabHelper.
+  // Weak reference; may be NULL if the contents don't have a
+  // BookmarkTabHelper (e.g. WebUI dialogs).
+  BookmarkTabHelper* bookmark_tab_helper_;
+
+  content::WebContents* web_contents_;
 
   DISALLOW_COPY_AND_ASSIGN(WebDragBookmarkHandlerWin);
 };
diff --git a/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc b/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc
index 95983d1f..e2b08fea 100644
--- a/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc
@@ -16,6 +16,8 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 
+int BookmarkTabHelper::kUserDataKey;
+
 namespace {
 
 bool CanShowBookmarkBar(content::WebUI* ui) {
@@ -27,10 +29,9 @@
 
 }  // namespace
 
-BookmarkTabHelper::BookmarkTabHelper(TabContents* tab_contents)
-    : content::WebContentsObserver(tab_contents->web_contents()),
+BookmarkTabHelper::BookmarkTabHelper(content::WebContents* web_contents)
+    : content::WebContentsObserver(web_contents),
       is_starred_(false),
-      tab_contents_(tab_contents),
       delegate_(NULL),
       bookmark_drag_(NULL) {
   // Register for notifications about URL starredness changing on any profile.
@@ -80,8 +81,9 @@
       // Somewhere, a URL has been starred.
       // Ignore notifications for profiles other than our current one.
       Profile* source_profile = content::Source<Profile>(source).ptr();
-      if (!source_profile ||
-          !source_profile->IsSameProfile(tab_contents_->profile()))
+      Profile* this_profile =
+          Profile::FromBrowserContext(web_contents()->GetBrowserContext());
+      if (!source_profile || !source_profile->IsSameProfile(this_profile))
         return;
 
       UpdateStarredStateForCurrentURL();
@@ -111,5 +113,5 @@
   is_starred_ = (model && model->IsBookmarked(web_contents()->GetURL()));
 
   if (is_starred_ != old_state && delegate())
-    delegate()->URLStarredChanged(tab_contents_, is_starred_);
+    delegate()->URLStarredChanged(web_contents(), is_starred_);
 }
diff --git a/chrome/browser/ui/bookmarks/bookmark_tab_helper.h b/chrome/browser/ui/bookmarks/bookmark_tab_helper.h
index e2a9b2b..b4321b7 100644
--- a/chrome/browser/ui/bookmarks/bookmark_tab_helper.h
+++ b/chrome/browser/ui/bookmarks/bookmark_tab_helper.h
@@ -5,17 +5,22 @@
 #ifndef CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_TAB_HELPER_H_
 #define CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_TAB_HELPER_H_
 
+#include "chrome/browser/tab_contents/web_contents_user_data.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_contents_observer.h"
 
-class BookmarkTabHelperDelegate;
-class TabContents;
 struct BookmarkNodeData;
+class BookmarkTabHelperDelegate;
+
+namespace content {
+class WebContents;
+}
 
 // Per-tab class to manage bookmarks.
 class BookmarkTabHelper : public content::NotificationObserver,
-                          public content::WebContentsObserver {
+                          public content::WebContentsObserver,
+                          public WebContentsUserData<BookmarkTabHelper> {
  public:
   // BookmarkDrag --------------------------------------------------------------
   // Interface for forwarding bookmark drag and drop to extenstions.
@@ -30,7 +35,6 @@
     virtual ~BookmarkDrag() {}
   };
 
-  explicit BookmarkTabHelper(TabContents* tab_contents);
   virtual ~BookmarkTabHelper();
 
   bool is_starred() const { return is_starred_; }
@@ -61,6 +65,10 @@
   BookmarkTabHelper::BookmarkDrag* GetBookmarkDragDelegate();
 
  private:
+  explicit BookmarkTabHelper(content::WebContents* web_contents);
+  static int kUserDataKey;
+  friend class WebContentsUserData<BookmarkTabHelper>;
+
   // Updates the starred state from the bookmark bar model. If the state has
   // changed, the delegate is notified.
   void UpdateStarredStateForCurrentURL();
@@ -71,9 +79,6 @@
   // Registers and unregisters us for notifications.
   content::NotificationRegistrar registrar_;
 
-  // Owning TabContents.
-  TabContents* tab_contents_;
-
   // Delegate for notifying our owner (usually Browser) about stuff. Not owned
   // by us.
   BookmarkTabHelperDelegate* delegate_;
diff --git a/chrome/browser/ui/bookmarks/bookmark_tab_helper_delegate.h b/chrome/browser/ui/bookmarks/bookmark_tab_helper_delegate.h
index c53d243f..e2f5ab6f 100644
--- a/chrome/browser/ui/bookmarks/bookmark_tab_helper_delegate.h
+++ b/chrome/browser/ui/bookmarks/bookmark_tab_helper_delegate.h
@@ -7,14 +7,17 @@
 
 #include "base/basictypes.h"
 
-class TabContents;
+namespace content {
+class WebContents;
+}
 
 // Objects implement this interface to get notified about changes in the
 // BookmarkTabHelper and to provide necessary functionality.
 class BookmarkTabHelperDelegate {
  public:
   // Notification that the starredness of the current URL changed.
-  virtual void URLStarredChanged(TabContents* source, bool starred) = 0;
+  virtual void URLStarredChanged(content::WebContents* web_contents,
+                                 bool starred) = 0;
 
  protected:
   virtual ~BookmarkTabHelperDelegate();
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 5b5127b5..aa5efc0 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1749,8 +1749,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 // Browser, BookmarkTabHelperDelegate implementation:
 
-void Browser::URLStarredChanged(TabContents* source, bool starred) {
-  if (source == chrome::GetActiveTabContents(this))
+void Browser::URLStarredChanged(content::WebContents* web_contents,
+                                bool starred) {
+  if (web_contents == chrome::GetActiveWebContents(this))
     window_->SetStarredState(starred);
 }
 
@@ -2175,8 +2176,10 @@
       (!window_ || !window_->IsFullscreen())) {
     state = BookmarkBar::SHOW;
   } else {
-    TabContents* tab = chrome::GetActiveTabContents(this);
-    if (tab && tab->bookmark_tab_helper()->ShouldShowBookmarkBar())
+    WebContents* web_contents = chrome::GetActiveWebContents(this);
+    BookmarkTabHelper* bookmark_tab_helper =
+        web_contents ? BookmarkTabHelper::FromWebContents(web_contents) : NULL;
+    if (bookmark_tab_helper && bookmark_tab_helper->ShouldShowBookmarkBar())
       state = BookmarkBar::DETACHED;
     else
       state = BookmarkBar::HIDDEN;
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index 6dd5fd8e..02462273 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -665,7 +665,7 @@
   virtual TabContents* GetConstrainingTabContents(TabContents* source) OVERRIDE;
 
   // Overridden from BookmarkTabHelperDelegate:
-  virtual void URLStarredChanged(TabContents* source,
+  virtual void URLStarredChanged(content::WebContents* web_contents,
                                  bool starred) OVERRIDE;
 
   // Overridden from ZoomObserver:
diff --git a/chrome/browser/ui/browser_adoption.cc b/chrome/browser/ui/browser_adoption.cc
index ec48871..9918f23d 100644
--- a/chrome/browser/ui/browser_adoption.cc
+++ b/chrome/browser/ui/browser_adoption.cc
@@ -45,7 +45,7 @@
   // ...and all the helpers.
   TabContents* tab = TabContents::FromWebContents(web_contents);
   tab->blocked_content_tab_helper()->set_delegate(delegate);
-  tab->bookmark_tab_helper()->set_delegate(delegate);
+  BookmarkTabHelper::FromWebContents(web_contents)->set_delegate(delegate);
   tab->constrained_window_tab_helper()->set_delegate(delegate);
   tab->core_tab_helper()->set_delegate(delegate);
   tab->search_engine_tab_helper()->set_delegate(delegate);
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 2d4c48c..3a4be68a 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -946,10 +946,9 @@
 }
 
 void BrowserCommandController::UpdateCommandsForTabState() {
-  TabContents* current_tab_contents = chrome::GetActiveTabContents(browser_);
-  if (!current_tab_contents)  // May be NULL during tab restore.
+  WebContents* current_web_contents = chrome::GetActiveWebContents(browser_);
+  if (!current_web_contents)  // May be NULL during tab restore.
     return;
-  WebContents* current_web_contents = current_tab_contents->web_contents();
 
   // Navigation commands
   command_updater_.UpdateCommandEnabled(IDC_BACK, CanGoBack(browser_));
@@ -966,7 +965,7 @@
 
   // Page-related commands
   window()->SetStarredState(
-      current_tab_contents->bookmark_tab_helper()->is_starred());
+      BookmarkTabHelper::FromWebContents(current_web_contents)->is_starred());
   window()->ZoomChangedForActiveTab(false);
   command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
                                         CanViewSource(browser_));
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
index 1f31c472..6d69a975e 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -486,8 +486,10 @@
 
 - (BOOL)shouldShowDetachedBookmarkBar {
   DCHECK(browser_.get());
-  TabContents* tab = chrome::GetActiveTabContents(browser_.get());
-  return (tab && tab->bookmark_tab_helper()->ShouldShowBookmarkBar() &&
+  WebContents* web_contents = chrome::GetActiveWebContents(browser_.get());
+  BookmarkTabHelper* bookmark_tab_helper =
+      web_contents ? BookmarkTabHelper::FromWebContents(web_contents) : NULL;
+  return (bookmark_tab_helper && bookmark_tab_helper->ShouldShowBookmarkBar() &&
           ![previewableContentsController_ isShowingPreview]);
 }
 
diff --git a/chrome/browser/ui/cocoa/tabpose_window.mm b/chrome/browser/ui/cocoa/tabpose_window.mm
index db93648..af1f926 100644
--- a/chrome/browser/ui/cocoa/tabpose_window.mm
+++ b/chrome/browser/ui/cocoa/tabpose_window.mm
@@ -237,10 +237,12 @@
         [infoBarContainer overlappingTipHeight];
   }
 
+  BookmarkTabHelper* bookmark_tab_helper =
+      BookmarkTabHelper::FromWebContents(contents_->web_contents());
   bool always_show_bookmark_bar =
       contents_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
   bool has_detached_bookmark_bar =
-      contents_->bookmark_tab_helper()->ShouldShowBookmarkBar() &&
+      bookmark_tab_helper->ShouldShowBookmarkBar() &&
       !always_show_bookmark_bar;
   if (has_detached_bookmark_bar)
     topOffset += bookmarks::kNTPBookmarkBarHeight;
diff --git a/chrome/browser/ui/tab_contents/tab_contents.cc b/chrome/browser/ui/tab_contents/tab_contents.cc
index 4382c61..48a0118 100644
--- a/chrome/browser/ui/tab_contents/tab_contents.cc
+++ b/chrome/browser/ui/tab_contents/tab_contents.cc
@@ -127,7 +127,7 @@
         autofill_external_delegate_.get());
   }
   blocked_content_tab_helper_.reset(new BlockedContentTabHelper(this));
-  bookmark_tab_helper_.reset(new BookmarkTabHelper(this));
+  BookmarkTabHelper::CreateForWebContents(contents);
   chrome_browser_net::LoadTimeStatsTabHelper::CreateForWebContents(contents);
   constrained_window_tab_helper_.reset(new ConstrainedWindowTabHelper(this));
   content_settings_.reset(new TabSpecificContentSettings(contents));
diff --git a/chrome/browser/ui/tab_contents/tab_contents.h b/chrome/browser/ui/tab_contents/tab_contents.h
index 29e0591..06ef588 100644
--- a/chrome/browser/ui/tab_contents/tab_contents.h
+++ b/chrome/browser/ui/tab_contents/tab_contents.h
@@ -17,7 +17,6 @@
 class AutomationTabHelper;
 class BasePanelBrowserTest;
 class BlockedContentTabHelper;
-class BookmarkTabHelper;
 class Browser;
 class BrowserCommandsTabContentsCreator;
 class BrowserLauncherItemControllerContentsCreator;
@@ -200,10 +199,6 @@
     return blocked_content_tab_helper_.get();
   }
 
-  BookmarkTabHelper* bookmark_tab_helper() {
-    return bookmark_tab_helper_.get();
-  }
-
 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
   captive_portal::CaptivePortalTabHelper* captive_portal_tab_helper() {
     return captive_portal_tab_helper_.get();
@@ -298,7 +293,6 @@
   scoped_ptr<AutofillExternalDelegate> autofill_external_delegate_;
   scoped_ptr<AutomationTabHelper> automation_tab_helper_;
   scoped_ptr<BlockedContentTabHelper> blocked_content_tab_helper_;
-  scoped_ptr<BookmarkTabHelper> bookmark_tab_helper_;
 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
   scoped_ptr<captive_portal::CaptivePortalTabHelper> captive_portal_tab_helper_;
 #endif
diff --git a/chrome/browser/ui/toolbar/action_box_menu_model.cc b/chrome/browser/ui/toolbar/action_box_menu_model.cc
index 31cafee..4aa1fd4 100644
--- a/chrome/browser/ui/toolbar/action_box_menu_model.cc
+++ b/chrome/browser/ui/toolbar/action_box_menu_model.cc
@@ -48,8 +48,11 @@
             rb.GetNativeImageNamed(IDR_MOBILE));
   }
 
-  TabContents* current_tab_contents = chrome::GetActiveTabContents(browser_);
-  bool starred = current_tab_contents->bookmark_tab_helper()->is_starred();
+  content::WebContents* current_web_contents =
+      chrome::GetActiveWebContents(browser_);
+  BookmarkTabHelper* bookmark_tab_helper =
+      BookmarkTabHelper::FromWebContents(current_web_contents);
+  bool starred = bookmark_tab_helper->is_starred();
   AddItemWithStringId(IDC_BOOKMARK_PAGE,
                       starred ? IDS_TOOLTIP_STARRED : IDS_TOOLTIP_STAR);
   SetIcon(GetIndexOfCommandId(IDC_BOOKMARK_PAGE),