NS_IMETHODIMP nsAbMDBDirectory::AddMailList(nsIAbDirectory *list, nsIAbDirectory **addedList)
{
  NS_ENSURE_ARG_POINTER(addedList);

  if (mIsQueryURI)
    return NS_ERROR_NOT_IMPLEMENTED;

  nsresult rv = NS_OK;
  if (!mDatabase)
    rv = GetAbDatabase();

  if (NS_FAILED(rv) || !mDatabase)
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIAbMDBDirectory> dblist(do_QueryInterface(list, &rv));
  if (NS_FAILED(rv))
  {
    nsCOMPtr<nsIAbDirectory> newlist(new nsAbMDBDirProperty);
    if (!newlist)
      return NS_ERROR_OUT_OF_MEMORY;

    rv = newlist->CopyMailList(list);
    NS_ENSURE_SUCCESS(rv, rv);

    dblist = do_QueryInterface(newlist, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
    
    mDatabase->CreateMailListAndAddToDB(newlist, true, this);
  }
  else
    mDatabase->CreateMailListAndAddToDB(list, true, this);

  mDatabase->Commit(nsAddrDBCommitType::kLargeCommit);

  uint32_t dbRowID;
  dblist->GetDbRowID(&dbRowID);

  nsAutoCString listUri(mURI);
  listUri.AppendLiteral("/MailList");
  listUri.AppendInt(dbRowID);

  nsCOMPtr<nsIAbDirectory> newList;
  rv = AddDirectory(listUri.get(), getter_AddRefs(newList));
  if (NS_SUCCEEDED(rv) && newList)
  {
    nsCOMPtr<nsIAbMDBDirectory> dbnewList(do_QueryInterface(newList, &rv));
    NS_ENSURE_SUCCESS(rv, rv);

    dbnewList->CopyDBMailList(dblist);
    AddMailListToDirectory(newList);
    NotifyItemAdded(newList);
  }

  NS_IF_ADDREF(*addedList = newList);
  return rv;
}
NS_IMETHODIMP nsAbMDBDirectory::DeleteCards(nsIArray *aCards)
{
  NS_ENSURE_ARG_POINTER(aCards);
  nsresult rv = NS_OK;

  if (mIsQueryURI) {
    // if this is a query, delete the cards from the directory (without the query)
    // before we do the delete, make this directory (which represents the search)
    // a listener on the database, so that it will get notified when the cards are deleted
    // after delete, remove this query as a listener.
    nsCOMPtr<nsIAddrDatabase> database;
    rv = GetDatabase(getter_AddRefs(database));
    NS_ENSURE_SUCCESS(rv,rv);

    rv = database->AddListener(this);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIAbManager> abManager =
        do_GetService(NS_ABMANAGER_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIAbDirectory> directory;
    rv = abManager->GetDirectory(mURINoQuery, getter_AddRefs(directory));
    NS_ENSURE_SUCCESS(rv, rv);

    rv = directory->DeleteCards(aCards);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = database->RemoveListener(this);
    NS_ENSURE_SUCCESS(rv, rv);
    return rv;
  }

  if (!mDatabase)
    rv = GetAbDatabase();

  if (NS_SUCCEEDED(rv) && mDatabase)
  {
    uint32_t cardCount;
    uint32_t i;
    rv = aCards->GetLength(&cardCount);
    NS_ENSURE_SUCCESS(rv, rv);
    for (i = 0; i < cardCount; i++)
    {
      nsCOMPtr<nsIAbCard> card(do_QueryElementAt(aCards, i, &rv));
      NS_ENSURE_SUCCESS(rv, rv);

      if (card)
      {
        uint32_t rowID;
        rv = card->GetPropertyAsUint32("DbRowID", &rowID);
        NS_ENSURE_SUCCESS(rv, rv);

        if (m_IsMailList)
        {
          mDatabase->DeleteCardFromMailList(this, card, true);

          uint32_t cardTotal = 0;
          int32_t i;
          if (m_AddressList)
            rv = m_AddressList->GetLength(&cardTotal);
          for (i = cardTotal - 1; i >= 0; i--)
          {            
            nsCOMPtr<nsIAbCard> arrayCard(do_QueryElementAt(m_AddressList, i, &rv));
            if (arrayCard)
            {
              // No card can have a row ID of 0
              uint32_t arrayRowID = 0;
              arrayCard->GetPropertyAsUint32("DbRowID", &arrayRowID);
              if (rowID == arrayRowID)
                m_AddressList->RemoveElementAt(i);
            }
          }
        }
        else
        {
          mDatabase->DeleteCard(card, true, this);
          bool bIsMailList = false;
          card->GetIsMailList(&bIsMailList);
          if (bIsMailList)
          {
            //to do, get mailing list dir side uri and notify nsIAbManager to remove it
            nsAutoCString listUri(mURI);
            listUri.AppendLiteral("/MailList");
            listUri.AppendInt(rowID);
            if (!listUri.IsEmpty())
            {
              nsresult rv = NS_OK;

              nsCOMPtr<nsIAbManager> abManager =
                  do_GetService(NS_ABMANAGER_CONTRACTID, &rv);
              NS_ENSURE_SUCCESS(rv, rv);

              nsCOMPtr<nsIAbDirectory> listDir;
              rv = abManager->GetDirectory(listUri, getter_AddRefs(listDir));
              NS_ENSURE_SUCCESS(rv, rv);

              uint32_t dirIndex;
              if (m_AddressList && NS_SUCCEEDED(m_AddressList->IndexOf(0, listDir, &dirIndex)))
                m_AddressList->RemoveElementAt(dirIndex);

              mSubDirectories.RemoveObject(listDir);

              if (listDir)
                NotifyItemDeleted(listDir);
            }
          }
          else
          { 
            rv = RemoveCardFromAddressList(card);
            NS_ENSURE_SUCCESS(rv,rv);
          }
        }
      }
    }
    mDatabase->Commit(nsAddrDBCommitType::kLargeCommit);
  }
  return rv;
}
NS_IMETHODIMP nsAbMDBDirectory::DeleteCards(nsIArray *aCards)
{
  nsresult rv = NS_OK;

  if (mIsQueryURI) {
    // if this is a query, delete the cards from the directory (without the query)
    // before we do the delete, make this directory (which represents the search)
    // a listener on the database, so that it will get notified when the cards are deleted
    // after delete, remove this query as a listener.
    nsCOMPtr<nsIAddrDatabase> database;
    rv = GetDatabase(getter_AddRefs(database));
    NS_ENSURE_SUCCESS(rv,rv);

    rv = database->AddListener(this);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIRDFResource> resource;
    rv = gRDFService->GetResource(mURINoQuery, getter_AddRefs(resource));
    NS_ENSURE_SUCCESS(rv, rv);
    
    nsCOMPtr<nsIAbDirectory> directory = do_QueryInterface(resource, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = directory->DeleteCards(aCards);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = database->RemoveListener(this);
    NS_ENSURE_SUCCESS(rv, rv);
    return rv;
  }

  if (!mDatabase)
    rv = GetAbDatabase();

  if (NS_SUCCEEDED(rv) && mDatabase)
  {
    PRUint32 cardCount;
    PRUint32 i;
    rv = aCards->GetLength(&cardCount);
    NS_ENSURE_SUCCESS(rv, rv);
    for (i = 0; i < cardCount; i++)
    {
      nsCOMPtr<nsIAbCard> card(do_QueryElementAt(aCards, i, &rv));
      NS_ENSURE_SUCCESS(rv, rv);

      nsCOMPtr<nsIAbMDBCard> dbcard(do_QueryInterface(card, &rv));
      NS_ENSURE_SUCCESS(rv, rv);

      if (card)
      {
        if (m_IsMailList)
        {
          mDatabase->DeleteCardFromMailList(this, card, PR_TRUE);

          PRUint32 cardTotal = 0;
          PRInt32 i;
          if (m_AddressList)
            rv = m_AddressList->GetLength(&cardTotal);
          for (i = cardTotal - 1; i >= 0; i--)
          {            
            nsCOMPtr<nsIAbMDBCard> dbarrayCard(do_QueryElementAt(m_AddressList, i, &rv));
            if (dbarrayCard)
            {
              PRUint32 tableID, rowID, cardTableID, cardRowID; 
              dbarrayCard->GetDbTableID(&tableID);
              dbarrayCard->GetDbRowID(&rowID);
              dbcard->GetDbTableID(&cardTableID);
              dbcard->GetDbRowID(&cardRowID);
              if (tableID == cardTableID && rowID == cardRowID)
                m_AddressList->RemoveElementAt(i);
            }
          }
        }
        else
        {
          mDatabase->DeleteCard(card, PR_TRUE, this);
          PRBool bIsMailList = PR_FALSE;
          card->GetIsMailList(&bIsMailList);
          if (bIsMailList)
          {
            //to do, get mailing list dir side uri and notify rdf to remove it
            PRUint32 rowID;
            dbcard->GetDbRowID(&rowID);
            nsCAutoString listUri(mURI);
            listUri.AppendLiteral("/MailList");
            listUri.AppendInt(rowID);
            if (!listUri.IsEmpty())
            {
              nsresult rv = NS_OK;
              nsCOMPtr<nsIRDFService> rdfService = 
                       do_GetService("@mozilla.org/rdf/rdf-service;1", &rv);

              if (NS_FAILED(rv))
                return rv;

              nsCOMPtr<nsIRDFResource> listResource;
              rv = rdfService->GetResource(listUri,
                                           getter_AddRefs(listResource));
              nsCOMPtr<nsIAbDirectory> listDir = do_QueryInterface(listResource, &rv);
              if (NS_FAILED(rv))
                return rv;

              PRUint32 dirIndex;
              if (m_AddressList && NS_SUCCEEDED(m_AddressList->IndexOf(0, listDir, &dirIndex)))
                m_AddressList->RemoveElementAt(dirIndex);

              mSubDirectories.RemoveObject(listDir);

              if (listDir)
                NotifyItemDeleted(listDir);
            }
          }
          else
          { 
            rv = RemoveCardFromAddressList(card);
            NS_ENSURE_SUCCESS(rv,rv);
          }
        }
      }
    }
    mDatabase->Commit(nsAddrDBCommitType::kLargeCommit);
  }
  return rv;
}