add the deleted flag to the groups table
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index a16c196..a8f7542 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -664,6 +664,7 @@
         columns.put(Groups.TITLE_RES, Groups.TITLE_RES);
         columns.put(Groups.GROUP_VISIBLE, Groups.GROUP_VISIBLE);
         columns.put(Groups.SYSTEM_ID, Groups.SYSTEM_ID);
+        columns.put(Groups.DELETED, Groups.DELETED);
         columns.put(Groups.NOTES, Groups.NOTES);
         columns.put(Groups.SYNC1, Tables.GROUPS + "." + Groups.SYNC1 + " AS " + Groups.SYNC1);
         columns.put(Groups.SYNC2, Tables.GROUPS + "." + Groups.SYNC2 + " AS " + Groups.SYNC2);
@@ -1787,15 +1788,7 @@
             }
 
             case GROUPS_ID: {
-                long groupId = ContentUris.parseId(uri);
-                final long groupMembershipMimetypeId = mOpenHelper
-                        .getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE);
-                int groupsDeleted = db.delete(Tables.GROUPS, Groups._ID + "=" + groupId, null);
-                int dataDeleted = db.delete(Tables.DATA, DataColumns.MIMETYPE_ID + "="
-                        + groupMembershipMimetypeId + " AND " + GroupMembership.GROUP_ROW_ID + "="
-                        + groupId, null);
-                mOpenHelper.updateAllVisible();
-                return groupsDeleted + dataDeleted;
+                return deleteGroup(uri);
             }
 
             case PRESENCE: {
@@ -1807,6 +1800,33 @@
         }
     }
 
+    private int deleteGroup(Uri uri) {
+        final String flag = uri.getQueryParameter(Groups.DELETE_PERMANENTLY);
+        final boolean permanently = flag != null && "true".equals(flag.toLowerCase());
+        return deleteGroup(ContentUris.parseId(uri), permanently);
+    }
+
+    private int deleteGroup(long groupId, boolean permanently) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        final long groupMembershipMimetypeId = mOpenHelper
+                .getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE);
+        db.delete(Tables.DATA, DataColumns.MIMETYPE_ID + "="
+                + groupMembershipMimetypeId + " AND " + GroupMembership.GROUP_ROW_ID + "="
+                + groupId, null);
+
+        try {
+            if (permanently) {
+                return db.delete(Tables.GROUPS, Groups._ID + "=" + groupId, null);
+            } else {
+                mValues.clear();
+                mValues.put(Groups.DELETED, 1);
+                return updateGroup(groupId, mValues, null, null);
+            }
+        } finally {
+            mOpenHelper.updateAllVisible();
+        }
+    }
+
     private int deleteRawContact(Uri uri) {
         final String flag = uri.getQueryParameter(RawContacts.DELETE_PERMANENTLY);
         final boolean permanently = flag != null && "true".equals(flag.toLowerCase());
@@ -1824,7 +1844,7 @@
             return db.delete(Tables.RAW_CONTACTS, RawContacts._ID + "=" + rawContactId, null);
         } else {
             mValues.clear();
-            mValues.put(RawContacts.DELETED, true);
+            mValues.put(RawContacts.DELETED, 1);
             mValues.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
             mValues.putNull(RawContacts.CONTACT_ID);
             return updateRawContact(rawContactId, mValues, null, null);
@@ -1891,14 +1911,7 @@
 
             case GROUPS_ID: {
                 long groupId = ContentUris.parseId(uri);
-                String selectionWithId = (Groups._ID + "=" + groupId + " ")
-                        + (selection == null ? "" : " AND " + selection);
-                count = db.update(Tables.GROUPS, values, selectionWithId, selectionArgs);
-
-                // If changing visibility, then update contacts
-                if (values.containsKey(Groups.GROUP_VISIBLE)) {
-                    mOpenHelper.updateAllVisible();
-                }
+                count = updateGroup(groupId, values, selection, selectionArgs);
 
                 break;
             }
@@ -1918,6 +1931,21 @@
         return count;
     }
 
+    private int updateGroup(long groupId, ContentValues values,
+            String selection, String[] selectionArgs) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count;
+        String selectionWithId = (Groups._ID + "=" + groupId + " ")
+                + (selection == null ? "" : " AND " + selection);
+        count = db.update(Tables.GROUPS, values, selectionWithId, selectionArgs);
+
+        // If changing visibility, then update contacts
+        if (values.containsKey(Groups.GROUP_VISIBLE)) {
+            mOpenHelper.updateAllVisible();
+        }
+        return count;
+    }
+
     private int updateRawContact(long rawContactId, ContentValues values, String selection,
             String[] selectionArgs) {
         final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
@@ -2597,7 +2625,8 @@
                 RawContacts.SYNC1,
                 RawContacts.SYNC2,
                 RawContacts.SYNC3,
-                RawContacts.SYNC4};
+                RawContacts.SYNC4,
+                RawContacts.DELETED};
 
         private static final int COLUMN_ACCOUNT_NAME = 0;
         private static final int COLUMN_ACCOUNT_TYPE = 1;
@@ -2616,6 +2645,7 @@
         private static final int COLUMN_SYNC2 = 32;
         private static final int COLUMN_SYNC3 = 33;
         private static final int COLUMN_SYNC4 = 34;
+        private static final int COLUMN_DELETED = 35;
 
         public ContactsEntityIterator(ContactsProvider2 provider, String contactsIdString, Uri uri,
                 String selection, String[] selectionArgs, String sortOrder) {
@@ -2684,6 +2714,7 @@
             contactValues.put(RawContacts.SYNC2, c.getString(COLUMN_SYNC2));
             contactValues.put(RawContacts.SYNC3, c.getString(COLUMN_SYNC3));
             contactValues.put(RawContacts.SYNC4, c.getString(COLUMN_SYNC4));
+            contactValues.put(RawContacts.DELETED, c.getLong(COLUMN_DELETED));
             Entity contact = new Entity(contactValues);
 
             // read data rows until the contact id changes
@@ -2749,7 +2780,8 @@
                 Groups.SYNC3,
                 Groups.SYNC4,
                 Groups.SYSTEM_ID,
-                Groups.NOTES};
+                Groups.NOTES,
+                Groups.DELETED};
 
         private static final int COLUMN_ID = 0;
         private static final int COLUMN_ACCOUNT_NAME = 1;
@@ -2767,6 +2799,7 @@
         private static final int COLUMN_SYNC4 = 13;
         private static final int COLUMN_SYSTEM_ID = 14;
         private static final int COLUMN_NOTES = 15;
+        private static final int COLUMN_DELETED = 16;
 
         public GroupsEntityIterator(ContactsProvider2 provider, String groupIdString, Uri uri,
                 String selection, String[] selectionArgs, String sortOrder) {
@@ -2841,6 +2874,7 @@
             groupValues.put(Groups.SYNC3, c.getString(COLUMN_SYNC3));
             groupValues.put(Groups.SYNC4, c.getString(COLUMN_SYNC4));
             groupValues.put(Groups.SYSTEM_ID, c.getString(COLUMN_SYSTEM_ID));
+            groupValues.put(Groups.DELETED, c.getLong(COLUMN_DELETED));
             groupValues.put(Groups.NOTES, c.getString(COLUMN_NOTES));
             Entity group = new Entity(groupValues);
 
diff --git a/src/com/android/providers/contacts/OpenHelper.java b/src/com/android/providers/contacts/OpenHelper.java
index 20eb9a9..ce17501 100644
--- a/src/com/android/providers/contacts/OpenHelper.java
+++ b/src/com/android/providers/contacts/OpenHelper.java
@@ -59,7 +59,7 @@
 /* package */ class OpenHelper extends SQLiteOpenHelper {
     private static final String TAG = "OpenHelper";
 
-    private static final int DATABASE_VERSION = 62;
+    private static final int DATABASE_VERSION = 63;
     private static final String DATABASE_NAME = "contacts2.db";
     private static final String DATABASE_PRESENCE = "presence_db";
 
@@ -730,6 +730,7 @@
                 Groups.TITLE_RES + " INTEGER," +
                 Groups.NOTES + " TEXT," +
                 Groups.SYSTEM_ID + " TEXT," +
+                Groups.DELETED + " INTEGER NOT NULL DEFAULT 0," +
                 Groups.GROUP_VISIBLE + " INTEGER," +
                 Groups.SYNC1 + " TEXT, " +
                 Groups.SYNC2 + " TEXT, " +
@@ -805,6 +806,7 @@
                 + RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + ","
                 + RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + ","
                 + RawContactsColumns.CONCRETE_DIRTY + " AS " + RawContacts.DIRTY + ","
+                + RawContactsColumns.CONCRETE_DELETED + " AS " + RawContacts.DELETED + ","
                 + PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE + ","
                 + RawContacts.CONTACT_ID + ", "
                 + RawContactsColumns.CONCRETE_SYNC1 + " AS " + RawContacts.SYNC1 + ", "
diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
index c240a07..6ffb9ab 100644
--- a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
@@ -352,6 +352,7 @@
         values.put(Groups.NOTES, "e");
         values.put(Groups.RES_PACKAGE, "f");
         values.put(Groups.SYSTEM_ID, "g");
+        values.put(Groups.DELETED, 1);
         values.put(Groups.SYNC1, "h");
         values.put(Groups.SYNC2, "i");
         values.put(Groups.SYNC3, "j");
diff --git a/tests/src/com/android/providers/contacts/GroupsTest.java b/tests/src/com/android/providers/contacts/GroupsTest.java
index 38715b5..d47f9ba 100644
--- a/tests/src/com/android/providers/contacts/GroupsTest.java
+++ b/tests/src/com/android/providers/contacts/GroupsTest.java
@@ -22,6 +22,7 @@
 import android.net.Uri;
 import android.provider.ContactsContract.Groups;
 import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract;
 import android.test.suitebuilder.annotation.LargeTest;
 
 /**
@@ -156,6 +157,32 @@
         assertDirty(uri, false);
     }
 
+    public void testGroupDeletion1() {
+        long groupId = createGroup(mAccount, "g1", "gt1");
+        Uri uri = ContentUris.withAppendedId(Groups.CONTENT_URI, groupId);
+
+        assertEquals(1, getCount(uri, null, null));
+        mResolver.delete(uri, null, null);
+        assertEquals(1, getCount(uri, null, null));
+        assertStoredValues(uri, Groups.DELETED, "1");
+
+        Uri permanentDeletionUri =
+                uri.buildUpon().appendQueryParameter(Groups.DELETE_PERMANENTLY, "true").build();
+        mResolver.delete(permanentDeletionUri, null, null);
+        assertEquals(0, getCount(uri, null, null));
+    }
+
+    public void testGroupDeletion2() {
+        long groupId = createGroup(mAccount, "g1", "gt1");
+        Uri uri = ContentUris.withAppendedId(Groups.CONTENT_URI, groupId);
+
+        assertEquals(1, getCount(uri, null, null));
+        Uri permanentDeletionUri =
+                uri.buildUpon().appendQueryParameter(Groups.DELETE_PERMANENTLY, "true").build();
+        mResolver.delete(permanentDeletionUri, null, null);
+        assertEquals(0, getCount(uri, null, null));
+    }
+
     public void testGroupVersionUpdates() {
         Uri uri = ContentUris.withAppendedId(Groups.CONTENT_URI,
                 createGroup(mAccount, "gsid1", "title1"));