Bug 392193 - first run migration / import from ie, opera and safari browser can be slow, migration should use "run in batch", r=sdwilsh
authorMarco Bonardo <mbonardo@mozilla.com>
Tue, 12 May 2009 11:15:02 +0200
changeset 28227 67e00891a9bfc6dd4c0e2b35d53d0ac0034601cf
parent 28226 ee88749b4b6edd6c9b74087717a1fe1f7a76bf8f
child 28228 ca08e548a10521a80daa9425e5eb0c73a395933a
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssdwilsh
bugs392193
milestone1.9.2a1pre
Bug 392193 - first run migration / import from ie, opera and safari browser can be slow, migration should use "run in batch", r=sdwilsh
browser/components/migration/src/nsBrowserProfileMigratorUtils.cpp
browser/components/migration/src/nsBrowserProfileMigratorUtils.h
browser/components/migration/src/nsIEProfileMigrator.cpp
browser/components/migration/src/nsIEProfileMigrator.h
browser/components/migration/src/nsMacIEProfileMigrator.cpp
browser/components/migration/src/nsOperaProfileMigrator.cpp
browser/components/migration/src/nsOperaProfileMigrator.h
browser/components/migration/src/nsSafariProfileMigrator.cpp
browser/components/migration/src/nsSafariProfileMigrator.h
--- a/browser/components/migration/src/nsBrowserProfileMigratorUtils.cpp
+++ b/browser/components/migration/src/nsBrowserProfileMigratorUtils.cpp
@@ -236,43 +236,45 @@ ImportBookmarksHTML(nsIFile* aBookmarksF
     NS_ENSURE_SUCCESS(rv, rv);
     return NS_OK;
   }
 
   // Get the source application name.
   nsCOMPtr<nsIStringBundleService> bundleService =
     do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
-
   nsCOMPtr<nsIStringBundle> bundle;
   rv = bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsString sourceName;
-  bundle->GetStringFromName(aImportSourceNameKey, getter_Copies(sourceName));
+  rv = bundle->GetStringFromName(aImportSourceNameKey,
+                                 getter_Copies(sourceName));
+  NS_ENSURE_SUCCESS(rv, rv);
 
   const PRUnichar* sourceNameStrings[] = { sourceName.get() };
   nsString importedBookmarksTitle;
-  bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
-                               sourceNameStrings, 1, 
-                               getter_Copies(importedBookmarksTitle));
+  rv = bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
+                                    sourceNameStrings, 1, 
+                                    getter_Copies(importedBookmarksTitle));
+  NS_ENSURE_SUCCESS(rv, rv);
 
   // Get the bookmarks service.
   nsCOMPtr<nsINavBookmarksService> bms =
     do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create an imported bookmarks folder under the bookmarks menu.
   PRInt64 root;
   rv = bms->GetBookmarksMenuFolder(&root);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt64 folder;
   rv = bms->CreateFolder(root, NS_ConvertUTF16toUTF8(importedBookmarksTitle),
-                         -1, &folder);
+                         nsINavBookmarksService::DEFAULT_INDEX, &folder);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Import the bookmarks into the folder.
   return importer->ImportHTMLFromFileToFolder(localFile, folder, PR_FALSE);
 }
 
 nsresult
 InitializeBookmarks(nsIFile* aTargetProfile)
--- a/browser/components/migration/src/nsBrowserProfileMigratorUtils.h
+++ b/browser/components/migration/src/nsBrowserProfileMigratorUtils.h
@@ -53,16 +53,21 @@
     NOTIFY_OBSERVERS(MIGRATION_ITEMBEFOREMIGRATE, index.get()); \
     rv = func(replace); \
     NOTIFY_OBSERVERS(MIGRATION_ITEMAFTERMIGRATE, index.get()); \
   }
 
 #define NC_URI(property) \
   NS_LITERAL_CSTRING("http://home.netscape.com/NC-rdf#"#property)
 
+#define BATCH_ACTION_HISTORY 0
+#define BATCH_ACTION_HISTORY_REPLACE 1
+#define BATCH_ACTION_BOOKMARKS 2
+#define BATCH_ACTION_BOOKMARKS_REPLACE 3
+
 #include "nsIPrefBranch.h"
 #include "nsIFile.h"
 #include "nsStringAPI.h"
 #include "nsCOMPtr.h"
 
 class nsIProfileStartup;
 
 
--- a/browser/components/migration/src/nsIEProfileMigrator.cpp
+++ b/browser/components/migration/src/nsIEProfileMigrator.cpp
@@ -89,19 +89,29 @@
 #include "nsIURL.h"
 #include "nsINavBookmarksService.h"
 #include "nsBrowserCompsCID.h"
 #include "nsIStringBundle.h"
 #include "nsNetUtil.h"
 #include "nsToolkitCompsCID.h"
 #include "nsUnicharUtils.h"
 #include "nsIWindowsRegKey.h"
+#include "nsISupportsPrimitives.h"
 
 #define TRIDENTPROFILE_BUNDLE       "chrome://browser/locale/migration/migration.properties"
 
+#define REGISTRY_IE_MAIN_KEY \
+  NS_LITERAL_STRING("Software\\Microsoft\\Internet Explorer\\Main")
+#define REGISTRY_IE_TYPEDURL_KEY \
+  NS_LITERAL_STRING("Software\\Microsoft\\Internet Explorer\\TypedURLs")
+#define REGISTRY_IE_TOOLBAR_KEY \
+  NS_LITERAL_STRING("Software\\Microsoft\\Internet Explorer\\Toolbar")
+#define REGISTRY_IE_SEARCHURL_KEY \
+  NS_LITERAL_STRING("Software\\Microsoft\\Internet Explorer\\SearchUrl")
+
 const int sInitialCookieBufferSize = 1024; // but it can grow
 const int sUsernameLengthLimit     = 80;
 const int sHostnameLengthLimit     = 255;
 
 //***********************************************************************
 //*** Replacements for comsupp.lib calls used by pstorec.dll
 //***********************************************************************
 void  __stdcall _com_issue_error(HRESULT hr)
@@ -484,21 +494,20 @@ nsIEProfileMigrator::GetSourceProfiles(n
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsIEProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
 {
   nsCOMPtr<nsIWindowsRegKey> regKey = 
     do_CreateInstance("@mozilla.org/windows-registry-key;1");
-  NS_NAMED_LITERAL_STRING(homeURLKey,
-                          "Software\\Microsoft\\Internet Explorer\\Main");
   if (!regKey ||
       NS_FAILED(regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
-                             homeURLKey, nsIWindowsRegKey::ACCESS_READ)))
+                             REGISTRY_IE_MAIN_KEY,
+                             nsIWindowsRegKey::ACCESS_READ)))
     return NS_OK;
   // Read in the main home page
   NS_NAMED_LITERAL_STRING(homeURLValName, "Start Page");
   nsAutoString homeURLVal;
 
   if (NS_SUCCEEDED(regKey->ReadStringValue(homeURLValName, homeURLVal))) {
     // Do we need this round-about way to get |homePageURL|? 
     // Perhaps, we do to have the form of URL under our control 
@@ -544,17 +553,17 @@ nsIEProfileMigrator::GetSourceHomePageUR
   return NS_OK;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 // nsIEProfileMigrator
 NS_IMPL_ISUPPORTS2(nsIEProfileMigrator, nsIBrowserProfileMigrator, nsINavHistoryBatchCallback);
 
-nsIEProfileMigrator::nsIEProfileMigrator() 
+nsIEProfileMigrator::nsIEProfileMigrator()
 {
   mObserverService = do_GetService("@mozilla.org/observer-service;1");
 }
 
 nsIEProfileMigrator::~nsIEProfileMigrator() 
 {
 }
 
@@ -622,28 +631,68 @@ nsIEProfileMigrator::TestForIE7()
     PRInt32 ver = wcstol(ieVersion.get(), nsnull, 0);
     if (ver >= 7) // Found 7 or greater major version
       return PR_TRUE;
   }
 
   return PR_FALSE;
 }
 
+NS_IMETHODIMP
+nsIEProfileMigrator::RunBatched(nsISupports* aUserData)
+{
+  PRUint8 batchAction;
+  nsCOMPtr<nsISupportsPRUint8> strWrapper(do_QueryInterface(aUserData));
+  NS_ASSERTION(strWrapper, "Unable to create nsISupportsPRUint8 wrapper!");
+  nsresult rv = strWrapper->GetData(&batchAction);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  switch (batchAction) {
+    case BATCH_ACTION_HISTORY:
+      rv = CopyHistoryBatched(PR_FALSE);
+      break;
+    case BATCH_ACTION_HISTORY_REPLACE:
+      rv = CopyHistoryBatched(PR_TRUE);
+      break;
+    case BATCH_ACTION_BOOKMARKS:
+      rv = CopyFavoritesBatched(PR_FALSE);
+      break;
+    case BATCH_ACTION_BOOKMARKS_REPLACE:
+      rv = CopyFavoritesBatched(PR_TRUE);
+      break;
+  }
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
 nsresult
-nsIEProfileMigrator::CopyHistory(PRBool aReplace) 
+nsIEProfileMigrator::CopyHistory(PRBool aReplace)
 {
   nsresult rv;
-  nsCOMPtr<nsINavHistoryService> history = do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID, &rv);
+  nsCOMPtr<nsINavHistoryService> history =
+    do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return history->RunInBatchMode(this, nsnull);
+  PRUint8 batchAction = aReplace ? BATCH_ACTION_HISTORY_REPLACE
+                                 : BATCH_ACTION_HISTORY;
+  nsCOMPtr<nsISupportsPRUint8> supports =
+    do_CreateInstance(NS_SUPPORTS_PRUINT8_CONTRACTID);
+  NS_ENSURE_TRUE(supports, NS_ERROR_OUT_OF_MEMORY);
+  rv = supports->SetData(batchAction);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = history->RunInBatchMode(this, supports);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsIEProfileMigrator::RunBatched(nsISupports* aUserData)
+nsresult
+nsIEProfileMigrator::CopyHistoryBatched(PRBool aReplace)
 {
   nsCOMPtr<nsIBrowserHistory> hist(do_GetService(NS_GLOBALHISTORY2_CONTRACTID));
   nsCOMPtr<nsIIOService> ios(do_GetService(NS_IOSERVICE_CONTRACTID));
 
   // First, Migrate standard IE History entries...
   ::CoInitialize(NULL);
 
   IUrlHistoryStg2* ieHistory;
@@ -733,21 +782,20 @@ nsIEProfileMigrator::RunBatched(nsISuppo
 
     ieHistory->Release();
   }
   ::CoUninitialize();
 
   // Now, find out what URLs were typed in by the user
   nsCOMPtr<nsIWindowsRegKey> regKey = 
     do_CreateInstance("@mozilla.org/windows-registry-key;1");
-  NS_NAMED_LITERAL_STRING(typedURLKey,
-                          "Software\\Microsoft\\Internet Explorer\\TypedURLs");
   if (regKey && 
       NS_SUCCEEDED(regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
-                                typedURLKey, nsIWindowsRegKey::ACCESS_READ))) {
+                                REGISTRY_IE_TYPEDURL_KEY,
+                                nsIWindowsRegKey::ACCESS_READ))) {
     int offset = 0;
 
     while (1) {
       nsAutoString valueName;
       if (NS_FAILED(regKey->GetValueName(offset, valueName)))
         break;
 
       nsAutoString url; 
@@ -1259,17 +1307,17 @@ nsIEProfileMigrator::CopyFormData(PRBool
 nsresult
 nsIEProfileMigrator::AddDataToFormHistory(const nsAString& aKey, PRUnichar* aData, unsigned long aCount)
 {
   nsCOMPtr<nsIFormHistory2> formHistory(do_GetService("@mozilla.org/satchel/form-history;1"));
   if (!formHistory)
     return NS_ERROR_OUT_OF_MEMORY;
 
   PRUnichar* cursor = aData;
-  PRInt32 offset = 0;
+  PRUint32 offset = 0;
 
   while (offset < aCount) {
     nsAutoString curr; curr = cursor;
 
     formHistory->AddEntry(aKey, curr);
 
     // Advance the cursor
     PRInt32 advance = curr.Length() + 1;
@@ -1280,154 +1328,193 @@ nsIEProfileMigrator::AddDataToFormHistor
   return NS_OK;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 //
 // favorites
 // search keywords
 //
+nsresult
+nsIEProfileMigrator::CopyFavorites(PRBool aReplace)
+{
+  nsresult rv;
+  nsCOMPtr<nsINavBookmarksService> bookmarks =
+    do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRBool batchAction = aReplace ? BATCH_ACTION_BOOKMARKS_REPLACE
+                                : BATCH_ACTION_BOOKMARKS;
+  nsCOMPtr<nsISupportsPRUint8> supports =
+    do_CreateInstance(NS_SUPPORTS_PRUINT8_CONTRACTID);
+  NS_ENSURE_TRUE(supports, NS_ERROR_OUT_OF_MEMORY);
+  rv = supports->SetData(batchAction);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = bookmarks->RunInBatchMode(this, supports);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
 
 nsresult
-nsIEProfileMigrator::CopyFavorites(PRBool aReplace) {
-  // If "aReplace" is true, merge into the root level of bookmarks. Otherwise, create
-  // a folder called "Imported IE Favorites" and place all the Bookmarks there. 
+nsIEProfileMigrator::CopyFavoritesBatched(PRBool aReplace)
+{
+  // If "aReplace" is true, merge into the root level of bookmarks. Otherwise,
+  // create a folder called "Imported IE Favorites" and place all the Bookmarks
+  // there.
   nsresult rv;
 
-  nsCOMPtr<nsINavBookmarksService> bms(do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv));
+  nsCOMPtr<nsINavBookmarksService> bms =
+    do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
-  PRInt64 root;
-  rv = bms->GetBookmarksMenuFolder(&root);
+
+  PRInt64 bookmarksMenuFolderId;
+  rv = bms->GetBookmarksMenuFolder(&bookmarksMenuFolderId);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString personalToolbarFolderName;
-
   PRInt64 folder;
   if (!aReplace) {
-    nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
-    if (NS_FAILED(rv)) return rv;
-    
+    nsCOMPtr<nsIStringBundleService> bundleService =
+      do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
     nsCOMPtr<nsIStringBundle> bundle;
-    bundleService->CreateBundle(TRIDENTPROFILE_BUNDLE, getter_AddRefs(bundle));
+    rv = bundleService->CreateBundle(TRIDENTPROFILE_BUNDLE,
+                                     getter_AddRefs(bundle));
+    NS_ENSURE_SUCCESS(rv, rv);
 
     nsString sourceNameIE;
-    bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameIE").get(), 
-                              getter_Copies(sourceNameIE));
+    rv = bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameIE").get(),
+                                   getter_Copies(sourceNameIE));
+    NS_ENSURE_SUCCESS(rv, rv);
 
     const PRUnichar* sourceNameStrings[] = { sourceNameIE.get() };
     nsString importedIEFavsTitle;
-    bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
-                                 sourceNameStrings, 1, getter_Copies(importedIEFavsTitle));
+    rv = bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
+                                      sourceNameStrings, 1,
+                                      getter_Copies(importedIEFavsTitle));
+    NS_ENSURE_SUCCESS(rv, rv);
 
-    bms->CreateFolder(root, NS_ConvertUTF16toUTF8(importedIEFavsTitle), -1,
-                      &folder);
+    rv = bms->CreateFolder(bookmarksMenuFolderId,
+                           NS_ConvertUTF16toUTF8(importedIEFavsTitle),
+                           nsINavBookmarksService::DEFAULT_INDEX,
+                           &folder);
+    NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
     // Initialize the default bookmarks
     nsCOMPtr<nsIFile> profile;
     GetProfilePath(nsnull, profile);
     rv = InitializeBookmarks(profile);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    // Locate the Links toolbar folder, we want to replace the Personal Toolbar content with 
-    // Favorites in this folder. 
-    nsCOMPtr<nsIWindowsRegKey> regKey = 
+    // Locate the Links toolbar folder, we want to replace the Personal Toolbar
+    // content with Favorites in this folder.
+    nsCOMPtr<nsIWindowsRegKey> regKey =
       do_CreateInstance("@mozilla.org/windows-registry-key;1");
-    NS_NAMED_LITERAL_STRING(toolbarKey,
-                            "Software\\Microsoft\\Internet Explorer\\Toolbar");
-    if (regKey && 
+    if (regKey &&
         NS_SUCCEEDED(regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
-                                  toolbarKey, nsIWindowsRegKey::ACCESS_READ))) {
+                                  REGISTRY_IE_TOOLBAR_KEY,
+                                  nsIWindowsRegKey::ACCESS_READ))) {
       nsAutoString linksFolderName;
       if (NS_SUCCEEDED(regKey->ReadStringValue(
-                       NS_LITERAL_STRING("LinksFolderName"),
-                       linksFolderName)))
-        personalToolbarFolderName = linksFolderName; 
+                         NS_LITERAL_STRING("LinksFolderName"),
+                         linksFolderName)))
+        personalToolbarFolderName = linksFolderName;
     }
-    folder = root;
+    folder = bookmarksMenuFolderId;
   }
 
-  nsCOMPtr<nsIProperties> fileLocator(do_GetService("@mozilla.org/file/directory_service;1", &rv));
-  if (NS_FAILED(rv)) 
-      return rv;
-
+  nsCOMPtr<nsIProperties> fileLocator =
+    do_GetService("@mozilla.org/file/directory_service;1", &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIFile> favoritesDirectory;
-  fileLocator->Get("Favs", NS_GET_IID(nsIFile), getter_AddRefs(favoritesDirectory));
+  (void)fileLocator->Get("Favs", NS_GET_IID(nsIFile),
+                         getter_AddRefs(favoritesDirectory));
 
-  // If |favoritesDirectory| is null, it means that we're on a Windows 
-  // platform that does not have a Favorites folder, e.g. Windows 95 
-  // (early SRs, before IE integrated with the shell). Only try to 
-  // read Favorites folder if it exists on the machine. 
+  // If |favoritesDirectory| is null, it means that we're on a Windows
+  // platform that does not have a Favorites folder, e.g. Windows 95
+  // (early SRs, before IE integrated with the shell).
+  // Only try to read Favorites folder if it exists on the machine.
   if (favoritesDirectory) {
-    rv = ParseFavoritesFolder(favoritesDirectory, folder, bms, personalToolbarFolderName, PR_TRUE);
+    rv = ParseFavoritesFolder(favoritesDirectory, folder, bms,
+                              personalToolbarFolderName, PR_TRUE);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  return CopySmartKeywords(root);
+  return CopySmartKeywords(bms, bookmarksMenuFolderId);
 }
 
 nsresult
-nsIEProfileMigrator::CopySmartKeywords(PRInt64 aParentFolder)
+nsIEProfileMigrator::CopySmartKeywords(nsINavBookmarksService* aBMS,
+                                       PRInt64 aParentFolder)
 { 
-  nsCOMPtr<nsIWindowsRegKey> regKey = 
+  nsresult rv;
+
+  nsCOMPtr<nsIWindowsRegKey> regKey =
     do_CreateInstance("@mozilla.org/windows-registry-key;1");
-  NS_NAMED_LITERAL_STRING(searchUrlKey,
-                          "Software\\Microsoft\\Internet Explorer\\SearchUrl");
   if (regKey && 
       NS_SUCCEEDED(regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
-                                searchUrlKey, nsIWindowsRegKey::ACCESS_READ))) {
-
-    nsresult rv;
-    nsCOMPtr<nsINavBookmarksService> bms(do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv));
-    NS_ENSURE_SUCCESS(rv, rv);
-    PRInt64 keywordsFolder = 0;
+                                REGISTRY_IE_SEARCHURL_KEY,
+                                nsIWindowsRegKey::ACCESS_READ))) {
 
-    nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
-    
+    nsCOMPtr<nsIStringBundleService> bundleService =
+      do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
     nsCOMPtr<nsIStringBundle> bundle;
-    bundleService->CreateBundle(TRIDENTPROFILE_BUNDLE, getter_AddRefs(bundle));
+    rv = bundleService->CreateBundle(TRIDENTPROFILE_BUNDLE,
+                                     getter_AddRefs(bundle));
+    NS_ENSURE_SUCCESS(rv, rv);
 
-
+    PRInt64 keywordsFolder = 0;
     int offset = 0;
     while (1) {
       nsAutoString keyName;
       if (NS_FAILED(regKey->GetChildName(offset, keyName)))
         break;
 
       if (!keywordsFolder) {
         nsString sourceNameIE;
-        bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameIE").get(), 
-                                  getter_Copies(sourceNameIE));
+        rv = bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameIE").get(),
+                                       getter_Copies(sourceNameIE));
+        NS_ENSURE_SUCCESS(rv, rv);
 
         const PRUnichar* sourceNameStrings[] = { sourceNameIE.get() };
         nsString importedIESearchUrlsTitle;
-        bundle->FormatStringFromName(NS_LITERAL_STRING("importedSearchURLsFolder").get(),
-                                    sourceNameStrings, 1, getter_Copies(importedIESearchUrlsTitle));
-        bms->CreateFolder(aParentFolder, NS_ConvertUTF16toUTF8(importedIESearchUrlsTitle),
-                          -1, &keywordsFolder);
+        rv = bundle->FormatStringFromName(NS_LITERAL_STRING("importedSearchURLsFolder").get(),
+                                          sourceNameStrings, 1,
+                                          getter_Copies(importedIESearchUrlsTitle));
+        NS_ENSURE_SUCCESS(rv, rv);
+        rv = aBMS->CreateFolder(aParentFolder,
+                                NS_ConvertUTF16toUTF8(importedIESearchUrlsTitle),
+                                nsINavBookmarksService::DEFAULT_INDEX,
+                                &keywordsFolder);
+        NS_ENSURE_SUCCESS(rv, rv);
       }
 
       nsCOMPtr<nsIWindowsRegKey> childKey; 
       if (NS_SUCCEEDED(regKey->OpenChild(keyName,
                        nsIWindowsRegKey::ACCESS_READ,
                        getter_AddRefs(childKey)))) {
         nsAutoString url; 
         if (NS_SUCCEEDED(childKey->ReadStringValue(EmptyString(), url))) {
           nsCOMPtr<nsIURI> uri;
           if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), url))) {
             NS_WARNING("Invalid url while importing smart keywords of MS IE");
             ++offset;
             childKey->Close();
             continue;
           }
           PRInt64 id;
-          bms->InsertBookmark(keywordsFolder, uri,
-                              nsINavBookmarksService::DEFAULT_INDEX,
-                              NS_ConvertUTF16toUTF8(keyName),
-                              &id);
+          rv = aBMS->InsertBookmark(keywordsFolder, uri,
+                                    nsINavBookmarksService::DEFAULT_INDEX,
+                                    NS_ConvertUTF16toUTF8(keyName),
+                                    &id);
+          NS_ENSURE_SUCCESS(rv, rv);
         }
         childKey->Close();
       }
 
       ++offset;
     }
   }
 
@@ -1460,25 +1547,25 @@ nsIEProfileMigrator::ResolveShortcut(con
     }
     urlLink->Release();
   }
 }
 
 nsresult
 nsIEProfileMigrator::ParseFavoritesFolder(nsIFile* aDirectory, 
                                           PRInt64 aParentFolder,
-                                          nsINavBookmarksService* aBookmarksService,
+                                          nsINavBookmarksService* aBMS,
                                           const nsAString& aPersonalToolbarFolderName,
                                           PRBool aIsAtRootLevel)
 {
   nsresult rv;
 
   nsCOMPtr<nsISimpleEnumerator> entries;
   rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
-  if (NS_FAILED(rv)) return rv;
+  NS_ENSURE_SUCCESS(rv, rv);
 
   do {
     PRBool hasMore = PR_FALSE;
     rv = entries->HasMoreElements(&hasMore);
     if (NS_FAILED(rv) || !hasMore) break;
 
     nsCOMPtr<nsISupports> supp;
     rv = entries->GetNext(getter_AddRefs(supp));
@@ -1523,38 +1610,41 @@ nsIEProfileMigrator::ParseFavoritesFolde
       NS_NAMED_LITERAL_STRING(lnkExt, ".lnk");
       PRInt32 lnkExtStart = bookmarkName.Length() - lnkExt.Length();
       if (StringEndsWith(bookmarkName, lnkExt,
                          CaseInsensitiveCompare))
         bookmarkName.SetLength(lnkExtStart);
 
       nsCOMPtr<nsIURI> bookmarkURI;
       rv = NS_NewFileURI(getter_AddRefs(bookmarkURI), localFile);
-      NS_ENSURE_SUCCESS(rv, rv);
+      if (NS_FAILED(rv)) continue;
       PRInt64 id;
-      rv = aBookmarksService->InsertBookmark(aParentFolder, bookmarkURI,
-                                             nsINavBookmarksService::DEFAULT_INDEX,
-                                             NS_ConvertUTF16toUTF8(bookmarkName), &id);
-      NS_ENSURE_SUCCESS(rv, rv);
+      rv = aBMS->InsertBookmark(aParentFolder, bookmarkURI,
+                                nsINavBookmarksService::DEFAULT_INDEX,
+                                NS_ConvertUTF16toUTF8(bookmarkName),
+                                &id);
       if (NS_FAILED(rv)) continue;
     }
     else if (isDir) {
-      PRInt64 folder;
+      PRInt64 folderId;
       if (bookmarkName.Equals(aPersonalToolbarFolderName)) {
-        aBookmarksService->GetToolbarFolder(&folder);
+        rv = aBMS->GetToolbarFolder(&folderId);
+        if (NS_FAILED(rv)) break;
       }
       else {
-        rv = aBookmarksService->CreateFolder(aParentFolder,
-                                             NS_ConvertUTF16toUTF8(bookmarkName),
-                                             nsINavBookmarksService::DEFAULT_INDEX,
-                                             &folder);
+        rv = aBMS->CreateFolder(aParentFolder,
+                                NS_ConvertUTF16toUTF8(bookmarkName),
+                                nsINavBookmarksService::DEFAULT_INDEX,
+                                &folderId);
         if (NS_FAILED(rv)) continue;
       }
 
-      rv = ParseFavoritesFolder(currFile, folder, aBookmarksService, aPersonalToolbarFolderName, PR_FALSE);
+      rv = ParseFavoritesFolder(currFile, folderId,
+                                aBMS, aPersonalToolbarFolderName,
+                                PR_FALSE);
       if (NS_FAILED(rv)) continue;
     }
     else {
       nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
       nsCAutoString extension;
 
       url->GetFileExtension(extension);
       if (!extension.Equals("url", CaseInsensitiveCompare))
@@ -1566,21 +1656,21 @@ nsIEProfileMigrator::ParseFavoritesFolde
       nsAutoString path;
       currFile->GetPath(path);
 
       nsCString resolvedURL;
       ResolveShortcut(path, getter_Copies(resolvedURL));
 
       nsCOMPtr<nsIURI> resolvedURI;
       rv = NS_NewURI(getter_AddRefs(resolvedURI), resolvedURL);
-      NS_ENSURE_SUCCESS(rv, rv);
+      if (NS_FAILED(rv)) continue;
       PRInt64 id;
-      rv = aBookmarksService->InsertBookmark(aParentFolder, resolvedURI,
-                                             nsINavBookmarksService::DEFAULT_INDEX,
-                                             NS_ConvertUTF16toUTF8(name), &id);
+      rv = aBMS->InsertBookmark(aParentFolder, resolvedURI,
+                                nsINavBookmarksService::DEFAULT_INDEX,
+                                NS_ConvertUTF16toUTF8(name), &id);
       if (NS_FAILED(rv)) continue;
     }
   }
   while (1);
 
   return rv;
 }
 
--- a/browser/components/migration/src/nsIEProfileMigrator.h
+++ b/browser/components/migration/src/nsIEProfileMigrator.h
@@ -74,38 +74,57 @@ public:
   virtual ~nsIEProfileMigrator();
 
 protected:
   nsresult CopyPreferences(PRBool aReplace);
   nsresult CopyStyleSheet(PRBool aReplace);
   nsresult CopyCookies(PRBool aReplace);
   nsresult CopyProxyPreferences(nsIPrefBranch* aPrefs);
   nsresult CopySecurityPrefs(nsIPrefBranch* aPrefs);
+  /**
+   * Migrate history to Places.
+   * This will end up calling CopyHistoryBatched helper, that provides batch
+   * support.  Batching allows for better performances and integrity.
+   *
+   * @param aReplace
+   *        Indicates if we should replace current history or append to it.
+   */
   nsresult CopyHistory(PRBool aReplace);
+  nsresult CopyHistoryBatched(PRBool aReplace);
 
   PRBool   KeyIsURI(const nsAString& aKey, char** aRealm);
 
   nsresult CopyPasswords(PRBool aReplace);
   nsresult MigrateSiteAuthSignons(IPStore* aPStore);
   nsresult GetSignonsListFromPStore(IPStore* aPStore, nsTArray<SignonData>* aSignonsFound);
   nsresult ResolveAndMigrateSignons(IPStore* aPStore, nsTArray<SignonData>* aSignonsFound);
   void     EnumerateUsernames(const nsAString& aKey, PRUnichar* aData, unsigned long aCount, nsTArray<SignonData>* aSignonsFound);
   void     GetUserNameAndPass(unsigned char* data, unsigned long len, unsigned char** username, unsigned char** pass);
 
   nsresult CopyFormData(PRBool aReplace);
   nsresult AddDataToFormHistory(const nsAString& aKey, PRUnichar* data, unsigned long len);
-
+  /**
+   * Migrate bookmarks to Places.
+   * This will end up calling CopyFavoritesBatched helper, that provides batch
+   * support.  Batching allows for better performances and integrity.
+   *
+   * @param aReplace
+   *        Indicates if we should replace current bookmarks or append to them.
+   *        When appending we will usually default to bookmarks menu.
+   */
   nsresult CopyFavorites(PRBool aReplace);
+  nsresult CopyFavoritesBatched(PRBool aReplace);
   void     ResolveShortcut(const nsString &aFileName, char** aOutURL);
   nsresult ParseFavoritesFolder(nsIFile* aDirectory, 
                                 PRInt64 aParentFolder,
                                 nsINavBookmarksService* aBookmarksService,
                                 const nsAString& aPersonalToolbarFolderName,
                                 PRBool aIsAtRootLevel);
-  nsresult CopySmartKeywords(PRInt64 aParentFolder);
+  nsresult CopySmartKeywords(nsINavBookmarksService* aBMS,
+                             PRInt64 aParentFolder);
 
   nsresult CopyCookiesFromBuffer(char *aBuffer, PRUint32 aBufferLength,
                                  nsICookieManager2 *aCookieManager);
   void     DelimitField(char **aBuffer, const char *aBufferEnd, char **aField);
   time_t   FileTimeToTimeT(const char *aLowDateIntString,
                            const char *aHighDateIntString);
   void     GetUserStyleSheetFile(nsIFile **aUserFile);
   PRBool   TestForIE7();
--- a/browser/components/migration/src/nsMacIEProfileMigrator.cpp
+++ b/browser/components/migration/src/nsMacIEProfileMigrator.cpp
@@ -226,32 +226,30 @@ nsMacIEProfileMigrator::CopyBookmarks(PR
   nsCOMPtr<nsIFile> tempFile;
   mTargetProfile->Clone(getter_AddRefs(tempFile));
   tempFile->Append(TEMP_BOOKMARKS_FILE_NAME);
 
   // Look for the localized name of the IE Favorites Bar
   nsCOMPtr<nsIStringBundleService> bundleService =
     do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
-
   nsCOMPtr<nsIStringBundle> bundle;
   rv = bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsString toolbarFolderNameMacIE;
-  bundle->GetStringFromName(NS_LITERAL_STRING("toolbarFolderNameMacIE").get(), 
-                            getter_Copies(toolbarFolderNameMacIE));
-  nsCAutoString ctoolbarFolderNameMacIE;
-  CopyUTF16toUTF8(toolbarFolderNameMacIE, ctoolbarFolderNameMacIE);
+  rv = bundle->GetStringFromName(NS_LITERAL_STRING("toolbarFolderNameMacIE").get(),
+                                 getter_Copies(toolbarFolderNameMacIE));
+  NS_ENSURE_SUCCESS(rv, rv);
 
   // Now read the 4.x bookmarks file, correcting the Personal Toolbar Folder 
   // line and writing to the temporary file.
   rv = AnnotatePersonalToolbarFolder(sourceFile,
                                      tempFile,
-                                     ctoolbarFolderNameMacIE.get());
+                                     NS_ConvertUTF16toUTF8(toolbarFolderNameMacIE).get());
   NS_ENSURE_SUCCESS(rv, rv);
 
   // import the temp file
   rv = ImportBookmarksHTML(tempFile,
                            PR_TRUE,
                            PR_FALSE,
                            EmptyString().get());
   NS_ENSURE_SUCCESS(rv, rv);
--- a/browser/components/migration/src/nsOperaProfileMigrator.cpp
+++ b/browser/components/migration/src/nsOperaProfileMigrator.cpp
@@ -963,28 +963,68 @@ nsOperaCookieMigrator::ReadHeader()
     mStream->Read16(&mTagTypeLength);
     mStream->Read16(&mPayloadTypeLength);
 
     return NS_OK;
   }
   return NS_ERROR_FAILURE;
 }
 
+NS_IMETHODIMP
+nsOperaProfileMigrator::RunBatched(nsISupports* aUserData)
+{
+  PRUint8 batchAction;
+  nsCOMPtr<nsISupportsPRUint8> strWrapper(do_QueryInterface(aUserData));
+  NS_ASSERTION(strWrapper, "Unable to create nsISupportsPRUint8 wrapper!");
+  nsresult rv = strWrapper->GetData(&batchAction);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  switch (batchAction) {
+    case BATCH_ACTION_HISTORY:
+      rv = CopyHistoryBatched(PR_FALSE);
+      break;
+    case BATCH_ACTION_HISTORY_REPLACE:
+      rv = CopyHistoryBatched(PR_TRUE);
+      break;
+    case BATCH_ACTION_BOOKMARKS:
+      rv = CopyBookmarksBatched(PR_FALSE);
+      break;
+    case BATCH_ACTION_BOOKMARKS_REPLACE:
+      rv = CopyBookmarksBatched(PR_TRUE);
+      break;
+  }
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
 nsresult
-nsOperaProfileMigrator::CopyHistory(PRBool aReplace)
+nsOperaProfileMigrator::CopyHistory(PRBool aReplace) 
 {
   nsresult rv;
-  nsCOMPtr<nsINavHistoryService> history = do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID, &rv);
+  nsCOMPtr<nsINavHistoryService> history =
+    do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
- 
-  return history->RunInBatchMode(this, nsnull);
+
+  PRUint8 batchAction = aReplace ? BATCH_ACTION_HISTORY_REPLACE
+                                 : BATCH_ACTION_HISTORY;
+  nsCOMPtr<nsISupportsPRUint8> supports =
+    do_CreateInstance(NS_SUPPORTS_PRUINT8_CONTRACTID);
+  NS_ENSURE_TRUE(supports, NS_ERROR_OUT_OF_MEMORY);
+  rv = supports->SetData(batchAction);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = history->RunInBatchMode(this, supports);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
 }
  
-NS_IMETHODIMP
-nsOperaProfileMigrator::RunBatched(nsISupports* aUserData)
+nsresult
+nsOperaProfileMigrator::CopyHistoryBatched(PRBool aReplace) 
 {
   nsCOMPtr<nsIBrowserHistory> hist(do_GetService(NS_GLOBALHISTORY2_CONTRACTID));
 
   nsCOMPtr<nsIFile> temp;
   mOperaProfile->Clone(getter_AddRefs(temp));
   nsCOMPtr<nsILocalFile> historyFile(do_QueryInterface(temp));
   historyFile->Append(OPERA_HISTORY_FILE_NAME);
 
@@ -1038,137 +1078,165 @@ nsOperaProfileMigrator::RunBatched(nsISu
   while (moreData);
 
   return NS_OK;
 }
 
 nsresult
 nsOperaProfileMigrator::CopyBookmarks(PRBool aReplace)
 {
+  nsresult rv;
+  nsCOMPtr<nsINavBookmarksService> bookmarks =
+    do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRUint8 batchAction = aReplace ? BATCH_ACTION_BOOKMARKS_REPLACE
+                                 : BATCH_ACTION_BOOKMARKS;
+  nsCOMPtr<nsISupportsPRUint8> supports =
+    do_CreateInstance(NS_SUPPORTS_PRUINT8_CONTRACTID);
+  NS_ENSURE_TRUE(supports, NS_ERROR_OUT_OF_MEMORY);
+  rv = supports->SetData(batchAction);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = bookmarks->RunInBatchMode(this, supports);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
+nsresult
+nsOperaProfileMigrator::CopyBookmarksBatched(PRBool aReplace)
+{
   // Find Opera Bookmarks
   nsCOMPtr<nsIFile> operaBookmarks;
   mOperaProfile->Clone(getter_AddRefs(operaBookmarks));
   operaBookmarks->Append(OPERA_BOOKMARKS_FILE_NAME);
 
   nsCOMPtr<nsIInputStream> fileInputStream;
   NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), operaBookmarks);
-  if (!fileInputStream) return NS_ERROR_OUT_OF_MEMORY;
+  NS_ENSURE_TRUE(fileInputStream, NS_ERROR_OUT_OF_MEMORY);
 
   nsCOMPtr<nsILineInputStream> lineInputStream(do_QueryInterface(fileInputStream));
 
   nsresult rv;
-  nsCOMPtr<nsINavBookmarksService> bms(do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv));
+  nsCOMPtr<nsINavBookmarksService> bms =
+    do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
-  PRInt64 root;
-  rv = bms->GetBookmarksMenuFolder(&root);
+  PRInt64 bookmarksMenuFolderId;
+  rv = bms->GetBookmarksMenuFolder(&bookmarksMenuFolderId);
   NS_ENSURE_SUCCESS(rv, rv);
-  PRInt64 parentFolder = root;
+  PRInt64 parentFolder = bookmarksMenuFolderId;
 
-  nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID));
+  nsCOMPtr<nsIStringBundleService> bundleService =
+    do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIStringBundle> bundle;
-  bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));
+  rv = bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));
+  NS_ENSURE_SUCCESS(rv, rv);
+
   if (!aReplace) {
     nsString sourceNameOpera;
-    bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameOpera").get(), 
-                              getter_Copies(sourceNameOpera));
+    rv = bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameOpera").get(), 
+                                   getter_Copies(sourceNameOpera));
+    NS_ENSURE_SUCCESS(rv, rv);
 
     const PRUnichar* sourceNameStrings[] = { sourceNameOpera.get() };
     nsString importedOperaHotlistTitle;
-    bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
-                                 sourceNameStrings, 1, 
-                                 getter_Copies(importedOperaHotlistTitle));
+    rv = bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
+                                      sourceNameStrings, 1, 
+                                      getter_Copies(importedOperaHotlistTitle));
+   NS_ENSURE_SUCCESS(rv, rv);
 
-    bms->CreateFolder(parentFolder, NS_ConvertUTF16toUTF8(importedOperaHotlistTitle),
-                      nsINavBookmarksService::DEFAULT_INDEX, &parentFolder);
+    rv = bms->CreateFolder(parentFolder,
+                           NS_ConvertUTF16toUTF8(importedOperaHotlistTitle),
+                           nsINavBookmarksService::DEFAULT_INDEX,
+                           &parentFolder);
+   NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
     nsCOMPtr<nsIFile> profile;
     GetProfilePath(nsnull, profile);
     rv = InitializeBookmarks(profile);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
 #if defined(XP_WIN) || (defined(XP_UNIX) && !defined(XP_MACOSX))
-  printf("*** about to copy smart keywords\n");
   CopySmartKeywords(bms, bundle, parentFolder);
-  printf("*** done copying smart keywords\n");
 #endif
 
-  PRInt64 toolbar;
-  rv = bms->GetToolbarFolder(&toolbar);
+  PRInt64 bookmarksToolbarFolderId;
+  rv = bms->GetToolbarFolder(&bookmarksToolbarFolderId);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = ParseBookmarksFolder(lineInputStream, parentFolder, toolbar, bms);
+  rv = ParseBookmarksFolder(lineInputStream, parentFolder,
+                            bookmarksToolbarFolderId, bms);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 #if defined(XP_WIN) || (defined(XP_UNIX) && !defined(XP_MACOSX))
 nsresult
 nsOperaProfileMigrator::CopySmartKeywords(nsINavBookmarksService* aBMS, 
-                                          nsIStringBundle* aBundle, 
+                                          nsIStringBundle* aBundle,
                                           PRInt64 aParentFolder)
 {
   nsresult rv;
 
   nsCOMPtr<nsIFile> smartKeywords;
   mOperaProfile->Clone(getter_AddRefs(smartKeywords));
   smartKeywords->Append(NS_LITERAL_STRING("search.ini"));
 
   nsCOMPtr<nsILocalFile> lf(do_QueryInterface(smartKeywords));
-  if (!lf)
-    return NS_OK;
-
   nsINIParser parser;
-  rv = parser.Init(lf);
-  if (NS_FAILED(rv))
+  if (!lf || NS_FAILED(parser.Init(lf)))
     return NS_OK;
 
   nsString sourceNameOpera;
-  aBundle->GetStringFromName(NS_LITERAL_STRING("sourceNameOpera").get(), 
-                             getter_Copies(sourceNameOpera));
+  rv = aBundle->GetStringFromName(NS_LITERAL_STRING("sourceNameOpera").get(),
+                                  getter_Copies(sourceNameOpera));
+  NS_ENSURE_SUCCESS(rv, rv);
 
   const PRUnichar* sourceNameStrings[] = { sourceNameOpera.get() };
   nsString importedSearchUrlsTitle;
-  aBundle->FormatStringFromName(NS_LITERAL_STRING("importedSearchURLsFolder").get(),
-                                sourceNameStrings, 1, 
-                                getter_Copies(importedSearchUrlsTitle));
+  rv = aBundle->FormatStringFromName(NS_LITERAL_STRING("importedSearchURLsFolder").get(),
+                                     sourceNameStrings, 1, 
+                                     getter_Copies(importedSearchUrlsTitle));
+  NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt64 keywordsFolder;
-  rv = aBMS->CreateFolder(aParentFolder, NS_ConvertUTF16toUTF8(importedSearchUrlsTitle),
-                          nsINavBookmarksService::DEFAULT_INDEX, &keywordsFolder);
+  rv = aBMS->CreateFolder(aParentFolder,
+                          NS_ConvertUTF16toUTF8(importedSearchUrlsTitle),
+                          nsINavBookmarksService::DEFAULT_INDEX,
+                          &keywordsFolder);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 sectionIndex = 1;
   nsCAutoString name, url, keyword;
   do {
     nsCAutoString section("Search Engine ");
     section.AppendInt(sectionIndex++);
 
     rv = parser.GetString(section.get(), "Name", name);
-    if (NS_FAILED(rv))
-      break;
+    if (NS_FAILED(rv) || name.IsEmpty())
+      continue;
 
     rv = parser.GetString(section.get(), "URL", url);
-    if (NS_FAILED(rv))
+    if (NS_FAILED(rv) || url.IsEmpty())
       continue;
 
     rv = parser.GetString(section.get(), "Key", keyword);
-    if (NS_FAILED(rv))
+    if (NS_FAILED(rv) || keyword.IsEmpty())
       continue;
 
     PRInt32 post;
     rv = GetInteger(parser, section.get(), "Is post", &post);
     if (NS_SUCCEEDED(rv) && post)
       continue;
 
-    if (url.IsEmpty() || keyword.IsEmpty() || name.IsEmpty())
-      continue;
-
     PRUint32 length = name.Length();
     PRInt32 index = 0;
     do {
       index = name.FindChar('&', index);
       if ((PRUint32)index >= length - 2)
         break;
 
       // Assume "&&" is an escaped ampersand in the search query title. 
@@ -1178,35 +1246,39 @@ nsOperaProfileMigrator::CopySmartKeyword
         continue;
       }
 
       name.Cut(index, 1);
     }
     while ((PRUint32)index < length);
 
     nsCOMPtr<nsIURI> uri;
-    NS_NewURI(getter_AddRefs(uri), url.get());
-    if (!uri)
-      return NS_ERROR_OUT_OF_MEMORY;
+    if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), url.get())) || !uri)
+      continue;
 
     nsCAutoString hostCStr;
     uri->GetHost(hostCStr);
     NS_ConvertASCIItoUTF16 host(hostCStr);
 
-    const PRUnichar* descStrings[] = { NS_ConvertUTF8toUTF16(keyword).get(), host.get() };
+    const PRUnichar* descStrings[] = { NS_ConvertUTF8toUTF16(keyword).get(),
+                                       host.get() };
     nsString keywordDesc;
-    aBundle->FormatStringFromName(NS_LITERAL_STRING("importedSearchUrlDesc").get(),
-                                  descStrings, 2, getter_Copies(keywordDesc));
+    rv = aBundle->FormatStringFromName(NS_LITERAL_STRING("importedSearchUrlDesc").get(),
+                                       descStrings, 2,
+                                       getter_Copies(keywordDesc));
+    NS_ENSURE_SUCCESS(rv, rv);
 
     PRInt64 newId;
     rv = aBMS->InsertBookmark(keywordsFolder, uri,
                               nsINavBookmarksService::DEFAULT_INDEX,
                               name, &newId);
     NS_ENSURE_SUCCESS(rv, rv);
-    // TODO -- set bookmark keyword to keyword and description to keywordDesc.
+    rv = aBMS->SetKeywordForBookmark(newId, NS_ConvertUTF8toUTF16(keyword));
+    NS_ENSURE_SUCCESS(rv, rv);
+    // TODO Bug 397771: set bookmark description to keywordDesc.
   }
   while (1);
   
   return rv;
 }
 #endif
 
 typedef enum { LineType_FOLDER, 
--- a/browser/components/migration/src/nsOperaProfileMigrator.h
+++ b/browser/components/migration/src/nsOperaProfileMigrator.h
@@ -93,27 +93,47 @@ public:
   static nsresult SetImageBehavior(void* aTransform, nsIPrefBranch* aBranch);
   static nsresult SetBool(void* aTransform, nsIPrefBranch* aBranch);
   static nsresult SetWString(void* aTransform, nsIPrefBranch* aBranch);
   static nsresult SetInt(void* aTransform, nsIPrefBranch* aBranch);
   static nsresult SetString(void* aTransform, nsIPrefBranch* aBranch);
 
 protected:
   nsresult CopyPreferences(PRBool aReplace);
-  nsresult ParseColor(nsINIParser &aParser, const char* aSectionName, char** aResult);
+  nsresult ParseColor(nsINIParser &aParser, const char* aSectionName,
+                      char** aResult);
   nsresult CopyUserContentSheet(nsINIParser &aParser);
   nsresult CopyProxySettings(nsINIParser &aParser, nsIPrefBranch* aBranch);
   nsresult GetInteger(nsINIParser &aParser, const char* aSectionName, 
                       const char* aKeyName, PRInt32* aResult);
 
   nsresult CopyCookies(PRBool aReplace);
+  /**
+   * Migrate history to Places.
+   * This will end up calling CopyHistoryBatched helper, that provides batch
+   * support.  Batching allows for better performances and integrity.
+   *
+   * @param aReplace
+   *        Indicates if we should replace current history or append to it.
+   */
   nsresult CopyHistory(PRBool aReplace);
-
+  nsresult CopyHistoryBatched(PRBool aReplace);
+  /**
+   * Migrate bookmarks to Places.
+   * This will end up calling CopyBookmarksBatched helper, that provides batch
+   * support.  Batching allows for better performances and integrity.
+   *
+   * @param aReplace
+   *        Indicates if we should replace current bookmarks or append to them.
+   *        When appending we will usually default to bookmarks menu.
+   */
   nsresult CopyBookmarks(PRBool aReplace);
-  void     ClearToolbarFolder(nsINavBookmarksService * aBookmarksService, PRInt64 aToolbarFolder);
+  nsresult CopyBookmarksBatched(PRBool aReplace);
+  void     ClearToolbarFolder(nsINavBookmarksService * aBookmarksService,
+                              PRInt64 aToolbarFolder);
   nsresult ParseBookmarksFolder(nsILineInputStream* aStream, 
                                 PRInt64 aFolder,
                                 PRInt64 aToolbar, 
                                 nsINavBookmarksService* aBMS);
 #if defined(XP_WIN) || (defined(XP_UNIX) && !defined(XP_MACOSX))
   nsresult CopySmartKeywords(nsINavBookmarksService* aBMS, 
                              nsIStringBundle* aBundle, 
                              PRInt64 aParentFolder);
@@ -192,13 +212,12 @@ private:
 
   PRUint32 mAppVersion;
   PRUint32 mFileVersion;
   PRUint16 mTagTypeLength;
   PRUint16 mPayloadTypeLength;
   PRBool   mCookieOpen;
   Cookie   mCurrCookie;
   PRUint8  mCurrHandlingInfo;
-
 };
 
 #endif
 
--- a/browser/components/migration/src/nsSafariProfileMigrator.cpp
+++ b/browser/components/migration/src/nsSafariProfileMigrator.cpp
@@ -251,17 +251,17 @@ CFDictionaryRef CopySafariPrefs()
   nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
   nsCOMPtr<nsILocalFile> safariPrefsFile;
   fileLocator->Get(NS_OSX_USER_PREFERENCES_DIR,
                    NS_GET_IID(nsILocalFile),
                    getter_AddRefs(safariPrefsFile));
 
   safariPrefsFile->Append(SAFARI_PREFERENCES_FILE_NAME);
 
-  return (CFDictionaryRef)CopyPListFromFile(safariPrefsFile);
+  return static_cast<CFDictionaryRef>(CopyPListFromFile(safariPrefsFile));
 }
 
 char*
 GetNullTerminatedString(CFStringRef aStringRef)
 {
   CFIndex bufferSize = ::CFStringGetLength(aStringRef) + 1;
   char* buffer = (char*)malloc(sizeof(char) * bufferSize);
   if (!buffer)
@@ -725,17 +725,17 @@ nsSafariProfileMigrator::CopyPreferences
   // setting in a separate WebFoundation preferences PList.
   nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
   nsCOMPtr<nsILocalFile> safariWebFoundationPrefsFile;
   fileLocator->Get(NS_OSX_USER_PREFERENCES_DIR, NS_GET_IID(nsILocalFile),
                    getter_AddRefs(safariWebFoundationPrefsFile));
   safariWebFoundationPrefsFile->Append(SAFARI_COOKIE_BEHAVIOR_FILE_NAME);
 
   CFDictionaryRef safariWebFoundationPrefs =
-                  (CFDictionaryRef)CopyPListFromFile(safariWebFoundationPrefsFile);
+    static_cast<CFDictionaryRef>(CopyPListFromFile(safariWebFoundationPrefsFile));
   if (safariWebFoundationPrefs) {
     // Mapping of Safari preference values to Firefox preference values:
     //
     // Setting                    Safari          Firefox
     // Always Accept              always          0
     // Accept from Originating    current page    1
     // Never Accept               never           2
     nsAutoString acceptCookies;
@@ -799,37 +799,78 @@ nsSafariProfileMigrator::CopyCookies(PRB
                          expiryTime);
     }
   }
   ::CFRelease(safariCookies);
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsSafariProfileMigrator::RunBatched(nsISupports* aUserData)
+{
+  PRUint8 batchAction;
+  nsCOMPtr<nsISupportsPRUint8> strWrapper(do_QueryInterface(aUserData));
+  NS_ASSERTION(strWrapper, "Unable to create nsISupportsPRUint8 wrapper!");
+  nsresult rv = strWrapper->GetData(&batchAction);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  switch (batchAction) {
+    case BATCH_ACTION_HISTORY:
+      rv = CopyHistoryBatched(PR_FALSE);
+      break;
+    case BATCH_ACTION_HISTORY_REPLACE:
+      rv = CopyHistoryBatched(PR_TRUE);
+      break;
+    case BATCH_ACTION_BOOKMARKS:
+      rv = CopyBookmarksBatched(PR_FALSE);
+      break;
+    case BATCH_ACTION_BOOKMARKS_REPLACE:
+      rv = CopyBookmarksBatched(PR_TRUE);
+      break;
+  }
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
 nsresult
 nsSafariProfileMigrator::CopyHistory(PRBool aReplace)
 {
   nsresult rv;
-  nsCOMPtr<nsINavHistoryService> history = do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID, &rv);
+  nsCOMPtr<nsINavHistoryService> history =
+    do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
- 
-  return history->RunInBatchMode(this, nsnull);
+
+  PRUint8 batchAction = aReplace ? BATCH_ACTION_HISTORY_REPLACE
+                                 : BATCH_ACTION_HISTORY;
+  nsCOMPtr<nsISupportsPRUint8> supports =
+    do_CreateInstance(NS_SUPPORTS_PRUINT8_CONTRACTID);
+  NS_ENSURE_TRUE(supports, NS_ERROR_OUT_OF_MEMORY);
+  rv = supports->SetData(batchAction);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = history->RunInBatchMode(this, supports);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return rv;
 }
  
-NS_IMETHODIMP
-nsSafariProfileMigrator::RunBatched(nsISupports* aUserData)
+nsresult
+nsSafariProfileMigrator::CopyHistoryBatched(PRBool aReplace)
 {
   nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
   nsCOMPtr<nsILocalFile> safariHistoryFile;
   fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile),
                    getter_AddRefs(safariHistoryFile));
   safariHistoryFile->Append(NS_LITERAL_STRING("Safari"));
   safariHistoryFile->Append(SAFARI_HISTORY_FILE_NAME);
 
-  CFDictionaryRef safariHistory = (CFDictionaryRef)CopyPListFromFile(safariHistoryFile);
+  CFDictionaryRef safariHistory =
+    static_cast<CFDictionaryRef>(CopyPListFromFile(safariHistoryFile));
   if (!safariHistory)
     return NS_OK;
 
   if (!::CFDictionaryContainsKey(safariHistory, CFSTR("WebHistoryDates"))) {
     ::CFRelease(safariHistory);
     return NS_OK;
   }
 
@@ -867,64 +908,93 @@ nsSafariProfileMigrator::RunBatched(nsIS
   ::CFRelease(safariHistory);
 
   return NS_OK;
 }
 
 nsresult
 nsSafariProfileMigrator::CopyBookmarks(PRBool aReplace)
 {
+  nsresult rv;
+  nsCOMPtr<nsINavBookmarksService> bookmarks =
+    do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRUint8 batchAction = aReplace ? BATCH_ACTION_BOOKMARKS_REPLACE
+                                 : BATCH_ACTION_BOOKMARKS;
+  nsCOMPtr<nsISupportsPRUint8> supports =
+    do_CreateInstance(NS_SUPPORTS_PRUINT8_CONTRACTID);
+  NS_ENSURE_TRUE(supports, NS_ERROR_OUT_OF_MEMORY);
+  rv = supports->SetData(batchAction);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = bookmarks->RunInBatchMode(this, supports);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
+nsresult
+nsSafariProfileMigrator::CopyBookmarksBatched(PRBool aReplace)
+{
   // If "aReplace" is true, merge into the root level of bookmarks. Otherwise, create
   // a folder called "Imported Safari Favorites" and place all the Bookmarks there.
   nsresult rv;
 
-  nsCOMPtr<nsINavBookmarksService> bms(do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv));
+  nsCOMPtr<nsINavBookmarksService> bms =
+    do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
-  PRInt64 root;
-  rv = bms->GetBookmarksMenuFolder(&root);
+  PRInt64 bookmarksMenuFolderId;
+  rv = bms->GetBookmarksMenuFolder(&bookmarksMenuFolderId);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt64 folder;
   if (!aReplace) {
-    nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
-    if (NS_FAILED(rv)) return rv;
-
+    nsCOMPtr<nsIStringBundleService> bundleService =
+      do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
     nsCOMPtr<nsIStringBundle> bundle;
-    bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));
+    rv = bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));
+    NS_ENSURE_SUCCESS(rv, rv);
 
     nsString sourceNameSafari;
-    bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameSafari").get(),
-                              getter_Copies(sourceNameSafari));
+    rv = bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameSafari").get(),
+                                   getter_Copies(sourceNameSafari));
+    NS_ENSURE_SUCCESS(rv, rv);
 
     const PRUnichar* sourceNameStrings[] = { sourceNameSafari.get() };
     nsString importedSafariBookmarksTitle;
-    bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
-                                 sourceNameStrings, 1,
-                                 getter_Copies(importedSafariBookmarksTitle));
+    rv = bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
+                                      sourceNameStrings, 1,
+                                      getter_Copies(importedSafariBookmarksTitle));
+    NS_ENSURE_SUCCESS(rv, rv);
 
-    bms->CreateFolder(root, NS_ConvertUTF16toUTF8(importedSafariBookmarksTitle),
-                      nsINavBookmarksService::DEFAULT_INDEX, &folder);
+    rv = bms->CreateFolder(bookmarksMenuFolderId,
+                           NS_ConvertUTF16toUTF8(importedSafariBookmarksTitle),
+                           nsINavBookmarksService::DEFAULT_INDEX, &folder);
+    NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
     nsCOMPtr<nsIFile> profile;
     GetProfilePath(nsnull, profile);
     rv = InitializeBookmarks(profile);
     NS_ENSURE_SUCCESS(rv, rv);
     // In replace mode we are merging at the top level.
-    folder = root;
+    folder = bookmarksMenuFolderId;
   }
 
   nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
   nsCOMPtr<nsILocalFile> safariBookmarksFile;
   fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile),
                    getter_AddRefs(safariBookmarksFile));
   safariBookmarksFile->Append(NS_LITERAL_STRING("Safari"));
   safariBookmarksFile->Append(SAFARI_BOOKMARKS_FILE_NAME);
 
-  CFDictionaryRef safariBookmarks = (CFDictionaryRef)CopyPListFromFile(safariBookmarksFile);
+  CFDictionaryRef safariBookmarks =
+    static_cast<CFDictionaryRef>(CopyPListFromFile(safariBookmarksFile));
   if (!safariBookmarks)
     return NS_OK;
 
   // The Safari Bookmarks file looks like this:
   // At the top level are all the Folders, Special Folders and Proxies. Proxies
   // are references to other data sources such as History, Rendezvous etc.
   // We ignore these. Special folders exist for the Bookmarks Toolbar folder
   // (called "BookmarksBar" and the Bookmarks Menu (called "BookmarksMenu").
--- a/browser/components/migration/src/nsSafariProfileMigrator.h
+++ b/browser/components/migration/src/nsSafariProfileMigrator.h
@@ -88,18 +88,37 @@ public:
   static nsresult SetDisplayImages(void* aTransform, nsIPrefBranch* aBranch);
   static nsresult SetFontName(void* aTransform, nsIPrefBranch* aBranch);
   static nsresult SetFontSize(void* aTransform, nsIPrefBranch* aBranch);
   static void CleanResource(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource);
 
 protected:
   nsresult CopyPreferences(PRBool aReplace);
   nsresult CopyCookies(PRBool aReplace);
+  /**
+   * Migrate history to Places.
+   * This will end up calling CopyHistoryBatched helper, that provides batch
+   * support.  Batching allows for better performances and integrity.
+   *
+   * @param aReplace
+   *        Indicates if we should replace current history or append to it.
+   */
   nsresult CopyHistory(PRBool aReplace);
+  nsresult CopyHistoryBatched(PRBool aReplace);
+  /**
+   * Migrate bookmarks to Places.
+   * This will end up calling CopyBookmarksBatched helper, that provides batch
+   * support.  Batching allows for better performances and integrity.
+   *
+   * @param aReplace
+   *        Indicates if we should replace current bookmarks or append to them.
+   *        When appending we will usually default to bookmarks menu.
+   */
   nsresult CopyBookmarks(PRBool aReplace);
+  nsresult CopyBookmarksBatched(PRBool aReplace);
   nsresult ParseBookmarksFolder(CFArrayRef aChildren, 
                                 PRInt64 aParentFolder,
                                 nsINavBookmarksService * aBookmarksService,
                                 PRBool aIsAtRootLevel);
   nsresult CopyFormData(PRBool aReplace);
   nsresult CopyOtherData(PRBool aReplace);
 
   nsresult ProfileHasContentStyleSheet(PRBool *outExists);