diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e64b0e3..700096a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -64,5 +64,6 @@
                 <action android:name="android.intent.action.DATE_CHANGED" />
             </intent-filter>
         </receiver>
+        <service android:name=".CalendarAppWidgetService" />
     </application>
 </manifest>
diff --git a/src/com/android/providers/calendar/AppWidgetShared.java b/src/com/android/providers/calendar/AppWidgetShared.java
new file mode 100644
index 0000000..cb155b2
--- /dev/null
+++ b/src/com/android/providers/calendar/AppWidgetShared.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.calendar;
+
+import android.app.Service;
+import android.os.PowerManager.WakeLock;
+import android.util.Log;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Set of static variables that are shared between
+ * {@link CalendarAppWidgetProvider} and {@link CalendarAppWidgetService} and
+ * guarded by {@link #sLock}.
+ */
+public class AppWidgetShared {
+    static final String TAG = "AppWidgetShared";
+    // STOPSHIP: remove this debugging flag
+    static final boolean LOGD = true;
+    
+    static Object sLock = new Object();
+    static WakeLock sWakeLock;
+    static boolean sUpdateRequested = false;
+    static boolean sUpdateRunning = false;
+    
+    /**
+     * {@link System#currentTimeMillis()} at last update request. 
+     */
+    static long sLastRequest = -1;
+
+    private static HashSet<Integer> sAppWidgetIds = new HashSet<Integer>();
+    private static HashSet<Long> sChangedEventIds = new HashSet<Long>();
+    
+    /**
+     * Merge a set of filtering appWidgetIds with those from other pending
+     * requests. If null, then reset the filter to match all.
+     * <p>
+     * Only call this while holding a {@link #sLock} lock.
+     */
+    static void mergeAppWidgetIdsLocked(int[] appWidgetIds) {
+        if (appWidgetIds != null) {
+            for (int appWidgetId : appWidgetIds) {
+                sAppWidgetIds.add(appWidgetId);
+            }
+        } else {
+            sAppWidgetIds.clear();
+        }
+    }
+    
+    /**
+     * Merge a set of filtering changedEventIds with those from other pending
+     * requests. If null, then reset the filter to match all.
+     * <p>
+     * Only call this while holding a {@link #sLock} lock.
+     */
+    static void mergeChangedEventIdsLocked(long[] changedEventIds) {
+        if (changedEventIds != null) {
+            for (long changedEventId : changedEventIds) {
+                sChangedEventIds.add(changedEventId);
+            }
+        } else {
+            sChangedEventIds.clear();
+        }
+    }
+
+    /**
+     * Collect all currently requested appWidgetId filters, returning as single
+     * list. This call also clears the internal list.
+     * <p>
+     * Only call this while holding a {@link #sLock} lock.
+     */
+    static int[] collectAppWidgetIdsLocked() {
+        final int size = sAppWidgetIds.size();
+        int[] array = new int[size];
+        Iterator<Integer> iterator = sAppWidgetIds.iterator();
+        for (int i = 0; i < size; i++) {
+            array[i] = iterator.next();
+        }
+        sAppWidgetIds.clear();
+        return array;
+    }
+
+    /**
+     * Collect all currently requested changedEventId filters, returning as
+     * single list. This call also clears the internal list.
+     * <p>
+     * Only call this while holding a {@link #sLock} lock.
+     */
+    static Set<Long> collectChangedEventIdsLocked() {
+        Set<Long> set = new HashSet<Long>();
+        for (Long value : sChangedEventIds) {
+            set.add(value);
+        }
+        sChangedEventIds.clear();
+        return set;
+    }
+
+    /**
+     * Call this at any point to release any {@link WakeLock} and reset to
+     * default state. Usually called before {@link Service#stopSelf()}.
+     * <p>
+     * Only call this while holding a {@link #sLock} lock.
+     */
+    static void clearLocked() {
+        if (sWakeLock != null && sWakeLock.isHeld()) {
+            if (LOGD) Log.d(TAG, "found held wakelock, so releasing");
+            sWakeLock.release();
+        }
+        sWakeLock = null;
+        
+        sUpdateRequested = false;
+        sUpdateRunning = false;
+        
+        sAppWidgetIds.clear();
+        sChangedEventIds.clear();
+    }
+}
diff --git a/src/com/android/providers/calendar/CalendarAppWidgetProvider.java b/src/com/android/providers/calendar/CalendarAppWidgetProvider.java
index 02e83ec..7050060 100644
--- a/src/com/android/providers/calendar/CalendarAppWidgetProvider.java
+++ b/src/com/android/providers/calendar/CalendarAppWidgetProvider.java
@@ -21,77 +21,25 @@
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProvider;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.Typeface;
-import android.graphics.Paint.FontMetrics;
-import android.net.Uri;
-import android.provider.Calendar.Attendees;
-import android.provider.Calendar.Calendars;
-import android.provider.Calendar.Instances;
-import android.text.format.DateFormat;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
 import android.text.format.DateUtils;
-import android.text.format.Time;
 import android.util.Log;
-import android.view.View;
-import android.widget.RemoteViews;
-
-import java.util.TimeZone;
 
 /**
  * Simple widget to show next upcoming calendar event.
  */
 public class CalendarAppWidgetProvider extends AppWidgetProvider {
     static final String TAG = "CalendarAppWidgetProvider";
+    // STOPSHIP: remove this debugging flag
     static final boolean LOGD = true;
-    
-    static final String EVENT_SORT_ORDER = "startDay ASC, allDay DESC, begin ASC";
 
-    static final String[] EVENT_PROJECTION = new String[] {
-        Instances.ALL_DAY,
-        Instances.BEGIN,
-        Instances.END,
-        Instances.COLOR,
-        Instances.TITLE,
-        Instances.RRULE,
-        Instances.HAS_ALARM,
-        Instances.EVENT_LOCATION,
-        Instances.CALENDAR_ID,
-        Instances.EVENT_ID,
-    };
-
-    static final int INDEX_ALL_DAY = 0;
-    static final int INDEX_BEGIN = 1;
-    static final int INDEX_END = 2;
-    static final int INDEX_COLOR = 3;
-    static final int INDEX_TITLE = 4;
-    static final int INDEX_RRULE = 5;
-    static final int INDEX_HAS_ALARM = 6;
-    static final int INDEX_EVENT_LOCATION = 7;
-    static final int INDEX_CALENDAR_ID = 8;
-    static final int INDEX_EVENT_ID = 9;
+    static final String ACTION_CALENDAR_APPWIDGET_UPDATE =
+            "com.android.providers.calendar.APPWIDGET_UPDATE";
     
-    static final long SEARCH_DURATION = DateUtils.WEEK_IN_MILLIS;
-    
-    static final long UPDATE_NO_EVENTS = DateUtils.HOUR_IN_MILLIS * 6;
-
-    static final String ACTION_CALENDAR_APPWIDGET_UPDATE = "com.android.calendar.APPWIDGET_UPDATE";
-    
-    static final String PACKAGE_DETAIL = "com.android.calendar";
-    static final String CLASS_DETAIL = "com.android.calendar.AgendaActivity";
-    
-    static final ComponentName THIS_APPWIDGET =
-        new ComponentName("com.android.providers.calendar",
-                "com.android.providers.calendar.CalendarAppWidgetProvider");
-
     /**
      * Threshold to check against when building widget updates. If system clock
      * has changed less than this amount, we consider ignoring the request.
@@ -99,10 +47,10 @@
     static final long UPDATE_THRESHOLD = DateUtils.MINUTE_IN_MILLIS;
 
     /**
-     * Last widget update, as provided by {@link System#currentTimeMillis()}
+     * Maximum time to hold {@link WakeLock} when performing widget updates.
      */
-    private static long sLastUpdate = -1;
-    
+    static final long WAKE_LOCK_TIMEOUT = DateUtils.MINUTE_IN_MILLIS;
+
     private static CalendarAppWidgetProvider sInstance;
     
     static synchronized CalendarAppWidgetProvider getInstance() {
@@ -122,7 +70,7 @@
         final String action = intent.getAction();
         if (ACTION_CALENDAR_APPWIDGET_UPDATE.equals(action)) {
             performUpdate(context, null /* all widgets */,
-                    -1 /* no eventId */, false /* don't ignore */);
+                    null /* no eventIds */, false /* don't ignore */);
         } else {
             super.onReceive(context, intent);
         }
@@ -164,7 +112,7 @@
      */
     @Override
     public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
-        performUpdate(context, appWidgetIds, -1 /* no eventId */, false /* don't ignore */);
+        performUpdate(context, appWidgetIds, null /* no eventIds */, false /* force */);
     }
     
     /**
@@ -172,9 +120,18 @@
      */
     private boolean hasInstances(Context context) {
         AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
-        int[] appWidgetIds = appWidgetManager.getAppWidgetIds(THIS_APPWIDGET);
+        ComponentName thisAppWidget = getComponentName(context);
+        int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
         return (appWidgetIds.length > 0);
     }
+    
+    /**
+     * Build {@link ComponentName} describing this specific
+     * {@link AppWidgetProvider}
+     */
+    static ComponentName getComponentName(Context context) {
+        return new ComponentName(context, CalendarAppWidgetProvider.class);
+    }
 
     /**
      * The {@link CalendarProvider} has been updated, which means we should push
@@ -187,7 +144,7 @@
     void providerUpdated(Context context, long changedEventId) {
         if (hasInstances(context)) {
             performUpdate(context, null /* all widgets */,
-                    changedEventId, false /* don't ignore */);
+                    new long[] { changedEventId }, false /* force */);
         }
     }
 
@@ -195,537 +152,89 @@
      * {@link TimeChangeReceiver} has triggered that the time changed.
      * 
      * @param context Context to use when creating widget.
-     * @param considerIgnore If true, compare {@link #sLastUpdate} against
+     * @param considerIgnore If true, compare
+     *            {@link AppWidgetShared#sLastRequest} against
      *            {@link #UPDATE_THRESHOLD} to consider ignoring this update
      *            request.
      */
     void timeUpdated(Context context, boolean considerIgnore) {
         if (hasInstances(context)) {
-            performUpdate(context, null /* all widgets */,
-                    -1 /* no eventId */, considerIgnore);
+            performUpdate(context, null /* all widgets */, null /* no events */, considerIgnore);
         }
     }
-
+    
     /**
-     * Process and push out an update for the given appWidgetIds.
+     * Process and push out an update for the given appWidgetIds. This call
+     * actually fires an intent to start {@link CalendarAppWidgetService} as a
+     * background service which handles the actual update, to prevent ANR'ing
+     * during database queries.
+     * <p>
+     * This call will acquire a single {@link WakeLock} and set a flag that an
+     * update has been requested.
      * 
-     * @param context Context to use when creating widget.
-     * @param appWidgetIds List of specific appWidgetIds to update, or null for all.
-     * @param changedEventId Specific event known to be changed, otherwise -1.
-     *            If present, we use it to decide if an update is necessary.
-     * @param considerIgnore If true, compare {@link #sLastUpdate} against
+     * @param context Context to use when acquiring {@link WakeLock} and
+     *            starting {@link CalendarAppWidgetService}.
+     * @param appWidgetIds List of specific appWidgetIds to update, or null for
+     *            all.
+     * @param changedEventIds Specific events known to be changed. If present,
+     *            we use it to decide if an update is necessary.
+     * @param considerIgnore If true, compare
+     *            {@link AppWidgetShared#sLastRequest} against
      *            {@link #UPDATE_THRESHOLD} to consider ignoring this update
      *            request.
      */
     private void performUpdate(Context context, int[] appWidgetIds,
-            long changedEventId, boolean considerIgnore) {
-        ContentResolver resolver = context.getContentResolver();
-        
-        long now = System.currentTimeMillis();
-        
-        // Check against delta if we have a last-updated value
-        if (considerIgnore && sLastUpdate != -1) {
-            long delta = Math.abs(now - sLastUpdate);
-            if (delta < UPDATE_THRESHOLD) {
-                if (LOGD) Log.d(TAG, "Ignoring update request because delta=" + delta);
-                return;
-            }
-        }
-        sLastUpdate = now;
-        
-        Cursor cursor = null;
-        RemoteViews views = null;
-        long triggerTime = -1;
-
-        try {
-            cursor = getUpcomingInstancesCursor(resolver, SEARCH_DURATION, now);
-            if (cursor != null) {
-                MarkedEvents events = buildMarkedEvents(cursor, changedEventId, now);
-                
-                boolean shouldUpdate = true;
-                if (changedEventId != -1) {
-                    shouldUpdate = events.watchFound;
+            long[] changedEventIds, boolean considerIgnore) {
+        synchronized (AppWidgetShared.sLock) {
+            // Consider ignoring this update request if inside threshold. This
+            // check is inside the lock because we depend on this "now" time.
+            long now = System.currentTimeMillis();
+            if (considerIgnore && AppWidgetShared.sLastRequest != -1) {
+                long delta = Math.abs(now - AppWidgetShared.sLastRequest);
+                if (delta < UPDATE_THRESHOLD) {
+                    if (LOGD) Log.d(TAG, "Ignoring update request because delta=" + delta);
+                    return;
                 }
-                
-                if (events.primaryCount == 0) {
-                    views = getAppWidgetNoEvents(context);
-                } else if (shouldUpdate) {
-                    views = getAppWidgetUpdate(context, cursor, events);
-                    triggerTime = calculateUpdateTime(cursor, events);
-                }
-            } else {
-                views = getAppWidgetNoEvents(context);
             }
-        } finally {
-            if (cursor != null) {
-                cursor.close();
+            
+            // We need to update, so make sure we have a valid, held wakelock
+            if (AppWidgetShared.sWakeLock == null ||
+                    !AppWidgetShared.sWakeLock.isHeld()) {
+                if (LOGD) Log.d(TAG, "no held wakelock found, so acquiring new one");
+                PowerManager powerManager = (PowerManager)
+                        context.getSystemService(Context.POWER_SERVICE);
+                AppWidgetShared.sWakeLock =
+                        powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+                AppWidgetShared.sWakeLock.setReferenceCounted(false);
+                AppWidgetShared.sWakeLock.acquire(WAKE_LOCK_TIMEOUT);
             }
+            
+            if (LOGD) Log.d(TAG, "setting request now=" + now);
+            AppWidgetShared.sLastRequest = now;
+            AppWidgetShared.sUpdateRequested = true;
+            
+            // Apply filters that would limit the scope of this update, or clear
+            // any pending filters if all requested.
+            AppWidgetShared.mergeAppWidgetIdsLocked(appWidgetIds);
+            AppWidgetShared.mergeChangedEventIdsLocked(changedEventIds);
+            
+            // Launch over to service so it can perform update
+            final Intent updateIntent = new Intent(context, CalendarAppWidgetService.class);
+            context.startService(updateIntent);
         }
-        
-        // Bail out early if no update built
-        if (views == null) {
-            if (LOGD) Log.d(TAG, "Didn't build update, possibly because changedEventId=" + changedEventId);
-            return;
-        }
-        
-        AppWidgetManager gm = AppWidgetManager.getInstance(context);
-        if (appWidgetIds != null) {
-            gm.updateAppWidget(appWidgetIds, views);
-        } else {
-            gm.updateAppWidget(THIS_APPWIDGET, views);
-        }
-
-        // Schedule an alarm to wake ourselves up for the next update.  We also cancel
-        // all existing wake-ups because PendingIntents don't match against extras.
-        
-        // If no next-update calculated, or bad trigger time in past, schedule
-        // update about six hours from now.
-        if (triggerTime == -1 || triggerTime < now) {
-            if (LOGD) Log.w(TAG, "Encountered bad trigger time " + formatDebugTime(triggerTime, now));
-            triggerTime = now + UPDATE_NO_EVENTS;
-        }
-        
-        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
-        PendingIntent pendingUpdate = getUpdateIntent(context);
-        
-        am.cancel(pendingUpdate);
-        am.set(AlarmManager.RTC, triggerTime, pendingUpdate);
-
-        if (LOGD) Log.d(TAG, "Scheduled next update at " + formatDebugTime(triggerTime, now));
     }
     
     /**
      * Build the {@link PendingIntent} used to trigger an update of all calendar
-     * widgets. Uses {@link ACTION_CALENDAR_APPWIDGET_UPDATE} to directly target
+     * widgets. Uses {@link #ACTION_CALENDAR_APPWIDGET_UPDATE} to directly target
      * all widgets instead of using {@link AppWidgetManager#EXTRA_APPWIDGET_IDS}.
      * 
      * @param context Context to use when building broadcast.
      */
-    private PendingIntent getUpdateIntent(Context context) {
+    static PendingIntent getUpdateIntent(Context context) {
         Intent updateIntent = new Intent(ACTION_CALENDAR_APPWIDGET_UPDATE);
         updateIntent.setComponent(new ComponentName(context, CalendarAppWidgetProvider.class));
         return PendingIntent.getBroadcast(context, 0 /* no requestCode */,
                 updateIntent, 0 /* no flags */);
     }
-
-    /**
-     * Format given time for debugging output.
-     * 
-     * @param unixTime Target time to report.
-     * @param now Current system time from {@link System#currentTimeMillis()}
-     *            for calculating time difference.
-     */
-    private String formatDebugTime(long unixTime, long now) {
-        Time time = new Time();
-        time.set(unixTime);
-        
-        long delta = unixTime - now;
-        if (delta > DateUtils.MINUTE_IN_MILLIS) {
-            delta /= DateUtils.MINUTE_IN_MILLIS;
-            return String.format("[%d] %s (%+d mins)", unixTime, time.format("%H:%M:%S"), delta);
-        } else {
-            delta /= DateUtils.SECOND_IN_MILLIS;
-            return String.format("[%d] %s (%+d secs)", unixTime, time.format("%H:%M:%S"), delta);
-        }
-    }
-    
-    /**
-     * Convert given UTC time into current local time.
-     * 
-     * @param recycle Time object to recycle, otherwise null.
-     * @param utcTime Time to convert, in UTC.
-     */
-    private long convertUtcToLocal(Time recycle, long utcTime) {
-        if (recycle == null) {
-            recycle = new Time();
-        }
-        recycle.timezone = Time.TIMEZONE_UTC;
-        recycle.set(utcTime);
-        recycle.timezone = TimeZone.getDefault().getID();
-        return recycle.normalize(true);
-    }
-    
-    /**
-     * Figure out the next time we should push widget updates. This is based on
-     * the time calculated by {@link #getEventFlip(Cursor, int)}.
-     * 
-     * @param cursor Valid cursor on {@link Instances#CONTENT_URI}
-     * @param events {@link MarkedEvents} parsed from the cursor
-     */
-    private long calculateUpdateTime(Cursor cursor, MarkedEvents events) {
-        long result = -1;
-        if (events.primaryRow != -1) {
-            cursor.moveToPosition(events.primaryRow);
-            long start = cursor.getLong(INDEX_BEGIN);
-            long end = cursor.getLong(INDEX_END);
-            boolean allDay = cursor.getInt(INDEX_ALL_DAY) != 0;
-            
-            // Adjust all-day times into local timezone
-            if (allDay) {
-                final Time recycle = new Time();
-                start = convertUtcToLocal(recycle, start);
-                end = convertUtcToLocal(recycle, end);
-            }
-
-            result = getEventFlip(cursor, start, end, allDay);
-        }
-        return result;
-    }
-    
-    /**
-     * Calculate flipping point for the given event; when we should hide this
-     * event and show the next one. This is usually half-way through the event.
-     * 
-     * @param start Event start time in local timezone.
-     * @param end Event end time in local timezone.
-     */
-    private long getEventFlip(Cursor cursor, long start, long end, boolean allDay) {
-        if (allDay) {
-            return start;
-        } else {
-            return (start + end) / 2;
-        }
-    }
-    
-    /**
-     * Build a set of {@link RemoteViews} that describes how to update any
-     * widget for a specific event instance.
-     * 
-     * @param cursor Valid cursor on {@link Instances#CONTENT_URI}
-     * @param events {@link MarkedEvents} parsed from the cursor
-     */
-    private RemoteViews getAppWidgetUpdate(Context context, Cursor cursor, MarkedEvents events) {
-        Resources res = context.getResources();
-        ContentResolver resolver = context.getContentResolver();
-        
-        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.agenda_appwidget);
-        
-        // Clicking on widget launches the agenda view in Calendar
-        Intent agendaIntent = new Intent();
-        agendaIntent.setComponent(new ComponentName(PACKAGE_DETAIL, CLASS_DETAIL));
-        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* no requestCode */,
-                agendaIntent, 0 /* no flags */);
-        
-        views.setOnClickPendingIntent(R.id.agenda_appwidget, pendingIntent);
-        
-        Time time = new Time();
-        time.setToNow();
-        int yearDay = time.yearDay;
-        int dateNumber = time.monthDay;
-
-        // Set calendar icon with actual date
-        views.setImageViewBitmap(R.id.icon, getDateOverlay(res, dateNumber));
-        views.setViewVisibility(R.id.icon, View.VISIBLE);
-        views.setViewVisibility(R.id.no_events, View.GONE);
-
-        // Fill primary event details
-        if (events.primaryRow != -1) {
-            views.setViewVisibility(R.id.primary_card, View.VISIBLE);
-            cursor.moveToPosition(events.primaryRow);
-            
-            // Color stripe
-            int colorFilter = cursor.getInt(INDEX_COLOR);
-            views.setDrawableParameters(R.id.when, true, -1, colorFilter,
-                    PorterDuff.Mode.SRC_IN, -1);
-            views.setTextColor(R.id.title, colorFilter);
-            views.setTextColor(R.id.where, colorFilter);
-            views.setDrawableParameters(R.id.divider, true, -1, colorFilter,
-                    PorterDuff.Mode.SRC_IN, -1);
-            views.setTextColor(R.id.title2, colorFilter);
-
-            // When
-            long start = cursor.getLong(INDEX_BEGIN);
-            boolean allDay = cursor.getInt(INDEX_ALL_DAY) != 0;
-            
-            int flags;
-            String whenString;
-            if (allDay) {
-                flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_UTC
-                        | DateUtils.FORMAT_SHOW_DATE;
-            } else {
-                flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_TIME;
-                
-                // Show date if different from today
-                time.set(start);
-                if (yearDay != time.yearDay) {
-                    flags = flags | DateUtils.FORMAT_SHOW_DATE;
-                }
-            }
-            if (DateFormat.is24HourFormat(context)) {
-                flags |= DateUtils.FORMAT_24HOUR;
-            }
-            whenString = DateUtils.formatDateRange(context, start, start, flags);
-            views.setTextViewText(R.id.when, whenString);
-
-            // What
-            String titleString = cursor.getString(INDEX_TITLE);
-            if (titleString == null || titleString.length() == 0) {
-                titleString = context.getString(R.string.no_title_label);
-            }
-            views.setTextViewText(R.id.title, titleString);
-            
-            // Where
-            String whereString = cursor.getString(INDEX_EVENT_LOCATION);
-            if (whereString != null && whereString.length() > 0) {
-                views.setViewVisibility(R.id.where, View.VISIBLE);
-                views.setViewVisibility(R.id.stub_where, View.INVISIBLE);
-                views.setTextViewText(R.id.where, whereString);
-            } else {
-                views.setViewVisibility(R.id.where, View.GONE);
-                views.setViewVisibility(R.id.stub_where, View.GONE);
-            }
-        }
-        
-        // Fill other primary events, if present
-        if (events.primaryConflictRow != -1) {
-            views.setViewVisibility(R.id.divider, View.VISIBLE);
-            views.setViewVisibility(R.id.title2, View.VISIBLE);
-
-            if (events.primaryCount > 2) {
-                // If more than two primary conflicts, format multiple message
-                int count = events.primaryCount - 1;
-                String titleString = String.format(res.getQuantityString(
-                        R.plurals.gadget_more_events, count), count);
-                views.setTextViewText(R.id.title2, titleString);
-            } else {
-                cursor.moveToPosition(events.primaryConflictRow);
-
-                // What
-                String titleString = cursor.getString(INDEX_TITLE);
-                if (titleString == null || titleString.length() == 0) {
-                    titleString = context.getString(R.string.no_title_label);
-                }
-                views.setTextViewText(R.id.title2, titleString);
-            }
-        } else {
-            views.setViewVisibility(R.id.divider, View.GONE);
-            views.setViewVisibility(R.id.title2, View.GONE);
-        }
-        
-        // Fill secondary event
-        if (events.secondaryRow != -1) {
-            views.setViewVisibility(R.id.secondary_card, View.VISIBLE);
-            views.setViewVisibility(R.id.secondary_when, View.VISIBLE);
-            views.setViewVisibility(R.id.secondary_title, View.VISIBLE);
-            
-            cursor.moveToPosition(events.secondaryRow);
-            
-            // Color stripe
-            int colorFilter = cursor.getInt(INDEX_COLOR);
-            views.setDrawableParameters(R.id.secondary_when, true, -1, colorFilter,
-                    PorterDuff.Mode.SRC_IN, -1);
-            views.setTextColor(R.id.secondary_title, colorFilter);
-            
-            // When
-            long start = cursor.getLong(INDEX_BEGIN);
-            boolean allDay = cursor.getInt(INDEX_ALL_DAY) != 0;
-            
-            int flags;
-            String whenString;
-            if (allDay) {
-                flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_UTC
-                        | DateUtils.FORMAT_SHOW_DATE;
-            } else {
-                flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_TIME;
-                
-                // Show date if different from today
-                time.set(start);
-                if (yearDay != time.yearDay) {
-                    flags = flags | DateUtils.FORMAT_SHOW_DATE;
-                }
-            }
-            if (DateFormat.is24HourFormat(context)) {
-                flags |= DateUtils.FORMAT_24HOUR;
-            }
-            whenString = DateUtils.formatDateRange(context, start, start, flags);
-            views.setTextViewText(R.id.secondary_when, whenString);
-            
-            if (events.secondaryCount > 1) {
-                // If more than two secondary conflicts, format multiple message
-                int count = events.secondaryCount;
-                String titleString = String.format(res.getQuantityString(
-                        R.plurals.gadget_more_events, count), count);
-                views.setTextViewText(R.id.secondary_title, titleString);
-            } else {
-                // What
-                String titleString = cursor.getString(INDEX_TITLE);
-                if (titleString == null || titleString.length() == 0) {
-                    titleString = context.getString(R.string.no_title_label);
-                }
-                views.setTextViewText(R.id.secondary_title, titleString);
-            }
-        } else {
-            views.setViewVisibility(R.id.secondary_when, View.GONE);
-            views.setViewVisibility(R.id.secondary_title, View.GONE);
-        }
-        
-        return views;
-    }
-
-    /**
-     * Build date overlay bitmap for positioning on widget. This is the textual
-     * number that has been corrected for font leading issues.
-     * 
-     * @param res {@link Resources} to use for paint color.
-     * @param dateNumber Numerical date to display.
-     */
-    public Bitmap getDateOverlay(Resources res, int dateNumber) {
-        String dateString = Integer.toString(dateNumber);
-        
-        Paint paint = new Paint();
-        paint.setTypeface(Typeface.DEFAULT_BOLD);
-        paint.setTextSize(18);
-        paint.setAntiAlias(true);
-        paint.setSubpixelText(true);
-        paint.setColor(res.getColor(R.color.appwidget_date));
-        
-        // Calculate exact size of text
-        FontMetrics metrics = paint.getFontMetrics();
-        int width = (int) Math.ceil(paint.measureText(dateString));
-        int height = (int) Math.ceil(-metrics.top + metrics.descent);
-        
-        // Add padding to left edge based on various obscure rules
-        // to make font center correctly
-        char firstChar = dateString.charAt(0);
-        char lastChar = dateString.charAt(dateString.length() - 1);
-        int leftPadding = (dateString.length() == 1 || firstChar == '2' ||
-                lastChar == '1' || lastChar == '0') ? 1 : 0;
-        
-        Bitmap overlay = Bitmap.createBitmap(width + leftPadding,
-                height, Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(overlay);
-        canvas.drawText(dateString, leftPadding, -metrics.top, paint);
-        
-        return overlay;
-    }
-    
-    /**
-     * Build a set of {@link RemoteViews} that describes an error state.
-     */
-    private RemoteViews getAppWidgetNoEvents(Context context) {
-        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.agenda_appwidget);
-
-        views.setViewVisibility(R.id.no_events, View.VISIBLE);
-        
-        views.setViewVisibility(R.id.icon, View.GONE);
-        views.setViewVisibility(R.id.primary_card, View.GONE);
-        views.setViewVisibility(R.id.secondary_card, View.GONE);
-        
-        // Clicking on widget launches the agenda view in Calendar
-        Intent agendaIntent = new Intent();
-        agendaIntent.setComponent(new ComponentName(PACKAGE_DETAIL, CLASS_DETAIL));
-        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* no requestCode */,
-                agendaIntent, 0 /* no flags */);
-        
-        views.setOnClickPendingIntent(R.id.agenda_appwidget, pendingIntent);
-
-        return views;
-    }
-    
-    private static class MarkedEvents {
-        long primaryTime = -1;
-        int primaryRow = -1;
-        int primaryConflictRow = -1;
-        int primaryCount = 0;
-        long secondaryTime = -1;
-        int secondaryRow = -1;
-        int secondaryCount = 0;
-        boolean watchFound = false;
-    }
-
-    /**
-     * Walk the given instances cursor and build a list of marked events to be
-     * used when updating the widget. This structure is also used to check if
-     * updates are needed.
-     * 
-     * @param cursor Valid cursor across {@link Instances#CONTENT_URI}.
-     * @param watchEventId Specific event to watch for, setting
-     *            {@link MarkedEvents#watchFound} if found during marking.
-     * @param now Current system time to use for this update, possibly from
-     *            {@link System#currentTimeMillis()}
-     */
-    private MarkedEvents buildMarkedEvents(Cursor cursor, long watchEventId, long now) {
-        MarkedEvents events = new MarkedEvents();
-        final Time recycle = new Time();
-        
-        cursor.moveToPosition(-1);
-        while (cursor.moveToNext()) {
-            int row = cursor.getPosition();
-            long eventId = cursor.getLong(INDEX_EVENT_ID);
-            long start = cursor.getLong(INDEX_BEGIN);
-            long end = cursor.getLong(INDEX_END);
-            boolean allDay = cursor.getInt(INDEX_ALL_DAY) != 0;
-
-            // Adjust all-day times into local timezone
-            if (allDay) {
-                start = convertUtcToLocal(recycle, start);
-                end = convertUtcToLocal(recycle, end);
-            }
-            
-            // Skip events that have already passed their flip times
-            long eventFlip = getEventFlip(cursor, start, end, allDay);
-            if (LOGD) Log.d(TAG, "Calculated flip time " + formatDebugTime(eventFlip, now));
-            if (eventFlip < now) {
-                continue;
-            }
-            
-            // Mark if we've encountered the watched event
-            if (eventId == watchEventId) {
-                events.watchFound = true;
-            }
-            
-            if (events.primaryRow == -1) {
-                // Found first event
-                events.primaryRow = row;
-                events.primaryTime = start;
-                events.primaryCount = 1;
-            } else if (events.primaryTime == start) {
-                // Found conflicting primary event
-                if (events.primaryConflictRow == -1) {
-                    events.primaryConflictRow = row;
-                }
-                events.primaryCount += 1;
-            } else if (events.secondaryRow == -1) {
-                // Found second event
-                events.secondaryRow = row;
-                events.secondaryTime = start;
-                events.secondaryCount = 1;
-            } else if (events.secondaryTime == start) {
-                // Found conflicting secondary event
-                events.secondaryCount += 1;
-            } else {
-                // Nothing interesting about this event, so bail out
-                break;
-            }
-        }
-        return events;
-    }
-
-    /**
-     * Query across all calendars for upcoming event instances from now until
-     * some time in the future.
-     * 
-     * @param resolver {@link ContentResolver} to use when querying
-     *            {@link Instances#CONTENT_URI}.
-     * @param searchDuration Distance into the future to look for event
-     *            instances, in milliseconds.
-     * @param now Current system time to use for this update, possibly from
-     *            {@link System#currentTimeMillis()}.
-     */
-    private Cursor getUpcomingInstancesCursor(ContentResolver resolver,
-            long searchDuration, long now) {
-        // Search for events from now until some time in the future
-        long end = now + searchDuration;
-        
-        Uri uri = Uri.withAppendedPath(Instances.CONTENT_URI,
-                String.format("%d/%d", now, end));
-
-        String selection = String.format("%s=1 AND %s!=%d",
-                Calendars.SELECTED, Instances.SELF_ATTENDEE_STATUS,
-                Attendees.ATTENDEE_STATUS_DECLINED);
-        
-        return resolver.query(uri, EVENT_PROJECTION, selection, null,
-                EVENT_SORT_ORDER);
-    }
-    
 }
diff --git a/src/com/android/providers/calendar/CalendarAppWidgetService.java b/src/com/android/providers/calendar/CalendarAppWidgetService.java
new file mode 100644
index 0000000..b88d2e4
--- /dev/null
+++ b/src/com/android/providers/calendar/CalendarAppWidgetService.java
@@ -0,0 +1,636 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.calendar;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.appwidget.AppWidgetManager;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.Typeface;
+import android.graphics.Paint.FontMetrics;
+import android.net.Uri;
+import android.os.IBinder;
+import android.provider.Calendar.Attendees;
+import android.provider.Calendar.Calendars;
+import android.provider.Calendar.Instances;
+import android.text.format.DateFormat;
+import android.text.format.DateUtils;
+import android.text.format.Time;
+import android.util.Log;
+import android.view.View;
+import android.widget.RemoteViews;
+
+import java.util.Set;
+import java.util.TimeZone;
+
+
+public class CalendarAppWidgetService extends Service implements Runnable {
+    static final String TAG = "CalendarAppWidgetService";
+    // STOPSHIP: remove this debugging flag
+    static final boolean LOGD = true;
+    
+    static final String EVENT_SORT_ORDER = "startDay ASC, allDay DESC, begin ASC";
+
+    static final String[] EVENT_PROJECTION = new String[] {
+        Instances.ALL_DAY,
+        Instances.BEGIN,
+        Instances.END,
+        Instances.COLOR,
+        Instances.TITLE,
+        Instances.RRULE,
+        Instances.HAS_ALARM,
+        Instances.EVENT_LOCATION,
+        Instances.CALENDAR_ID,
+        Instances.EVENT_ID,
+    };
+
+    static final int INDEX_ALL_DAY = 0;
+    static final int INDEX_BEGIN = 1;
+    static final int INDEX_END = 2;
+    static final int INDEX_COLOR = 3;
+    static final int INDEX_TITLE = 4;
+    static final int INDEX_RRULE = 5;
+    static final int INDEX_HAS_ALARM = 6;
+    static final int INDEX_EVENT_LOCATION = 7;
+    static final int INDEX_CALENDAR_ID = 8;
+    static final int INDEX_EVENT_ID = 9;
+    
+    static final long SEARCH_DURATION = DateUtils.WEEK_IN_MILLIS;
+    
+    static final long UPDATE_NO_EVENTS = DateUtils.HOUR_IN_MILLIS * 6;
+    
+    static final String ACTION_PACKAGE = "com.android.calendar";
+    static final String ACTION_CLASS = "com.android.calendar.AgendaActivity";
+    
+    @Override
+    public void onStart(Intent intent, int startId) {
+        super.onStart(intent, startId);
+        
+        // Only start processing thread if not already running
+        synchronized (AppWidgetShared.sLock) {
+            if (!AppWidgetShared.sUpdateRunning) {
+                if (LOGD) Log.d(TAG, "no thread running, so starting new one");
+                AppWidgetShared.sUpdateRunning = true;
+                new Thread(this).start();
+            }
+        }
+    }
+    
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+    
+    /**
+     * Thread loop to handle 
+     */
+    public void run() {
+        while (true) {
+            long now = -1;
+            int[] appWidgetIds;
+            Set<Long> changedEventIds;
+            
+            synchronized (AppWidgetShared.sLock) {
+                // Bail out if no remaining updates 
+                if (!AppWidgetShared.sUpdateRequested) {
+                    // Clear current shared state, release wakelock, and stop service
+                    if (LOGD) Log.d(TAG, "no requested update or expired wakelock, bailing");
+                    AppWidgetShared.clearLocked();
+                    stopSelf();
+                    return;
+                }
+                
+                // Clear requested flag and collect latest parameters 
+                AppWidgetShared.sUpdateRequested = false;
+                
+                now = AppWidgetShared.sLastRequest;
+                appWidgetIds = AppWidgetShared.collectAppWidgetIdsLocked();
+                changedEventIds = AppWidgetShared.collectChangedEventIdsLocked();
+            }
+            
+            // Process this update
+            if (LOGD) Log.d(TAG, "processing requested update now=" + now);
+            performUpdate(this, appWidgetIds, changedEventIds, now);
+        }
+    }
+
+    /**
+     * Process and push out an update for the given appWidgetIds.
+     * 
+     * @param context Context to use when updating widget.
+     * @param appWidgetIds List of appWidgetIds to update, or null for all.
+     * @param changedEventIds Specific events known to be changed, otherwise
+     *            null. If present, we use to decide if an update is necessary.
+     * @param now System clock time to use during this update.
+     */
+    private void performUpdate(Context context, int[] appWidgetIds,
+            Set<Long> changedEventIds, long now) {
+        ContentResolver resolver = context.getContentResolver();
+        
+        Cursor cursor = null;
+        RemoteViews views = null;
+        long triggerTime = -1;
+
+        try {
+            cursor = getUpcomingInstancesCursor(resolver, SEARCH_DURATION, now);
+            if (cursor != null) {
+                MarkedEvents events = buildMarkedEvents(cursor, changedEventIds, now);
+                
+                boolean shouldUpdate = true;
+                if (changedEventIds.size() > 0) {
+                    shouldUpdate = events.watchFound;
+                }
+                
+                if (events.primaryCount == 0) {
+                    views = getAppWidgetNoEvents(context);
+                } else if (shouldUpdate) {
+                    views = getAppWidgetUpdate(context, cursor, events);
+                    triggerTime = calculateUpdateTime(cursor, events);
+                }
+            } else {
+                views = getAppWidgetNoEvents(context);
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+        
+        // Bail out early if no update built
+        if (views == null) {
+            if (LOGD) Log.d(TAG, "Didn't build update, possibly because changedEventIds=" +
+                    changedEventIds.toString());
+            return;
+        }
+        
+        AppWidgetManager gm = AppWidgetManager.getInstance(context);
+        if (appWidgetIds != null) {
+            gm.updateAppWidget(appWidgetIds, views);
+        } else {
+            ComponentName thisWidget = CalendarAppWidgetProvider.getComponentName(context);
+            gm.updateAppWidget(thisWidget, views);
+        }
+
+        // Schedule an alarm to wake ourselves up for the next update.  We also cancel
+        // all existing wake-ups because PendingIntents don't match against extras.
+        
+        // If no next-update calculated, or bad trigger time in past, schedule
+        // update about six hours from now.
+        if (triggerTime == -1 || triggerTime < now) {
+            if (LOGD) Log.w(TAG, "Encountered bad trigger time " + formatDebugTime(triggerTime, now));
+            triggerTime = now + UPDATE_NO_EVENTS;
+        }
+        
+        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+        PendingIntent pendingUpdate = CalendarAppWidgetProvider.getUpdateIntent(context);
+        
+        am.cancel(pendingUpdate);
+        am.set(AlarmManager.RTC, triggerTime, pendingUpdate);
+
+        if (LOGD) Log.d(TAG, "Scheduled next update at " + formatDebugTime(triggerTime, now));
+    }
+
+    /**
+     * Format given time for debugging output.
+     * 
+     * @param unixTime Target time to report.
+     * @param now Current system time from {@link System#currentTimeMillis()}
+     *            for calculating time difference.
+     */
+    private String formatDebugTime(long unixTime, long now) {
+        Time time = new Time();
+        time.set(unixTime);
+        
+        long delta = unixTime - now;
+        if (delta > DateUtils.MINUTE_IN_MILLIS) {
+            delta /= DateUtils.MINUTE_IN_MILLIS;
+            return String.format("[%d] %s (%+d mins)", unixTime, time.format("%H:%M:%S"), delta);
+        } else {
+            delta /= DateUtils.SECOND_IN_MILLIS;
+            return String.format("[%d] %s (%+d secs)", unixTime, time.format("%H:%M:%S"), delta);
+        }
+    }
+    
+    /**
+     * Convert given UTC time into current local time.
+     * 
+     * @param recycle Time object to recycle, otherwise null.
+     * @param utcTime Time to convert, in UTC.
+     */
+    private long convertUtcToLocal(Time recycle, long utcTime) {
+        if (recycle == null) {
+            recycle = new Time();
+        }
+        recycle.timezone = Time.TIMEZONE_UTC;
+        recycle.set(utcTime);
+        recycle.timezone = TimeZone.getDefault().getID();
+        return recycle.normalize(true);
+    }
+
+    /**
+     * Figure out the next time we should push widget updates, usually the time
+     * calculated by {@link #getEventFlip(Cursor, long, long, boolean)}.
+     * 
+     * @param cursor Valid cursor on {@link Instances#CONTENT_URI}
+     * @param events {@link MarkedEvents} parsed from the cursor
+     */
+    private long calculateUpdateTime(Cursor cursor, MarkedEvents events) {
+        long result = -1;
+        if (events.primaryRow != -1) {
+            cursor.moveToPosition(events.primaryRow);
+            long start = cursor.getLong(INDEX_BEGIN);
+            long end = cursor.getLong(INDEX_END);
+            boolean allDay = cursor.getInt(INDEX_ALL_DAY) != 0;
+            
+            // Adjust all-day times into local timezone
+            if (allDay) {
+                final Time recycle = new Time();
+                start = convertUtcToLocal(recycle, start);
+                end = convertUtcToLocal(recycle, end);
+            }
+
+            result = getEventFlip(cursor, start, end, allDay);
+        }
+        return result;
+    }
+    
+    /**
+     * Calculate flipping point for the given event; when we should hide this
+     * event and show the next one. This is usually half-way through the event.
+     * 
+     * @param start Event start time in local timezone.
+     * @param end Event end time in local timezone.
+     */
+    private long getEventFlip(Cursor cursor, long start, long end, boolean allDay) {
+        if (allDay) {
+            return start;
+        } else {
+            return (start + end) / 2;
+        }
+    }
+    
+    /**
+     * Build a set of {@link RemoteViews} that describes how to update any
+     * widget for a specific event instance.
+     * 
+     * @param cursor Valid cursor on {@link Instances#CONTENT_URI}
+     * @param events {@link MarkedEvents} parsed from the cursor
+     */
+    private RemoteViews getAppWidgetUpdate(Context context, Cursor cursor, MarkedEvents events) {
+        Resources res = context.getResources();
+        ContentResolver resolver = context.getContentResolver();
+        
+        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.agenda_appwidget);
+        
+        // Clicking on widget launches the agenda view in Calendar
+        Intent agendaIntent = new Intent();
+        agendaIntent.setComponent(new ComponentName(ACTION_PACKAGE, ACTION_CLASS));
+        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* no requestCode */,
+                agendaIntent, 0 /* no flags */);
+        
+        views.setOnClickPendingIntent(R.id.agenda_appwidget, pendingIntent);
+        
+        Time time = new Time();
+        time.setToNow();
+        int yearDay = time.yearDay;
+        int dateNumber = time.monthDay;
+
+        // Set calendar icon with actual date
+        views.setImageViewBitmap(R.id.icon, getDateOverlay(res, dateNumber));
+        views.setViewVisibility(R.id.icon, View.VISIBLE);
+        views.setViewVisibility(R.id.no_events, View.GONE);
+
+        // Fill primary event details
+        if (events.primaryRow != -1) {
+            views.setViewVisibility(R.id.primary_card, View.VISIBLE);
+            cursor.moveToPosition(events.primaryRow);
+            
+            // Color stripe
+            int colorFilter = cursor.getInt(INDEX_COLOR);
+            views.setDrawableParameters(R.id.when, true, -1, colorFilter,
+                    PorterDuff.Mode.SRC_IN, -1);
+            views.setTextColor(R.id.title, colorFilter);
+            views.setTextColor(R.id.where, colorFilter);
+            views.setDrawableParameters(R.id.divider, true, -1, colorFilter,
+                    PorterDuff.Mode.SRC_IN, -1);
+            views.setTextColor(R.id.title2, colorFilter);
+
+            // When
+            long start = cursor.getLong(INDEX_BEGIN);
+            boolean allDay = cursor.getInt(INDEX_ALL_DAY) != 0;
+            
+            int flags;
+            String whenString;
+            if (allDay) {
+                flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_UTC
+                        | DateUtils.FORMAT_SHOW_DATE;
+            } else {
+                flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_TIME;
+                
+                // Show date if different from today
+                time.set(start);
+                if (yearDay != time.yearDay) {
+                    flags = flags | DateUtils.FORMAT_SHOW_DATE;
+                }
+            }
+            if (DateFormat.is24HourFormat(context)) {
+                flags |= DateUtils.FORMAT_24HOUR;
+            }
+            whenString = DateUtils.formatDateRange(context, start, start, flags);
+            views.setTextViewText(R.id.when, whenString);
+
+            // What
+            String titleString = cursor.getString(INDEX_TITLE);
+            if (titleString == null || titleString.length() == 0) {
+                titleString = context.getString(R.string.no_title_label);
+            }
+            views.setTextViewText(R.id.title, titleString);
+            
+            // Where
+            String whereString = cursor.getString(INDEX_EVENT_LOCATION);
+            if (whereString != null && whereString.length() > 0) {
+                views.setViewVisibility(R.id.where, View.VISIBLE);
+                views.setViewVisibility(R.id.stub_where, View.INVISIBLE);
+                views.setTextViewText(R.id.where, whereString);
+            } else {
+                views.setViewVisibility(R.id.where, View.GONE);
+                views.setViewVisibility(R.id.stub_where, View.GONE);
+            }
+        }
+        
+        // Fill other primary events, if present
+        if (events.primaryConflictRow != -1) {
+            views.setViewVisibility(R.id.divider, View.VISIBLE);
+            views.setViewVisibility(R.id.title2, View.VISIBLE);
+
+            if (events.primaryCount > 2) {
+                // If more than two primary conflicts, format multiple message
+                int count = events.primaryCount - 1;
+                String titleString = String.format(res.getQuantityString(
+                        R.plurals.gadget_more_events, count), count);
+                views.setTextViewText(R.id.title2, titleString);
+            } else {
+                cursor.moveToPosition(events.primaryConflictRow);
+
+                // What
+                String titleString = cursor.getString(INDEX_TITLE);
+                if (titleString == null || titleString.length() == 0) {
+                    titleString = context.getString(R.string.no_title_label);
+                }
+                views.setTextViewText(R.id.title2, titleString);
+            }
+        } else {
+            views.setViewVisibility(R.id.divider, View.GONE);
+            views.setViewVisibility(R.id.title2, View.GONE);
+        }
+        
+        // Fill secondary event
+        if (events.secondaryRow != -1) {
+            views.setViewVisibility(R.id.secondary_card, View.VISIBLE);
+            views.setViewVisibility(R.id.secondary_when, View.VISIBLE);
+            views.setViewVisibility(R.id.secondary_title, View.VISIBLE);
+            
+            cursor.moveToPosition(events.secondaryRow);
+            
+            // Color stripe
+            int colorFilter = cursor.getInt(INDEX_COLOR);
+            views.setDrawableParameters(R.id.secondary_when, true, -1, colorFilter,
+                    PorterDuff.Mode.SRC_IN, -1);
+            views.setTextColor(R.id.secondary_title, colorFilter);
+            
+            // When
+            long start = cursor.getLong(INDEX_BEGIN);
+            boolean allDay = cursor.getInt(INDEX_ALL_DAY) != 0;
+            
+            int flags;
+            String whenString;
+            if (allDay) {
+                flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_UTC
+                        | DateUtils.FORMAT_SHOW_DATE;
+            } else {
+                flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_TIME;
+                
+                // Show date if different from today
+                time.set(start);
+                if (yearDay != time.yearDay) {
+                    flags = flags | DateUtils.FORMAT_SHOW_DATE;
+                }
+            }
+            if (DateFormat.is24HourFormat(context)) {
+                flags |= DateUtils.FORMAT_24HOUR;
+            }
+            whenString = DateUtils.formatDateRange(context, start, start, flags);
+            views.setTextViewText(R.id.secondary_when, whenString);
+            
+            if (events.secondaryCount > 1) {
+                // If more than two secondary conflicts, format multiple message
+                int count = events.secondaryCount;
+                String titleString = String.format(res.getQuantityString(
+                        R.plurals.gadget_more_events, count), count);
+                views.setTextViewText(R.id.secondary_title, titleString);
+            } else {
+                // What
+                String titleString = cursor.getString(INDEX_TITLE);
+                if (titleString == null || titleString.length() == 0) {
+                    titleString = context.getString(R.string.no_title_label);
+                }
+                views.setTextViewText(R.id.secondary_title, titleString);
+            }
+        } else {
+            views.setViewVisibility(R.id.secondary_when, View.GONE);
+            views.setViewVisibility(R.id.secondary_title, View.GONE);
+        }
+        
+        return views;
+    }
+
+    /**
+     * Build date overlay bitmap for positioning on widget. This is the textual
+     * number that has been corrected for font leading issues.
+     * 
+     * @param res {@link Resources} to use for paint color.
+     * @param dateNumber Numerical date to display.
+     */
+    public Bitmap getDateOverlay(Resources res, int dateNumber) {
+        String dateString = Integer.toString(dateNumber);
+        
+        Paint paint = new Paint();
+        paint.setTypeface(Typeface.DEFAULT_BOLD);
+        paint.setTextSize(18);
+        paint.setAntiAlias(true);
+        paint.setSubpixelText(true);
+        paint.setColor(res.getColor(R.color.appwidget_date));
+        
+        // Calculate exact size of text
+        FontMetrics metrics = paint.getFontMetrics();
+        int width = (int) Math.ceil(paint.measureText(dateString));
+        int height = (int) Math.ceil(-metrics.top + metrics.descent);
+        
+        // Add padding to left edge based on various obscure rules
+        // to make font center correctly
+        char firstChar = dateString.charAt(0);
+        char lastChar = dateString.charAt(dateString.length() - 1);
+        int leftPadding = (dateString.length() == 1 || firstChar == '2' ||
+                lastChar == '1' || lastChar == '0') ? 1 : 0;
+        
+        Bitmap overlay = Bitmap.createBitmap(width + leftPadding,
+                height, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(overlay);
+        canvas.drawText(dateString, leftPadding, -metrics.top, paint);
+        
+        return overlay;
+    }
+    
+    /**
+     * Build a set of {@link RemoteViews} that describes an error state.
+     */
+    private RemoteViews getAppWidgetNoEvents(Context context) {
+        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.agenda_appwidget);
+
+        views.setViewVisibility(R.id.no_events, View.VISIBLE);
+        
+        views.setViewVisibility(R.id.icon, View.GONE);
+        views.setViewVisibility(R.id.primary_card, View.GONE);
+        views.setViewVisibility(R.id.secondary_card, View.GONE);
+        
+        // Clicking on widget launches the agenda view in Calendar
+        Intent agendaIntent = new Intent();
+        agendaIntent.setComponent(new ComponentName(ACTION_PACKAGE, ACTION_CLASS));
+        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* no requestCode */,
+                agendaIntent, 0 /* no flags */);
+        
+        views.setOnClickPendingIntent(R.id.agenda_appwidget, pendingIntent);
+
+        return views;
+    }
+    
+    private class MarkedEvents {
+        long primaryTime = -1;
+        int primaryRow = -1;
+        int primaryConflictRow = -1;
+        int primaryCount = 0;
+        long secondaryTime = -1;
+        int secondaryRow = -1;
+        int secondaryCount = 0;
+        boolean watchFound = false;
+    }
+
+    /**
+     * Walk the given instances cursor and build a list of marked events to be
+     * used when updating the widget. This structure is also used to check if
+     * updates are needed.
+     * 
+     * @param cursor Valid cursor across {@link Instances#CONTENT_URI}.
+     * @param watchEventIds Specific events to watch for, setting
+     *            {@link MarkedEvents#watchFound} if found during marking.
+     * @param now Current system time to use for this update, possibly from
+     *            {@link System#currentTimeMillis()}
+     */
+    private MarkedEvents buildMarkedEvents(Cursor cursor, Set<Long> watchEventIds, long now) {
+        MarkedEvents events = new MarkedEvents();
+        final Time recycle = new Time();
+        
+        cursor.moveToPosition(-1);
+        while (cursor.moveToNext()) {
+            int row = cursor.getPosition();
+            long eventId = cursor.getLong(INDEX_EVENT_ID);
+            long start = cursor.getLong(INDEX_BEGIN);
+            long end = cursor.getLong(INDEX_END);
+            boolean allDay = cursor.getInt(INDEX_ALL_DAY) != 0;
+
+            // Adjust all-day times into local timezone
+            if (allDay) {
+                start = convertUtcToLocal(recycle, start);
+                end = convertUtcToLocal(recycle, end);
+            }
+            
+            // Skip events that have already passed their flip times
+            long eventFlip = getEventFlip(cursor, start, end, allDay);
+            if (LOGD) Log.d(TAG, "Calculated flip time " + formatDebugTime(eventFlip, now));
+            if (eventFlip < now) {
+                continue;
+            }
+            
+            // Mark if we've encountered the watched event
+            if (watchEventIds.contains(eventId)) {
+                events.watchFound = true;
+            }
+            
+            if (events.primaryRow == -1) {
+                // Found first event
+                events.primaryRow = row;
+                events.primaryTime = start;
+                events.primaryCount = 1;
+            } else if (events.primaryTime == start) {
+                // Found conflicting primary event
+                if (events.primaryConflictRow == -1) {
+                    events.primaryConflictRow = row;
+                }
+                events.primaryCount += 1;
+            } else if (events.secondaryRow == -1) {
+                // Found second event
+                events.secondaryRow = row;
+                events.secondaryTime = start;
+                events.secondaryCount = 1;
+            } else if (events.secondaryTime == start) {
+                // Found conflicting secondary event
+                events.secondaryCount += 1;
+            } else {
+                // Nothing interesting about this event, so bail out
+                break;
+            }
+        }
+        return events;
+    }
+
+    /**
+     * Query across all calendars for upcoming event instances from now until
+     * some time in the future.
+     * 
+     * @param resolver {@link ContentResolver} to use when querying
+     *            {@link Instances#CONTENT_URI}.
+     * @param searchDuration Distance into the future to look for event
+     *            instances, in milliseconds.
+     * @param now Current system time to use for this update, possibly from
+     *            {@link System#currentTimeMillis()}.
+     */
+    private Cursor getUpcomingInstancesCursor(ContentResolver resolver,
+            long searchDuration, long now) {
+        // Search for events from now until some time in the future
+        long end = now + searchDuration;
+        
+        Uri uri = Uri.withAppendedPath(Instances.CONTENT_URI,
+                String.format("%d/%d", now, end));
+
+        String selection = String.format("%s=1 AND %s!=%d",
+                Calendars.SELECTED, Instances.SELF_ATTENDEE_STATUS,
+                Attendees.ATTENDEE_STATUS_DECLINED);
+        
+        return resolver.query(uri, EVENT_PROJECTION, selection, null,
+                EVENT_SORT_ORDER);
+    }
+}
