Part4: lazy statements creation (and minor cleanup) in nsFaviconService, r=sdwilsh
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 08 Jan 2010 13:57:49 +0100
changeset 36952 ed1e9fa499b521b18a1750accdeb07b51029e236
parent 36951 765335600809c6fe847897351ea6b6cb17c913da
child 36953 f15229bbbf8352d5f62eb0932ff167c8cf55f0cc
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssdwilsh
milestone1.9.3a1pre
Part4: lazy statements creation (and minor cleanup) in nsFaviconService, r=sdwilsh
toolkit/components/places/src/nsFaviconService.cpp
toolkit/components/places/src/nsFaviconService.h
--- a/toolkit/components/places/src/nsFaviconService.cpp
+++ b/toolkit/components/places/src/nsFaviconService.cpp
@@ -65,18 +65,16 @@
 #include "nsStreamUtils.h"
 #include "nsStringStream.h"
 #include "plbase64.h"
 #include "nsPlacesTables.h"
 #include "nsPlacesMacros.h"
 #include "nsIPrefService.h"
 #include "Helpers.h"
 
-#include "mozilla/storage.h"
-
 // For large favicons optimization.
 #include "imgITools.h"
 #include "imgIContainer.h"
 
 // Default value for mOptimizedIconDimension
 #define OPTIMIZED_FAVICON_DIMENSION 16
 
 // Most icons will be smaller than this rough estimate of the size of an
@@ -132,22 +130,22 @@ private:
 ////////////////////////////////////////////////////////////////////////////////
 //// ExpireFaviconsStatementCallbackNotifier definition
 
 // Used to notify a topic to system observers on async execute completion.
 // Will throw on error.
 class ExpireFaviconsStatementCallbackNotifier : public AsyncStatementCallback
 {
 public:
-  ExpireFaviconsStatementCallbackNotifier(bool *aFaviconsExpirationRunning);
+  ExpireFaviconsStatementCallbackNotifier(bool* aFaviconsExpirationRunning);
   NS_DECL_ISUPPORTS
   NS_DECL_ASYNCSTATEMENTCALLBACK
 
 private:
-  bool *mFaviconsExpirationRunning;
+  bool* mFaviconsExpirationRunning;
 };
 
 PLACES_FACTORY_SINGLETON_IMPLEMENTATION(nsFaviconService, gFaviconService)
 
 NS_IMPL_ISUPPORTS1(
   nsFaviconService
 , nsIFaviconService
 )
@@ -160,106 +158,113 @@ namespace {
  * @param aPageURI
  *        The page that is trying to load the favicon.
  * @param aFaviconURI
  *        The URI of the favicon in question.
  * @return the URI to load this favicon for, or null if this icon should not be
  *         loaded.
  */
 already_AddRefed<nsIURI>
-GetEffectivePageForFavicon(nsIURI *aPageURI,
-                              nsIURI *aFaviconURI)
+GetEffectivePageForFavicon(nsIURI* aPageURI, nsIURI* aFaviconURI)
 {
   NS_ASSERTION(aPageURI, "Must provide a pageURI!");
   NS_ASSERTION(aFaviconURI, "Must provide a favicon URI!");
 
   nsCOMPtr<nsIURI> pageURI(aPageURI);
 
-  nsNavHistory *history = nsNavHistory::GetHistoryService();
+  nsNavHistory* history = nsNavHistory::GetHistoryService();
   NS_ENSURE_TRUE(history, nsnull);
 
   PRBool canAddToHistory;
   nsresult rv = history->CanAddURI(pageURI, &canAddToHistory);
-  NS_ENSURE_TRUE(NS_SUCCEEDED(rv), nsnull);
+  if (NS_FAILED(rv))
+    return nsnull;
 
   // If history is disabled or the page isn't addable to history, only load
   // favicons if the page is bookmarked.
   if (!canAddToHistory || history->IsHistoryDisabled()) {
-    nsNavBookmarks *bmSvc = nsNavBookmarks::GetBookmarksService();
+    nsNavBookmarks* bmSvc = nsNavBookmarks::GetBookmarksService();
     NS_ENSURE_TRUE(bmSvc, nsnull);
 
     // Check if the page is bookmarked.
     nsCOMPtr<nsIURI> bookmarkedURI;
     rv = bmSvc->GetBookmarkedURIFor(aPageURI, getter_AddRefs(bookmarkedURI));
-    NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && bookmarkedURI, nsnull);
+    NS_ENSURE_SUCCESS(rv, nsnull);
+    if (!bookmarkedURI)
+      return nsnull;
 
     // We always want to use the bookmark URI regardless of aPageURI.
     pageURI = bookmarkedURI.forget();
   }
 
   // If we are given a URI to an image, the favicon URI will be the same as the
   // page URI.
   // TODO: In future we'll probably want to store a resample of the image, but
   // for now we just avoid that, for database size concerns.
   PRBool pageEqualsFavicon;
   rv = pageURI->Equals(aFaviconURI, &pageEqualsFavicon);
-  NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && !pageEqualsFavicon, nsnull);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+  if (pageEqualsFavicon)
+    return nsnull;
 
   // We don't store favicons to error pages.
   nsCOMPtr<nsIURI> errorPageFaviconURI;
   rv = NS_NewURI(getter_AddRefs(errorPageFaviconURI),
                  NS_LITERAL_CSTRING(FAVICON_ERRORPAGE_URL));
   NS_ENSURE_SUCCESS(rv, nsnull);
   PRBool isErrorPage;
   rv = aFaviconURI->Equals(errorPageFaviconURI, &isErrorPage);
-  NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && !isErrorPage, nsnull);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+  if (isErrorPage)
+    return nsnull;
 
   // This favicon should load, so return the page's URI.
   return pageURI.forget();
 }
 
 /**
  * This class gets the expiration data for a favicon, and starts the lookup of
  * the favicon's data if it should be loaded.
  */
 class FaviconExpirationGetter : public AsyncStatementCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
-  FaviconExpirationGetter(nsIURI *aPageURI,
-                          nsIURI *aFaviconURI,
+  FaviconExpirationGetter(nsIURI* aPageURI,
+                          nsIURI* aFaviconURI,
                           bool aForceReload) :
     mPageURI(aPageURI)
   , mFaviconURI(aFaviconURI)
   , mForceReload(aForceReload)
   , mHasData(false)
   , mExpiration(0)
   {
   }
 
   /**
    * Performs a lookup of the needed information asynchronously, and loads the
    * icon if necessary.
    */
-  NS_IMETHOD checkAndLoad(mozIStorageStatement *aStatement)
+  NS_IMETHOD checkAndLoad(mozIStorageStatement* aStatement)
   {
+    NS_ENSURE_STATE(aStatement);
     mozStorageStatementScoper scoper(aStatement);
     nsresult rv = BindStatementURI(aStatement, 0, mFaviconURI);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<mozIStoragePendingStatement> ps;
     rv = aStatement->ExecuteAsync(this, getter_AddRefs(ps));
     NS_ENSURE_SUCCESS(rv, rv);
     // ExecuteAsync will reset the statement for us.
     scoper.Abandon();
     return NS_OK;
   }
 
-  NS_IMETHOD HandleResult(mozIStorageResultSet *aResultSet)
+  NS_IMETHOD HandleResult(mozIStorageResultSet* aResultSet)
   {
     nsCOMPtr<mozIStorageRow> row;
     nsresult rv = aResultSet->GetNextRow(getter_AddRefs(row));
     NS_ENSURE_SUCCESS(rv, rv);
 
     PRInt32 dataSize = 0;
     (void)row->GetInt32(1, &dataSize);
     mHasData = dataSize > 0;
@@ -277,17 +282,17 @@ public:
     // NOT want to set the favicon for the page unless we know we have it.  For
     // example, if I go to random site x.com, the browser will still tell us
     // that the favicon is x.com/favicon.ico even if there is no such file.  We
     // don't want to pollute our tables with this useless data.  We also do not
     // want to reload the icon if it hasn't expired yet.
     if (mHasData && PR_Now() < mExpiration && !mForceReload) {
       // Our data is likely still valid, but we should check to make sure the
       // URI has changed, otherwise there is no need to notify.
-      nsFaviconService *fs = nsFaviconService::GetFaviconService();
+      nsFaviconService* fs = nsFaviconService::GetFaviconService();
       NS_ENSURE_TRUE(fs, NS_ERROR_OUT_OF_MEMORY);
       fs->checkAndNotify(mPageURI, mFaviconURI);
       return NS_OK;
     }
 
     nsCOMPtr<nsIChannel> channel;
     nsresult rv = NS_NewChannel(getter_AddRefs(channel), mFaviconURI);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -316,168 +321,175 @@ private:
 NS_IMPL_ISUPPORTS1(
   FaviconExpirationGetter,
   mozIStorageStatementCallback
 )
 
 } // anonymous namespace
 
 
-nsFaviconService::nsFaviconService() : mFaviconsExpirationRunning(false)
-                                     , mOptimizedIconDimension(OPTIMIZED_FAVICON_DIMENSION)
-                                     , mFailedFaviconSerial(0)
+nsFaviconService::nsFaviconService()
+: mFaviconsExpirationRunning(false)
+, mOptimizedIconDimension(OPTIMIZED_FAVICON_DIMENSION)
+, mFailedFaviconSerial(0)
+, mShuttingDown(false)
 {
   NS_ASSERTION(!gFaviconService,
                "Attempting to create two instances of the service!");
   gFaviconService = this;
 }
 
+
 nsFaviconService::~nsFaviconService()
 {
   NS_ASSERTION(gFaviconService == this,
                "Deleting a non-singleton instance of the service");
   if (gFaviconService == this)
     gFaviconService = nsnull;
 }
 
+
 nsresult
 nsFaviconService::Init()
 {
-  // creation of history service will call InitTables
+  // Creation of history service will call InitTables.
   nsNavHistory* historyService = nsNavHistory::GetHistoryService();
   NS_ENSURE_TRUE(historyService, NS_ERROR_OUT_OF_MEMORY);
   mDBConn = historyService->GetStorageConnection();
   NS_ENSURE_TRUE(mDBConn, NS_ERROR_FAILURE);
 
-  nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      "SELECT id, length(data), expiration FROM moz_favicons WHERE url = ?1"),
-    getter_AddRefs(mDBGetIconInfo));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // We can avoid checking for duplicates in the unified table since an uri
-  // can only have one favicon associated. LIMIT 1 will ensure that we get
-  // only one result.
-  rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      "SELECT f.id, f.url, length(f.data), f.expiration "
-      "FROM ( "
-        "SELECT " MOZ_PLACES_COLUMNS " FROM moz_places_temp "
-        "WHERE url = ?1 "
-        "UNION ALL "
-        "SELECT " MOZ_PLACES_COLUMNS " FROM moz_places "
-        "WHERE url = ?1 "
-      ") AS h JOIN moz_favicons f ON h.favicon_id = f.id "
-      "LIMIT 1"),
-    getter_AddRefs(mDBGetURL));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      "SELECT f.data, f.mime_type FROM moz_favicons f WHERE url = ?1"),
-    getter_AddRefs(mDBGetData));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      "INSERT INTO moz_favicons (url, data, mime_type, expiration) "
-      "VALUES (?1, ?2, ?3, ?4)"),
-    getter_AddRefs(mDBInsertIcon));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      "UPDATE moz_favicons SET data = ?2, mime_type = ?3, expiration = ?4 "
-      "WHERE id = ?1"),
-    getter_AddRefs(mDBUpdateIcon));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      "UPDATE moz_places_view SET favicon_id = ?2 WHERE id = ?1"),
-    getter_AddRefs(mDBSetPageFavicon));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // failed favicon cache
-  if (! mFailedFavicons.Init(MAX_FAVICON_CACHE_SIZE))
+  // Init failed favicon cache.
+  if (!mFailedFavicons.Init(MAX_FAVICON_CACHE_SIZE))
     return NS_ERROR_OUT_OF_MEMORY;
 
   nsCOMPtr<nsIPrefBranch> pb = do_GetService(NS_PREFSERVICE_CONTRACTID);
-  if (pb)
-    pb->GetIntPref("places.favicons.optimizeToDimension", &mOptimizedIconDimension);
+  if (pb) {
+    (void)pb->GetIntPref("places.favicons.optimizeToDimension",
+                         &mOptimizedIconDimension);
+  }
 
   return NS_OK;
 }
 
+
+mozIStorageStatement*
+nsFaviconService::GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt)
+{
+#define RETURN_IF_STMT(_stmt, _sql)                                        \
+  PR_BEGIN_MACRO                                                           \
+  if (address_of(_stmt) == address_of(aStmt)) {                            \
+    if (!_stmt) {                                                          \
+      nsresult rv = mDBConn->CreateStatement(_sql, getter_AddRefs(_stmt)); \
+      NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && _stmt, nsnull);                   \
+    }                                                                      \
+    return _stmt.get();                                                    \
+  }                                                                        \
+  PR_END_MACRO
+
+  if (mShuttingDown)
+    return nsnull;
+
+  RETURN_IF_STMT(mDBGetIconInfo, NS_LITERAL_CSTRING(
+    "SELECT id, length(data), expiration FROM moz_favicons WHERE url = ?1"));
+
+  RETURN_IF_STMT(mDBGetURL, NS_LITERAL_CSTRING(
+    "SELECT f.id, f.url, length(f.data), f.expiration "
+    "FROM ( "
+      "SELECT " MOZ_PLACES_COLUMNS " FROM moz_places_temp "
+      "WHERE url = ?1 "
+      "UNION ALL "
+      "SELECT " MOZ_PLACES_COLUMNS " FROM moz_places "
+      "WHERE url = ?1 "
+    ") AS h JOIN moz_favicons f ON h.favicon_id = f.id "
+    "LIMIT 1"));
+
+
+  RETURN_IF_STMT(mDBGetData, NS_LITERAL_CSTRING(
+    "SELECT f.data, f.mime_type FROM moz_favicons f WHERE url = ?1"));
+
+  RETURN_IF_STMT(mDBInsertIcon, NS_LITERAL_CSTRING(
+    "INSERT INTO moz_favicons (url, data, mime_type, expiration) "
+      "VALUES (?1, ?2, ?3, ?4)"));
+
+  RETURN_IF_STMT(mDBUpdateIcon, NS_LITERAL_CSTRING(
+    "UPDATE moz_favicons SET data = ?2, mime_type = ?3, expiration = ?4 "
+    "WHERE id = ?1"));
+
+  RETURN_IF_STMT(mDBSetPageFavicon, NS_LITERAL_CSTRING(
+    "UPDATE moz_places_view SET favicon_id = ?2 WHERE id = ?1"));
+
+  RETURN_IF_STMT(mDBRemoveOnDiskReferences, NS_LITERAL_CSTRING(
+    "UPDATE moz_places "
+    "SET favicon_id = NULL "
+    "WHERE favicon_id NOT NULL"));
+
+  RETURN_IF_STMT(mDBRemoveTempReferences, NS_LITERAL_CSTRING(
+    "UPDATE moz_places_temp "
+    "SET favicon_id = NULL "
+    "WHERE favicon_id NOT NULL"));
+
+  RETURN_IF_STMT(mDBRemoveAllFavicons, NS_LITERAL_CSTRING(
+    "DELETE FROM moz_favicons WHERE id NOT IN ("
+      "SELECT favicon_id FROM moz_places_temp WHERE favicon_id NOT NULL "
+      "UNION ALL "
+      "SELECT favicon_id FROM moz_places WHERE favicon_id NOT NULL "
+    ")"));
+
+  return nsnull;
+#undef RETURN_IF_STMT
+}
+
+
 // nsFaviconService::InitTables
 //
 //    Called by the history service to create the favicon table. The history
 //    service uses this table in its queries, so it must exist even if
 //    nobody has called the favicon service.
 
 nsresult // static
 nsFaviconService::InitTables(mozIStorageConnection* aDBConn)
 {
   nsresult rv;
   PRBool exists = PR_FALSE;
   aDBConn->TableExists(NS_LITERAL_CSTRING("moz_favicons"), &exists);
-  if (! exists) {
+  if (!exists) {
     rv = aDBConn->ExecuteSimpleSQL(CREATE_MOZ_FAVICONS);
     NS_ENSURE_SUCCESS(rv, rv);
   }
+
   return NS_OK;
 }
 
+
 NS_IMETHODIMP
 nsFaviconService::ExpireAllFavicons()
 {
   mFaviconsExpirationRunning = true;
 
-  // Remove all references to favicons.
   // We do this in 2 steps, first we null-out all favicons in the disk table,
   // then we do the same in the temp table.  This is because the view UPDATE
   // trigger does not allow setting a NULL value to prevent dataloss.
-  nsCOMPtr<mozIStorageStatement> removeOnDiskReferences;
-  nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      "UPDATE moz_places "
-      "SET favicon_id = NULL "
-      "WHERE favicon_id NOT NULL"
-    ), getter_AddRefs(removeOnDiskReferences));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<mozIStorageStatement> removeTempReferences;
-  rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      "UPDATE moz_places_temp "
-      "SET favicon_id = NULL "
-      "WHERE favicon_id NOT NULL"
-    ), getter_AddRefs(removeTempReferences));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Remove all favicons.
-  // We run async, so be sure to not remove any favicon that could have been
-  // created in the meantime.
-  nsCOMPtr<mozIStorageStatement> removeFavicons;
-  rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
-      "DELETE FROM moz_favicons WHERE id NOT IN ("
-        "SELECT favicon_id FROM moz_places_temp WHERE favicon_id NOT NULL "
-        "UNION ALL "
-        "SELECT favicon_id FROM moz_places WHERE favicon_id NOT NULL "
-      ")"
-    ), getter_AddRefs(removeFavicons));
-  NS_ENSURE_SUCCESS(rv, rv);
 
   mozIStorageStatement *stmts[] = {
-    removeOnDiskReferences,
-    removeTempReferences,
-    removeFavicons
+    GetStatement(mDBRemoveOnDiskReferences),
+    GetStatement(mDBRemoveTempReferences),
+    GetStatement(mDBRemoveAllFavicons),
   };
+  NS_ENSURE_STATE(stmts[0] && stmts[1] && stmts[2]);
   nsCOMPtr<mozIStoragePendingStatement> ps;
   nsCOMPtr<ExpireFaviconsStatementCallbackNotifier> callback =
     new ExpireFaviconsStatementCallbackNotifier(&mFaviconsExpirationRunning);
-  rv = mDBConn->ExecuteAsync(stmts, NS_ARRAY_LENGTH(stmts), callback,
-                             getter_AddRefs(ps));
+  nsresult rv = mDBConn->ExecuteAsync(stmts, NS_ARRAY_LENGTH(stmts), callback,
+                                      getter_AddRefs(ps));
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
 //// nsIFaviconService
 
 NS_IMETHODIMP
 nsFaviconService::SetFaviconUrlForPage(nsIURI* aPageURI, nsIURI* aFaviconURI)
 {
   NS_ENSURE_ARG(aPageURI);
   NS_ENSURE_ARG(aFaviconURI);
@@ -490,30 +502,32 @@ nsFaviconService::SetFaviconUrlForPage(n
   NS_ENSURE_SUCCESS(rv, rv);
 
   // send favicon change notifications if the URL has any data
   if (hasData)
     SendFaviconNotifications(aPageURI, aFaviconURI);
   return NS_OK;
 }
 
+
 NS_IMETHODIMP
 nsFaviconService::GetDefaultFavicon(nsIURI** _retval)
 {
   NS_ENSURE_ARG_POINTER(_retval);
 
   // not found, use default
   if (!mDefaultIcon) {
     nsresult rv = NS_NewURI(getter_AddRefs(mDefaultIcon),
                             NS_LITERAL_CSTRING(FAVICON_DEFAULT_URL));
     NS_ENSURE_SUCCESS(rv, rv);
   }
   return mDefaultIcon->Clone(_retval);
 }
 
+
 // nsFaviconService::SetFaviconUrlForPageInternal
 //
 //    This creates a new entry in the favicon table if necessary and tells the
 //    history service to associate the given favicon ID with the given URI. We
 //    don't want to update the history table directly since that may involve
 //    creating a new row in the history table, which should only be done by
 //    history.
 //
@@ -535,78 +549,87 @@ nsFaviconService::SetFaviconUrlForPageIn
   nsNavHistory* historyService = nsNavHistory::GetHistoryService();
   NS_ENSURE_TRUE(historyService, NS_ERROR_OUT_OF_MEMORY);
 
   if (historyService->InPrivateBrowsingMode())
     return NS_OK;
 
   mozStorageTransaction transaction(mDBConn, PR_FALSE);
   {
-    mozStorageStatementScoper scoper(mDBGetIconInfo);
-    rv = BindStatementURI(mDBGetIconInfo, 0, aFaviconURI);
+    mozIStorageStatement* stmt = GetStatement(mDBGetIconInfo);
+    NS_ENSURE_STATE(stmt);
+    mozStorageStatementScoper scoper(stmt);
+    rv = BindStatementURI(stmt, 0, aFaviconURI);
     NS_ENSURE_SUCCESS(rv, rv);
 
     PRBool hasResult = PR_FALSE;
-    if (NS_SUCCEEDED(mDBGetIconInfo->ExecuteStep(&hasResult)) && hasResult) {
+    if (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
       // We already have an entry for this icon, just get the stats
-      rv = mDBGetIconInfo->GetInt64(0, &iconId);
+      rv = stmt->GetInt64(0, &iconId);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // see if this icon has data already
       PRInt32 dataSize;
-      rv = mDBGetIconInfo->GetInt32(1, &dataSize);
+      rv = stmt->GetInt32(1, &dataSize);
       NS_ENSURE_SUCCESS(rv, rv);
       if (dataSize > 0)
         *aHasData = PR_TRUE;
     }
   }
 
   if (iconId == -1) {
     // We did not find any entry, so create a new one
 
     // not-binded params are automatically nullified by mozStorage
-    mozStorageStatementScoper scoper(mDBInsertIcon);
-    rv = BindStatementURI(mDBInsertIcon, 0, aFaviconURI);
+    mozIStorageStatement* stmt = GetStatement(mDBInsertIcon);
+    NS_ENSURE_STATE(stmt);
+    mozStorageStatementScoper scoper(stmt);
+    rv = BindStatementURI(stmt, 0, aFaviconURI);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = mDBInsertIcon->Execute();
+    rv = stmt->Execute();
     NS_ENSURE_SUCCESS(rv, rv);
 
     {
-      mozStorageStatementScoper scoper(mDBGetIconInfo);
+      mozIStorageStatement* getInfoStmt = GetStatement(mDBGetIconInfo);
+      NS_ENSURE_STATE(getInfoStmt);
+      mozStorageStatementScoper scoper(getInfoStmt);
 
-      rv = BindStatementURI(mDBGetIconInfo, 0, aFaviconURI);
+      rv = BindStatementURI(getInfoStmt, 0, aFaviconURI);
       NS_ENSURE_SUCCESS(rv, rv);
 
       PRBool hasResult;
-      rv = mDBGetIconInfo->ExecuteStep(&hasResult);
+      rv = getInfoStmt->ExecuteStep(&hasResult);
       NS_ENSURE_SUCCESS(rv, rv);
       NS_ASSERTION(hasResult, "hasResult is false but the call succeeded?");
-      iconId = mDBGetIconInfo->AsInt64(0);
+      iconId = getInfoStmt->AsInt64(0);
     }
   }
 
   // now link our icon entry with the page
   PRInt64 pageId;
   rv = historyService->GetUrlIdFor(aPageURI, &pageId, PR_TRUE);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  mozStorageStatementScoper scoper(mDBSetPageFavicon);
-  rv = mDBSetPageFavicon->BindInt64Parameter(0, pageId);
+  mozIStorageStatement* stmt = GetStatement(mDBSetPageFavicon);
+  NS_ENSURE_STATE(stmt);
+  mozStorageStatementScoper scoper(stmt);
+  rv = stmt->BindInt64Parameter(0, pageId);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = mDBSetPageFavicon->BindInt64Parameter(1, iconId);
+  rv = stmt->BindInt64Parameter(1, iconId);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = mDBSetPageFavicon->Execute();
+  rv = stmt->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = transaction.Commit();
   NS_ENSURE_SUCCESS(rv, rv);
   return NS_OK;
 }
 
+
 // nsFaviconService::UpdateBookmarkRedirectFavicon
 //
 //    It is not uncommon to have a bookmark (usually manually entered or
 //    modified) that redirects to some other page. For example, "mozilla.org"
 //    redirects to "www.mozilla.org". We want that bookmark's favicon to get
 //    updated. So, we see if this URI has a bookmark redirect and set the
 //    favicon there as well.
 //
@@ -644,16 +667,17 @@ nsFaviconService::UpdateBookmarkRedirect
     // send notifications
     SendFaviconNotifications(bookmarkURI, aFaviconURI);
   } else {
     NS_WARNING("Calling UpdateBookmarkRedirectFavicon when you don't have data for the favicon yet.");
   }
   return NS_OK;
 }
 
+
 // nsFaviconService::SendFaviconNotifications
 //
 //    Call to send out favicon changed notifications. Should only be called
 //    when you know there is data loaded for the favicon.
 
 void
 nsFaviconService::SendFaviconNotifications(nsIURI* aPageURI,
                                            nsIURI* aFaviconURI)
@@ -662,16 +686,17 @@ nsFaviconService::SendFaviconNotificatio
   nsNavHistory* historyService = nsNavHistory::GetHistoryService();
   if (historyService && NS_SUCCEEDED(aFaviconURI->GetSpec(faviconSpec))) {
     historyService->SendPageChangedNotification(aPageURI,
                                        nsINavHistoryObserver::ATTRIBUTE_FAVICON,
                                        NS_ConvertUTF8toUTF16(faviconSpec));
   }
 }
 
+
 NS_IMETHODIMP
 nsFaviconService::SetAndLoadFaviconForPage(nsIURI* aPageURI,
                                            nsIURI* aFaviconURI,
                                            PRBool aForceReload)
 {
   NS_ENSURE_ARG(aPageURI);
   NS_ENSURE_ARG(aFaviconURI);
 
@@ -684,16 +709,17 @@ nsFaviconService::SetAndLoadFaviconForPa
   return historyService->AddLazyLoadFaviconMessage(aPageURI,
                                                    aFaviconURI,
                                                    aForceReload);
 #else
   return DoSetAndLoadFaviconForPage(aPageURI, aFaviconURI, aForceReload);
 #endif
 }
 
+
 nsresult
 nsFaviconService::DoSetAndLoadFaviconForPage(nsIURI* aPageURI,
                                              nsIURI* aFaviconURI,
                                              PRBool aForceReload)
 {
   if (mFaviconsExpirationRunning)
     return NS_OK;
 
@@ -713,23 +739,24 @@ nsFaviconService::DoSetAndLoadFaviconFor
   // we don't want to save this favicon, so we early return.
   nsCOMPtr<nsIURI> page = GetEffectivePageForFavicon(aPageURI, aFaviconURI);
   NS_ENSURE_TRUE(page, NS_OK);
 
   nsRefPtr<FaviconExpirationGetter> dataGetter =
     new FaviconExpirationGetter(page, aFaviconURI, !!aForceReload);
   NS_ENSURE_TRUE(dataGetter, NS_ERROR_OUT_OF_MEMORY);
 
-  rv = dataGetter->checkAndLoad(mDBGetIconInfo);
+  rv = dataGetter->checkAndLoad(GetStatement(mDBGetIconInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // DB will be updated and observers notified when data has finished loading.
   return NS_OK;
 }
 
+
 // nsFaviconService::SetFaviconData
 //
 //    See the IDL for this function for lots of info. Note from there: we don't
 //    send out notifications.
 
 NS_IMETHODIMP
 nsFaviconService::SetFaviconData(nsIURI* aFaviconURI, const PRUint8* aData,
                                  PRUint32 aDataLen, const nsACString& aMimeType,
@@ -762,51 +789,60 @@ nsFaviconService::SetFaviconData(nsIURI*
       return NS_ERROR_FAILURE;
     }
   }
 
   mozIStorageStatement* statement;
   {
     // this block forces the scoper to reset our statement: necessary for the
     // next statement
-    mozStorageStatementScoper scoper(mDBGetIconInfo);
-    rv = BindStatementURI(mDBGetIconInfo, 0, aFaviconURI);
+    mozIStorageStatement* stmt = GetStatement(mDBGetIconInfo);
+    NS_ENSURE_STATE(stmt);
+    mozStorageStatementScoper scoper(stmt);
+    rv = BindStatementURI(stmt, 0, aFaviconURI);
     NS_ENSURE_SUCCESS(rv, rv);
 
     PRBool hasResult;
-    rv = mDBGetIconInfo->ExecuteStep(&hasResult);
+    rv = stmt->ExecuteStep(&hasResult);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (hasResult) {
       // update old one (statement parameter 0 = ID)
       PRInt64 id;
-      rv = mDBGetIconInfo->GetInt64(0, &id);
+      rv = stmt->GetInt64(0, &id);
       NS_ENSURE_SUCCESS(rv, rv);
-      statement = mDBUpdateIcon;
+      statement = GetStatement(mDBUpdateIcon);
+      NS_ENSURE_STATE(statement);
       rv = statement->BindInt64Parameter(0, id);
-    } else {
+    }
+    else {
       // insert new one (statement parameter 0 = favicon URL)
-      statement = mDBInsertIcon;
+      statement = GetStatement(mDBInsertIcon);
+      NS_ENSURE_STATE(statement);
       rv = BindStatementURI(statement, 0, aFaviconURI);
     }
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   mozStorageStatementScoper scoper(statement);
 
   // the insert and update statements share all but the 0th parameter
   rv = statement->BindBlobParameter(1, data, dataLen);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = statement->BindUTF8StringParameter(2, *mimeType);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = statement->BindInt64Parameter(3, aExpiration);
   NS_ENSURE_SUCCESS(rv, rv);
-  return statement->Execute();
+  rv = statement->Execute();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
 }
 
+
 NS_IMETHODIMP
 nsFaviconService::SetFaviconDataFromDataURL(nsIURI* aFaviconURI,
                                             const nsAString& aDataURL,
                                             PRTime aExpiration)
 {
   NS_ENSURE_ARG(aFaviconURI);
   if (mFaviconsExpirationRunning)
     return NS_OK;
@@ -856,38 +892,42 @@ nsFaviconService::SetFaviconDataFromData
   // SetFaviconData can now do the dirty work 
   rv = SetFaviconData(aFaviconURI, buffer, available, mimeType, aExpiration);
   nsMemory::Free(buffer);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
+
 NS_IMETHODIMP
 nsFaviconService::GetFaviconData(nsIURI* aFaviconURI, nsACString& aMimeType,
                                  PRUint32* aDataLen, PRUint8** aData)
 {
   NS_ENSURE_ARG(aFaviconURI);
   NS_ENSURE_ARG_POINTER(aDataLen);
   NS_ENSURE_ARG_POINTER(aData);
 
-  mozStorageStatementScoper scoper(mDBGetData);
-  nsresult rv = BindStatementURI(mDBGetData, 0, aFaviconURI);
+  mozIStorageStatement* stmt = GetStatement(mDBGetData);
+  NS_ENSURE_STATE(stmt);
+  mozStorageStatementScoper scoper(stmt);
+  nsresult rv = BindStatementURI(stmt, 0, aFaviconURI);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool hasResult = PR_FALSE;
-  if (NS_SUCCEEDED(mDBGetData->ExecuteStep(&hasResult)) && hasResult) {
-    rv = mDBGetData->GetUTF8String(1, aMimeType);
+  if (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
+    rv = stmt->GetUTF8String(1, aMimeType);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    return mDBGetData->GetBlob(0, aDataLen, aData);
+    return stmt->GetBlob(0, aDataLen, aData);
   }
   return NS_ERROR_NOT_AVAILABLE;
 }
 
+
 NS_IMETHODIMP
 nsFaviconService::GetFaviconDataAsDataURL(nsIURI* aFaviconURI,
                                           nsAString& aDataURL)
 {
   NS_ENSURE_ARG(aFaviconURI);
 
   PRUint8* data;
   PRUint32 dataLen;
@@ -912,93 +952,102 @@ nsFaviconService::GetFaviconDataAsDataUR
   AppendUTF8toUTF16(mimeType, aDataURL);
   aDataURL.AppendLiteral(";base64,");
   AppendUTF8toUTF16(encoded, aDataURL);
 
   nsMemory::Free(encoded);
   return NS_OK;
 }
 
+
 NS_IMETHODIMP
 nsFaviconService::GetFaviconForPage(nsIURI* aPageURI, nsIURI** _retval)
 {
   NS_ENSURE_ARG(aPageURI);
   NS_ENSURE_ARG_POINTER(_retval);
 
-  mozStorageStatementScoper scoper(mDBGetURL);
-  nsresult rv = BindStatementURI(mDBGetURL, 0, aPageURI);
+  mozIStorageStatement* stmt = GetStatement(mDBGetURL);
+  NS_ENSURE_STATE(stmt);
+  mozStorageStatementScoper scoper(stmt);
+  nsresult rv = BindStatementURI(stmt, 0, aPageURI);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool hasResult;
-  if (NS_SUCCEEDED(mDBGetURL->ExecuteStep(&hasResult)) && hasResult) {
+  if (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
     nsCAutoString url;
-    rv = mDBGetURL->GetUTF8String(1, url);
+    rv = stmt->GetUTF8String(1, url);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_NewURI(_retval, url);
   }
   return NS_ERROR_NOT_AVAILABLE;
 }
 
+
 NS_IMETHODIMP
 nsFaviconService::GetFaviconImageForPage(nsIURI* aPageURI, nsIURI** _retval)
 {
   NS_ENSURE_ARG(aPageURI);
   NS_ENSURE_ARG_POINTER(_retval);
 
-  mozStorageStatementScoper scoper(mDBGetURL);
-  nsresult rv = BindStatementURI(mDBGetURL, 0, aPageURI);
+  mozIStorageStatement* stmt = GetStatement(mDBGetURL);
+  NS_ENSURE_STATE(stmt);
+  mozStorageStatementScoper scoper(stmt);
+  nsresult rv = BindStatementURI(stmt, 0, aPageURI);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool hasResult;
   nsCOMPtr<nsIURI> faviconURI;
-  if (NS_SUCCEEDED(mDBGetURL->ExecuteStep(&hasResult)) && hasResult) {
+  if (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
     PRInt32 dataLen;
-    rv = mDBGetURL->GetInt32(2, &dataLen);
+    rv = stmt->GetInt32(2, &dataLen);
     NS_ENSURE_SUCCESS(rv, rv);
     if (dataLen > 0) {
       // this page has a favicon entry with data
       nsCAutoString favIconUri;
-      rv = mDBGetURL->GetUTF8String(1, favIconUri);
+      rv = stmt->GetUTF8String(1, favIconUri);
       NS_ENSURE_SUCCESS(rv, rv);
 
       return GetFaviconLinkForIconString(favIconUri, _retval);
     }
   }
 
   // not found, use default
   return GetDefaultFavicon(_retval);
 }
 
+
 nsresult
 nsFaviconService::GetFaviconLinkForIcon(nsIURI* aFaviconURI,
                                         nsIURI** aOutputURI)
 {
   NS_ENSURE_ARG(aFaviconURI);
   NS_ENSURE_ARG_POINTER(aOutputURI);
 
   nsCAutoString spec;
   if (aFaviconURI) {
     nsresult rv = aFaviconURI->GetSpec(spec);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   return GetFaviconLinkForIconString(spec, aOutputURI);
 }
 
+
 static PLDHashOperator
 ExpireFailedFaviconsCallback(nsCStringHashKey::KeyType aKey,
                              PRUint32& aData,
                              void* userArg)
 {
   PRUint32* threshold = reinterpret_cast<PRUint32*>(userArg);
   if (aData < *threshold)
     return PL_DHASH_REMOVE;
   return PL_DHASH_NEXT;
 }
 
+
 NS_IMETHODIMP
 nsFaviconService::AddFailedFavicon(nsIURI* aFaviconURI)
 {
   NS_ENSURE_ARG(aFaviconURI);
 
   nsCAutoString spec;
   nsresult rv = aFaviconURI->GetSpec(spec);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -1012,43 +1061,46 @@ nsFaviconService::AddFailedFavicon(nsIUR
     // of items that are the oldest
     PRUint32 threshold = mFailedFaviconSerial -
                          MAX_FAVICON_CACHE_SIZE + FAVICON_CACHE_REDUCE_COUNT;
     mFailedFavicons.Enumerate(ExpireFailedFaviconsCallback, &threshold);
   }
   return NS_OK;
 }
 
+
 NS_IMETHODIMP
 nsFaviconService::RemoveFailedFavicon(nsIURI* aFaviconURI)
 {
   NS_ENSURE_ARG(aFaviconURI);
 
   nsCAutoString spec;
   nsresult rv = aFaviconURI->GetSpec(spec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // we silently do nothing and succeed if the icon is not in the cache
   mFailedFavicons.Remove(spec);
   return NS_OK;
 }
 
+
 NS_IMETHODIMP
 nsFaviconService::IsFailedFavicon(nsIURI* aFaviconURI, PRBool* _retval)
 {
   NS_ENSURE_ARG(aFaviconURI);
   nsCAutoString spec;
   nsresult rv = aFaviconURI->GetSpec(spec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRUint32 serial;
   *_retval = mFailedFavicons.Get(spec, &serial);
   return NS_OK;
 }
 
+
 // nsFaviconService::GetFaviconLinkForIconString
 //
 //    This computes a favicon URL with string input and using the cached
 //    default one to minimize parsing.
 
 nsresult
 nsFaviconService::GetFaviconLinkForIconString(const nsCString& aSpec,
                                               nsIURI** aOutput)
@@ -1070,16 +1122,17 @@ nsFaviconService::GetFaviconLinkForIconS
   }
 
   nsCAutoString annoUri;
   annoUri.AssignLiteral("moz-anno:" FAVICON_ANNOTATION_NAME ":");
   annoUri += aSpec;
   return NS_NewURI(aOutput, annoUri);
 }
 
+
 // nsFaviconService::GetFaviconSpecForIconString
 //
 //    This computes a favicon spec for when you don't want a URI object (as in
 //    the tree view implementation), sparing all parsing and normalization.
 void
 nsFaviconService::GetFaviconSpecForIconString(const nsCString& aSpec,
                                               nsACString& aOutput)
 {
@@ -1088,16 +1141,17 @@ nsFaviconService::GetFaviconSpecForIconS
   } else if (StringBeginsWith(aSpec, NS_LITERAL_CSTRING("chrome:"))) {
     aOutput = aSpec;
   } else {
     aOutput.AssignLiteral("moz-anno:" FAVICON_ANNOTATION_NAME ":");
     aOutput += aSpec;
   }
 }
 
+
 // nsFaviconService::OptimizeFaviconImage
 //
 // Given a blob of data (a image file already read into a buffer), optimize
 // its size by recompressing it as a 16x16 PNG.
 nsresult
 nsFaviconService::OptimizeFaviconImage(const PRUint8* aData, PRUint32 aDataLen,
                                        const nsACString& aMimeType,
                                        nsACString& aNewData,
@@ -1131,47 +1185,57 @@ nsFaviconService::OptimizeFaviconImage(c
 
   // Read the stream into a new buffer.
   rv = NS_ConsumeStream(iconStream, PR_UINT32_MAX, aNewData);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
+
 nsresult
 nsFaviconService::FinalizeStatements() {
+  mShuttingDown = true;
+
   mozIStorageStatement* stmts[] = {
     mDBGetURL,
     mDBGetData,
     mDBGetIconInfo,
     mDBInsertIcon,
     mDBUpdateIcon,
-    mDBSetPageFavicon
+    mDBSetPageFavicon,
+    mDBRemoveOnDiskReferences,
+    mDBRemoveTempReferences,
+    mDBRemoveAllFavicons,
   };
 
   for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(stmts); i++) {
     nsresult rv = nsNavHistory::FinalizeStatement(stmts[i]);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
+
 nsresult
 nsFaviconService::GetFaviconDataAsync(nsIURI* aFaviconURI,
                                       mozIStorageStatementCallback *aCallback)
 {
   NS_ASSERTION(aCallback, "Doesn't make sense to call this without a callback");
-  nsresult rv = BindStatementURI(mDBGetData, 0, aFaviconURI);
+  mozIStorageStatement* stmt = GetStatement(mDBGetData);
+  NS_ENSURE_STATE(stmt);
+  nsresult rv = BindStatementURI(stmt, 0, aFaviconURI);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<mozIStoragePendingStatement> pendingStatement;
-  return mDBGetData->ExecuteAsync(aCallback, getter_AddRefs(pendingStatement));
+  return stmt->ExecuteAsync(aCallback, getter_AddRefs(pendingStatement));
 }
 
+
 void
 nsFaviconService::checkAndNotify(nsIURI *aPageURI,
                                  nsIURI *aFaviconURI)
 {
   // For page revisits (pretty common) we DON'T want to send out any
   // notifications if we've already set the favicon. These notifications will
   // cause parts of the UI to update and will be slow. This also saves us a
   // database write in these cases.
@@ -1189,44 +1253,49 @@ nsFaviconService::checkAndNotify(nsIURI 
     return;
 
   if (hasData) {
     SendFaviconNotifications(aPageURI, aFaviconURI);
     UpdateBookmarkRedirectFavicon(aPageURI, aFaviconURI);
   }
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
 //// FaviconLoadListener
 
 NS_IMPL_ISUPPORTS4(FaviconLoadListener,
                    nsIRequestObserver,
                    nsIStreamListener,
                    nsIInterfaceRequestor,
                    nsIChannelEventSink)
 
+
 FaviconLoadListener::FaviconLoadListener(nsIURI* aPageURI,
                                          nsIURI* aFaviconURI,
                                          nsIChannel* aChannel) :
   mChannel(aChannel),
   mPageURI(aPageURI),
   mFaviconURI(aFaviconURI)
 {
 }
 
+
 FaviconLoadListener::~FaviconLoadListener()
 {
 }
 
+
 NS_IMETHODIMP
 FaviconLoadListener::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
 {
   return NS_OK;
 }
 
+
 NS_IMETHODIMP
 FaviconLoadListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
                                  nsresult aStatusCode)
 {
   nsFaviconService *fs = nsFaviconService::GetFaviconService();
   NS_ENSURE_TRUE(fs, NS_ERROR_OUT_OF_MEMORY);
 
   if (NS_FAILED(aStatusCode) || mData.Length() == 0) {
@@ -1317,59 +1386,65 @@ FaviconLoadListener::OnStopRequest(nsIRe
 
   rv = transaction.Commit();
   NS_ENSURE_SUCCESS(rv, rv);
 
   fs->SendFaviconNotifications(mPageURI, mFaviconURI);
   return NS_OK;
 }
 
+
 NS_IMETHODIMP
-FaviconLoadListener::OnDataAvailable(nsIRequest *aRequest,
-                                     nsISupports *aContext,
-                                     nsIInputStream *aInputStream,
+FaviconLoadListener::OnDataAvailable(nsIRequest* aRequest,
+                                     nsISupports* aContext,
+                                     nsIInputStream* aInputStream,
                                      PRUint32 aOffset,
                                      PRUint32 aCount)
 {
   nsCString buffer;
   nsresult rv = NS_ConsumeStream(aInputStream, aCount, buffer);
   if (rv != NS_BASE_STREAM_WOULD_BLOCK && NS_FAILED(rv))
     return rv;
 
   mData.Append(buffer);
   return NS_OK;
 }
 
+
 NS_IMETHODIMP
 FaviconLoadListener::GetInterface(const nsIID& uuid, void** aResult)
 {
   return QueryInterface(uuid, aResult);
 }
 
+
 NS_IMETHODIMP
 FaviconLoadListener::OnChannelRedirect(nsIChannel* oldChannel,
                                        nsIChannel* newChannel,
                                        PRUint32 flags)
 {
   mChannel = newChannel;
   return NS_OK;
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
 //// ExpireFaviconsStatementCallbackNotifier
 
 NS_IMPL_ISUPPORTS1(ExpireFaviconsStatementCallbackNotifier,
                    mozIStorageStatementCallback)
 
-ExpireFaviconsStatementCallbackNotifier::ExpireFaviconsStatementCallbackNotifier(bool *aFaviconsExpirationRunning)
-  : mFaviconsExpirationRunning(aFaviconsExpirationRunning)
+ExpireFaviconsStatementCallbackNotifier::ExpireFaviconsStatementCallbackNotifier(
+  bool* aFaviconsExpirationRunning)
+: mFaviconsExpirationRunning(aFaviconsExpirationRunning)
 {
   NS_ASSERTION(mFaviconsExpirationRunning, "Pointer to bool mFaviconsExpirationRunning can't be null");
 }
 
+
 NS_IMETHODIMP
 ExpireFaviconsStatementCallbackNotifier::HandleCompletion(PRUint16 aReason)
 {
   *mFaviconsExpirationRunning = false;
 
   // We should dispatch only if expiration has been successful.
   if (aReason != mozIStorageStatementCallback::REASON_FINISHED)
     return NS_OK;
@@ -1380,14 +1455,15 @@ ExpireFaviconsStatementCallbackNotifier:
     (void)observerService->NotifyObservers(nsnull,
                                            NS_PLACES_FAVICONS_EXPIRED_TOPIC_ID,
                                            nsnull);
   }
 
   return NS_OK;
 }
 
+
 NS_IMETHODIMP
-ExpireFaviconsStatementCallbackNotifier::HandleResult(mozIStorageResultSet *aResultSet)
+ExpireFaviconsStatementCallbackNotifier::HandleResult(mozIStorageResultSet* aResultSet)
 {
   NS_ASSERTION(PR_FALSE, "You cannot use this statement callback to get async statements resultset");
   return NS_OK;
 }
--- a/toolkit/components/places/src/nsFaviconService.h
+++ b/toolkit/components/places/src/nsFaviconService.h
@@ -36,21 +36,21 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsCOMPtr.h"
 #include "nsDataHashtable.h"
 #include "nsIFaviconService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
-#include "mozIStorageConnection.h"
-#include "mozIStorageValueArray.h"
-#include "mozIStorageStatement.h"
+
 #include "nsToolkitCompsCID.h"
 
+#include "mozilla/storage.h"
+
 // Favicons bigger than this size should not be saved to the db to avoid
 // bloating it with large image blobs.
 // This still allows us to accept a favicon even if we cannot optimize it.
 #define MAX_FAVICON_SIZE 10240
 
 // forward class definitions
 class mozIStorageStatementCallback;
 
@@ -60,31 +60,31 @@ class FaviconLoadListener;
 class nsFaviconService : public nsIFaviconService
 {
 public:
   nsFaviconService();
 
   /**
    * Obtains the service's object.
    */
-  static nsFaviconService * GetSingleton();
+  static nsFaviconService* GetSingleton();
 
   /**
    * Initializes the service's object.  This should only be called once.
    */
   nsresult Init();
 
   // called by nsNavHistory::Init
   static nsresult InitTables(mozIStorageConnection* aDBConn);
 
   /**
    * Returns a cached pointer to the favicon service for consumers in the
    * places directory.
    */
-  static nsFaviconService * GetFaviconService()
+  static nsFaviconService* GetFaviconService()
   {
     if (!gFaviconService) {
       nsCOMPtr<nsIFaviconService> serv =
         do_GetService(NS_FAVICONSERVICE_CONTRACTID);
       NS_ENSURE_TRUE(serv, nsnull);
       NS_ASSERTION(gFaviconService, "Should have static instance pointer now");
     }
     return gFaviconService;
@@ -107,51 +107,58 @@ public:
    *
    * @param aFaviconURI
    *        The URI representing the favicon we are looking for.
    * @param aCallback
    *        The callback where results or errors will be dispatch to.  In the
    *        returned result, the favicon binary data will be at index 0, and the
    *        mime type will be at index 1.
    */
-  nsresult GetFaviconDataAsync(nsIURI *aFaviconURI,
-                               mozIStorageStatementCallback *aCallback);
+  nsresult GetFaviconDataAsync(nsIURI* aFaviconURI,
+                               mozIStorageStatementCallback* aCallback);
 
   /**
    * Checks to see if a favicon's URI has changed, and notifies callers if it
    * has.
    *
    * @param aPageURI
    *        The URI of the page aFaviconURI is for.
    * @param aFaviconURI
    *        The URI for the favicon we want to test for on aPageURI.
    */
-  void checkAndNotify(nsIURI *aPageURI, nsIURI *aFaviconURI);
+  void checkAndNotify(nsIURI* aPageURI, nsIURI* aFaviconURI);
 
   /**
    * Finalize all internal statements.
    */
   nsresult FinalizeStatements();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIFAVICONSERVICE
 
 private:
   ~nsFaviconService();
 
   nsCOMPtr<mozIStorageConnection> mDBConn; // from history service
 
+  /**
+   * Always use this getter and never use directly the statement nsCOMPtr.
+   */
+  mozIStorageStatement* GetStatement(const nsCOMPtr<mozIStorageStatement>& aStmt);
   nsCOMPtr<mozIStorageStatement> mDBGetURL; // returns URL, data len given page
   nsCOMPtr<mozIStorageStatement> mDBGetData; // returns actual data given URL
   nsCOMPtr<mozIStorageStatement> mDBGetIconInfo;
   nsCOMPtr<mozIStorageStatement> mDBInsertIcon;
   nsCOMPtr<mozIStorageStatement> mDBUpdateIcon;
   nsCOMPtr<mozIStorageStatement> mDBSetPageFavicon;
+  nsCOMPtr<mozIStorageStatement> mDBRemoveOnDiskReferences;
+  nsCOMPtr<mozIStorageStatement> mDBRemoveTempReferences;
+  nsCOMPtr<mozIStorageStatement> mDBRemoveAllFavicons;
 
-  static nsFaviconService *gFaviconService;
+  static nsFaviconService* gFaviconService;
 
   /**
    * A cached URI for the default icon. We return this a lot, and don't want to
    * re-parse and normalize our unchanging string many times.  Important: do
    * not return this directly; use Clone() since callers may change the object
    * they get back. May be null, in which case it needs initialization.
    */
   nsCOMPtr<nsIURI> mDefaultIcon;
@@ -171,13 +178,15 @@ private:
 
   nsresult SetFaviconUrlForPageInternal(nsIURI* aURI, nsIURI* aFavicon,
                                         PRBool* aHasData);
 
   nsresult UpdateBookmarkRedirectFavicon(nsIURI* aPage, nsIURI* aFavicon);
   void SendFaviconNotifications(nsIURI* aPage, nsIURI* aFaviconURI);
 
   friend class FaviconLoadListener;
+
+  bool mShuttingDown;
 };
 
 #define FAVICON_DEFAULT_URL "chrome://mozapps/skin/places/defaultFavicon.png"
 #define FAVICON_ERRORPAGE_URL "chrome://global/skin/icons/warning-16.png"
 #define FAVICON_ANNOTATION_NAME "favicon"