private void addMember(Member member) {
    // Update the display list
    mListMembersToAdd.add(member);
    mListToDisplay.add(member);
    mMemberListAdapter.notifyDataSetChanged();

    // Update the autocomplete adapter so the contact doesn't get suggested again
    mAutoCompleteAdapter.addNewMember(member.getContactId());
  }
  private void addExistingMembers(List<Member> members) {

    // Re-create the list to display
    mListToDisplay.clear();
    mListToDisplay.addAll(members);
    mListToDisplay.addAll(mListMembersToAdd);
    mListToDisplay.removeAll(mListMembersToRemove);
    mMemberListAdapter.notifyDataSetChanged();

    // Update the autocomplete adapter (if there is one) so these contacts don't get suggested
    if (mAutoCompleteAdapter != null) {
      mAutoCompleteAdapter.updateExistingMembersList(members);
    }
  }
  private void removeMember(Member member) {
    // If the contact was just added during this session, remove it from the list of
    // members to add
    if (mListMembersToAdd.contains(member)) {
      mListMembersToAdd.remove(member);
    } else {
      // Otherwise this contact was already part of the existing list of contacts,
      // so we need to do a content provider deletion operation
      mListMembersToRemove.add(member);
    }
    // In either case, update the UI so the contact is no longer in the list of
    // members
    mListToDisplay.remove(member);
    mMemberListAdapter.notifyDataSetChanged();

    // Update the autocomplete adapter so the contact can get suggested again
    mAutoCompleteAdapter.removeMember(member.getContactId());
  }
  /** Sets up the editor based on the group's account name and type. */
  private void setupEditorForAccount() {
    final AccountType accountType = getAccountType();
    final boolean editable = isGroupMembershipEditable();
    boolean isNewEditor = false;
    mMemberListAdapter.setIsGroupMembershipEditable(editable);

    // Since this method can be called multiple time, remove old editor if the editor type
    // is different from the new one and mark the editor with a tag so it can be found for
    // removal if needed
    View editorView;
    int newGroupEditorId =
        editable ? R.layout.group_editor_view : R.layout.external_group_editor_view;
    if (newGroupEditorId != mLastGroupEditorId) {
      View oldEditorView = mRootView.findViewWithTag(CURRENT_EDITOR_TAG);
      if (oldEditorView != null) {
        mRootView.removeView(oldEditorView);
      }
      editorView = mLayoutInflater.inflate(newGroupEditorId, mRootView, false);
      editorView.setTag(CURRENT_EDITOR_TAG);
      mAutoCompleteAdapter = null;
      mLastGroupEditorId = newGroupEditorId;
      isNewEditor = true;
    } else {
      editorView = mRootView.findViewWithTag(CURRENT_EDITOR_TAG);
      if (editorView == null) {
        throw new IllegalStateException("Group editor view not found");
      }
    }

    mGroupNameView = (TextView) editorView.findViewById(R.id.group_name);
    mAutoCompleteTextView = (AutoCompleteTextView) editorView.findViewById(R.id.add_member_field);

    mListView = (ListView) editorView.findViewById(android.R.id.list);
    mListView.setAdapter(mMemberListAdapter);

    // Setup the account header, only when exists.
    if (editorView.findViewById(R.id.account_header) != null) {
      CharSequence accountTypeDisplayLabel = accountType.getDisplayLabel(mContext);
      ImageView accountIcon = (ImageView) editorView.findViewById(R.id.account_icon);
      TextView accountTypeTextView = (TextView) editorView.findViewById(R.id.account_type);
      TextView accountNameTextView = (TextView) editorView.findViewById(R.id.account_name);
      if (!TextUtils.isEmpty(mAccountName)) {
        accountNameTextView.setText(mContext.getString(R.string.from_account_format, mAccountName));
      }
      accountTypeTextView.setText(accountTypeDisplayLabel);
      accountIcon.setImageDrawable(accountType.getDisplayIcon(mContext));
    }

    // Setup the autocomplete adapter (for contacts to suggest to add to the group) based on the
    // account name and type. For groups that cannot have membership edited, there will be no
    // autocomplete text view.
    if (mAutoCompleteTextView != null) {
      mAutoCompleteAdapter =
          new SuggestedMemberListAdapter(mContext, android.R.layout.simple_dropdown_item_1line);
      mAutoCompleteAdapter.setContentResolver(mContentResolver);
      mAutoCompleteAdapter.setAccountType(mAccountType);
      mAutoCompleteAdapter.setAccountName(mAccountName);
      mAutoCompleteAdapter.setDataSet(mDataSet);
      mAutoCompleteTextView.setAdapter(mAutoCompleteAdapter);
      mAutoCompleteTextView.setOnItemClickListener(
          new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
              SuggestedMember member = (SuggestedMember) view.getTag();
              if (member == null) {
                return; // just in case
              }
              loadMemberToAddToGroup(
                  member.getRawContactId(), String.valueOf(member.getContactId()));

              // Update the autocomplete adapter so the contact doesn't get suggested again
              mAutoCompleteAdapter.addNewMember(member.getContactId());

              // Clear out the text field
              mAutoCompleteTextView.setText("");
            }
          });
      // Update the exempt list.  (mListToDisplay might have been restored from the saved
      // state.)
      mAutoCompleteAdapter.updateExistingMembersList(mListToDisplay);
    }

    // If the group name is ready only, don't let the user focus on the field.
    mGroupNameView.setFocusable(!mGroupNameIsReadOnly);
    if (isNewEditor) {
      mRootView.addView(editorView);
    }
    mStatus = Status.EDITING;
  }