NS_IMETHODIMP mozPersonalDictionary::EndSession()
{
  WaitForLoad();

  WaitForSave();
  mIgnoreTable.Clear();
  return NS_OK;
}
NS_IMETHODIMP mozPersonalDictionary::RemoveWord(const char16_t *aWord, const char16_t *aLang)
{
  nsresult res;
  WaitForLoad();

  mDictionaryTable.RemoveEntry(aWord);
  res = Save();
  return res;
}
NS_IMETHODIMP mozPersonalDictionary::Check(const char16_t *aWord, const char16_t *aLanguage, bool *aResult)
{
  NS_ENSURE_ARG_POINTER(aWord);
  NS_ENSURE_ARG_POINTER(aResult);

  WaitForLoad();

  *aResult = (mDictionaryTable.GetEntry(aWord) || mIgnoreTable.GetEntry(aWord));
  return NS_OK;
}
NS_IMETHODIMP
mozPersonalDictionary::RemoveWord(const nsAString& aWord)
{
  nsresult res;
  WaitForLoad();

  mDictionaryTable.RemoveEntry(aWord);
  res = Save();
  return res;
}
NS_IMETHODIMP
mozPersonalDictionary::Check(const nsAString& aWord, bool* aResult)
{
  NS_ENSURE_ARG_POINTER(aResult);

  WaitForLoad();

  *aResult = (mDictionaryTable.GetEntry(aWord) || mIgnoreTable.GetEntry(aWord));
  return NS_OK;
}
NS_IMETHODIMP mozPersonalDictionary::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *aData)
{
  if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
    // The observer is registered in Init() which calls Load and in turn
    // LoadInternal(); i.e. Observe() can't be called before Load().
    WaitForLoad();
    mIsLoaded = false;
    Load(); // load automatically clears out the existing dictionary table
  } else if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
    WaitForSave();
  }

  return NS_OK;
}
NS_IMETHODIMP mozPersonalDictionary::GetWordList(nsIStringEnumerator **aWords)
{
  NS_ENSURE_ARG_POINTER(aWords);
  *aWords = nullptr;

  WaitForLoad();

  nsTArray<nsString> *array = new nsTArray<nsString>();
  nsString* elems = array->AppendElements(mDictionaryTable.Count());
  for (auto iter = mDictionaryTable.Iter(); !iter.Done(); iter.Next()) {
    elems->Assign(iter.Get()->GetKey());
    elems++;
  }

  array->Sort();

  return NS_NewAdoptingStringEnumerator(aWords, array);
}