Address various groups TODOs and small bug fixes

* Style the group name edit dialog with standard min
  width style.  Also restrict names to be a single
  line and add a hint to the EditText.  Finally,
  bring up the keyboard when the dialog is first created.
* Change the "edit" group menu option name to "rename",
  remove the icon, and keep it under the overflow.
* Sort groups consistently on the main list and contact
  editor spinnner.
* Don't load deleted groups. We don't need to  handle
  deleted groups in the members loader because the metadata
  loader omits them in the selection clause.
* Show a toast after deleting a group.  Also don't prompt
  for confirmation when deleting if the group is empty.
* Remove some unnecessary header binding in the group member
  list adapter.

Bug 28955365
Bug 28936603
Bug 18641067

Change-Id: Icec1e1d3bbafb7e1e94a7e841860836d256177f1
diff --git a/res/layout/group_name_edit_dialog.xml b/res/layout/group_name_edit_dialog.xml
index 2858388..34af7ca 100644
--- a/res/layout/group_name_edit_dialog.xml
+++ b/res/layout/group_name_edit_dialog.xml
@@ -30,6 +30,8 @@
         android:layout_marginLeft="4dp"
         android:layout_marginRight="4dp"
         android:layout_marginTop="16dp"
+        android:hint="@string/group_name_dialog_hint"
         android:inputType="textCapWords|textNoSuggestions"
+        android:singleLine="true"
         android:maxLength="40"/>
 </LinearLayout>
\ No newline at end of file
diff --git a/res/menu/view_group.xml b/res/menu/view_group.xml
index a937598..cf945fd 100644
--- a/res/menu/view_group.xml
+++ b/res/menu/view_group.xml
@@ -24,10 +24,8 @@
         contacts:showAsAction="ifRoom" />
 
     <item
-        android:id="@+id/menu_edit_group"
-        android:icon="@drawable/ic_create_24dp"
-        android:title="@string/menu_editGroup"
-        contacts:showAsAction="ifRoom" />
+        android:id="@+id/menu_rename_group"
+        android:title="@string/menu_renameGroup"/>
 
     <item
         android:id="@+id/menu_delete_group"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8e7fdfd..7f71b9c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -134,6 +134,9 @@
     <!-- Menu item that edits the currently selected label [CHAR LIMIT=30] -->
     <string name="menu_editGroup">Edit</string>
 
+    <!-- Menu item to rename the currently selected label [CHAR LIMIT=30] -->
+    <string name="menu_renameGroup">Rename label</string>
+
     <!-- Menu item that deletes the currently selected label [CHAR LIMIT=30] -->
     <string name="menu_deleteGroup">Delete label</string>
 
@@ -326,6 +329,9 @@
     <!-- Toast displayed when a label is saved [CHAR LIMIT=30] -->
     <string name="groupSavedToast">Label saved</string>
 
+    <!-- Toast displayed when a label name is delted. [CHAR LIMIT=50] -->
+    <string name="groupDeletedToast">Label deleted</string>
+
     <!-- Toast displayed when a label name is updated. [CHAR LIMIT=50] -->
     <string name="groupCreatedToast">Label created</string>
 
@@ -429,10 +435,13 @@
     <string name="dialog_new_group_account">Choose account</string>
 
     <!-- Title for the create new label dialog. CHAR LIMIT=40] -->
-    <string name="insert_group_dialog_title">Create label</string>
+    <string name="group_name_dialog_insert_title">Create label</string>
 
     <!-- Title for the update label dialog. CHAR LIMIT=40] -->
-    <string name="update_group_dialog_title">Update label</string>
+    <string name="group_name_dialog_update_title">Rename label</string>
+
+    <!-- Hint for the label name input field on the insert and update label dialogs [CHAR LIMIT=30] -->
+    <string name="group_name_dialog_hint">Label name</string>
 
     <!-- Generic action string for starting an audio chat. Used by AccessibilityService to announce the purpose of the view. [CHAR LIMIT=NONE] -->
     <string name="audio_chat">Voice chat</string>
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index 08eb1c7..b9fc949 100755
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -46,6 +46,7 @@
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.RawContactsEntity;
 import android.support.v4.os.ResultReceiver;
+import android.text.TextUtils;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -777,10 +778,19 @@
     /**
      * Creates an intent that can be sent to this service to delete a group.
      */
-    public static Intent createGroupDeletionIntent(Context context, long groupId) {
+    public static Intent createGroupDeletionIntent(Context context, long groupId,
+            Class<? extends Activity> callbackActivity, String callbackAction) {
         Intent serviceIntent = new Intent(context, ContactSaveService.class);
         serviceIntent.setAction(ContactSaveService.ACTION_DELETE_GROUP);
         serviceIntent.putExtra(ContactSaveService.EXTRA_GROUP_ID, groupId);
+
+        // Callback intent will be invoked by the service once the group is updated
+        if (callbackActivity != null && !TextUtils.isEmpty(callbackAction)) {
+            final Intent callbackIntent = new Intent(context, callbackActivity);
+            callbackIntent.setAction(callbackAction);
+            serviceIntent.putExtra(ContactSaveService.EXTRA_CALLBACK_INTENT, callbackIntent);
+        }
+
         return serviceIntent;
     }
 
@@ -793,6 +803,13 @@
 
         getContentResolver().delete(
                 ContentUris.withAppendedId(Groups.CONTENT_URI, groupId), null, null);
+
+        final Intent callbackIntent = intent.getParcelableExtra(EXTRA_CALLBACK_INTENT);
+        if (callbackIntent != null) {
+            final Uri groupUri = ContentUris.withAppendedId(Groups.CONTENT_URI, groupId);
+            callbackIntent.setData(groupUri);
+            deliverCallback(callbackIntent);
+        }
     }
 
     /**
diff --git a/src/com/android/contacts/GroupListLoader.java b/src/com/android/contacts/GroupListLoader.java
index d43f561..fbb68db 100644
--- a/src/com/android/contacts/GroupListLoader.java
+++ b/src/com/android/contacts/GroupListLoader.java
@@ -28,6 +28,11 @@
  */
 public final class GroupListLoader extends CursorLoader {
 
+    public final static String DEFAULT_SELECTION =
+            Groups.ACCOUNT_TYPE + " NOT NULL AND " +
+                    Groups.ACCOUNT_NAME + " NOT NULL AND " + Groups.AUTO_ADD + "=0 AND " +
+                    Groups.FAVORITES + "=0 AND " + Groups.DELETED + "=0";
+
     private final static String[] COLUMNS = new String[] {
         Groups.ACCOUNT_NAME,
         Groups.ACCOUNT_TYPE,
@@ -50,11 +55,9 @@
         super(context,
                 GROUP_LIST_URI,
                 COLUMNS,
-                Groups.ACCOUNT_TYPE + " NOT NULL AND " +
-                        Groups.ACCOUNT_NAME + " NOT NULL AND " + Groups.AUTO_ADD + "=0 AND " +
-                        Groups.FAVORITES + "=0 AND " + Groups.DELETED + "=0",
+                DEFAULT_SELECTION,
                 null,
                 Groups.ACCOUNT_TYPE + ", " + Groups.ACCOUNT_NAME + ", " + Groups.DATA_SET + ", " +
-                Groups.TITLE + " COLLATE LOCALIZED ASC");
+                Groups.TITLE + " COLLATE NOCASE ASC");
     }
 }
diff --git a/src/com/android/contacts/GroupMetaDataLoader.java b/src/com/android/contacts/GroupMetaDataLoader.java
index 9bfcd42..ad9b0f9 100644
--- a/src/com/android/contacts/GroupMetaDataLoader.java
+++ b/src/com/android/contacts/GroupMetaDataLoader.java
@@ -49,8 +49,10 @@
     public final static int DELETED = 8;
 
     public GroupMetaDataLoader(Context context, Uri groupUri) {
-        super(context, ensureIsGroupUri(groupUri), COLUMNS, Groups.ACCOUNT_TYPE + " NOT NULL AND "
-                + Groups.ACCOUNT_NAME + " NOT NULL", null, Groups.TITLE + " COLLATE NOCASE");
+        super(context, ensureIsGroupUri(groupUri), COLUMNS,
+                Groups.ACCOUNT_TYPE + " NOT NULL AND " + Groups.ACCOUNT_NAME + " NOT NULL AND "
+                        + Groups.DELETED + "=0",
+                null, Groups.TITLE + " COLLATE NOCASE ASC");
     }
 
     /**
diff --git a/src/com/android/contacts/activities/GroupEditorActivity.java b/src/com/android/contacts/activities/GroupEditorActivity.java
index e316902..58c593e 100644
--- a/src/com/android/contacts/activities/GroupEditorActivity.java
+++ b/src/com/android/contacts/activities/GroupEditorActivity.java
@@ -31,7 +31,7 @@
 import com.android.contacts.quickcontact.QuickContactActivity;
 import com.android.contacts.util.DialogManager;
 
-// TODO(wjang): it longer works. will be deleted shortly
+// TODO(wjang): it no longer works. will be deleted shortly
 public class GroupEditorActivity extends ContactsActivity
         implements DialogManager.DialogShowingViewActivity {
 
diff --git a/src/com/android/contacts/activities/GroupMembersActivity.java b/src/com/android/contacts/activities/GroupMembersActivity.java
index 9b9e8b0..c8d2c19 100644
--- a/src/com/android/contacts/activities/GroupMembersActivity.java
+++ b/src/com/android/contacts/activities/GroupMembersActivity.java
@@ -65,7 +65,6 @@
 /**
  * Displays the members of a group and allows the user to edit it.
  */
-// TODO(wjang): rename it to GroupActivity since it does both display and edit now.
 public class GroupMembersActivity extends AppCompatContactsActivity implements
         ActionBarAdapter.Listener,
         MultiSelectContactsListFragment.OnCheckBoxListActionListener,
@@ -85,6 +84,7 @@
 
     private static final int LOADER_GROUP_MEMBERS = 0;
 
+    private static final String ACTION_DELETE_GROUP = "deleteGroup";
     private static final String ACTION_CREATE_GROUP = "createGroup";
     private static final String ACTION_UPDATE_GROUP = "updateGroup";
     private static final String ACTION_ADD_TO_GROUP = "addToGroup";
@@ -241,7 +241,11 @@
     protected void onNewIntent(Intent newIntent) {
         super.onNewIntent(newIntent);
 
-        if (isSaveAction(newIntent.getAction())) {
+        if (isDeleteAction(newIntent.getAction())) {
+            Toast.makeText(this, R.string.groupDeletedToast, Toast.LENGTH_SHORT).show();
+            setResult(RESULT_OK);
+            finish();
+        } else if (isSaveAction(newIntent.getAction())) {
             final Uri groupUri = newIntent.getData();
             if (groupUri == null) {
                 Toast.makeText(this, R.string.groupSavedErrorToast, Toast.LENGTH_SHORT).show();
@@ -269,6 +273,10 @@
         }
     }
 
+    private static boolean isDeleteAction(String action) {
+        return ACTION_DELETE_GROUP.equals(action);
+    }
+
     private static boolean isSaveAction(String action) {
         return ACTION_CREATE_GROUP.equals(action)
                 || ACTION_UPDATE_GROUP.equals(action)
@@ -306,7 +314,7 @@
         setVisible(menu, R.id.menu_add,
                 isGroupEditable &&!isSelectionMode && !isSearchMode);
 
-        setVisible(menu, R.id.menu_edit_group,
+        setVisible(menu, R.id.menu_rename_group,
                 isGroupEditable && !isSelectionMode && !isSearchMode);
 
         setVisible(menu, R.id.menu_delete_group,
@@ -338,27 +346,20 @@
                 }
                 return true;
             }
-            case R.id.menu_edit_group: {
+            case R.id.menu_rename_group: {
                 GroupNameEditDialogFragment.showUpdateDialog(
                         getFragmentManager(), TAG_GROUP_NAME_EDIT_DIALOG, mGroupMetadata.groupName);
                 return true;
             }
             case R.id.menu_delete_group: {
-                // TODO(wjang): add a Toast after deletion after deleting the editor fragment
-                GroupDeletionDialogFragment.show(getFragmentManager(), mGroupMetadata.groupId,
-                        mGroupMetadata.groupName, /* endActivity */ true);
+                deleteGroup();
                 return true;
             }
             case R.id.menu_remove_from_group: {
                 if (mMembersListFragment == null) {
                     return false;
                 }
-                final int count = mMembersListFragment.getAdapter().getCount();
-                final int numSelected =
-                        mMembersListFragment.getAdapter().getSelectedContactIdsArray().length;
-                Logger.logListEvent(ListEvent.ActionType.REMOVE_LABEL,
-                        mMembersListFragment.getListType(), count, /* clickedIndex */ -1,
-                        numSelected);
+                logListEvent();
                 removeSelectedContacts();
                 return true;
             }
@@ -366,13 +367,35 @@
         return super.onOptionsItemSelected(item);
     }
 
+    private void deleteGroup() {
+        if (mGroupMetadata.memberCount == 0) {
+            final Intent intent = ContactSaveService.createGroupDeletionIntent(
+                    this, mGroupMetadata.groupId,
+                    GroupMembersActivity.class, ACTION_DELETE_GROUP);
+            startService(intent);
+        } else {
+            GroupDeletionDialogFragment.show(getFragmentManager(), mGroupMetadata.groupId,
+                    mGroupMetadata.groupName, /* endActivity */ false, ACTION_DELETE_GROUP);
+        }
+    }
+
+    // TODO(wjang): replace this with group events
+    private void logListEvent() {
+        Logger.logListEvent(
+                ListEvent.ActionType.REMOVE_LABEL,
+                mMembersListFragment.getListType(),
+                mMembersListFragment.getAdapter().getCount(),
+                /* clickedIndex */ -1,
+                mMembersListFragment.getAdapter().getSelectedContactIdsArray().length);
+    }
+
     private void removeSelectedContacts() {
         final long[] rawContactsToRemove =
                 mMembersListFragment.getAdapter().getSelectedContactIdsArray();
         final Intent intent = ContactSaveService.createGroupUpdateIntent(
                 this, mGroupMetadata.groupId, /* groupName */ null,
                 /* rawContactsToAdd */ null, rawContactsToRemove, getClass(),
-                GroupMembersActivity.ACTION_REMOVE_FROM_GROUP);
+                ACTION_REMOVE_FROM_GROUP);
         startService(intent);
 
         mActionBarAdapter.setSelectionMode(false);
@@ -498,11 +521,11 @@
             saveIntent = ContactSaveService.createNewGroupIntent(this,
                     mGroupMetadata.createAccountWithDataSet(), groupName,
                     /* rawContactsToAdd */ null, GroupMembersActivity.class,
-                    GroupMembersActivity.ACTION_CREATE_GROUP);
+                    ACTION_CREATE_GROUP);
         } else {
             saveIntent = ContactSaveService.createGroupRenameIntent(this,
                     mGroupMetadata.groupId, groupName, GroupMembersActivity.class,
-                    GroupMembersActivity.ACTION_UPDATE_GROUP);
+                    ACTION_UPDATE_GROUP);
         }
         startService(saveIntent);
     }
@@ -548,7 +571,7 @@
                 final Intent intent = ContactSaveService.createGroupUpdateIntent(
                         GroupMembersActivity.this, mGroupMetadata.groupId, /* newLabel */ null,
                         rawContactIdsToAdd, /* rawContactIdsToRemove */ null,
-                        GroupMembersActivity.class, GroupMembersActivity.ACTION_ADD_TO_GROUP);
+                        GroupMembersActivity.class, ACTION_ADD_TO_GROUP);
                 startService(intent);
 
                 // Update the autocomplete adapter so the contact doesn't get suggested again
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 2b96f5a..2a5f8fb 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -928,7 +928,8 @@
                 final String title = groupListItem.getTitle();
                 final MenuItem menuItem =
                         subMenu.add(R.id.nav_groups_items, Menu.NONE, Menu.NONE, title);
-                menuItem.setIntent(GroupUtil.createViewGroupIntent(this, groupListItem.getGroupId()));
+                menuItem.setIntent(GroupUtil.createViewGroupIntent(
+                        this, groupListItem.getGroupId()));
                 menuItem.setIcon(R.drawable.ic_menu_label);
             }
         }
diff --git a/src/com/android/contacts/group/GroupBrowseListAdapter.java b/src/com/android/contacts/group/GroupBrowseListAdapter.java
index 71b235c..5fa8770 100644
--- a/src/com/android/contacts/group/GroupBrowseListAdapter.java
+++ b/src/com/android/contacts/group/GroupBrowseListAdapter.java
@@ -61,7 +61,7 @@
         if (mSelectedGroupUri == null && cursor != null && cursor.getCount() > 0) {
             GroupListItem firstItem = getItem(0);
             long groupId = (firstItem == null) ? 0 : firstItem.getGroupId();
-            mSelectedGroupUri = GroupUtil.getGroupUriFromId(groupId);
+            mSelectedGroupUri = ContentUris.withAppendedId(Groups.CONTENT_URI, groupId);
         }
 
         notifyDataSetChanged();
@@ -76,7 +76,7 @@
         mCursor.moveToPosition(-1);
         while (mCursor.moveToNext()) {
             long groupId = mCursor.getLong(GroupListLoader.GROUP_ID);
-            Uri uri = GroupUtil.getGroupUriFromId(groupId);
+            final Uri uri = ContentUris.withAppendedId(Groups.CONTENT_URI, groupId);
             if (mSelectedGroupUri.equals(uri)) {
                   return index;
             }
@@ -152,7 +152,7 @@
         }
 
         // Bind the group data
-        Uri groupUri = GroupUtil.getGroupUriFromId(entry.getGroupId());
+        final Uri groupUri = ContentUris.withAppendedId(Groups.CONTENT_URI, entry.getGroupId());
         String memberCountString = mContext.getResources().getQuantityString(
                 R.plurals.group_list_num_contacts_in_group, entry.getMemberCount(),
                 entry.getMemberCount());
diff --git a/src/com/android/contacts/group/GroupDetailFragment.java b/src/com/android/contacts/group/GroupDetailFragment.java
index c9cf6bd..b75b82e 100644
--- a/src/com/android/contacts/group/GroupDetailFragment.java
+++ b/src/com/android/contacts/group/GroupDetailFragment.java
@@ -449,7 +449,7 @@
         mOptionsMenuGroupDeletable = isGroupDeletable() && isVisible();
         mOptionsMenuGroupEditable = isGroupEditableAndPresent() && isVisible();
 
-        final MenuItem editMenu = menu.findItem(R.id.menu_edit_group);
+        final MenuItem editMenu = menu.findItem(R.id.menu_rename_group);
         editMenu.setVisible(mOptionsMenuGroupEditable);
 
         final MenuItem deleteMenu = menu.findItem(R.id.menu_delete_group);
@@ -459,7 +459,7 @@
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
-            case R.id.menu_edit_group: {
+            case R.id.menu_rename_group: {
                 if (mListener != null) mListener.onEditRequested(mGroupUri);
                 break;
             }
diff --git a/src/com/android/contacts/group/GroupMembersListAdapter.java b/src/com/android/contacts/group/GroupMembersListAdapter.java
index 167c014..fe692e7 100644
--- a/src/com/android/contacts/group/GroupMembersListAdapter.java
+++ b/src/com/android/contacts/group/GroupMembersListAdapter.java
@@ -72,7 +72,6 @@
     public GroupMembersListAdapter(Context context) {
         super(context, GroupMembersQuery.RAW_CONTACT_ID);
         mUnknownNameText = context.getText(android.R.string.unknownName);
-        setIndexedPartition(0);
     }
 
     /** Sets the ID of the group whose members will be displayed. */
@@ -133,7 +132,6 @@
                 super.newView(context, partition, cursor, position, parent);
         view.setUnknownNameText(mUnknownNameText);
         view.setQuickContactEnabled(isQuickContactEnabled());
-        view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled());
         return view;
     }
 
@@ -141,22 +139,11 @@
     protected void bindView(View v, int partition, Cursor cursor, int position) {
         super.bindView(v, partition, cursor, position);
         final ContactListItemView view = (ContactListItemView) v;
-        bindSectionHeaderAndDivider(view, position);
-        bindName(view, cursor);
         bindViewId(view, cursor, GroupMembersQuery.CONTACT_ID);
+        bindName(view, cursor);
         bindPhoto(view, cursor);
     }
 
-    private void bindSectionHeaderAndDivider(final ContactListItemView view, int position) {
-        final int section = getSectionForPosition(position);
-        if (getPositionForSection(section) == position) {
-            final String header = (String) getSections()[section];
-            view.setSectionHeader(header);
-        } else {
-            view.setSectionHeader(null);
-        }
-    }
-
     private void bindName(ContactListItemView view, Cursor cursor) {
         view.showDisplayName(cursor, GroupMembersQuery.CONTACT_DISPLAY_NAME,
                 getContactNameDisplayOrder());
diff --git a/src/com/android/contacts/group/GroupMembersListFragment.java b/src/com/android/contacts/group/GroupMembersListFragment.java
index 8553b9b..5c86d04 100644
--- a/src/com/android/contacts/group/GroupMembersListFragment.java
+++ b/src/com/android/contacts/group/GroupMembersListFragment.java
@@ -79,7 +79,6 @@
                 }
                 return;
             }
-            // TODO(wjang): how should we handle deleted groups
             mGroupMetadata = new GroupMetadata();
             mGroupMetadata.uri = mGroupUri;
             mGroupMetadata.accountName = cursor.getString(GroupMetaDataLoader.ACCOUNT_NAME);
@@ -109,8 +108,7 @@
         public CursorLoader onCreateLoader(int id, Bundle args) {
             final GroupListLoader groupListLoader = new GroupListLoader(getActivity());
 
-            // TODO(wjang): modify GroupListLoader to accept this selection criteria more naturally
-            groupListLoader.setSelection(groupListLoader.getSelection()
+            groupListLoader.setSelection(GroupListLoader.DEFAULT_SELECTION
                     + " AND " + ContactsContract.Groups._ID + "=?");
 
             final String[] selectionArgs = new String[1];
diff --git a/src/com/android/contacts/group/GroupNameEditDialogFragment.java b/src/com/android/contacts/group/GroupNameEditDialogFragment.java
index f7ee6bf..bc877a2 100644
--- a/src/com/android/contacts/group/GroupNameEditDialogFragment.java
+++ b/src/com/android/contacts/group/GroupNameEditDialogFragment.java
@@ -19,12 +19,16 @@
 import android.app.Dialog;
 import android.app.DialogFragment;
 import android.app.FragmentManager;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.os.Bundle;
 import android.text.Editable;
 import android.text.TextUtils;
 import android.text.TextWatcher;
+import android.view.ContextThemeWrapper;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.Button;
 import android.widget.EditText;
 
@@ -87,9 +91,12 @@
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         // Build a dialog with two buttons and a view of a single EditText input field
-        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
-                .setTitle(mIsInsert ? R.string.insert_group_dialog_title
-                        : R.string.update_group_dialog_title)
+        final ContextThemeWrapper context = new ContextThemeWrapper(getActivity(),
+                android.R.style.Theme_Holo_Light_Dialog_MinWidth);
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context)
+                .setTitle(mIsInsert
+                        ? R.string.group_name_dialog_insert_title
+                        : R.string.group_name_dialog_update_title)
                 .setView(R.layout.group_name_edit_dialog)
                 .setNegativeButton(android.R.string.cancel, new OnClickListener() {
                     @Override
@@ -132,6 +139,8 @@
                         createButton.setEnabled(!TextUtils.isEmpty(s));
                     }
                 });
+
+                showInputMethod(mGroupNameEditText);
             }
         });
         return alertDialog;
@@ -150,6 +159,14 @@
         outState.putString(KEY_GROUP_NAME, getGroupName());
     }
 
+    private void showInputMethod(View view) {
+        final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
+                Context.INPUT_METHOD_SERVICE);
+        if (imm != null) {
+            imm.showSoftInput(view, /* flags */ 0);
+        }
+    }
+
     private Listener getListener() {
         if (!(getActivity() instanceof Listener)) {
             throw new ClassCastException(getActivity() + " must implement " +
diff --git a/src/com/android/contacts/group/GroupUtil.java b/src/com/android/contacts/group/GroupUtil.java
index f9f5007..67df13a 100644
--- a/src/com/android/contacts/group/GroupUtil.java
+++ b/src/com/android/contacts/group/GroupUtil.java
@@ -80,16 +80,9 @@
 
     /** Returns an Intent to view the details of the group identified by the given ID. */
     public static Intent createViewGroupIntent(Context context, long groupId) {
-        return createViewGroupIntent(context, getGroupUriFromId(groupId));
-    }
-
-    /** Returns an Intent to view the details of the group identified by the given Uri. */
-    public static Intent createViewGroupIntent(Context context, Uri uri) {
         final Intent intent = new Intent(context, GroupMembersActivity.class);
         intent.setAction(Intent.ACTION_VIEW);
-        // TODO(wjang): do we still need it?
-        // intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        intent.setData(uri);
+        intent.setData(ContentUris.withAppendedId(Groups.CONTENT_URI, groupId));
         return intent;
     }
 
@@ -106,9 +99,4 @@
         final Uri legacyContentUri = Uri.parse(LEGACY_CONTACTS_URI);
         return ContentUris.withAppendedId(legacyContentUri, groupId);
     }
-
-    /** TODO: Make it private after {@link GroupBrowseListAdapter} is removed. */
-    static Uri getGroupUriFromId(long groupId) {
-        return ContentUris.withAppendedId(Groups.CONTENT_URI, groupId);
-    }
 }
\ No newline at end of file
diff --git a/src/com/android/contacts/group/Member.java b/src/com/android/contacts/group/Member.java
index f8c56fd..ad6f9b2 100644
--- a/src/com/android/contacts/group/Member.java
+++ b/src/com/android/contacts/group/Member.java
@@ -38,7 +38,6 @@
         }
     };
 
-    // TODO: Switch to just dealing with raw contact IDs everywhere if possible
     private final long mRawContactId;
     private final long mContactId;
     private final Uri mLookupUri;
diff --git a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
index 2df7fe2..752a89a 100644
--- a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
@@ -33,14 +33,21 @@
     private static final String ARG_GROUP_ID = "groupId";
     private static final String ARG_LABEL = "label";
     private static final String ARG_SHOULD_END_ACTIVITY = "endActivity";
+    private static final String ARG_CALLBACK_ACTION = "callbackAction";
 
     public static void show(FragmentManager fragmentManager, long groupId, String label,
             boolean endActivity) {
+        show(fragmentManager, groupId, label, endActivity, /* callbackAction */ null);
+    }
+
+    public static void show(FragmentManager fragmentManager, long groupId, String label,
+            boolean endActivity, String callbackAction) {
         GroupDeletionDialogFragment dialog = new GroupDeletionDialogFragment();
         Bundle args = new Bundle();
         args.putLong(ARG_GROUP_ID, groupId);
         args.putString(ARG_LABEL, label);
         args.putBoolean(ARG_SHOULD_END_ACTIVITY, endActivity);
+        args.putString(ARG_CALLBACK_ACTION, callbackAction);
         dialog.setArguments(args);
         dialog.show(fragmentManager, "deleteGroup");
     }
@@ -68,9 +75,10 @@
     protected void deleteGroup() {
         Bundle arguments = getArguments();
         long groupId = arguments.getLong(ARG_GROUP_ID);
+        final String callbackAction = arguments.getString(ARG_CALLBACK_ACTION);
 
         getActivity().startService(ContactSaveService.createGroupDeletionIntent(
-                getActivity(), groupId));
+                getActivity(), groupId, getActivity().getClass(), callbackAction));
         if (shouldEndActivity()) {
             getActivity().finish();
         }