void
nsOperaProfileMigrator::GetOperaProfile(const PRUnichar* aProfile, nsILocalFile** aFile)
{
    nsCOMPtr<nsIProperties> fileLocator(do_GetService("@mozilla.org/file/directory_service;1"));
    nsCOMPtr<nsILocalFile> file;
#ifdef XP_WIN
    fileLocator->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));

    // Opera profile lives under %APP_DATA%\Opera\<operaver>\profile
    file->Append(OPERA_PREFERENCES_FOLDER_NAME);
    file->Append(nsDependentString(aProfile));
    file->Append(NS_LITERAL_STRING("profile"));
#elif defined (XP_MACOSX)
    fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));

    file->Append(NS_LITERAL_STRING("Preferences"));
    file->Append(OPERA_PREFERENCES_FOLDER_NAME);
#elif defined (XP_UNIX)
    fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));

    file->Append(OPERA_PREFERENCES_FOLDER_NAME);
#endif

    *aFile = file;
    NS_ADDREF(*aFile);
}
nsresult
nsSafariProfileMigrator::SetDownloadFolder(void* aTransform, nsIPrefBranch* aBranch)
{
  PrefTransform* xform = (PrefTransform*)aTransform;

  nsCOMPtr<nsILocalFile> downloadFolder;
  nsresult rv = NS_NewNativeLocalFile(nsDependentCString(xform->stringValue),
                                      true, getter_AddRefs(downloadFolder));
  NS_ENSURE_SUCCESS(rv, rv);

  // If the Safari download folder is the desktop, set the folderList pref
  // appropriately so that "Desktop" is selected in the list in our Preferences
  // UI instead of just the raw path being shown.
  nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
  nsCOMPtr<nsILocalFile> desktopFolder;
  fileLocator->Get(NS_OSX_USER_DESKTOP_DIR, NS_GET_IID(nsILocalFile),
                   getter_AddRefs(desktopFolder));

  bool equals;
  downloadFolder->Equals(desktopFolder, &equals);
  aBranch->SetIntPref("browser.download.folderList", equals ? 0 : 2);
  aBranch->SetComplexValue("browser.download.dir",
                           NS_GET_IID(nsILocalFile), downloadFolder);

  return NS_OK;
}
nsresult
nsThunderbirdProfileMigrator::FillProfileDataFromRegistry()
{
  // Find the Thunderbird Registry
  nsCOMPtr<nsIProperties> fileLocator(
    do_GetService("@mozilla.org/file/directory_service;1"));
  nsCOMPtr<nsIFile> thunderbirdData;
#ifdef XP_WIN
  fileLocator->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsIFile),
                   getter_AddRefs(thunderbirdData));

  thunderbirdData->Append(NS_LITERAL_STRING("Thunderbird"));

#elif defined(XP_MACOSX)
  fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsIFile),
                   getter_AddRefs(thunderbirdData));
  
  thunderbirdData->Append(NS_LITERAL_STRING("Thunderbird"));

#elif defined(XP_UNIX)
  fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsIFile),
                   getter_AddRefs(thunderbirdData));
  
  thunderbirdData->Append(NS_LITERAL_STRING(".thunderbird"));

#else
  // On other OS just abort
  return NS_ERROR_FILE_NOT_FOUND;
#endif

  // Try profiles.ini first
  return GetProfileDataFromProfilesIni(thunderbirdData,
                                       mProfileNames,
                                       mProfileLocations);
}
nsresult
nsSeamonkeyProfileMigrator::FillProfileDataFromSeamonkeyRegistry()
{
  // Find the Seamonkey Registry
  nsCOMPtr<nsIProperties> fileLocator(do_GetService("@mozilla.org/file/directory_service;1"));
  nsCOMPtr<nsILocalFile> seamonkeyRegistry;
#ifdef XP_WIN
  fileLocator->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));

  seamonkeyRegistry->Append(NS_LITERAL_STRING("Mozilla"));
  seamonkeyRegistry->Append(NS_LITERAL_STRING("registry.dat"));
#elif defined(XP_MACOSX)
  fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));
  
  seamonkeyRegistry->Append(NS_LITERAL_STRING("Mozilla"));
  seamonkeyRegistry->Append(NS_LITERAL_STRING("Application Registry"));
#elif defined(XP_UNIX)
  fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));
  
  seamonkeyRegistry->Append(NS_LITERAL_STRING(".mozilla"));
  seamonkeyRegistry->Append(NS_LITERAL_STRING("appreg"));
#elif defined(XP_BEOS)
   fileLocator->Get(NS_BEOS_SETTINGS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));

   seamonkeyRegistry->Append(NS_LITERAL_STRING("Mozilla"));
   seamonkeyRegistry->Append(NS_LITERAL_STRING("appreg"));
#elif defined(XP_OS2)
  fileLocator->Get(NS_OS2_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));
  
  seamonkeyRegistry->Append(NS_LITERAL_STRING("Mozilla"));
  seamonkeyRegistry->Append(NS_LITERAL_STRING("registry.dat"));
#endif

  return GetProfileDataFromRegistry(seamonkeyRegistry, mProfileNames, mProfileLocations);
}
NS_IMETHODIMP
nsSafariProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
                                        bool aReplace,
                                        PRUint16* aResult)
{
  *aResult = 0;
  nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
  nsCOMPtr<nsILocalFile> safariSettingsDir, safariCookiesDir;
  fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile),
                   getter_AddRefs(safariSettingsDir));
  safariSettingsDir->Append(NS_LITERAL_STRING("Safari"));
  fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile),
                   getter_AddRefs(safariCookiesDir));
  safariCookiesDir->Append(NS_LITERAL_STRING("Cookies"));

  // Safari stores most of its user settings under ~/Library/Safari/
  MigrationData data[] = { { ToNewUnicode(SAFARI_HISTORY_FILE_NAME),
                             nsIBrowserProfileMigrator::HISTORY,
                             false },
                           { ToNewUnicode(SAFARI_BOOKMARKS_FILE_NAME),
                             nsIBrowserProfileMigrator::BOOKMARKS,
                             false } };
  // Frees file name strings allocated above.
  GetMigrateDataFromArray(data, sizeof(data)/sizeof(MigrationData),
                          aReplace, safariSettingsDir, aResult);

  // Safari stores Cookies under ~/Library/Cookies/Cookies.plist
  MigrationData data2[] = { { ToNewUnicode(SAFARI_COOKIES_FILE_NAME),
                              nsIBrowserProfileMigrator::COOKIES,
                              false } };
  GetMigrateDataFromArray(data2, sizeof(data2)/sizeof(MigrationData),
                          aReplace, safariCookiesDir, aResult);

  // Safari stores Preferences under ~/Library/Preferences/
  nsCOMPtr<nsILocalFile> systemPrefsDir;
  fileLocator->Get(NS_OSX_USER_PREFERENCES_DIR, NS_GET_IID(nsILocalFile),
                   getter_AddRefs(systemPrefsDir));
  MigrationData data3[]= { { ToNewUnicode(SAFARI_PREFERENCES_FILE_NAME),
                             nsIBrowserProfileMigrator::SETTINGS,
                             false } };
  GetMigrateDataFromArray(data3, sizeof(data3)/sizeof(MigrationData),
                          aReplace, systemPrefsDir, aResult);

  // Don't offer to import the Safari user style sheet if the active profile
  // already has a content style sheet (userContent.css)
  bool hasContentStylesheet = false;
  if (NS_SUCCEEDED(ProfileHasContentStyleSheet(&hasContentStylesheet)) &&
      !hasContentStylesheet) {
    nsCOMPtr<nsILocalFile> safariUserStylesheetFile;
    if (NS_SUCCEEDED(GetSafariUserStyleSheet(getter_AddRefs(safariUserStylesheetFile))))
      *aResult |= nsIBrowserProfileMigrator::OTHERDATA;
  }
  
  // Don't offer to import that Safari form data if there isn't any
  if (HasFormDataToImport())
    *aResult |= nsIBrowserProfileMigrator::FORMDATA;

  return NS_OK;
}
nsresult
nsSafariProfileMigrator::CopyHistoryBatched(bool 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 =
    static_cast<CFDictionaryRef>(CopyPListFromFile(safariHistoryFile));
  if (!safariHistory)
    return NS_OK;

  if (!::CFDictionaryContainsKey(safariHistory, CFSTR("WebHistoryDates"))) {
    ::CFRelease(safariHistory);
    return NS_OK;
  }

  nsCOMPtr<nsIBrowserHistory> history(do_GetService(NS_GLOBALHISTORY2_CONTRACTID));

  CFArrayRef children = (CFArrayRef)
                ::CFDictionaryGetValue(safariHistory, CFSTR("WebHistoryDates"));
  if (children) {
    CFIndex count = ::CFArrayGetCount(children);
    for (PRInt32 i = 0; i < count; ++i) {
      CFDictionaryRef entry = (CFDictionaryRef)::CFArrayGetValueAtIndex(children, i);

      CFStringRef lastVisitedDate = (CFStringRef)
                        ::CFDictionaryGetValue(entry, CFSTR("lastVisitedDate"));
      nsAutoString url, title;
      if (GetDictionaryStringValue(entry, CFSTR(""), url) &&
          GetDictionaryStringValue(entry, CFSTR("title"), title) &&
          lastVisitedDate) {

        double lvd = ::CFStringGetDoubleValue(lastVisitedDate) + SAFARI_DATE_OFFSET;
        PRTime lastVisitTime;
        PRInt64 temp, million;
        LL_D2L(temp, lvd);
        LL_I2L(million, PR_USEC_PER_SEC);
        LL_MUL(lastVisitTime, temp, million);

        nsCOMPtr<nsIURI> uri;
        NS_NewURI(getter_AddRefs(uri), url);
        if (uri)
          history->AddPageWithDetails(uri, title.get(), lastVisitTime);
      }
    }
  }

  ::CFRelease(safariHistory);

  return NS_OK;
}
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 static_cast<CFDictionaryRef>(CopyPListFromFile(safariPrefsFile));
}
nsresult
nsSafariProfileMigrator::CopyCookies(bool aReplace)
{
  nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
  nsCOMPtr<nsILocalFile> safariCookiesFile;
  fileLocator->Get(NS_MAC_USER_LIB_DIR,
                   NS_GET_IID(nsILocalFile),
                   getter_AddRefs(safariCookiesFile));
  safariCookiesFile->Append(NS_LITERAL_STRING("Cookies"));
  safariCookiesFile->Append(SAFARI_COOKIES_FILE_NAME);

  CFArrayRef safariCookies = (CFArrayRef)CopyPListFromFile(safariCookiesFile);
  if (!safariCookies)
    return NS_OK;

  nsCOMPtr<nsICookieManager2> cookieManager(do_GetService(NS_COOKIEMANAGER_CONTRACTID));
  CFIndex count = ::CFArrayGetCount(safariCookies);
  for (PRInt32 i = 0; i < count; ++i) {
    CFDictionaryRef entry = (CFDictionaryRef)::CFArrayGetValueAtIndex(safariCookies, i);

    CFDateRef date = (CFDateRef)::CFDictionaryGetValue(entry, CFSTR("Expires"));

    nsCAutoString domain, path, name, value;
    if (date &&
        GetDictionaryCStringValue(entry, CFSTR("Domain"), domain,
                                  kCFStringEncodingUTF8) &&
        GetDictionaryCStringValue(entry, CFSTR("Path"), path,
                                  kCFStringEncodingUTF8) &&
        GetDictionaryCStringValue(entry, CFSTR("Name"), name,
                                  kCFStringEncodingASCII) &&
        GetDictionaryCStringValue(entry, CFSTR("Value"), value,
                                  kCFStringEncodingASCII)) {
      PRInt64 expiryTime;
      LL_D2L(expiryTime, (double)::CFDateGetAbsoluteTime(date));

      expiryTime += SAFARI_DATE_OFFSET;
      cookieManager->Add(domain, path, name, value,
                         false, // isSecure
                         false, // isHttpOnly
                         false, // isSession
                         expiryTime);
    }
  }
  ::CFRelease(safariCookies);

  return NS_OK;
}
NS_IMETHODIMP
nsMacShellService::SetDesktopBackground(nsIDOMElement* aElement, 
                                        int32_t aPosition)
{
  // Note: We don't support aPosition on OS X.

  // Get the image URI:
  nsresult rv;
  nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement,
                                                                    &rv);
  NS_ENSURE_SUCCESS(rv, rv);
  nsCOMPtr<nsIURI> imageURI;
  rv = imageContent->GetCurrentURI(getter_AddRefs(imageURI));
  NS_ENSURE_SUCCESS(rv, rv);

  // We need the referer URI for nsIWebBrowserPersist::saveURI
  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsIURI *docURI = content->OwnerDoc()->GetDocumentURI();
  if (!docURI)
    return NS_ERROR_FAILURE;

  // Get the desired image file name
  nsCOMPtr<nsIURL> imageURL(do_QueryInterface(imageURI));
  if (!imageURL) {
    // XXXmano (bug 300293): Non-URL images (e.g. the data: protocol) are not
    // yet supported. What filename should we take here?
    return NS_ERROR_NOT_IMPLEMENTED;
  }

  nsAutoCString fileName;
  imageURL->GetFileName(fileName);
  nsCOMPtr<nsIProperties> fileLocator
    (do_GetService("@mozilla.org/file/directory_service;1", &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  // Get the current user's "Pictures" folder (That's ~/Pictures):
  fileLocator->Get(NS_OSX_PICTURE_DOCUMENTS_DIR, NS_GET_IID(nsIFile),
                   getter_AddRefs(mBackgroundFile));
  if (!mBackgroundFile)
    return NS_ERROR_OUT_OF_MEMORY;

  nsAutoString fileNameUnicode;
  CopyUTF8toUTF16(fileName, fileNameUnicode);

  // and add the imgage file name itself:
  mBackgroundFile->Append(fileNameUnicode);

  // Download the image; the desktop background will be set in OnStateChange()
  nsCOMPtr<nsIWebBrowserPersist> wbp
    (do_CreateInstance("@mozilla.org/embedding/browser/nsWebBrowserPersist;1", &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  uint32_t flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION | 
                   nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES |
                   nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;

  wbp->SetPersistFlags(flags);
  wbp->SetProgressListener(this);

  nsCOMPtr<nsILoadContext> loadContext;
  nsCOMPtr<nsISupports> container = content->OwnerDoc()->GetContainer();
  nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
  if (docShell) {
    loadContext = do_QueryInterface(docShell);
  }

  return wbp->SaveURI(imageURI, nullptr,
                      docURI, content->OwnerDoc()->GetReferrerPolicy(),
                      nullptr, nullptr,
                      mBackgroundFile, loadContext);
}
NS_IMETHODIMP
nsOperaProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult)
{
    if (!mProfiles) {
        nsresult rv;

        mProfiles = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
        if (NS_FAILED(rv)) return rv;

        nsCOMPtr<nsIProperties> fileLocator(do_GetService("@mozilla.org/file/directory_service;1"));
        nsCOMPtr<nsILocalFile> file;
#ifdef XP_WIN
        fileLocator->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));

        // Opera profile lives under %APP_DATA%\Opera\<operaver>\profile
        file->Append(OPERA_PREFERENCES_FOLDER_NAME);

        nsCOMPtr<nsISimpleEnumerator> e;
        rv = file->GetDirectoryEntries(getter_AddRefs(e));
        if (NS_FAILED(rv))
            return rv;

        PRBool hasMore;
        e->HasMoreElements(&hasMore);
        while (hasMore) {
            nsCOMPtr<nsILocalFile> curr;
            e->GetNext(getter_AddRefs(curr));

            PRBool isDirectory = PR_FALSE;
            curr->IsDirectory(&isDirectory);
            if (isDirectory) {
                nsCOMPtr<nsISupportsString> string(do_CreateInstance("@mozilla.org/supports-string;1"));
                nsAutoString leafName;
                curr->GetLeafName(leafName);
                string->SetData(leafName);
                mProfiles->AppendElement(string);
            }

            e->HasMoreElements(&hasMore);
        }
#elif defined (XP_MACOSX)
        fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));

        file->Append(NS_LITERAL_STRING("Preferences"));
        file->Append(OPERA_PREFERENCES_FOLDER_NAME);

        PRBool exists;
        file->Exists(&exists);

        if (exists) {
            nsCOMPtr<nsISupportsString> string(do_CreateInstance("@mozilla.org/supports-string;1"));
            string->SetData(OPERA_PREFERENCES_FOLDER_NAME);
            mProfiles->AppendElement(string);
        }
#elif defined (XP_UNIX)
        fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(file));

        file->Append(OPERA_PREFERENCES_FOLDER_NAME);

        PRBool exists;
        file->Exists(&exists);

        if (exists) {
            nsCOMPtr<nsISupportsString> string(do_CreateInstance("@mozilla.org/supports-string;1"));
            string->SetData(OPERA_PREFERENCES_FOLDER_NAME);
            mProfiles->AppendElement(string);
        }
#endif
    }

    *aResult = mProfiles;
    NS_IF_ADDREF(*aResult);
    return NS_OK;
}
nsresult
nsSafariProfileMigrator::CopyBookmarksBatched(bool 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);
  NS_ENSURE_SUCCESS(rv, rv);
  PRInt64 bookmarksMenuFolderId;
  rv = bms->GetBookmarksMenuFolder(&bookmarksMenuFolderId);
  NS_ENSURE_SUCCESS(rv, rv);

  PRInt64 folder;
  if (!aReplace) {
    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 sourceNameSafari;
    rv = bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameSafari").get(),
                                   getter_Copies(sourceNameSafari));
    NS_ENSURE_SUCCESS(rv, rv);

    const PRUnichar* sourceNameStrings[] = { sourceNameSafari.get() };
    nsString importedSafariBookmarksTitle;
    rv = bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
                                      sourceNameStrings, 1,
                                      getter_Copies(importedSafariBookmarksTitle));
    NS_ENSURE_SUCCESS(rv, rv);

    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 = 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 =
    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").
  // We put the contents of the "BookmarksBar" folder into our Personal Toolbar
  // and merge the contents of the "BookmarksMenu" folder and the other toplevel
  // non-special folders under our NC:BookmarksRoot.
  if (::CFDictionaryContainsKey(safariBookmarks, CFSTR("Children")) &&
      ::CFDictionaryContainsKey(safariBookmarks, CFSTR("WebBookmarkFileVersion")) ) {
    CFNumberRef intValue =
      (CFNumberRef)::CFDictionaryGetValue(safariBookmarks,
                                          CFSTR("WebBookmarkFileVersion"));
    PRInt32 value = 0;
    if (::CFNumberGetValue(intValue, kCFNumberSInt32Type, &value) && value ==1) {
      CFArrayRef children =
        (CFArrayRef)::CFDictionaryGetValue(safariBookmarks, CFSTR("Children"));
      if (children) {
        rv = ParseBookmarksFolder(children, folder, bms, true);
      }
    }
  }
  ::CFRelease(safariBookmarks);
  return rv;
}
nsresult
nsSafariProfileMigrator::CopyPreferences(bool aReplace)
{
  nsCOMPtr<nsIPrefBranch> branch(do_GetService(NS_PREFSERVICE_CONTRACTID));

  CFDictionaryRef safariPrefs = CopySafariPrefs();
  if (!safariPrefs)
    return NS_ERROR_FAILURE;

  // Traverse the standard transforms
  PrefTransform* transform;
  PrefTransform* end = gTransforms +
                       sizeof(gTransforms) / sizeof(PrefTransform);

  for (transform = gTransforms; transform < end; ++transform) {
    Boolean hasValue = ::CFDictionaryContainsKey(safariPrefs, transform->keyName);
    if (!hasValue)
      continue;

    transform->prefHasValue = false;
    switch (transform->type) {
    case _SPM(STRING): {
        CFStringRef stringValue = (CFStringRef)
                                  ::CFDictionaryGetValue(safariPrefs,
                                                         transform->keyName);
        char* value = GetNullTerminatedString(stringValue);
        if (value) {
          transform->stringValue = value;
          transform->prefHasValue = true;
        }
      }
      break;
    case _SPM(INT): {
        CFNumberRef intValue = (CFNumberRef)
                               ::CFDictionaryGetValue(safariPrefs,
                                                      transform->keyName);
        PRInt32 value = 0;
        if (::CFNumberGetValue(intValue, kCFNumberSInt32Type, &value)) {
          transform->intValue = value;
          transform->prefHasValue = true;
        }
      }
      break;
    case _SPM(BOOL): {
        CFBooleanRef boolValue = (CFBooleanRef)
                                 ::CFDictionaryGetValue(safariPrefs,
                                                        transform->keyName);
        transform->boolValue = boolValue == kCFBooleanTrue;
        transform->prefHasValue = true;
      }
      break;
    default:
      break;
    }

    if (transform->prefHasValue)
      transform->prefSetterFunc(transform, branch);

    if (transform->type == _SPM(STRING))
      FreeNullTerminatedString(transform->stringValue);
  }

  ::CFRelease(safariPrefs);

  // Safari stores the Cookie "Accept/Don't Accept/Don't Accept Foreign" cookie
  // 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 =
    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;
    if (GetDictionaryStringValue(safariWebFoundationPrefs,
                                 CFSTR("NSHTTPAcceptCookies"), acceptCookies)) {
      PRInt32 cookieValue = 0;
      if (acceptCookies.EqualsLiteral("never"))
        cookieValue = 2;
      else if (acceptCookies.EqualsLiteral("current page"))
        cookieValue = 1;

      branch->SetIntPref("network.cookie.cookieBehavior", cookieValue);
    }

    ::CFRelease(safariWebFoundationPrefs);
  }

  return NS_OK;
}
nsresult
nsSafariProfileMigrator::SetDownloadHandlers(void* aTransform, nsIPrefBranch* aBranch)
{
  PrefTransform* xform = (PrefTransform*)aTransform;
  if (!xform->boolValue) {
    // If we're not set to auto-open safe downloads, we need to clear out the
    // mime types list which contains default handlers.

    nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
    nsCOMPtr<nsILocalFile> mimeRegistryFile;
    fileLocator->Get(NS_APP_USER_MIMETYPES_50_FILE, NS_GET_IID(nsILocalFile),
                     getter_AddRefs(mimeRegistryFile));

    nsCOMPtr<nsIIOService> ioService(do_GetService("@mozilla.org/network/io-service;1"));
    nsCOMPtr<nsIProtocolHandler> ph;
    ioService->GetProtocolHandler("file", getter_AddRefs(ph));
    nsCOMPtr<nsIFileProtocolHandler> fph(do_QueryInterface(ph));

    nsCOMPtr<nsIRDFService> rdfService(do_GetService("@mozilla.org/rdf/rdf-service;1"));
    nsCOMPtr<nsIRDFDataSource> mimeTypes;

    nsCAutoString dsURL;
    fph->GetURLSpecFromFile(mimeRegistryFile, dsURL);
    rdfService->GetDataSourceBlocking(dsURL.get(), getter_AddRefs(mimeTypes));

    nsCOMPtr<nsIRDFResource> overridesListResource;
    rdfService->GetResource(NS_LITERAL_CSTRING("urn:mimetypes:root"),
                            getter_AddRefs(overridesListResource));

    nsCOMPtr<nsIRDFContainer> overridesList(do_CreateInstance("@mozilla.org/rdf/container;1"));
    overridesList->Init(mimeTypes, overridesListResource);

    nsCOMPtr<nsIRDFResource> handlerPropArc, externalApplicationArc;
    rdfService->GetResource(NC_URI(handlerProp), getter_AddRefs(handlerPropArc));
    rdfService->GetResource(NC_URI(externalApplication),
                            getter_AddRefs(externalApplicationArc));

    PRInt32 count;
    overridesList->GetCount(&count);
    for (PRInt32 i = count; i >= 1; --i) {
      nsCOMPtr<nsIRDFNode> currOverrideNode;
      overridesList->RemoveElementAt(i, false, getter_AddRefs(currOverrideNode));
      nsCOMPtr<nsIRDFResource> currOverride(do_QueryInterface(currOverrideNode));

      nsCOMPtr<nsIRDFNode> handlerPropNode;
      mimeTypes->GetTarget(currOverride, handlerPropArc, true,
                           getter_AddRefs(handlerPropNode));
      nsCOMPtr<nsIRDFResource> handlerPropResource(do_QueryInterface(handlerPropNode));

      if (handlerPropResource) {
        nsCOMPtr<nsIRDFNode> externalApplicationNode;
        mimeTypes->GetTarget(handlerPropResource, externalApplicationArc,
                             true, getter_AddRefs(externalApplicationNode));
        nsCOMPtr<nsIRDFResource> externalApplicationResource(do_QueryInterface(externalApplicationNode));

        // Strip the resources down so that the datasource is completely flushed.
        if (externalApplicationResource)
          CleanResource(mimeTypes, externalApplicationResource);

        CleanResource(mimeTypes, handlerPropResource);
      }
      CleanResource(mimeTypes, currOverride);
    }

    nsCOMPtr<nsIRDFRemoteDataSource> rds(do_QueryInterface(mimeTypes));
    if (rds)
      rds->Flush();
  }
  return NS_OK;
}
nsresult
nsSafariProfileMigrator::CopyBookmarks(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;

#ifdef MOZ_PLACES
    nsCOMPtr<nsINavBookmarksService> bms(do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv));
    NS_ENSURE_SUCCESS(rv, rv);
    PRInt64 root;
    rv = bms->GetBookmarksRoot(&root);
    NS_ENSURE_SUCCESS(rv, rv);

    PRInt64 folder;
#else
    nsCOMPtr<nsIRDFService> rdf(do_GetService("@mozilla.org/rdf/rdf-service;1"));
    nsCOMPtr<nsIRDFResource> root;
    rdf->GetResource(NS_LITERAL_CSTRING("NC:BookmarksRoot"), getter_AddRefs(root));

    nsCOMPtr<nsIBookmarksService> bms(do_GetService("@mozilla.org/browser/bookmarks-service;1"));
    NS_ENSURE_TRUE(bms, NS_ERROR_FAILURE);
    PRBool dummy;
    bms->ReadBookmarks(&dummy);

    nsCOMPtr<nsIRDFResource> folder;
#endif
    if (!aReplace) {
        nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(kStringBundleServiceCID, &rv);
        if (NS_FAILED(rv)) return rv;

        nsCOMPtr<nsIStringBundle> bundle;
        bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));

        nsXPIDLString sourceNameSafari;
        bundle->GetStringFromName(NS_LITERAL_STRING("sourceNameSafari").get(),
                                  getter_Copies(sourceNameSafari));

        const PRUnichar* sourceNameStrings[] = { sourceNameSafari.get() };
        nsXPIDLString importedSafariBookmarksTitle;
        bundle->FormatStringFromName(NS_LITERAL_STRING("importedBookmarksFolder").get(),
                                     sourceNameStrings, 1,
                                     getter_Copies(importedSafariBookmarksTitle));

#ifdef MOZ_PLACES
        bms->CreateFolder(root, importedSafariBookmarksTitle, -1, &folder);
#else
        bms->CreateFolderInContainer(importedSafariBookmarksTitle.get(), root, -1,
                                     getter_AddRefs(folder));
#endif
    }
    else {
        // In non-replace mode we are merging at the top level.
        folder = root;
    }

    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);
    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").
    // We put the contents of the "BookmarksBar" folder into our Personal Toolbar
    // and merge the contents of the "BookmarksMenu" folder and the other toplevel
    // non-special folders under our NC:BookmarksRoot.
    if (!::CFDictionaryContainsKey(safariBookmarks, CFSTR("Children")) ||
            !::CFDictionaryContainsKey(safariBookmarks, CFSTR("WebBookmarkFileVersion")) ) {
        ::CFRelease(safariBookmarks);
        return NS_OK;
    }

    CFNumberRef intValue = (CFNumberRef)::CFDictionaryGetValue(safariBookmarks,
                           CFSTR("WebBookmark" \
                                 "FileVersion"));
    PRInt32 value = 0;
    if (!::CFNumberGetValue(intValue, kCFNumberSInt32Type, &value) || value != 1)
        return NS_OK;

    CFArrayRef children = (CFArrayRef)::CFDictionaryGetValue(safariBookmarks,
                          CFSTR("Children"));
    if (children) {
        nsresult rv = ParseBookmarksFolder(children, folder, bms, PR_TRUE);
        if (NS_FAILED(rv)) return rv;
    }

    ::CFRelease(safariBookmarks);

    return NS_OK;
}