NS_IMETHODIMP GnomeKeyring::SetLoginSavingEnabled(const nsAString & aHost,
                                                  bool isEnabled)
{
  GnomeKeyringResult result;

  if (isEnabled) {
    AutoFoundList foundList;
    result = findHostItems(aHost, &foundList);
    MGK_GK_CHECKF_NS(result);

    return deleteFoundItems(foundList, PR_TRUE);
  }

  // TODO should check if host is already enabled

  AutoAttributeList attributes;
  newDisabledHostsAttributes(&attributes);
  addAttribute(attributes, kDisabledHostAttrName, aHost);

  // TODO name should be more explicit
  const char* name = "Mozilla disabled host entry";
  guint itemId;

  result = gnome_keyring_item_create_sync(keyringName.get(),
            GNOME_KEYRING_ITEM_NOTE,
            name,
            attributes,
            "", // no secret
            TRUE,
            &itemId);

  MGK_GK_CHECK_NS(result);
  return NS_OK;
}
NS_IMETHODIMP GnomeKeyring::RemoveLogin(nsILoginInfo *aLogin)
{
  AutoAttributeList attributes;
  newLoginInfoAttributes(&attributes);
  appendAttributesFromLogin(aLogin, attributes);

  AutoFoundList foundList;
  GnomeKeyringResult result = findLoginItems(attributes, &foundList);
  MGK_GK_CHECK_NS(result);

  return deleteFoundItems(foundList, PR_TRUE);
}
NS_IMETHODIMP GnomeKeyring::AddLogin(nsILoginInfo *aLogin)
{
  AutoAttributeList attributes;
  newLoginInfoAttributes(&attributes);
  appendAttributesFromLogin(aLogin, attributes);

  nsAutoString password, hostname;
  aLogin->GetPassword(password);
  aLogin->GetHostname(hostname);
  guint itemId;

  GnomeKeyringResult result = gnome_keyring_item_create_sync(keyringName.get(),
                                        GNOME_KEYRING_ITEM_GENERIC_SECRET,
                                        NS_ConvertUTF16toUTF8(hostname).get(),
                                        attributes,
                                        NS_ConvertUTF16toUTF8(password).get(),
                                        TRUE,
                                        &itemId);
  MGK_GK_CHECK_NS(result);

  return NS_OK;
}
nsresult
GnomeKeyring::deleteFoundItems(GList* foundList,
                               bool aExpectOnlyOne = PR_FALSE)
{
  if (foundList == NULL) {
    GK_LOG(("Found not items to delete"));
    return NS_OK;
  }

  bool deleted = PR_FALSE;
  for (GList* l = foundList; l != NULL; l = l->next, deleted = PR_TRUE)
  {
    if (aExpectOnlyOne && deleted)
      NS_WARNING("Expected only one item to delete, but found more");

    GnomeKeyringFound* found = static_cast<GnomeKeyringFound*>(l->data);
    GK_LOG(("Found item with id %i\n", found->item_id));

    GnomeKeyringResult result = gnome_keyring_item_delete_sync(found->keyring,
                                                               found->item_id);
    MGK_GK_CHECK_NS(result);
  }
  return NS_OK;
}
NS_IMETHODIMP GnomeKeyring::ModifyLogin(nsILoginInfo *oldLogin,
                                        nsISupports *modLogin)
{
  nsresult interfaceok;

  /* If the second argument is an nsILoginInfo,
   * just remove the old login and add the new one */
  nsCOMPtr<nsILoginInfo> newLogin( do_QueryInterface(modLogin, &interfaceok) );
  if (interfaceok == NS_OK) {
    nsresult rvremovelogin = RemoveLogin(oldLogin);
    nsresult rvaddlogin = AddLogin(newLogin);
    if(NS_FAILED(rvremovelogin)) {
        return rvremovelogin;
    } else {
        return rvaddlogin;
    }
  }

  /* Otherwise, it has to be an nsIPropertyBag.
   * Let's get the attributes from the old login, then append the ones
   * fetched from the property bag. Gracefully, if an attribute appears
   * twice in an attribut list, the last value is stored. */
  nsCOMPtr<nsIPropertyBag> matchData( do_QueryInterface(modLogin, &interfaceok) );
  if (interfaceok != NS_OK) {
    return interfaceok;
  }

  GnomeKeyringResult result;

  AutoAttributeList attributes;
  newLoginInfoAttributes(&attributes);
  appendAttributesFromLogin(oldLogin, attributes);

  // We need the id of the keyring item to set its attributes.
  AutoFoundList foundList;
  result = findLoginItems(attributes, &foundList);
  MGK_GK_CHECK_NS(result);
  PRUint32 i = 0, id;
  for (GList* l = foundList; l != NULL; l = l->next, i++)
  {
    GnomeKeyringFound* found = static_cast<GnomeKeyringFound*>(l->data);
    id = found->item_id;
    if (i >= 1) {
      NS_ERROR("found more than one item to edit");
      return NS_ERROR_FAILURE;
    }
  }

  // set new attributes
  appendAttributesFromBag(matchData.get(), attributes);
  result = gnome_keyring_item_set_attributes_sync(keyringName.get(),
                                                  id,
                                                  attributes);
  MGK_GK_CHECK_NS(result);

  // set new iteminfo, e.g. password
  AutoItemInfo itemInfo;
  result = gnome_keyring_item_get_info_sync(keyringName.get(),
                                            id,
                                            &itemInfo);
  MGK_GK_CHECK_NS(result);
  appendItemInfoFromBag(matchData.get(), itemInfo);
  result = gnome_keyring_item_set_info_sync(keyringName.get(),
                                            id,
                                            itemInfo);
  MGK_GK_CHECK_NS(result);

  return NS_OK;
}