diff --git a/src/com/android/providers/calendar/CalendarProvider.java b/src/com/android/providers/calendar/CalendarProvider.java
index 39695a7..9cd6f86 100644
--- a/src/com/android/providers/calendar/CalendarProvider.java
+++ b/src/com/android/providers/calendar/CalendarProvider.java
@@ -62,7 +62,6 @@
 import android.pim.RecurrenceSet;
 import android.provider.Calendar;
 import android.provider.Calendar.Attendees;
-import android.provider.Calendar.BusyBits;
 import android.provider.Calendar.CalendarAlerts;
 import android.provider.Calendar.Calendars;
 import android.provider.Calendar.Events;
@@ -134,24 +133,6 @@
      */
     MetaData mMetaData;
 
-    // The interval in minutes for calculating busy bits
-    private static final int BUSYBIT_INTERVAL = 60;
-
-    // A lookup table for getting a bit mask of length N, for N <= 32
-    // For example, BIT_MASKS[4] gives 0xf (which has 4 bits set to 1).
-    // We use this for computing the busy bits for events.
-    private static final int[] BIT_MASKS = {
-            0,
-            0x00000001, 0x00000003, 0x00000007, 0x0000000f,
-            0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
-            0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
-            0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
-            0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
-            0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
-            0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
-            0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
-    };
-
     // To determine if a recurrence exception originally overlapped the
     // window, we need to assume a maximum duration, since we only know
     // the original start time.
@@ -265,12 +246,6 @@
     private static final int INSTANCES_INDEX_END_MINUTE = 3;
     private static final int INSTANCES_INDEX_ALL_DAY = 4;
 
-    private static final String[] sBusyBitProjection = new String[] {
-            BusyBits.DAY, BusyBits.BUSYBITS, BusyBits.ALL_DAY_COUNT };
-
-    private static final int BUSYBIT_INDEX_DAY = 0;
-    private static final int BUSYBIT_INDEX_BUSYBITS= 1;
-    private static final int BUSYBIT_INDEX_ALL_DAY_COUNT = 2;
 
     private CalendarClient mCalendarClient = null;
 
@@ -392,12 +367,6 @@
         handleInstanceQuery(qb, begin, end, new String[] { Instances._ID },
                 null /* selection */, null /* sort */, false /* searchByDayInsteadOfMillis */);
 
-        // Also pre-compute the BusyBits table for this month.
-        int startDay = Time.getJulianDay(begin, time.gmtoff);
-        int endDay = startDay + 31;
-        qb = new SQLiteQueryBuilder();
-        handleBusyBitsQuery(qb, startDay, endDay, sBusyBitProjection,
-                null /* selection */, null /* sort */);
         rescheduleMissedAlarms();
     }
 
@@ -1137,7 +1106,7 @@
                 }
                 return handleInstanceQuery(qb, begin, end, projectionIn,
                         selection, sort, match == INSTANCES_BY_DAY);
-            case BUSYBITS:
+            case EVENT_DAYS:
                 int startDay;
                 int endDay;
                 try {
@@ -1152,8 +1121,7 @@
                     throw new IllegalArgumentException("Cannot parse end day "
                             + url.getPathSegments().get(3));
                 }
-                return handleBusyBitsQuery(qb, startDay, endDay, projectionIn,
-                        selection, sort);
+                return handleEventDayQuery(qb, startDay, endDay, projectionIn, selection);
             case ATTENDEES:
                 qb.setTables("Attendees, Events, Calendars");
                 qb.setProjectionMap(sAttendeesProjectionMap);
@@ -1269,18 +1237,19 @@
         return qb.query(db, projectionIn, selection, null, null, null, sort);
     }
 
-    private Cursor handleBusyBitsQuery(SQLiteQueryBuilder qb, int startDay,
-            int endDay, String[] projectionIn,
-            String selection, String sort) {
+    private Cursor handleEventDayQuery(SQLiteQueryBuilder qb, int begin, int end,
+            String[] projection, String selection) {
         final SQLiteDatabase db = getDatabase();
-        acquireBusyBitRange(startDay, endDay);
-        qb.setTables("BusyBits");
-        qb.setProjectionMap(sBusyBitsProjectionMap);
-        qb.appendWhere("day >= ");
-        qb.appendWhere(String.valueOf(startDay));
-        qb.appendWhere(" AND day <= ");
-        qb.appendWhere(String.valueOf(endDay));
-        return qb.query(db, projectionIn, selection, null, null, null, sort);
+        qb.setTables("Instances INNER JOIN Events ON (Instances.event_id=Events._id) " +
+                "INNER JOIN Calendars ON (Events.calendar_id = Calendars._id)");
+        qb.setProjectionMap(sInstancesProjectionMap);
+        acquireInstanceRange(begin, end, true);
+        qb.appendWhere("startDay <= ");
+        qb.appendWhere(String.valueOf(end));
+        qb.appendWhere(" AND endDay >= ");
+        qb.appendWhere(String.valueOf(begin));
+        return qb.query(db, projection, selection, null /* selectionArgs */,
+                Instances.START_DAY /* groupBy */, null /* having */, null);
     }
 
     /**
@@ -1304,20 +1273,6 @@
     }
 
     /**
-     * Expands the Instances table (if needed) and the BusyBits table.
-     * Acquires the database lock and calls {@link #acquireBusyBitRangeLocked}.
-     */
-    private void acquireBusyBitRange(final int startDay, final int endDay) {
-        mDb.beginTransaction();
-        try {
-            acquireBusyBitRangeLocked(startDay, endDay);
-            mDb.setTransactionSuccessful();
-        } finally {
-            mDb.endTransaction();
-        }
-    }
-
-    /**
      * Ensure that the date range given has all elements in the instance
      * table.  The database lock must be held when calling this method.
      *
@@ -1355,9 +1310,8 @@
         if (maxInstance == 0 || timezoneChanged) {
             // Empty the Instances table and expand from scratch.
             mDb.execSQL("DELETE FROM Instances;");
-            mDb.execSQL("DELETE FROM BusyBits;");
             if (Config.LOGV) {
-                Log.v(TAG, "acquireInstanceRangeLocked() deleted Instances and Busybits,"
+                Log.v(TAG, "acquireInstanceRangeLocked() deleted Instances,"
                         + " timezone changed: " + timezoneChanged);
             }
             expandInstanceRangeLocked(expandBegin, expandEnd, localTimezone);
@@ -1405,122 +1359,6 @@
                 fields.minBusyBit, fields.maxBusyBit);
     }
 
-    private void acquireBusyBitRangeLocked(int firstDay, int lastDay) {
-        if (firstDay > lastDay) {
-            throw new IllegalArgumentException("firstDay must not be greater than lastDay");
-        }
-        String localTimezone = TimeZone.getDefault().getID();
-        MetaData.Fields fields = mMetaData.getFieldsLocked();
-        String dbTimezone = fields.timezone;
-        int minBusyBit = fields.minBusyBit;
-        int maxBusyBit = fields.maxBusyBit;
-        boolean timezoneChanged = (dbTimezone == null) || !dbTimezone.equals(localTimezone);
-        if (firstDay >= minBusyBit && lastDay <= maxBusyBit && !timezoneChanged) {
-            if (Config.LOGV) {
-                Log.v(TAG, "acquireBusyBitRangeLocked() no expansion needed");
-            }
-            return;
-        }
-
-        // Avoid gaps in the BusyBit table and avoid recomputing the busy bits
-        // that are already in the table.  If the busy bit range has been cleared,
-        // don't bother checking.
-        if (maxBusyBit != 0) {
-            if (firstDay > maxBusyBit) {
-                firstDay = maxBusyBit;
-            } else if (lastDay < minBusyBit) {
-                lastDay = minBusyBit;
-            } else if (firstDay < minBusyBit && lastDay <= maxBusyBit) {
-                lastDay = minBusyBit;
-            } else if (lastDay > maxBusyBit && firstDay >= minBusyBit) {
-                firstDay = maxBusyBit;
-            }
-        }
-
-        // Allocate space for the busy bits, one 32-bit integer for each day.
-        int numDays = lastDay - firstDay + 1;
-        int[] busybits = new int[numDays];
-        int[] allDayCounts = new int[numDays];
-
-        // Convert the first and last Julian day range to a range that uses
-        // UTC milliseconds.
-        Time time = new Time();
-        long begin = time.setJulianDay(firstDay);
-
-        // We add one to lastDay because the time is set to 12am on the given
-        // Julian day and we want to include all the events on the last day.
-        long end = time.setJulianDay(lastDay + 1);
-
-        // Make sure the Instances table includes events in the range
-        // [begin, end].
-        acquireInstanceRange(begin, end, true /* use minimum expansion window */);
-
-        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-        qb.setTables("Instances INNER JOIN Events ON (Instances.event_id=Events._id) " +
-                "INNER JOIN Calendars ON (Events.calendar_id = Calendars._id)");
-        qb.setProjectionMap(sInstancesProjectionMap);
-        qb.appendWhere("begin <= ");
-        qb.appendWhere(String.valueOf(end));
-        qb.appendWhere(" AND end >= ");
-        qb.appendWhere(String.valueOf(begin));
-        qb.appendWhere(" AND ");
-        qb.appendWhere(Instances.SELECTED);
-        qb.appendWhere("=1");
-
-        final SQLiteDatabase db = getDatabase();
-        // Get all the instances that overlap the range [begin,end]
-        Cursor cursor = qb.query(db, sInstancesProjection, null, null, null, null, null);
-        int count = 0;
-        try {
-            count = cursor.getCount();
-            while (cursor.moveToNext()) {
-                int startDay = cursor.getInt(INSTANCES_INDEX_START_DAY);
-                int endDay = cursor.getInt(INSTANCES_INDEX_END_DAY);
-                int startMinute = cursor.getInt(INSTANCES_INDEX_START_MINUTE);
-                int endMinute = cursor.getInt(INSTANCES_INDEX_END_MINUTE);
-                boolean allDay = cursor.getInt(INSTANCES_INDEX_ALL_DAY) != 0;
-                fillBusyBits(firstDay, startDay, endDay, startMinute, endMinute,
-                        allDay, busybits, allDayCounts);
-            }
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-
-        if (count == 0) {
-            return;
-        }
-
-        // Read the busybit range again because that may have changed when we
-        // called acquireInstanceRange().
-        fields = mMetaData.getFieldsLocked();
-        minBusyBit = fields.minBusyBit;
-        maxBusyBit = fields.maxBusyBit;
-
-        // If the busybit range was cleared, then delete all the entries.
-        if (maxBusyBit == 0) {
-            mDb.execSQL("DELETE FROM BusyBits;");
-        }
-
-        // Merge the busy bits with the database.
-        mergeBusyBits(firstDay, lastDay, busybits, allDayCounts);
-        if (maxBusyBit == 0) {
-            minBusyBit = firstDay;
-            maxBusyBit = lastDay;
-        } else {
-            if (firstDay < minBusyBit) {
-                minBusyBit = firstDay;
-            }
-            if (lastDay > maxBusyBit) {
-                maxBusyBit = lastDay;
-            }
-        }
-        // Update the busy bit range
-        mMetaData.writeLocked(fields.timezone, fields.minInstance, fields.maxInstance,
-                minBusyBit, maxBusyBit);
-    }
-
     private static final String[] EXPAND_COLUMNS = new String[] {
             Events._ID,
             Events._SYNC_ID,
@@ -1960,324 +1798,6 @@
         values.put(Instances.END_MINUTE, endMinute);
     }
 
-    private void fillBusyBits(int minDay, int startDay, int endDay, int startMinute,
-            int endMinute, boolean allDay, int[] busybits, int[] allDayCounts) {
-
-        // The startDay can be less than the minDay if we have an event
-        // that starts earlier than the time range we are interested in.
-        // In that case, we ignore the time range that falls outside the
-        // the range we are interested in.
-        if (startDay < minDay) {
-            startDay = minDay;
-            startMinute = 0;
-        }
-
-        // Likewise, truncate the event's end day so that it doesn't go past
-        // the expected range.
-        int numDays = busybits.length;
-        int stopDay = endDay;
-        if (stopDay > minDay + numDays - 1) {
-            stopDay = minDay + numDays - 1;
-        }
-        int dayIndex = startDay - minDay;
-
-        if (allDay) {
-            for (int day = startDay; day <= stopDay; day++, dayIndex++) {
-                allDayCounts[dayIndex] += 1;
-            }
-            return;
-        }
-
-        for (int day = startDay; day <= stopDay; day++, dayIndex++) {
-            int endTime = endMinute;
-            // If the event ends on a future day, then show it extending to
-            // the end of this day.
-            if (endDay > day) {
-                endTime = 24 * 60;
-            }
-
-            int startBit = startMinute / BUSYBIT_INTERVAL ;
-            int endBit = (endTime + BUSYBIT_INTERVAL - 1) / BUSYBIT_INTERVAL;
-            int len = endBit - startBit;
-            if (len == 0) {
-                len = 1;
-            }
-            if (len < 0 || len > 24) {
-                Log.e("Cal", "fillBusyBits() error: len " + len
-                        + " startMinute,endTime " + startMinute + " , " + endTime
-                        + " startDay,endDay " + startDay + " , " + endDay);
-            } else {
-                int oneBits = BIT_MASKS[len];
-                busybits[dayIndex] |= oneBits << startBit;
-            }
-
-            // Set the start minute to the beginning of the day, in
-            // case this event spans multiple days.
-            startMinute = 0;
-        }
-    }
-
-    private void mergeBusyBits(int startDay, int endDay, int[] busybits, int[] allDayCounts) {
-        mDb.beginTransaction();
-        try {
-            mergeBusyBitsLocked(startDay, endDay, busybits, allDayCounts);
-            mDb.setTransactionSuccessful();
-        } finally {
-            mDb.endTransaction();
-        }
-    }
-
-    private void mergeBusyBitsLocked(int startDay, int endDay, int[] busybits,
-            int[] allDayCounts) {
-        final SQLiteDatabase db = getDatabase();
-        Cursor cursor = null;
-        try {
-            String selection = "day>=" + startDay + " AND day<=" + endDay;
-            cursor = db.query("BusyBits", sBusyBitProjection, selection, null, null, null, null);
-            if (cursor == null) {
-                return;
-            }
-            while (cursor.moveToNext()) {
-                int day = cursor.getInt(BUSYBIT_INDEX_DAY);
-                int busy = cursor.getInt(BUSYBIT_INDEX_BUSYBITS);
-                int allDayCount = cursor.getInt(BUSYBIT_INDEX_ALL_DAY_COUNT);
-
-                int dayIndex = day - startDay;
-                busybits[dayIndex] |= busy;
-                allDayCounts[dayIndex] += allDayCount;
-            }
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-
-        // Allocate a map that we can reuse
-        ContentValues values = new ContentValues();
-
-        // Write the busy bits to the database
-        int len = busybits.length;
-        for (int dayIndex = 0; dayIndex < len; dayIndex++) {
-            int busy = busybits[dayIndex];
-            int allDayCount = allDayCounts[dayIndex];
-            if (busy == 0 && allDayCount == 0) {
-                continue;
-            }
-            int day = startDay + dayIndex;
-
-            values.clear();
-            values.put(BusyBits.DAY, day);
-            values.put(BusyBits.BUSYBITS, busy);
-            values.put(BusyBits.ALL_DAY_COUNT, allDayCount);
-            db.replace("BusyBits", null, values);
-        }
-    }
-
-    /**
-     * Updates the BusyBit table when a new event is inserted into the Events
-     * table.  This is called after the event has been entered into the Events
-     * table.  If the event time is not within the date range of the current
-     * BusyBits table, then the busy bits are not updated.  The BusyBits
-     * table is not automatically expanded to include this event.
-     *
-     * @param eventId the id of the newly created event
-     * @param values the ContentValues for the new event
-     */
-    private void insertBusyBitsLocked(long eventId, ContentValues values) {
-        MetaData.Fields fields = mMetaData.getFieldsLocked();
-        if (fields.maxBusyBit == 0) {
-            return;
-        }
-
-        // If this is a recurrence event, then the expanded Instances range
-        // should be 0 because this is called after updateInstancesLocked().
-        // But for now check this condition and report an error if it occurs.
-        // In the future, we could even support recurring events by
-        // expanding them here and updating the busy bits for each instance.
-        if (isRecurrenceEvent(values))  {
-            Log.e(TAG, "insertBusyBitsLocked(): unexpected recurrence event\n");
-            return;
-        }
-
-        long dtstartMillis = values.getAsLong(Events.DTSTART);
-        Long dtendMillis = values.getAsLong(Events.DTEND);
-        if (dtendMillis == null) {
-            dtendMillis = dtstartMillis;
-        }
-
-        boolean allDay = false;
-        Integer allDayInteger = values.getAsInteger(Events.ALL_DAY);
-        if (allDayInteger != null) {
-            allDay = allDayInteger != 0;
-        }
-
-        Time time = new Time();
-        if (allDay) {
-            time.timezone = Time.TIMEZONE_UTC;
-        }
-
-        ContentValues busyValues = new ContentValues();
-        computeTimezoneDependentFields(dtstartMillis, dtendMillis, time, busyValues);
-
-        int startDay = busyValues.getAsInteger(Instances.START_DAY);
-        int endDay = busyValues.getAsInteger(Instances.END_DAY);
-
-        // If the event time is not in the expanded BusyBits range,
-        // then return.
-        if (startDay > fields.maxBusyBit || endDay < fields.minBusyBit) {
-            return;
-        }
-
-        // Allocate space for the busy bits, one 32-bit integer for each day,
-        // plus 24 bytes for the count of events that occur in each time slot.
-        int numDays = endDay - startDay + 1;
-        int[] busybits = new int[numDays];
-        int[] allDayCounts = new int[numDays];
-
-        int startMinute = busyValues.getAsInteger(Instances.START_MINUTE);
-        int endMinute = busyValues.getAsInteger(Instances.END_MINUTE);
-        fillBusyBits(startDay, startDay, endDay, startMinute, endMinute,
-                allDay, busybits, allDayCounts);
-        mergeBusyBits(startDay, endDay, busybits, allDayCounts);
-    }
-
-    /**
-     * Updates the busy bits for an event that is being updated.  This is
-     * called before the event is updated in the Events table because we need
-     * to know the time of the event before it was changed.
-     *
-     * @param eventId the id of the event being updated
-     * @param values the ContentValues for the updated event
-     */
-    private void updateBusyBitsLocked(long eventId, ContentValues values) {
-        MetaData.Fields fields = mMetaData.getFieldsLocked();
-        if (fields.maxBusyBit == 0) {
-            return;
-        }
-
-        // If this is a recurring event, then clear the BusyBits table.
-        if (isRecurrenceEvent(values))  {
-            mMetaData.writeLocked(fields.timezone, fields.minInstance, fields.maxInstance,
-                    0 /* startDay */, 0 /* endDay */);
-            return;
-        }
-
-        // If the event fields being updated don't contain the start or end
-        // time, then we don't need to bother updating the BusyBits table.
-        Long dtstartLong = values.getAsLong(Events.DTSTART);
-        Long dtendLong = values.getAsLong(Events.DTEND);
-        if (dtstartLong == null && dtendLong == null) {
-            return;
-        }
-
-        // If the timezone has changed, then clear the busy bits table
-        // and return.
-        String dbTimezone = fields.timezone;
-        String localTimezone = TimeZone.getDefault().getID();
-        boolean timezoneChanged = (dbTimezone == null) || !dbTimezone.equals(localTimezone);
-        if (timezoneChanged) {
-            mMetaData.writeLocked(fields.timezone, fields.minInstance, fields.maxInstance,
-                    0 /* startDay */, 0 /* endDay */);
-            return;
-        }
-
-        // Read the existing event start and end times from the Events table.
-        TimeRange eventRange = readEventStartEnd(eventId);
-
-        // Fill in the new start time (if missing) or the new end time (if
-        // missing) from the existing event start and end times.
-        long dtstartMillis;
-        if (dtstartLong != null) {
-            dtstartMillis = dtstartLong;
-        } else {
-            dtstartMillis = eventRange.begin;
-        }
-
-        long dtendMillis;
-        if (dtendLong != null) {
-            dtendMillis = dtendLong;
-        } else {
-            dtendMillis = eventRange.end;
-        }
-
-        // Compute the start and end Julian days for the event.
-        Time time = new Time();
-        if (eventRange.allDay) {
-            time.timezone = Time.TIMEZONE_UTC;
-        }
-        ContentValues busyValues = new ContentValues();
-        computeTimezoneDependentFields(eventRange.begin, eventRange.end, time, busyValues);
-        int oldStartDay = busyValues.getAsInteger(Instances.START_DAY);
-        int oldEndDay = busyValues.getAsInteger(Instances.END_DAY);
-
-        boolean allDay = false;
-        Integer allDayInteger = values.getAsInteger(Events.ALL_DAY);
-        if (allDayInteger != null) {
-            allDay = allDayInteger != 0;
-        }
-
-        if (allDay) {
-            time.timezone = Time.TIMEZONE_UTC;
-        } else {
-            time.timezone = TimeZone.getDefault().getID();
-        }
-
-        computeTimezoneDependentFields(dtstartMillis, dtendMillis, time, busyValues);
-        int newStartDay = busyValues.getAsInteger(Instances.START_DAY);
-        int newEndDay = busyValues.getAsInteger(Instances.END_DAY);
-
-        // If both the old and new event times are outside the expanded
-        // BusyBits table, then return.
-        if ((oldStartDay > fields.maxBusyBit || oldEndDay < fields.minBusyBit)
-                && (newStartDay > fields.maxBusyBit || newEndDay < fields.minBusyBit)) {
-            return;
-        }
-
-        // If the old event time is within the expanded Instances range,
-        // then clear the BusyBits table and return.
-        if (oldStartDay <= fields.maxBusyBit && oldEndDay >= fields.minBusyBit) {
-            // We could recompute the busy bits for the days containing the
-            // old event time.  For now, just clear the BusyBits table.
-            mMetaData.writeLocked(fields.timezone, fields.minInstance, fields.maxInstance,
-                    0 /* startDay */, 0 /* endDay */);
-            return;
-        }
-
-        // The new event time is within the expanded Instances range.
-        // So insert the busy bits for that day (or days).
-
-        // Allocate space for the busy bits, one 32-bit integer for each day,
-        // plus 24 bytes for the count of events that occur in each time slot.
-        int numDays = newEndDay - newStartDay + 1;
-        int[] busybits = new int[numDays];
-        int[] allDayCounts = new int[numDays];
-
-        int startMinute = busyValues.getAsInteger(Instances.START_MINUTE);
-        int endMinute = busyValues.getAsInteger(Instances.END_MINUTE);
-        fillBusyBits(newStartDay, newStartDay, newEndDay, startMinute, endMinute,
-                allDay, busybits, allDayCounts);
-        mergeBusyBits(newStartDay, newEndDay, busybits, allDayCounts);
-    }
-
-    /**
-     * This method is called just before an event is deleted.
-     *
-     * @param eventId
-     */
-    private void deleteBusyBitsLocked(long eventId) {
-        MetaData.Fields fields = mMetaData.getFieldsLocked();
-        if (fields.maxBusyBit == 0) {
-            return;
-        }
-
-        // TODO: if the event being deleted is not a recurring event and the
-        // start and end time are outside the BusyBit range, then we could
-        // avoid clearing the BusyBits table.  For now, always clear the
-        // BusyBits table because deleting events is relatively rare.
-        mMetaData.writeLocked(fields.timezone, fields.minInstance, fields.maxInstance,
-                0 /* startDay */, 0 /* endDay */);
-    }
-
     // Read the start and end time for an event from the Events table.
     // Also read the "all-day" indicator.
     private TimeRange readEventStartEnd(long eventId) {
@@ -2324,9 +1844,8 @@
                 return "vnd.android.cursor.item/calendar-alert";
             case INSTANCES:
             case INSTANCES_BY_DAY:
+            case EVENT_DAYS:
                 return "vnd.android.cursor.dir/event-instance";
-            case BUSYBITS:
-                return "vnd.android.cursor.dir/busybits";
             default:
                 throw new IllegalArgumentException("Unknown URL " + url);
         }
@@ -2379,7 +1898,6 @@
                 if (!isTemporary() && rowId != -1) {
                     updateEventRawTimesLocked(rowId, updatedValues);
                     updateInstancesLocked(updatedValues, rowId, true /* new event */, db);
-                    insertBusyBitsLocked(rowId, updatedValues);
 
                     // If we inserted a new event that specified the self-attendee
                     // status, then we need to add an entry to the attendees table.
@@ -2462,6 +1980,7 @@
             case EXTENDED_PROPERTIES_ID:
             case INSTANCES:
             case INSTANCES_BY_DAY:
+            case EVENT_DAYS:
                 throw new UnsupportedOperationException("Cannot insert into that URL");
             default:
                 throw new IllegalArgumentException("Unknown URL " + url);
@@ -2953,7 +2472,6 @@
                             + match);
                 }
                 if (!isTemporary()) {
-                    deleteBusyBitsLocked(Integer.parseInt(id));
 
                     // Query this event to get the fields needed for inserting
                     // a new row in the DeletedEvents table.
@@ -3068,6 +2586,7 @@
                 return deleteMatchingCalendars(where);
             case INSTANCES:
             case INSTANCES_BY_DAY:
+            case EVENT_DAYS:
                 throw new UnsupportedOperationException("Cannot delete that URL");
             default:
                 throw new IllegalArgumentException("Unknown URL " + url);
@@ -3124,14 +2643,6 @@
                 }
 
                 int result = db.update("Calendars", values, "_id="+ id, null);
-                if (!isTemporary()) {
-                    // When we change the display status of a Calendar
-                    // we need to update the busy bits.
-                    if (values.containsKey(Calendars.SELECTED) || (syncEvents != null)) {
-                        // Clear the BusyBits table.
-                        mMetaData.clearBusyBitRange();
-                    }
-                }
 
                 return result;
             }
@@ -3157,7 +2668,6 @@
                                 + " in Events table is not allowed.");
                     }
 
-                    updateBusyBitsLocked(id, values);
                 }
 
                 ContentValues updatedValues = updateContentValuesFromEvent(values);
@@ -3699,7 +3209,6 @@
             insertExtendedPropertiesIfNecessary(diffs, diffsRowId, rowId, db);
             updateEventRawTimesLocked(rowId, mValues);
             updateInstancesLocked(mValues, rowId, true /* new event */, db);
-            insertBusyBitsLocked(rowId, mValues);
 
             // Update the _SYNC_DIRTY flag of the event. We have to do this
             // after inserting since the update of the reminders and extended properties
@@ -3818,7 +3327,6 @@
                 Cursor diffsCursor) {
             rowToContentValues(diffsCursor, mValues);
             final SQLiteDatabase db = getDatabase();
-            updateBusyBitsLocked(localId, mValues);
             int numRows = db.update(mTable, mValues, "_id=" + localId, null /* selectionArgs */);
 
             if (numRows <= 0) {
@@ -3864,7 +3372,6 @@
         @Override
         public void deleteRow(Cursor localCursor) {
             long localId = localCursor.getLong(localCursor.getColumnIndexOrThrow(Events._ID));
-            deleteBusyBitsLocked(localId);
 
             // we have to read this row from the DB since the projection that is used
             // by cursor doesn't necessarily contain the columns we need
@@ -3955,8 +3462,8 @@
     private static final int CALENDAR_ALERTS = 13;
     private static final int CALENDAR_ALERTS_ID = 14;
     private static final int CALENDAR_ALERTS_BY_INSTANCE = 15;
-    private static final int BUSYBITS = 16;
-    private static final int INSTANCES_BY_DAY = 17;
+    private static final int INSTANCES_BY_DAY = 16;
+    private static final int EVENT_DAYS = 17;
 
     private static final UriMatcher sURLMatcher = new UriMatcher(UriMatcher.NO_MATCH);
     private static final HashMap<String, String> sInstancesProjectionMap;
@@ -3964,11 +3471,11 @@
     private static final HashMap<String, String> sAttendeesProjectionMap;
     private static final HashMap<String, String> sRemindersProjectionMap;
     private static final HashMap<String, String> sCalendarAlertsProjectionMap;
-    private static final HashMap<String, String> sBusyBitsProjectionMap;
 
     static {
         sURLMatcher.addURI("calendar", "instances/when/*/*", INSTANCES);
         sURLMatcher.addURI("calendar", "instances/whenbyday/*/*", INSTANCES_BY_DAY);
+        sURLMatcher.addURI("calendar", "instances/groupbyday/*/*", EVENT_DAYS);
         sURLMatcher.addURI("calendar", "events", EVENTS);
         sURLMatcher.addURI("calendar", "events/#", EVENTS_ID);
         sURLMatcher.addURI("calendar", "calendars", CALENDARS);
@@ -3983,7 +3490,6 @@
         sURLMatcher.addURI("calendar", "calendar_alerts", CALENDAR_ALERTS);
         sURLMatcher.addURI("calendar", "calendar_alerts/#", CALENDAR_ALERTS_ID);
         sURLMatcher.addURI("calendar", "calendar_alerts/by_instance", CALENDAR_ALERTS_BY_INSTANCE);
-        sURLMatcher.addURI("calendar", "busybits/when/*/*", BUSYBITS);
 
 
         sEventsProjectionMap = new HashMap<String, String>();
@@ -4053,12 +3559,6 @@
         sInstancesProjectionMap.put(Instances.START_MINUTE, "startMinute");
         sInstancesProjectionMap.put(Instances.END_MINUTE, "endMinute");
 
-        // BusyBits columns
-        sBusyBitsProjectionMap = new HashMap<String, String>();
-        sBusyBitsProjectionMap.put(BusyBits.DAY, "day");
-        sBusyBitsProjectionMap.put(BusyBits.BUSYBITS, "busyBits");
-        sBusyBitsProjectionMap.put(BusyBits.ALL_DAY_COUNT, "allDayCount");
-
         // Attendees columns
         sAttendeesProjectionMap.put(Attendees.EVENT_ID, "event_id");
         sAttendeesProjectionMap.put(Attendees._ID, "Attendees._id AS _id");
diff --git a/src/com/android/providers/calendar/CalendarProvider2.java b/src/com/android/providers/calendar/CalendarProvider2.java
index b7879a2..ef0ca24 100644
--- a/src/com/android/providers/calendar/CalendarProvider2.java
+++ b/src/com/android/providers/calendar/CalendarProvider2.java
@@ -43,7 +43,6 @@
 import android.provider.BaseColumns;
 import android.provider.Calendar;
 import android.provider.Calendar.Attendees;
-import android.provider.Calendar.BusyBits;
 import android.provider.Calendar.CalendarAlerts;
 import android.provider.Calendar.Calendars;
 import android.provider.Calendar.Events;
@@ -111,24 +110,6 @@
     private static final Uri SYNCSTATE_CONTENT_URI =
             Uri.parse("content://syncstate/state");
 
-    // The interval in minutes for calculating busy bits
-    private static final int BUSYBIT_INTERVAL = 60;
-
-    // A lookup table for getting a bit mask of length N, for N <= 32
-    // For example, BIT_MASKS[4] gives 0xf (which has 4 bits set to 1).
-    // We use this for computing the busy bits for events.
-    private static final int[] BIT_MASKS = {
-            0,
-            0x00000001, 0x00000003, 0x00000007, 0x0000000f,
-            0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
-            0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
-            0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
-            0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
-            0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
-            0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
-            0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
-    };
-
     // To determine if a recurrence exception originally overlapped the
     // window, we need to assume a maximum duration, since we only know
     // the original start time.
@@ -236,13 +217,6 @@
     private static final int INSTANCES_INDEX_END_MINUTE = 3;
     private static final int INSTANCES_INDEX_ALL_DAY = 4;
 
-    private static final String[] sBusyBitProjection = new String[] {
-            BusyBits.DAY, BusyBits.BUSYBITS, BusyBits.ALL_DAY_COUNT };
-
-    private static final int BUSYBIT_INDEX_DAY = 0;
-    private static final int BUSYBIT_INDEX_BUSYBITS= 1;
-    private static final int BUSYBIT_INDEX_ALL_DAY_COUNT = 2;
-
     private CalendarClient mCalendarClient = null;
 
     private AlarmManager mAlarmManager;
@@ -371,12 +345,6 @@
         handleInstanceQuery(qb, begin, end, new String[] { Instances._ID },
                 null /* selection */, null /* sort */, false /* searchByDayInsteadOfMillis */);
 
-        // Also pre-compute the BusyBits table for this month.
-        int startDay = Time.getJulianDay(begin, time.gmtoff);
-        int endDay = startDay + 31;
-        qb = new SQLiteQueryBuilder();
-        handleBusyBitsQuery(qb, startDay, endDay, sBusyBitProjection,
-                null /* selection */, null /* sort */);
         rescheduleMissedAlarms();
     }
 
@@ -481,7 +449,7 @@
                 }
                 return handleInstanceQuery(qb, begin, end, projection,
                         selection, sortOrder, match == INSTANCES_BY_DAY);
-            case BUSYBITS:
+            case EVENT_DAYS:
                 int startDay;
                 int endDay;
                 try {
@@ -496,8 +464,7 @@
                     throw new IllegalArgumentException("Cannot parse end day "
                             + uri.getPathSegments().get(3));
                 }
-                return handleBusyBitsQuery(qb, startDay, endDay, projection,
-                        selection, sortOrder);
+                return handleEventDayQuery(qb, startDay, endDay, projection, selection);
             case ATTENDEES:
                 qb.setTables("Attendees, Events, Calendars");
                 qb.setProjectionMap(sAttendeesProjectionMap);
@@ -617,18 +584,18 @@
                 null /* having */, sort);
     }
 
-    private Cursor handleBusyBitsQuery(SQLiteQueryBuilder qb, int startDay,
-            int endDay, String[] projection,
-            String selection, String sort) {
-        acquireBusyBitRange(startDay, endDay);
-        qb.setTables("BusyBits");
-        qb.setProjectionMap(sBusyBitsProjectionMap);
-        qb.appendWhere("day >= ");
-        qb.appendWhere(String.valueOf(startDay));
-        qb.appendWhere(" AND day <= ");
-        qb.appendWhere(String.valueOf(endDay));
-        return qb.query(mDb, projection, selection, null /* selectionArgs */, null /* groupBy */,
-                null /* having */, sort);
+    private Cursor handleEventDayQuery(SQLiteQueryBuilder qb, int begin, int end,
+            String[] projection, String selection) {
+        qb.setTables("Instances INNER JOIN Events ON (Instances.event_id=Events._id) " +
+                "INNER JOIN Calendars ON (Events.calendar_id = Calendars._id)");
+        qb.setProjectionMap(sInstancesProjectionMap);
+        acquireInstanceRange(begin, end, true);
+        qb.appendWhere("startDay <= ");
+        qb.appendWhere(String.valueOf(end));
+        qb.appendWhere(" AND endDay >= ");
+        qb.appendWhere(String.valueOf(begin));
+        return qb.query(mDb, projection, selection, null /* selectionArgs */,
+                Instances.START_DAY /* groupBy */, null /* having */, null);
     }
 
     /**
@@ -652,20 +619,6 @@
     }
 
     /**
-     * Expands the Instances table (if needed) and the BusyBits table.
-     * Acquires the database lock and calls {@link #acquireBusyBitRangeLocked}.
-     */
-    private void acquireBusyBitRange(final int startDay, final int endDay) {
-        mDb.beginTransaction();
-        try {
-            acquireBusyBitRangeLocked(startDay, endDay);
-            mDb.setTransactionSuccessful();
-        } finally {
-            mDb.endTransaction();
-        }
-    }
-
-    /**
      * Ensure that the date range given has all elements in the instance
      * table.  The database lock must be held when calling this method.
      *
@@ -703,9 +656,8 @@
         if (maxInstance == 0 || timezoneChanged) {
             // Empty the Instances table and expand from scratch.
             mDb.execSQL("DELETE FROM Instances;");
-            mDb.execSQL("DELETE FROM BusyBits;");
             if (Config.LOGV) {
-                Log.v(TAG, "acquireInstanceRangeLocked() deleted Instances and Busybits,"
+                Log.v(TAG, "acquireInstanceRangeLocked() deleted Instances,"
                         + " timezone changed: " + timezoneChanged);
             }
             expandInstanceRangeLocked(expandBegin, expandEnd, localTimezone);
@@ -750,124 +702,7 @@
 
         // Update the bounds on the Instances table.
         mMetaData.writeLocked(localTimezone, minInstance, maxInstance,
-                fields.minBusyBit, fields.maxBusyBit);
-    }
-
-    private void acquireBusyBitRangeLocked(int firstDay, int lastDay) {
-        if (firstDay > lastDay) {
-            throw new IllegalArgumentException("firstDay must not be greater than lastDay");
-        }
-        String localTimezone = TimeZone.getDefault().getID();
-        MetaData.Fields fields = mMetaData.getFieldsLocked();
-        String dbTimezone = fields.timezone;
-        int minBusyBit = fields.minBusyBit;
-        int maxBusyBit = fields.maxBusyBit;
-        boolean timezoneChanged = (dbTimezone == null) || !dbTimezone.equals(localTimezone);
-        if (firstDay >= minBusyBit && lastDay <= maxBusyBit && !timezoneChanged) {
-            if (Config.LOGV) {
-                Log.v(TAG, "acquireBusyBitRangeLocked() no expansion needed");
-            }
-            return;
-        }
-
-        // Avoid gaps in the BusyBit table and avoid recomputing the busy bits
-        // that are already in the table.  If the busy bit range has been cleared,
-        // don't bother checking.
-        if (maxBusyBit != 0) {
-            if (firstDay > maxBusyBit) {
-                firstDay = maxBusyBit;
-            } else if (lastDay < minBusyBit) {
-                lastDay = minBusyBit;
-            } else if (firstDay < minBusyBit && lastDay <= maxBusyBit) {
-                lastDay = minBusyBit;
-            } else if (lastDay > maxBusyBit && firstDay >= minBusyBit) {
-                firstDay = maxBusyBit;
-            }
-        }
-
-        // Allocate space for the busy bits, one 32-bit integer for each day.
-        int numDays = lastDay - firstDay + 1;
-        int[] busybits = new int[numDays];
-        int[] allDayCounts = new int[numDays];
-
-        // Convert the first and last Julian day range to a range that uses
-        // UTC milliseconds.
-        Time time = new Time();
-        long begin = time.setJulianDay(firstDay);
-
-        // We add one to lastDay because the time is set to 12am on the given
-        // Julian day and we want to include all the events on the last day.
-        long end = time.setJulianDay(lastDay + 1);
-
-        // Make sure the Instances table includes events in the range
-        // [begin, end].
-        acquireInstanceRange(begin, end, true /* use minimum expansion window */);
-
-        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-        qb.setTables("Instances INNER JOIN Events ON (Instances.event_id=Events._id) " +
-                "INNER JOIN Calendars ON (Events.calendar_id = Calendars._id)");
-        qb.setProjectionMap(sInstancesProjectionMap);
-        qb.appendWhere("begin <= ");
-        qb.appendWhere(String.valueOf(end));
-        qb.appendWhere(" AND end >= ");
-        qb.appendWhere(String.valueOf(begin));
-        qb.appendWhere(" AND ");
-        qb.appendWhere(Instances.SELECTED);
-        qb.appendWhere("=1");
-
-        // Get all the instances that overlap the range [begin,end]
-        Cursor cursor = qb.query(mDb, sInstancesProjection, null /* selection */,
-                null /* selectionArgs */, null /* groupBy */,
-                null /* having */, null /* sortOrder */);
-        int count = 0;
-        try {
-            count = cursor.getCount();
-            while (cursor.moveToNext()) {
-                int startDay = cursor.getInt(INSTANCES_INDEX_START_DAY);
-                int endDay = cursor.getInt(INSTANCES_INDEX_END_DAY);
-                int startMinute = cursor.getInt(INSTANCES_INDEX_START_MINUTE);
-                int endMinute = cursor.getInt(INSTANCES_INDEX_END_MINUTE);
-                boolean allDay = cursor.getInt(INSTANCES_INDEX_ALL_DAY) != 0;
-                fillBusyBits(firstDay, startDay, endDay, startMinute, endMinute,
-                        allDay, busybits, allDayCounts);
-            }
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-
-        if (count == 0) {
-            return;
-        }
-
-        // Read the busybit range again because that may have changed when we
-        // called acquireInstanceRange().
-        fields = mMetaData.getFieldsLocked();
-        minBusyBit = fields.minBusyBit;
-        maxBusyBit = fields.maxBusyBit;
-
-        // If the busybit range was cleared, then delete all the entries.
-        if (maxBusyBit == 0) {
-            mDb.execSQL("DELETE FROM BusyBits;");
-        }
-
-        // Merge the busy bits with the database.
-        mergeBusyBits(firstDay, lastDay, busybits, allDayCounts);
-        if (maxBusyBit == 0) {
-            minBusyBit = firstDay;
-            maxBusyBit = lastDay;
-        } else {
-            if (firstDay < minBusyBit) {
-                minBusyBit = firstDay;
-            }
-            if (lastDay > maxBusyBit) {
-                maxBusyBit = lastDay;
-            }
-        }
-        // Update the busy bit range
-        mMetaData.writeLocked(fields.timezone, fields.minInstance, fields.maxInstance,
-                minBusyBit, maxBusyBit);
+                0 /*unused*/, 0 /*unused*/);
     }
 
     private static final String[] EXPAND_COLUMNS = new String[] {
@@ -1311,351 +1146,6 @@
         values.put(Instances.END_MINUTE, endMinute);
     }
 
-    private void fillBusyBits(int minDay, int startDay, int endDay, int startMinute,
-            int endMinute, boolean allDay, int[] busybits, int[] allDayCounts) {
-
-        // The startDay can be less than the minDay if we have an event
-        // that starts earlier than the time range we are interested in.
-        // In that case, we ignore the time range that falls outside the
-        // the range we are interested in.
-        if (startDay < minDay) {
-            startDay = minDay;
-            startMinute = 0;
-        }
-
-        // Likewise, truncate the event's end day so that it doesn't go past
-        // the expected range.
-        int numDays = busybits.length;
-        int stopDay = endDay;
-        if (stopDay > minDay + numDays - 1) {
-            stopDay = minDay + numDays - 1;
-        }
-        int dayIndex = startDay - minDay;
-
-        if (allDay) {
-            for (int day = startDay; day <= stopDay; day++, dayIndex++) {
-                allDayCounts[dayIndex] += 1;
-            }
-            return;
-        }
-
-        for (int day = startDay; day <= stopDay; day++, dayIndex++) {
-            int endTime = endMinute;
-            // If the event ends on a future day, then show it extending to
-            // the end of this day.
-            if (endDay > day) {
-                endTime = 24 * 60;
-            }
-
-            int startBit = startMinute / BUSYBIT_INTERVAL ;
-            int endBit = (endTime + BUSYBIT_INTERVAL - 1) / BUSYBIT_INTERVAL;
-            int len = endBit - startBit;
-            if (len == 0) {
-                len = 1;
-            }
-            if (len < 0 || len > 24) {
-                Log.e("Cal", "fillBusyBits() error: len " + len
-                        + " startMinute,endTime " + startMinute + " , " + endTime
-                        + " startDay,endDay " + startDay + " , " + endDay);
-            } else {
-                int oneBits = BIT_MASKS[len];
-                busybits[dayIndex] |= oneBits << startBit;
-            }
-
-            // Set the start minute to the beginning of the day, in
-            // case this event spans multiple days.
-            startMinute = 0;
-        }
-    }
-
-    private void mergeBusyBits(int startDay, int endDay, int[] busybits, int[] allDayCounts) {
-        mDb.beginTransaction();
-        try {
-            mergeBusyBitsLocked(startDay, endDay, busybits, allDayCounts);
-            mDb.setTransactionSuccessful();
-        } finally {
-            mDb.endTransaction();
-        }
-    }
-
-    private void mergeBusyBitsLocked(int startDay, int endDay, int[] busybits,
-            int[] allDayCounts) {
-        Cursor cursor = null;
-        try {
-            String selection = "day>=" + startDay + " AND day<=" + endDay;
-            cursor = mDb.query("BusyBits", sBusyBitProjection, selection,
-                null /* selectionArgs */, null /* groupBy */,
-                null /* having */, null /* sortOrder */);
-            if (cursor == null) {
-                return;
-            }
-            while (cursor.moveToNext()) {
-                int day = cursor.getInt(BUSYBIT_INDEX_DAY);
-                int busy = cursor.getInt(BUSYBIT_INDEX_BUSYBITS);
-                int allDayCount = cursor.getInt(BUSYBIT_INDEX_ALL_DAY_COUNT);
-
-                int dayIndex = day - startDay;
-                busybits[dayIndex] |= busy;
-                allDayCounts[dayIndex] += allDayCount;
-            }
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-
-        // Allocate a map that we can reuse
-        ContentValues values = new ContentValues();
-
-        // Write the busy bits to the database
-        int len = busybits.length;
-        for (int dayIndex = 0; dayIndex < len; dayIndex++) {
-            int busy = busybits[dayIndex];
-            int allDayCount = allDayCounts[dayIndex];
-            if (busy == 0 && allDayCount == 0) {
-                continue;
-            }
-            int day = startDay + dayIndex;
-
-            values.clear();
-            values.put(BusyBits.DAY, day);
-            values.put(BusyBits.BUSYBITS, busy);
-            values.put(BusyBits.ALL_DAY_COUNT, allDayCount);
-            mDb.replace("BusyBits", null, values);
-        }
-    }
-
-    /**
-     * Updates the BusyBit table when a new event is inserted into the Events
-     * table.  This is called after the event has been entered into the Events
-     * table.  If the event time is not within the date range of the current
-     * BusyBits table, then the busy bits are not updated.  The BusyBits
-     * table is not automatically expanded to include this event.
-     *
-     * @param eventId the id of the newly created event
-     * @param values the ContentValues for the new event
-     */
-    private void insertBusyBitsLocked(long eventId, ContentValues values) {
-        MetaData.Fields fields = mMetaData.getFieldsLocked();
-        if (fields.maxBusyBit == 0) {
-            return;
-        }
-
-        // If this is a recurrence event, then the expanded Instances range
-        // should be 0 because this is called after updateInstancesLocked().
-        // But for now check this condition and report an error if it occurs.
-        // In the future, we could even support recurring events by
-        // expanding them here and updating the busy bits for each instance.
-        if (isRecurrenceEvent(values))  {
-            Log.e(TAG, "insertBusyBitsLocked(): unexpected recurrence event\n");
-            return;
-        }
-
-        long dtstartMillis = values.getAsLong(Events.DTSTART);
-        Long dtendMillis = values.getAsLong(Events.DTEND);
-        if (dtendMillis == null) {
-            dtendMillis = dtstartMillis;
-        }
-
-        boolean allDay = false;
-        Integer allDayInteger = values.getAsInteger(Events.ALL_DAY);
-        if (allDayInteger != null) {
-            allDay = allDayInteger != 0;
-        }
-
-        Time time = new Time();
-        if (allDay) {
-            time.timezone = Time.TIMEZONE_UTC;
-        }
-
-        ContentValues busyValues = new ContentValues();
-        computeTimezoneDependentFields(dtstartMillis, dtendMillis, time, busyValues);
-
-        int startDay = busyValues.getAsInteger(Instances.START_DAY);
-        int endDay = busyValues.getAsInteger(Instances.END_DAY);
-
-        // If the event time is not in the expanded BusyBits range,
-        // then return.
-        if (startDay > fields.maxBusyBit || endDay < fields.minBusyBit) {
-            return;
-        }
-
-        // Allocate space for the busy bits, one 32-bit integer for each day,
-        // plus 24 bytes for the count of events that occur in each time slot.
-        int numDays = endDay - startDay + 1;
-        int[] busybits = new int[numDays];
-        int[] allDayCounts = new int[numDays];
-
-        int startMinute = busyValues.getAsInteger(Instances.START_MINUTE);
-        int endMinute = busyValues.getAsInteger(Instances.END_MINUTE);
-        fillBusyBits(startDay, startDay, endDay, startMinute, endMinute,
-                allDay, busybits, allDayCounts);
-        mergeBusyBits(startDay, endDay, busybits, allDayCounts);
-    }
-
-    /**
-     * Updates the busy bits for an event that is being updated.  This is
-     * called before the event is updated in the Events table because we need
-     * to know the time of the event before it was changed.
-     *
-     * @param eventId the id of the event being updated
-     * @param values the ContentValues for the updated event
-     */
-    private void updateBusyBitsLocked(long eventId, ContentValues values) {
-        MetaData.Fields fields = mMetaData.getFieldsLocked();
-        if (fields.maxBusyBit == 0) {
-            return;
-        }
-
-        // If this is a recurring event, then clear the BusyBits table.
-        if (isRecurrenceEvent(values))  {
-            mMetaData.writeLocked(fields.timezone, fields.minInstance, fields.maxInstance,
-                    0 /* startDay */, 0 /* endDay */);
-            return;
-        }
-
-        // If the event fields being updated don't contain the start or end
-        // time, then we don't need to bother updating the BusyBits table.
-        Long dtstartLong = values.getAsLong(Events.DTSTART);
-        Long dtendLong = values.getAsLong(Events.DTEND);
-        if (dtstartLong == null && dtendLong == null) {
-            return;
-        }
-
-        // If the timezone has changed, then clear the busy bits table
-        // and return.
-        String dbTimezone = fields.timezone;
-        String localTimezone = TimeZone.getDefault().getID();
-        boolean timezoneChanged = (dbTimezone == null) || !dbTimezone.equals(localTimezone);
-        if (timezoneChanged) {
-            mMetaData.writeLocked(fields.timezone, fields.minInstance, fields.maxInstance,
-                    0 /* startDay */, 0 /* endDay */);
-            return;
-        }
-
-        // Read the existing event start and end times from the Events table.
-        TimeRange eventRange = readEventStartEnd(eventId);
-
-        // Fill in the new start time (if missing) or the new end time (if
-        // missing) from the existing event start and end times.
-        long dtstartMillis;
-        if (dtstartLong != null) {
-            dtstartMillis = dtstartLong;
-        } else {
-            dtstartMillis = eventRange.begin;
-        }
-
-        long dtendMillis;
-        if (dtendLong != null) {
-            dtendMillis = dtendLong;
-        } else {
-            dtendMillis = eventRange.end;
-        }
-
-        // Compute the start and end Julian days for the event.
-        Time time = new Time();
-        if (eventRange.allDay) {
-            time.timezone = Time.TIMEZONE_UTC;
-        }
-        ContentValues busyValues = new ContentValues();
-        computeTimezoneDependentFields(eventRange.begin, eventRange.end, time, busyValues);
-        int oldStartDay = busyValues.getAsInteger(Instances.START_DAY);
-        int oldEndDay = busyValues.getAsInteger(Instances.END_DAY);
-
-        boolean allDay = false;
-        Integer allDayInteger = values.getAsInteger(Events.ALL_DAY);
-        if (allDayInteger != null) {
-            allDay = allDayInteger != 0;
-        }
-
-        if (allDay) {
-            time.timezone = Time.TIMEZONE_UTC;
-        } else {
-            time.timezone = TimeZone.getDefault().getID();
-        }
-
-        computeTimezoneDependentFields(dtstartMillis, dtendMillis, time, busyValues);
-        int newStartDay = busyValues.getAsInteger(Instances.START_DAY);
-        int newEndDay = busyValues.getAsInteger(Instances.END_DAY);
-
-        // If both the old and new event times are outside the expanded
-        // BusyBits table, then return.
-        if ((oldStartDay > fields.maxBusyBit || oldEndDay < fields.minBusyBit)
-                && (newStartDay > fields.maxBusyBit || newEndDay < fields.minBusyBit)) {
-            return;
-        }
-
-        // If the old event time is within the expanded Instances range,
-        // then clear the BusyBits table and return.
-        if (oldStartDay <= fields.maxBusyBit && oldEndDay >= fields.minBusyBit) {
-            // We could recompute the busy bits for the days containing the
-            // old event time.  For now, just clear the BusyBits table.
-            mMetaData.writeLocked(fields.timezone, fields.minInstance, fields.maxInstance,
-                    0 /* startDay */, 0 /* endDay */);
-            return;
-        }
-
-        // The new event time is within the expanded Instances range.
-        // So insert the busy bits for that day (or days).
-
-        // Allocate space for the busy bits, one 32-bit integer for each day,
-        // plus 24 bytes for the count of events that occur in each time slot.
-        int numDays = newEndDay - newStartDay + 1;
-        int[] busybits = new int[numDays];
-        int[] allDayCounts = new int[numDays];
-
-        int startMinute = busyValues.getAsInteger(Instances.START_MINUTE);
-        int endMinute = busyValues.getAsInteger(Instances.END_MINUTE);
-        fillBusyBits(newStartDay, newStartDay, newEndDay, startMinute, endMinute,
-                allDay, busybits, allDayCounts);
-        mergeBusyBits(newStartDay, newEndDay, busybits, allDayCounts);
-    }
-
-    /**
-     * This method is called just before an event is deleted.
-     *
-     * @param eventId
-     */
-    private void deleteBusyBitsLocked(long eventId) {
-        MetaData.Fields fields = mMetaData.getFieldsLocked();
-        if (fields.maxBusyBit == 0) {
-            return;
-        }
-
-        // TODO: if the event being deleted is not a recurring event and the
-        // start and end time are outside the BusyBit range, then we could
-        // avoid clearing the BusyBits table.  For now, always clear the
-        // BusyBits table because deleting events is relatively rare.
-        mMetaData.writeLocked(fields.timezone, fields.minInstance, fields.maxInstance,
-                0 /* startDay */, 0 /* endDay */);
-    }
-
-    // Read the start and end time for an event from the Events table.
-    // Also read the "all-day" indicator.
-    private TimeRange readEventStartEnd(long eventId) {
-        Cursor cursor = null;
-        TimeRange range = new TimeRange();
-        try {
-            cursor = query(ContentUris.withAppendedId(Events.CONTENT_URI, eventId),
-                    new String[] { Events.DTSTART, Events.DTEND, Events.ALL_DAY },
-                    null /* selection */,
-                    null /* selectionArgs */,
-                    null /* sort */);
-            if (cursor == null || !cursor.moveToFirst()) {
-                Log.d(TAG, "Couldn't find " + eventId + " in Events table");
-                return null;
-            }
-            range.begin = cursor.getLong(0);
-            range.end = cursor.getLong(1);
-            range.allDay = cursor.getInt(2) != 0;
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-        return range;
-    }
-
     @Override
     public String getType(Uri url) {
         int match = sUriMatcher.match(url);
@@ -1676,9 +1166,8 @@
                 return "vnd.android.cursor.item/calendar-alert";
             case INSTANCES:
             case INSTANCES_BY_DAY:
+            case EVENT_DAYS:
                 return "vnd.android.cursor.dir/event-instance";
-            case BUSYBITS:
-                return "vnd.android.cursor.dir/busybits";
             default:
                 throw new IllegalArgumentException("Unknown URL " + url);
         }
@@ -1738,7 +1227,6 @@
                 if (id != -1) {
                     updateEventRawTimesLocked(id, updatedValues);
                     updateInstancesLocked(updatedValues, id, true /* new event */, mDb);
-                    insertBusyBitsLocked(id, updatedValues);
 
                     // If we inserted a new event that specified the self-attendee
                     // status, then we need to add an entry to the attendees table.
@@ -1819,6 +1307,7 @@
             case EXTENDED_PROPERTIES_ID:
             case INSTANCES:
             case INSTANCES_BY_DAY:
+            case EVENT_DAYS:
                 throw new UnsupportedOperationException("Cannot insert into that URL: " + uri);
             default:
                 throw new IllegalArgumentException("Unknown URL " + uri);
@@ -2333,7 +1822,6 @@
                             + "doesn't support selection based deletion for type "
                             + match);
                 }
-                deleteBusyBitsLocked(id);
 
                 if (callerIsSyncAdapter) {
                     mDb.delete("Events", "_id = " + id, null);
@@ -2486,6 +1974,7 @@
                 return deleteMatchingCalendars(selection); // TODO: handle in sync adapter
             case INSTANCES:
             case INSTANCES_BY_DAY:
+            case EVENT_DAYS:
                 throw new UnsupportedOperationException("Cannot delete that URL");
             default:
                 throw new IllegalArgumentException("Unknown URL " + uri);
@@ -2622,12 +2111,6 @@
                 }
 
                 int result = mDb.update("Calendars", values, "_id="+ id, null /* selectionArgs */);
-                // When we change the display status of a Calendar
-                // we need to update the busy bits.
-                if (values.containsKey(Calendars.SELECTED) || (syncEvents != null)) {
-                    // Clear the BusyBits table.
-                    mMetaData.clearBusyBitRange();
-                }
 
                 return result;
             }
@@ -2670,8 +2153,6 @@
                             + " in Events table is not allowed.");
                 }
 
-                updateBusyBitsLocked(id, values);
-
                 ContentValues updatedValues = updateContentValuesFromEvent(values);
                 if (updatedValues == null) {
                     Log.w(TAG, "Could not update event.");
@@ -3236,12 +2717,12 @@
     private static final int CALENDAR_ALERTS = 13;
     private static final int CALENDAR_ALERTS_ID = 14;
     private static final int CALENDAR_ALERTS_BY_INSTANCE = 15;
-    private static final int BUSYBITS = 16;
-    private static final int INSTANCES_BY_DAY = 17;
-    private static final int SYNCSTATE = 18;
-    private static final int SYNCSTATE_ID = 19;
-    private static final int EVENT_ENTITIES = 20;
-    private static final int EVENT_ENTITIES_ID = 21;
+    private static final int INSTANCES_BY_DAY = 16;
+    private static final int SYNCSTATE = 17;
+    private static final int SYNCSTATE_ID = 18;
+    private static final int EVENT_ENTITIES = 19;
+    private static final int EVENT_ENTITIES_ID = 20;
+    private static final int EVENT_DAYS = 21;
 
     private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
     private static final HashMap<String, String> sInstancesProjectionMap;
@@ -3250,11 +2731,11 @@
     private static final HashMap<String, String> sAttendeesProjectionMap;
     private static final HashMap<String, String> sRemindersProjectionMap;
     private static final HashMap<String, String> sCalendarAlertsProjectionMap;
-    private static final HashMap<String, String> sBusyBitsProjectionMap;
 
     static {
         sUriMatcher.addURI("calendar", "instances/when/*/*", INSTANCES);
         sUriMatcher.addURI("calendar", "instances/whenbyday/*/*", INSTANCES_BY_DAY);
+        sUriMatcher.addURI("calendar", "instances/groupbyday/*/*", EVENT_DAYS);
         sUriMatcher.addURI("calendar", "events", EVENTS);
         sUriMatcher.addURI("calendar", "events/#", EVENTS_ID);
         sUriMatcher.addURI("calendar", "event_entities", EVENT_ENTITIES);
@@ -3271,7 +2752,6 @@
         sUriMatcher.addURI("calendar", "calendar_alerts", CALENDAR_ALERTS);
         sUriMatcher.addURI("calendar", "calendar_alerts/#", CALENDAR_ALERTS_ID);
         sUriMatcher.addURI("calendar", "calendar_alerts/by_instance", CALENDAR_ALERTS_BY_INSTANCE);
-        sUriMatcher.addURI("calendar", "busybits/when/*/*", BUSYBITS);
         sUriMatcher.addURI("calendar", SyncStateContentProviderHelper.PATH, SYNCSTATE);
         sUriMatcher.addURI("calendar", SyncStateContentProviderHelper.PATH + "/#", SYNCSTATE_ID);
 
@@ -3381,12 +2861,6 @@
         sInstancesProjectionMap.put(Instances.START_MINUTE, "startMinute");
         sInstancesProjectionMap.put(Instances.END_MINUTE, "endMinute");
 
-        // BusyBits columns
-        sBusyBitsProjectionMap = new HashMap<String, String>();
-        sBusyBitsProjectionMap.put(BusyBits.DAY, "day");
-        sBusyBitsProjectionMap.put(BusyBits.BUSYBITS, "busyBits");
-        sBusyBitsProjectionMap.put(BusyBits.ALL_DAY_COUNT, "allDayCount");
-
         // Attendees columns
         sAttendeesProjectionMap.put(Attendees.EVENT_ID, "event_id");
         sAttendeesProjectionMap.put(Attendees._ID, "Attendees._id AS _id");
diff --git a/src/com/android/providers/calendar/MetaData.java b/src/com/android/providers/calendar/MetaData.java
index ed7f9d9..ded6d4f 100644
--- a/src/com/android/providers/calendar/MetaData.java
+++ b/src/com/android/providers/calendar/MetaData.java
@@ -44,12 +44,12 @@
         public int minBusyBit;      // Julian start day
         public int maxBusyBit;      // Julian end day
     }
-    
+
     /**
      * The cached copy of the meta-data fields from the database.
      */
     private Fields mFields = new Fields();
-    
+
     private final SQLiteOpenHelper mOpenHelper;
     private boolean mInitialized;
 
@@ -60,24 +60,20 @@
     private static final String[] sCalendarMetaDataProjection = {
         CalendarMetaData.LOCAL_TIMEZONE,
         CalendarMetaData.MIN_INSTANCE,
-        CalendarMetaData.MAX_INSTANCE,
-        CalendarMetaData.MIN_BUSYBITS,
-        CalendarMetaData.MAX_BUSYBITS };
-    
+        CalendarMetaData.MAX_INSTANCE};
+
     private static final int METADATA_INDEX_LOCAL_TIMEZONE = 0;
     private static final int METADATA_INDEX_MIN_INSTANCE = 1;
     private static final int METADATA_INDEX_MAX_INSTANCE = 2;
-    private static final int METADATA_INDEX_MIN_BUSYBIT = 3;
-    private static final int METADATA_INDEX_MAX_BUSYBIT = 4;
-    
+
     public MetaData(SQLiteOpenHelper openHelper) {
         mOpenHelper = openHelper;
     }
-    
+
     /**
      * Returns a copy of all the MetaData fields.  This method grabs a
      * database lock to read all the fields atomically.
-     * 
+     *
      * @return a copy of all the MetaData fields.
      */
     public Fields getFields() {
@@ -104,12 +100,12 @@
 
     /**
      * This method must be called only while holding a database lock.
-     * 
+     *
      * <p>
      * Returns a copy of all the MetaData fields.  This method assumes
      * the database lock has already been acquired.
      * </p>
-     * 
+     *
      * @return a copy of all the MetaData fields.
      */
     public Fields getFieldsLocked() {
@@ -128,7 +124,7 @@
         fields.maxBusyBit = mFields.maxBusyBit;
         return fields;
     }
-    
+
     /**
      * Reads the meta-data for the CalendarProvider from the database and
      * updates the member variables.  This method executes while the database
@@ -149,8 +145,6 @@
                 timezone = cursor.getString(METADATA_INDEX_LOCAL_TIMEZONE);
                 minInstance = cursor.getLong(METADATA_INDEX_MIN_INSTANCE);
                 maxInstance = cursor.getLong(METADATA_INDEX_MAX_INSTANCE);
-                minBusyBit = cursor.getInt(METADATA_INDEX_MIN_BUSYBIT);
-                maxBusyBit = cursor.getInt(METADATA_INDEX_MAX_BUSYBIT);
             }
         } finally {
             if (cursor != null) {
@@ -164,7 +158,7 @@
         mFields.maxInstance = maxInstance;
         mFields.minBusyBit = minBusyBit;
         mFields.maxBusyBit = maxBusyBit;
-        
+
         // Mark the fields as initialized
         mInitialized = true;
     }
@@ -173,7 +167,7 @@
      * Writes the meta-data for the CalendarProvider.  The values to write are
      * passed in as parameters.  All of the values are updated atomically,
      * including the cached copy of the meta-data.
-     * 
+     *
      * @param timezone the local timezone used for Instance expansion
      * @param begin the start of the Instance expansion in UTC milliseconds
      * @param end the end of the Instance expansion in UTC milliseconds
@@ -193,13 +187,13 @@
 
     /**
      * This method must be called only while holding a database lock.
-     * 
+     *
      * <p>
      * Writes the meta-data for the CalendarProvider.  The values to write are
      * passed in as parameters.  All of the values are updated atomically,
      * including the cached copy of the meta-data.
      * </p>
-     * 
+     *
      * @param timezone the local timezone used for Instance expansion
      * @param begin the start of the Instance expansion in UTC milliseconds
      * @param end the end of the Instance expansion in UTC milliseconds
@@ -212,8 +206,6 @@
         values.put(CalendarMetaData.LOCAL_TIMEZONE, timezone);
         values.put(CalendarMetaData.MIN_INSTANCE, begin);
         values.put(CalendarMetaData.MAX_INSTANCE, end);
-        values.put(CalendarMetaData.MIN_BUSYBITS, startDay);
-        values.put(CalendarMetaData.MAX_BUSYBITS, endDay);
 
         // Atomically update the database and the cached members.
         try {
@@ -239,7 +231,7 @@
      * Clears the time range for the Instances table.  The rows in the
      * Instances table will be deleted (and regenerated) the next time
      * that the Instances table is queried.
-     * 
+     *
      * Also clears the time range for the BusyBits table because that depends
      * on the Instances table.
      */
