nsCOMTypeInfo<nsIMdbFactoryFactory>::GetIID(),
NS_GET_IID(nsIMdbFactoryFactory),
nsGlobalHistory::OpenDB(){  nsresult rv;  nsCOMPtr <nsIFileSpec> historyFile;  nsFileSpec dbfile;  NS_WITH_SERVICE(nsIFileLocator, locator, kFileLocatorCID, &rv);  if (NS_FAILED(rv)) return rv;  rv = locator->GetFileLocation(nsSpecialFileSpec::App_History50, getter_AddRefs(historyFile));  if (NS_FAILED(rv)) return rv;   rv = historyFile->GetFileSpec(&dbfile);  if (NS_FAILED(rv)) return rv;  static NS_DEFINE_CID(kMorkCID, NS_MORK_CID);  nsCOMPtr<nsIMdbFactoryFactory> factoryfactory;  rv = nsComponentManager::CreateInstance(kMorkCID,                                          nsnull,                                          nsCOMTypeInfo<nsIMdbFactoryFactory>::GetIID(),                                          getter_AddRefs(factoryfactory));  if (NS_FAILED(rv)) return rv;  // Leaving XPCOM, entering MDB. They may look like XPCOM interfaces,  // but they're not. The 'factory' is an interface; however, it isn't  // reference counted. So no, this isn't a leak.  nsIMdbFactory* factory;  rv = factoryfactory->GetMdbFactory(&factory);  NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create mork factory factory");  if (NS_FAILED(rv)) return rv;  mdb_err err;  err = factory->MakeEnv(nsnull, &mEnv);  NS_ASSERTION((err == 0), "unable to create mdb env");  if (err != 0) return NS_ERROR_FAILURE;  nsIMdbHeap* dbHeap = 0;  mdb_bool dbFrozen = mdbBool_kFalse; // not readonly, we want modifiable  if (dbfile.Exists()) {    mdb_bool canopen = 0;    mdbYarn outfmt = { nsnull, 0, 0, 0, 0, nsnull };    nsMdbPtr<nsIMdbFile> oldFile(mEnv); // ensures file is released    err = factory->OpenOldFile(mEnv, dbHeap, dbfile.GetNativePathCString(),                               dbFrozen, getter_Acquires(oldFile));    if ((err != 0) || !oldFile) return NS_ERROR_FAILURE;    err = factory->CanOpenFilePort(mEnv, oldFile, // the file to investigate                                   &canopen, &outfmt);    // XXX possible that format out of date, in which case we should    // just re-write the file.    if ((err != 0) || !canopen) return NS_ERROR_FAILURE;    nsIMdbThumb* thumb = nsnull;    mdbOpenPolicy policy = { { 0, 0 }, 0, 0 };		err = factory->OpenFileStore(mEnv, dbHeap, oldFile, &policy, &thumb);     if ((err != 0) || !thumb) return NS_ERROR_FAILURE;    mdb_count total;    mdb_count current;    mdb_bool done;    mdb_bool broken;    do {      err = thumb->DoMore(mEnv, &total, &current, &done, &broken);    } while ((err == 0) && !broken && !done);    if ((err == 0) && done) {      err = factory->ThumbToOpenStore(mEnv, thumb, &mStore);    }    thumb->CutStrongRef(mEnv);    thumb = nsnull;    if ((err != 0) || !done) return NS_ERROR_FAILURE;    rv = CreateTokens();    if (NS_FAILED(rv)) return rv;    mdbOid oid = { kToken_HistoryRowScope, 1 };    err = mStore->GetTable(mEnv, &oid, &mTable);    if (err != 0) return NS_ERROR_FAILURE;  }  else {    nsMdbPtr<nsIMdbFile> newFile(mEnv); // ensures file is released    err = factory->CreateNewFile(mEnv, dbHeap, dbfile.GetNativePathCString(),                                 getter_Acquires(newFile));    if ((err != 0) || !newFile) return NS_ERROR_FAILURE;    mdbOpenPolicy policy = { { 0, 0 }, 0, 0 };    err = factory->CreateNewFileStore(mEnv, dbHeap, newFile, &policy, &mStore);    if (err != 0) return NS_ERROR_FAILURE;    rv = CreateTokens();    if (NS_FAILED(rv)) return rv;    // Create the one and only table in the history db    err = mStore->NewTable(mEnv, kToken_HistoryRowScope, kToken_HistoryKind, PR_TRUE, nsnull, &mTable);    if (err != 0) return NS_ERROR_FAILURE;    // Force a commit now to get it written out.    nsMdbPtr<nsIMdbThumb> thumb(mEnv);    err = mStore->LargeCommit(mEnv, getter_Acquires(thumb));    if (err != 0) return NS_ERROR_FAILURE;    mdb_count total;    mdb_count current;    mdb_bool done;    mdb_bool broken;    do {      err = thumb->DoMore(mEnv, &total, &current, &done, &broken);    } while ((err == 0) && !broken && !done);    if ((err != 0) || !done) return NS_ERROR_FAILURE;  }  return NS_OK;}