nsresult nsProfileMigratorBase::ImportFilters(nsIImportModule * aImportModule)
{
  nsresult rv = NS_OK;

  nsCOMPtr<nsIImportFilters> importFilters;
  nsresult rv2 = aImportModule->GetImportInterface(NS_IMPORT_FILTERS_STR, getter_AddRefs(importFilters));

  if (NS_SUCCEEDED(rv2))
  {
    nsAutoString index;
    index.AppendInt(nsIMailProfileMigrator::FILTERS);
    NOTIFY_OBSERVERS(MIGRATION_ITEMBEFOREMIGRATE, index.get());

    bool importedFilters = false;
    PRUnichar* error;

    rv = importFilters->Import(&error, &importedFilters);

    NOTIFY_OBSERVERS(MIGRATION_ITEMAFTERMIGRATE, index.get());
  }

  // migration is now done...notify the UI.
  NOTIFY_OBSERVERS(MIGRATION_ENDED, nullptr);

  return rv;
}
NS_IMETHODIMP
nsSafariProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup,
                                 const PRUnichar* aProfile)
{
  nsresult rv = NS_OK;

  bool replace = false;

  if (aStartup) {
    replace = true;
    rv = aStartup->DoStartup();
    NS_ENSURE_SUCCESS(rv, rv);
  }

  NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);

  COPY_DATA(CopyPreferences,  replace, nsIBrowserProfileMigrator::SETTINGS);
  COPY_DATA(CopyCookies,      replace, nsIBrowserProfileMigrator::COOKIES);
  COPY_DATA(CopyHistory,      replace, nsIBrowserProfileMigrator::HISTORY);
  COPY_DATA(CopyBookmarks,    replace, nsIBrowserProfileMigrator::BOOKMARKS);
  COPY_DATA(CopyFormData,     replace, nsIBrowserProfileMigrator::FORMDATA);
  COPY_DATA(CopyOtherData,    replace, nsIBrowserProfileMigrator::OTHERDATA);

  NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);

  return rv;
}
nsresult
nsNetscapeProfileMigratorBase::CopyAddressBookDirectories(PBStructArray &aLdapServers,
                                                          nsIPrefService* aPrefService)
{
  // each server has a pref ending with .filename. The value of that pref
  // points to a profile which we need to migrate.
  nsAutoString index;
  index.AppendInt(nsISuiteProfileMigrator::ADDRESSBOOK_DATA);
  NOTIFY_OBSERVERS(MIGRATION_ITEMBEFOREMIGRATE, index.get());

  uint32_t count = aLdapServers.Length();
  for (uint32_t i = 0; i < count; ++i) {
    PrefBranchStruct* pref = aLdapServers.ElementAt(i);
    nsDependentCString prefName(pref->prefName);

    if (StringEndsWith(prefName, NS_LITERAL_CSTRING(".filename"))) {
      CopyFile(pref->stringValue, pref->stringValue);
    }

    // we don't need to do anything to the fileName pref itself
  }

  NOTIFY_OBSERVERS(MIGRATION_ITEMAFTERMIGRATE, index.get());

  return NS_OK;
}
NS_IMETHODIMP
nsMacIEProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
{
  nsresult rv = NS_OK;

  PRBool replace = aStartup ? PR_TRUE : PR_FALSE;

  if (!mTargetProfile) { 
    GetProfilePath(aStartup, mTargetProfile);
    if (!mTargetProfile) return NS_ERROR_FAILURE;
  }

  if (!mSourceProfile) {
    nsCOMPtr<nsIProperties> fileLocator =
      do_GetService("@mozilla.org/file/directory_service;1", &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    fileLocator->Get(NS_OSX_USER_PREFERENCES_DIR,
                     NS_GET_IID(nsILocalFile),
                     getter_AddRefs(mSourceProfile));
    mSourceProfile->Append(MACIE_PREFERENCES_FOLDER_NAME);
  }

  NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);

  COPY_DATA(CopyBookmarks, replace, nsIBrowserProfileMigrator::BOOKMARKS);

  NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);

  return rv;
}
NS_IMETHODIMP
nsDogbertProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup,
                                  const PRUnichar* aProfile)
{
  nsresult rv = NS_OK;
  PRBool aReplace = aStartup ? PR_TRUE : PR_FALSE;

  if (!mTargetProfile) { 
    GetProfilePath(aStartup, mTargetProfile);
    if (!mTargetProfile) return NS_ERROR_FAILURE;
  }

  if (!mSourceProfile) {
    GetSourceProfile(aProfile);
    if (!mSourceProfile)
      return NS_ERROR_FAILURE;
  }

  NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);

  COPY_DATA(CopyPreferences,  aReplace, nsIBrowserProfileMigrator::SETTINGS);
  COPY_DATA(CopyCookies,      aReplace, nsIBrowserProfileMigrator::COOKIES);
  COPY_DATA(CopyBookmarks,    aReplace, nsIBrowserProfileMigrator::BOOKMARKS);

  NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);

  return rv;
}
NS_IMETHODIMP
nsOperaProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
{
    nsresult rv = NS_OK;
    PRBool aReplace = aStartup ? PR_TRUE : PR_FALSE;

    if (aStartup) {
        rv = aStartup->DoStartup();
        NS_ENSURE_SUCCESS(rv, rv);
    }

    if (!mOperaProfile)
        GetOperaProfile(aProfile, getter_AddRefs(mOperaProfile));

    NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);

    COPY_DATA(CopyPreferences,  aReplace, nsIBrowserProfileMigrator::SETTINGS);
    COPY_DATA(CopyCookies,      aReplace, nsIBrowserProfileMigrator::COOKIES);
    COPY_DATA(CopyHistory,      aReplace, nsIBrowserProfileMigrator::HISTORY);
    COPY_DATA(CopyBookmarks,    aReplace, nsIBrowserProfileMigrator::BOOKMARKS);

    NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);

    return rv;
}
NS_IMETHODIMP
nsThunderbirdProfileMigrator::Migrate(uint16_t aItems,
                                      nsIProfileStartup* aStartup,
                                      const PRUnichar* aProfile)
{
  nsresult rv = NS_OK;
  bool aReplace = aStartup ? true : false;

  if (!mTargetProfile) {
    GetProfilePath(aStartup, getter_AddRefs(mTargetProfile));
    if (!mTargetProfile)
      return NS_ERROR_FILE_NOT_FOUND;
  }
  if (!mSourceProfile) {
    GetSourceProfile(aProfile);
    if (!mSourceProfile)
      return NS_ERROR_FILE_NOT_FOUND;
  }

  NOTIFY_OBSERVERS(MIGRATION_STARTED, nullptr);

  COPY_DATA(CopyPreferences,  aReplace, nsISuiteProfileMigrator::SETTINGS);
  COPY_DATA(CopyCookies,      aReplace, nsISuiteProfileMigrator::COOKIES);
  COPY_DATA(CopyHistory,      aReplace, nsISuiteProfileMigrator::HISTORY);
  COPY_DATA(CopyPasswords,    aReplace, nsISuiteProfileMigrator::PASSWORDS);
  COPY_DATA(CopyOtherData,    aReplace, nsISuiteProfileMigrator::OTHERDATA);

  // fake notifications for things we've already imported as part of
  // CopyPreferences
  nsAutoString index;
  index.AppendInt(nsISuiteProfileMigrator::ACCOUNT_SETTINGS);
  NOTIFY_OBSERVERS(MIGRATION_ITEMBEFOREMIGRATE, index.get());
  NOTIFY_OBSERVERS(MIGRATION_ITEMAFTERMIGRATE, index.get());

  index.Truncate();
  index.AppendInt(nsISuiteProfileMigrator::NEWSDATA);
  NOTIFY_OBSERVERS(MIGRATION_ITEMBEFOREMIGRATE, index.get());
  NOTIFY_OBSERVERS(MIGRATION_ITEMAFTERMIGRATE, index.get());

  // copy junk mail training file
  COPY_DATA(CopyJunkTraining, aReplace, nsISuiteProfileMigrator::JUNKTRAINING);

  if (aReplace &&
      (aItems & nsISuiteProfileMigrator::SETTINGS ||
       aItems & nsISuiteProfileMigrator::COOKIES ||
       aItems & nsISuiteProfileMigrator::PASSWORDS ||
       !aItems)) {
    // Permissions (Images, Cookies, Popups)
    rv |= CopyFile(FILE_NAME_SITEPERM_NEW, FILE_NAME_SITEPERM_NEW);
    rv |= CopyFile(FILE_NAME_SITEPERM_OLD, FILE_NAME_SITEPERM_OLD);
  }

  // the last thing to do is to actually copy over any mail folders
  // we have marked for copying we want to do this last and it will be
  // asynchronous so the UI doesn't freeze up while we perform
  // this potentially very long operation.
  CopyMailFolders();

  return rv;
}
NS_IMETHODIMP
nsCaminoProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
{
  nsresult rv = NS_OK;

  NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);

  NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);

  return rv;
}
void nsNetscapeProfileMigratorBase::EndCopyFolders()
{
  mFileCopyTransactions.Clear();
  mFileCopyTransactionIndex = 0;

  // notify the UI that we are done with the migration process
  nsAutoString index;
  index.AppendInt(nsIMailProfileMigrator::MAILDATA);
  NOTIFY_OBSERVERS(MIGRATION_ITEMAFTERMIGRATE, index.get());

  NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);
}
nsresult nsProfileMigratorBase::ImportMailData(nsIImportModule * aImportModule)
{
  nsresult rv;

  nsAutoString index;
  index.AppendInt(nsIMailProfileMigrator::MAILDATA);
  NOTIFY_OBSERVERS(MIGRATION_ITEMBEFOREMIGRATE, index.get());

  rv = aImportModule->GetImportInterface(NS_IMPORT_MAIL_STR, getter_AddRefs(mGenericImporter));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsISupportsPRBool> migrating = do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  // by setting the migration flag, we force the import utility to install local folders from OE
  // directly into Local Folders and not as a subfolder
  migrating->SetData(true);
  mGenericImporter->SetData("migration", migrating);

  bool importResult;
  bool wantsProgress;
  mGenericImporter->WantsProgress(&wantsProgress);
  rv = mGenericImporter->BeginImport(nullptr, nullptr, &importResult);

  mProcessingMailFolders = true;

  if (wantsProgress)
    ContinueImport();
  else
    FinishCopyingMailFolders();

  return rv;
}
NS_IMETHODIMP
nsOEProfileMigrator::Notify(nsITimer *timer)
{
  int32_t progress;
  mGenericImporter->GetProgress(&progress);

  nsAutoString index;
  index.AppendInt( progress );
  NOTIFY_OBSERVERS(MIGRATION_PROGRESS, index.get());

  if (progress == 100) // are we done yet?
  {
    if (mProcessingMailFolders)
      return FinishCopyingMailFolders();
    else
      return FinishCopyingAddressBookData();
  }
  else
  {
    // fire a timer to handle the next one.
    mFileIOTimer = do_CreateInstance("@mozilla.org/timer;1");
    if (mFileIOTimer)
      mFileIOTimer->InitWithCallback(static_cast<nsITimerCallback *>(this), 100, nsITimer::TYPE_ONE_SHOT);
  }
  return NS_OK;
}
nsresult nsProfileMigratorBase::ImportAddressBook(nsIImportModule * aImportModule)
{
  nsresult rv;

  nsAutoString index;
  index.AppendInt(nsIMailProfileMigrator::ADDRESSBOOK_DATA);
  NOTIFY_OBSERVERS(MIGRATION_ITEMBEFOREMIGRATE, index.get());

  rv = aImportModule->GetImportInterface(NS_IMPORT_ADDRESS_STR, getter_AddRefs(mGenericImporter));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsISupportsCString> pabString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  // we want to migrate the outlook express addressbook into our personal address book
  pabString->SetData(nsDependentCString(kPersonalAddressbookUri));
  mGenericImporter->SetData("addressDestination", pabString);

  bool importResult;
  bool wantsProgress;
  mGenericImporter->WantsProgress(&wantsProgress);
  rv = mGenericImporter->BeginImport(nullptr, nullptr, &importResult);

  if (wantsProgress)
    ContinueImport();
  else
    FinishCopyingAddressBookData();

  return rv;
}
void nsNetscapeProfileMigratorBase::CopyNextFolder()
{
  if (mFileCopyTransactionIndex < mFileCopyTransactions.Length())
  {
    fileTransactionEntry fileTransaction =
      mFileCopyTransactions.ElementAt(mFileCopyTransactionIndex++);

    // copy the file
    fileTransaction.srcFile->CopyTo(fileTransaction.destFile,
                                    fileTransaction.newName);

    // add to our current progress
    int64_t fileSize;
    fileTransaction.srcFile->GetFileSize(&fileSize);
    mCurrentProgress += fileSize;

    uint32_t percentage = (uint32_t)(mCurrentProgress * 100 / mMaxProgress);

    nsAutoString index;
    index.AppendInt(percentage);

    NOTIFY_OBSERVERS(MIGRATION_PROGRESS, index.get());

    // fire a timer to handle the next one.
    mFileIOTimer = do_CreateInstance("@mozilla.org/timer;1");

    if (mFileIOTimer)
      mFileIOTimer->InitWithCallback(static_cast<nsITimerCallback *>(this), percentage == 100 ? 500 : 0, nsITimer::TYPE_ONE_SHOT);
  } else
    EndCopyFolders();

  return;
}
NS_IMETHODIMP
nsSeamonkeyProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
{
  nsresult rv = NS_OK;
  PRBool aReplace = aStartup ? PR_TRUE : PR_FALSE;

  if (!mTargetProfile) {
    GetProfilePath(aStartup, mTargetProfile);
    if (!mTargetProfile) return NS_ERROR_FAILURE;
  }
  if (!mSourceProfile)
    GetSourceProfile(aProfile);

  NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);

  COPY_DATA(CopyPreferences,  aReplace, nsIBrowserProfileMigrator::SETTINGS);
  COPY_DATA(CopyCookies,      aReplace, nsIBrowserProfileMigrator::COOKIES);
  COPY_DATA(CopyHistory,      aReplace, nsIBrowserProfileMigrator::HISTORY);
  COPY_DATA(CopyPasswords,    aReplace, nsIBrowserProfileMigrator::PASSWORDS);
  COPY_DATA(CopyOtherData,    aReplace, nsIBrowserProfileMigrator::OTHERDATA);

  // Need to do startup before trying to copy bookmarks, since bookmarks
  // import requires a profile. Can't do it earlier because services might
  // end up creating the files we try to copy above.
  if (aStartup) {
    rv = aStartup->DoStartup();
    NS_ENSURE_SUCCESS(rv, rv);
  }

  COPY_DATA(CopyBookmarks,    aReplace, nsIBrowserProfileMigrator::BOOKMARKS);

  if (aReplace && 
      (aItems & nsIBrowserProfileMigrator::SETTINGS || 
       aItems & nsIBrowserProfileMigrator::COOKIES || 
       aItems & nsIBrowserProfileMigrator::PASSWORDS ||
       !aItems)) {
    // Permissions (Images, Cookies, Popups)
    rv |= CopyFile(FILE_NAME_SITEPERM_NEW, FILE_NAME_SITEPERM_NEW);
    rv |= CopyFile(FILE_NAME_SITEPERM_OLD, FILE_NAME_SITEPERM_OLD);
  }

  NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);

  return rv;
}
nsresult nsProfileMigratorBase::FinishCopyingMailFolders()
{
  nsAutoString index;
  index.AppendInt(nsIMailProfileMigrator::MAILDATA);
  NOTIFY_OBSERVERS(MIGRATION_ITEMAFTERMIGRATE, index.get());

  // now kick off the filters migration code
  return ImportFilters(mImportModule);
}
nsresult nsProfileMigratorBase::ImportSettings(nsIImportModule * aImportModule)
{
  nsresult rv;

  nsAutoString index;
  index.AppendInt(nsIMailProfileMigrator::ACCOUNT_SETTINGS);
  NOTIFY_OBSERVERS(MIGRATION_ITEMBEFOREMIGRATE, index.get());

  nsCOMPtr<nsIImportSettings> importSettings;
  rv = aImportModule->GetImportInterface(NS_IMPORT_SETTINGS_STR, getter_AddRefs(importSettings));
  NS_ENSURE_SUCCESS(rv, rv);

  bool importedSettings = false;

  rv = importSettings->Import(getter_AddRefs(mLocalFolderAccount), &importedSettings);

  NOTIFY_OBSERVERS(MIGRATION_ITEMAFTERMIGRATE, index.get());

  return rv;
}
nsresult nsProfileMigratorBase::FinishCopyingAddressBookData()
{
  nsAutoString index;
  index.AppendInt(nsIMailProfileMigrator::ADDRESSBOOK_DATA);
  NOTIFY_OBSERVERS(MIGRATION_ITEMAFTERMIGRATE, index.get());

  // now kick off the mail migration code
  ImportMailData(mImportModule);

  return NS_OK;
}
NS_IMETHODIMP
nsSeamonkeyProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
{
  nsresult rv = NS_OK;
  PRBool aReplace = aStartup ? PR_TRUE : PR_FALSE;

  if (!mTargetProfile) {
    GetProfilePath(aStartup, mTargetProfile);
    if (!mTargetProfile) return NS_ERROR_FAILURE;
  }
  if (!mSourceProfile)
    GetSourceProfile(aProfile);

  NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);

  COPY_DATA(CopyPreferences,  aReplace, nsIBrowserProfileMigrator::SETTINGS);
  COPY_DATA(CopyCookies,      aReplace, nsIBrowserProfileMigrator::COOKIES);
  COPY_DATA(CopyHistory,      aReplace, nsIBrowserProfileMigrator::HISTORY);
  COPY_DATA(CopyPasswords,    aReplace, nsIBrowserProfileMigrator::PASSWORDS);
  COPY_DATA(CopyOtherData,    aReplace, nsIBrowserProfileMigrator::OTHERDATA);
  COPY_DATA(CopyBookmarks,    aReplace, nsIBrowserProfileMigrator::BOOKMARKS);

  if (aReplace && 
      (aItems & nsIBrowserProfileMigrator::SETTINGS || 
       aItems & nsIBrowserProfileMigrator::COOKIES || 
       aItems & nsIBrowserProfileMigrator::PASSWORDS ||
       !aItems)) {
    // Permissions (Images, Cookies, Popups)
    rv |= CopyFile(FILE_NAME_SITEPERM_NEW, FILE_NAME_SITEPERM_NEW);
    rv |= CopyFile(FILE_NAME_SITEPERM_OLD, FILE_NAME_SITEPERM_OLD);
  }

  NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);

  return rv;
}
void
nsNetscapeProfileMigratorBase::CopyMailFolders()
{
  nsAutoString index;
  index.AppendInt(nsISuiteProfileMigrator::MAILDATA);
  NOTIFY_OBSERVERS(MIGRATION_ITEMBEFOREMIGRATE, index.get());

  // Generate the max progress value now that we know all of the files we
  // need to copy
  uint32_t count = mFileCopyTransactions.Length();
  mMaxProgress = 0;
  mCurrentProgress = 0;

  for (uint32_t i = 0; i < count; ++i) {
    fileTransactionEntry fileTransaction = mFileCopyTransactions[i];
    int64_t fileSize;
    fileTransaction.srcFile->GetFileSize(&fileSize);
    mMaxProgress += fileSize;
  }

  CopyNextFolder();
}
NS_IMETHODIMP
nsOEProfileMigrator::Migrate(uint16_t aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
{
  nsresult rv = NS_OK;

  if (aStartup)
  {
    rv = aStartup->DoStartup();
    NS_ENSURE_SUCCESS(rv, rv);
  }

  NOTIFY_OBSERVERS(MIGRATION_STARTED, nullptr);
  rv = ImportSettings(mImportModule);

  // now import address books
  // this routine will asynchronously import address book data and it will then kick off
  // the final migration step, copying the mail folders over.
  rv = ImportAddressBook(mImportModule);

  // don't broadcast an on end migration here. We aren't done until our asynch import process says we are done.
  return rv;
}