void updateListNameInDataBase(ContactList list) {
    ContactListAdapter listAdapter = getContactListAdapter(list.getAddress());

    Uri uri = ContentUris.withAppendedId(Imps.ContactList.CONTENT_URI, listAdapter.getDataBaseId());
    ContentValues values = new ContentValues(1);
    values.put(Imps.ContactList.NAME, list.getName());

    mResolver.update(uri, values, null, null);
  }
  void deleteContactFromDataBase(Contact contact, ContactList list) {
    String selection = Imps.Contacts.USERNAME + "=? AND " + Imps.Contacts.CONTACTLIST + "=?";
    long listId = getContactListAdapter(list.getAddress()).getDataBaseId();
    String username = contact.getAddress().getFullName();
    String[] selectionArgs = {username, Long.toString(listId)};

    mResolver.delete(mContactUrl, selection, selectionArgs);

    // clear the history message if the contact doesn't exist in any list
    // anymore.
    if (mAdaptee.getContact(contact.getAddress()) == null) {
      clearHistoryMessages(username);
    }
  }
  void addContactListContent(ContactList list) {
    String selection =
        Imps.ContactList.NAME
            + "=? AND "
            + Imps.ContactList.PROVIDER
            + "=? AND "
            + Imps.ContactList.ACCOUNT
            + "=?";
    String[] selectionArgs = {
      list.getName(), Long.toString(mProviderId), Long.toString(mAccountId)
    };
    Cursor cursor =
        mResolver.query(
            Imps.ContactList.CONTENT_URI,
            CONTACT_LIST_ID_PROJECTION,
            selection,
            selectionArgs,
            null); // no sort order
    long listId = 0;
    Uri uri = null;
    try {
      if (cursor.moveToFirst()) {
        listId = cursor.getLong(0);
        uri = ContentUris.withAppendedId(Imps.ContactList.CONTENT_URI, listId);
        // Log.d(TAG,"Found and removing ContactList with name "+list.getName());
      }
    } finally {
      cursor.close();
    }
    if (uri != null) {
      // remove existing ContactList and Contacts of that list for replacement by the newly
      // downloaded list
      mResolver.delete(
          mContactUrl, Imps.Contacts.CONTACTLIST + "=?", new String[] {Long.toString(listId)});
      mResolver.delete(uri, selection, selectionArgs);
    }

    ContentValues contactListValues = new ContentValues(3);
    contactListValues.put(Imps.ContactList.NAME, list.getName());
    contactListValues.put(Imps.ContactList.PROVIDER, mProviderId);
    contactListValues.put(Imps.ContactList.ACCOUNT, mAccountId);

    // Log.d(TAG, "Adding ContactList name="+list.getName());
    mValidatedContactLists.add(list.getName());
    uri = mResolver.insert(Imps.ContactList.CONTENT_URI, contactListValues);
    listId = ContentUris.parseId(uri);

    synchronized (mContactLists) {
      mContactLists.put(list.getAddress(), new ContactListAdapter(list, listId));
    }

    Collection<Contact> contacts = list.getContacts();
    if (contacts == null || contacts.size() == 0) {
      return;
    }

    Iterator<Contact> iter = contacts.iterator();
    while (iter.hasNext()) {
      Contact c = iter.next();
      String address = c.getAddress().getFullName();
      if (isTemporary(address)) {
        moveTemporaryContactToList(address, listId);
        iter.remove();
      }
      mValidatedContacts.add(address);
    }

    ArrayList<String> usernames = new ArrayList<String>();
    ArrayList<String> nicknames = new ArrayList<String>();
    ArrayList<String> contactTypeArray = new ArrayList<String>();
    for (Contact c : contacts) {
      String username = c.getAddress().getFullName();
      String nickname = c.getName();
      int type = Imps.Contacts.TYPE_NORMAL;
      if (isTemporary(username)) {
        type = Imps.Contacts.TYPE_TEMPORARY;
      }
      if (isBlocked(username)) {
        type = Imps.Contacts.TYPE_BLOCKED;
      }

      usernames.add(username);
      nicknames.add(nickname);
      contactTypeArray.add(String.valueOf(type));
    }
    ContentValues values = new ContentValues(6);

    values.put(Imps.Contacts.PROVIDER, mProviderId);
    values.put(Imps.Contacts.ACCOUNT, mAccountId);
    values.put(Imps.Contacts.CONTACTLIST, listId);
    putStringArrayList(values, Imps.Contacts.USERNAME, usernames);
    putStringArrayList(values, Imps.Contacts.NICKNAME, nicknames);
    putStringArrayList(values, Imps.Contacts.TYPE, contactTypeArray);

    mResolver.insert(Imps.Contacts.BULK_CONTENT_URI, values);
  }
    public void onContactChange(final int type, final ContactList list, final Contact contact) {
      ContactListAdapter removed = null;
      String notificationText = null;

      switch (type) {
        case LIST_LOADED:
        case LIST_CREATED:
          addContactListContent(list);
          break;

        case LIST_DELETED:
          removed = removeContactListFromDataBase(list.getName());
          // handle case where a list is deleted before mAllContactsLoaded
          if (!mAllContactsLoaded) {
            // if a cached contact list is deleted before the actual contact list is
            // downloaded from the server, we will have to remove the list again once
            // once mAllContactsLoaded is true
            if (!mValidatedContactLists.contains(list.getName())) {
              mDelayedContactChanges.add(new StoredContactChange(type, list, contact));
            }
          }
          break;

        case LIST_CONTACT_ADDED:
          long listId = getContactListAdapter(list.getAddress()).getDataBaseId();
          String contactAddress = contact.getAddress().getFullName();
          if (isTemporary(contactAddress)) {
            moveTemporaryContactToList(contactAddress, listId);
          } else {
            insertContactContent(contact, listId);
          }
          notificationText =
              mContext.getResources().getString(R.string.add_contact_success, contact.getName());
          // handle case where a contact is added before mAllContactsLoaded
          if (!mAllContactsLoaded) {
            // if a contact is added to a cached contact list before the actual contact
            // list is downloaded from the server, we will have to add the contact to
            // the contact list once mAllContactsLoaded is true
            if (!mValidatedContactLists.contains(list.getName())) {
              mDelayedContactChanges.add(new StoredContactChange(type, list, contact));
            }
          }
          break;

        case LIST_CONTACT_REMOVED:
          deleteContactFromDataBase(contact, list);
          // handle case where a contact is removed before mAllContactsLoaded
          if (!mAllContactsLoaded) {
            // if a contact is added to a cached contact list before the actual contact
            // list is downloaded from the server, we will have to add the contact to
            // the contact list once mAllContactsLoaded is true
            if (!mValidatedContactLists.contains(list.getName())) {
              mDelayedContactChanges.add(new StoredContactChange(type, list, contact));
            }
          }

          // Clear ChatSession if any.
          String address = contact.getAddress().getFullName();
          closeChatSession(address);

          notificationText =
              mContext.getResources().getString(R.string.delete_contact_success, contact.getName());
          break;

        case LIST_RENAMED:
          updateListNameInDataBase(list);
          // handle case where a list is renamed before mAllContactsLoaded
          if (!mAllContactsLoaded) {
            // if a contact list name is updated before the actual contact list is
            // downloaded from the server, we will have to update the list name again
            // once mAllContactsLoaded is true
            if (!mValidatedContactLists.contains(list.getName())) {
              mDelayedContactChanges.add(new StoredContactChange(type, list, contact));
            }
          }
          break;

        case CONTACT_BLOCKED:
          insertBlockedContactToDataBase(contact);
          address = contact.getAddress().getFullName();
          updateContactType(address, Imps.Contacts.TYPE_BLOCKED);
          closeChatSession(address);
          notificationText =
              mContext.getResources().getString(R.string.block_contact_success, contact.getName());
          break;

        case CONTACT_UNBLOCKED:
          removeBlockedContactFromDataBase(contact);
          notificationText =
              mContext
                  .getResources()
                  .getString(R.string.unblock_contact_success, contact.getName());
          // handle case where a contact is unblocked before mAllContactsLoaded
          if (!mAllContactsLoaded) {
            // if a contact list name is updated before the actual contact list is
            // downloaded from the server, we will have to update the list name again
            // once mAllContactsLoaded is true
            if (!mValidatedBlockedContacts.contains(contact.getName())) {
              mDelayedContactChanges.add(new StoredContactChange(type, list, contact));
            }
          }
          break;

        default:
          Log.e(TAG, "Unknown list update event!");
          break;
      }

      final ContactListAdapter listAdapter;
      if (type == LIST_DELETED) {
        listAdapter = removed;
      } else {
        listAdapter = (list == null) ? null : getContactListAdapter(list.getAddress());
      }
      final int N = mRemoteContactListeners.beginBroadcast();
      for (int i = 0; i < N; i++) {
        IContactListListener listener = mRemoteContactListeners.getBroadcastItem(i);
        try {
          listener.onContactChange(type, listAdapter, contact);
        } catch (RemoteException e) {
          // The RemoteCallbackList will take care of removing the
          // dead listeners.
        }
      }
      mRemoteContactListeners.finishBroadcast();

      if (mAllContactsLoaded && notificationText != null) {
        mContext.showToast(notificationText, Toast.LENGTH_SHORT);
      }
    }