diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..4a83dbb
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := user
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+# TODO: Remove dependency of application on the test runner (android.test.runner) 
+# library.
+LOCAL_JAVA_LIBRARIES := ext android.test.runner
+
+# We depend on googlelogin-client also, but that is already being included by google-framework
+LOCAL_STATIC_JAVA_LIBRARIES := google-framework
+
+LOCAL_PACKAGE_NAME := CalendarProvider
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..5a4b2b3
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.providers.calendar"
+        android:sharedUserId="android.uid.calendar">
+
+    <uses-permission android:name="android.permission.READ_CALENDAR" />
+    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+    <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH" />
+    <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.cl" />
+    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+    <uses-permission android:name="android.permission.READ_SYNC_STATS" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_READ" />
+    <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE" />
+
+    <application android:process="com.android.calendar"
+                 android:label="Calendar Storage"
+                 android:icon="@drawable/app_icon">
+        <!-- TODO: Remove dependency of application on the test runner
+             (android.test) library. -->
+        <uses-library android:name="android.test.runner" />
+        <provider android:name="CalendarProvider" android:authorities="calendar"
+                android:syncable="true" android:multiprocess="false"
+                android:readPermission="android.permission.READ_CALENDAR"
+                android:writePermission="android.permission.WRITE_CALENDAR" />
+        <activity android:name="CalendarContentProviderTests" android:label="Calendar Content Provider">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.UNIT_TEST" />
+            </intent-filter>
+        </activity>
+        <receiver android:name="CalendarReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.BOOT_COMPLETED" />
+            </intent-filter>
+        </receiver>
+    </application>
+</manifest>
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, 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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/maketests.py b/maketests.py
new file mode 100644
index 0000000..f5f5cb1
--- /dev/null
+++ b/maketests.py
@@ -0,0 +1,127 @@
+#
+# Usage: Fill in the configuration variables.  It will download the feed
+# for it, parse it, and print out test cases to add to the unit test.
+#
+
+EMAIL = "onoratoj@gmail.com"
+PRIVATE_COOKIE = "432802670aefa458daf036597ec8136b"
+START_DATE = ("2006","01","01")
+END_DATE = ("2009","01","01")
+
+
+
+import sys, urllib, re
+from xml.dom import minidom
+
+def fmt(n):
+    if n < 10:
+        return "0" + str(n)
+    else:
+        return str(n)
+
+def makeDate(d):
+    return d[0] + "-" + d[1] + "-" + d[2]
+
+def makeZDate(d):
+    return d[0] + d[1] + d[2] + "T000000Z"
+
+url = "http://www.google.com/calendar/feeds/onoratoj@gmail.com/private-" \
+        + PRIVATE_COOKIE + "/composite?start-min=" + makeDate(START_DATE) \
+        + "&start-max=" + makeDate(END_DATE)
+
+#data = open("out.xml")
+data = urllib.urlopen(url)
+
+DTSTART_TZID = re.compile("DTSTART;TZID=(.*):(.*)")
+DTSTART = re.compile("DTSTART:(.*)")
+DURATION = re.compile("DURATION:(.*)")
+RRULE = re.compile("RRULE:(.*)")
+TIME = re.compile("(....)-(..)-(..)T(..):(..):(..)....([+-])(..):(..)")
+TIMEZ = re.compile("(....)-(..)-(..)T(..):(..):(..)....Z")
+
+def stripTimezone(str):
+    lines = str.split("\n")
+    drop = False
+    result = []
+    for line in lines:
+        if line == "BEGIN:VTIMEZONE":
+            drop = True
+        if not drop:
+            result.append(line)
+        if line == "END:VTIMEZONE":
+            drop = False
+    return result
+
+def fixInstance(s):
+    m = TIME.match(s[0])
+    if m:
+        if m.group(7) == "+":
+            sign = -1
+        else:
+            sign = 1
+        hour = int(m.group(4)) + (sign * int(m.group(8)))
+        return m.group(1) + m.group(2) + m.group(3) + "T" + fmt(hour) \
+                + m.group(5) + m.group(6) + "Z"
+    m = TIMEZ.match(s[0])
+    if m:
+        return m.group(1) + m.group(2) + m.group(3) + "T" + m.group(4) \
+                + m.group(5) + m.group(6) + "Z"
+    return s[0]
+
+dom = minidom.parse(data)
+root = dom.documentElement
+
+entries = root.getElementsByTagName("entry")
+
+for entry in entries:
+    recurrences = entry.getElementsByTagName("gd:recurrence")
+    dtstart = ""
+    tzid = ""
+    duration = ""
+    rrule = ""
+    if len(recurrences) > 0:
+        recurrence = recurrences[0]
+        s = ""
+        for c in recurrence.childNodes:
+            s = s + c.nodeValue
+        lines = stripTimezone(s)
+        for s in lines:
+            re_dtstart = DTSTART_TZID.match(s)
+            if re_dtstart:
+                dtstart = re_dtstart.group(2)
+                tzid = re_dtstart.group(1)
+            re_dtstart = DTSTART.match(s)
+            if re_dtstart:
+                dtstart = re_dtstart.group(1)
+            re_duration = DURATION.match(s)
+            if re_duration:
+                duration = re_duration.group(1)
+            re_rrule = RRULE.match(s)
+            if re_rrule:
+                rrule = re_rrule.group(1)
+    whens = entry.getElementsByTagName("gd:when")
+    instances = []
+    for w in whens:
+        startTime = w.getAttribute("startTime")
+        endTime = w.getAttribute("endTime")
+        instances.append((startTime,endTime))
+
+    instances = map(fixInstance, instances)
+    instances.sort()
+    if dtstart != "":
+        title = ""
+        for c in entry.getElementsByTagName('title')[0].childNodes:
+            title = title + c.nodeValue
+
+        print "            // " + title
+        print "            test(\"" + dtstart + "\","
+        print "                    \"" + rrule + "\","
+        print "                    \"" + makeZDate(START_DATE) \
+                                    + "\", \"" + makeZDate(END_DATE) + "\","
+        print "                    new String[] {"
+        for i in instances:
+            print "                        \"" + i + "\","
+        print "                    });"
+        print
+
+
diff --git a/res/drawable/app_icon.png b/res/drawable/app_icon.png
new file mode 100644
index 0000000..9241090
--- /dev/null
+++ b/res/drawable/app_icon.png
Binary files differ
diff --git a/src/com/android/providers/calendar/CalendarProvider.java b/src/com/android/providers/calendar/CalendarProvider.java
new file mode 100644
index 0000000..7a2a41f
--- /dev/null
+++ b/src/com/android/providers/calendar/CalendarProvider.java
@@ -0,0 +1,3637 @@
+/*
+**
+** Copyright 2006, 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,
+** See the License for the specific language governing permissions and
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** limitations under the License.
+*/
+
+package com.android.providers.calendar;
+
+import com.google.android.collect.Sets;
+import com.google.android.gdata.client.AndroidGDataClient;
+import com.google.android.gdata.client.AndroidXmlParserFactory;
+import com.google.android.googlelogin.GoogleLoginServiceBlockingHelper;
+import com.google.android.googlelogin.GoogleLoginServiceNotFoundException;
+import com.google.android.providers.AbstractGDataSyncAdapter;
+import com.google.android.providers.AbstractGDataSyncAdapter.GDataSyncData;
+import com.google.wireless.gdata.calendar.client.CalendarClient;
+import com.google.wireless.gdata.calendar.data.CalendarEntry;
+import com.google.wireless.gdata.calendar.data.CalendarsFeed;
+import com.google.wireless.gdata.calendar.parser.xml.XmlCalendarGDataParserFactory;
+import com.google.wireless.gdata.client.AllDeletedUnavailableException;
+import com.google.wireless.gdata.client.AuthenticationException;
+import com.google.wireless.gdata.data.Entry;
+import com.google.wireless.gdata.parser.GDataParser;
+import com.google.wireless.gdata.parser.ParseException;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.AbstractTableMerger;
+import android.content.BroadcastReceiver;
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SyncAdapter;
+import android.content.SyncContext;
+import android.content.SyncableContentProvider;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Process;
+import android.pim.DateException;
+import android.pim.RecurrenceSet;
+import android.pim.Time;
+import android.provider.Calendar;
+import android.provider.SyncConstValue;
+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;
+import android.provider.Calendar.ExtendedProperties;
+import android.provider.Calendar.Instances;
+import android.provider.Calendar.Reminders;
+import android.text.TextUtils;
+import android.util.Config;
+import android.util.Log;
+import android.util.TimeFormatException;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.TreeSet;
+
+public class CalendarProvider extends SyncableContentProvider {
+
+    private static final boolean PROFILE = false;
+    private static final boolean DEBUG_ALARMS = false;
+    private static final boolean MULTIPLE_ATTENDEES_PER_EVENT = false;
+    private static final String[] ACCOUNTS_PROJECTION = new String[] { Calendars._SYNC_ACCOUNT};
+
+    private static final String[] EVENTS_PROJECTION = new String[] {
+        Events._SYNC_ID,
+        Events._SYNC_VERSION,
+        Events._SYNC_ACCOUNT,
+        Events.CALENDAR_ID };
+    private static final int EVENTS_SYNC_ID_INDEX = 0;
+    private static final int EVENTS_SYNC_VERSION_INDEX = 1;
+    private static final int EVENTS_SYNC_ACCOUNT_INDEX = 2;
+    private static final int EVENTS_CALENDAR_ID_INDEX = 3;
+
+    private DatabaseUtils.InsertHelper mCalendarsInserter;
+    private DatabaseUtils.InsertHelper mEventsInserter;
+    private DatabaseUtils.InsertHelper mEventsRawTimesInserter;
+    private DatabaseUtils.InsertHelper mDeletedEventsInserter;
+    private DatabaseUtils.InsertHelper mInstancesInserter;
+    private DatabaseUtils.InsertHelper mAttendeesInserter;
+    private DatabaseUtils.InsertHelper mRemindersInserter;
+    private DatabaseUtils.InsertHelper mCalendarAlertsInserter;
+    private DatabaseUtils.InsertHelper mExtendedPropertiesInserter;
+
+    /**
+     * The cached copy of the CalendarMetaData database table.
+     * Make this "package private" instead of "private" so that test code
+     * can access it.
+     */
+    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,
+    };
+
+    public static final class TimeRange {
+        public long begin;
+        public long end;
+        public boolean allDay;
+    }
+
+    public static final class InstancesRange {
+        public long begin;
+        public long end;
+
+        public InstancesRange(long begin, long end) {
+            this.begin = begin;
+            this.end = end;
+        }
+    }
+
+    public static final class InstancesList
+            extends ArrayList<ContentValues> {
+    }
+
+    public static final class EventInstancesMap
+            extends HashMap<String, InstancesList> {
+        public void add(String syncId, ContentValues values) {
+            InstancesList instances = get(syncId);
+            if (instances == null) {
+                instances = new InstancesList();
+                put(syncId, instances);
+            }
+            instances.add(values);
+        }
+    }
+
+    // A thread that runs in the background and schedules the next
+    // calendar event alarm.
+    private class AlarmScheduler implements Runnable {
+
+        public AlarmScheduler() {
+        }
+
+        public void run() {
+            try {
+                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+                runScheduleNextAlarm();
+            } catch (SQLException e) {
+                Log.e(TAG, "runScheduleNextAlarm() failed", e);
+            }
+        }
+    }
+
+    /**
+     * We search backward in time for event reminders that we may have missed
+     * and schedule them if the event has not yet expired.  The amount in
+     * the past to search backwards is controlled by this constant.  It
+     * should be at least a few minutes to allow for an event that was
+     * recently created on the web to make its way to the phone.  Two hours
+     * might seem like overkill, but it is useful in the case where the user
+     * just crossed into a new timezone and might have just missed an alarm.
+     */
+    private static final long SCHEDULE_ALARM_SLACK = 2 * android.pim.DateUtils.HOUR_IN_MILLIS;
+
+    /**
+     * Alarms older than this threshold will be deleted from the CalendarAlerts
+     * table.  This should be about a day because if the timezone is
+     * wrong and the user corrects it we might delete good alarms that
+     * appear to be old because the device time was incorrectly in the future.
+     * This threshold must also be larger than SCHEDULE_ALARM_SLACK.  We add
+     * the SCHEDULE_ALARM_SLACK to ensure this.
+     */
+    private static final long CLEAR_OLD_ALARM_THRESHOLD = android.pim.DateUtils.DAY_IN_MILLIS
+            + SCHEDULE_ALARM_SLACK;
+
+    // A lock for synchronizing access to fields that are shared
+    // with the AlarmScheduler thread.
+    private Object mAlarmLock = new Object();
+
+    private static final String TAG = "CalendarProvider";
+    private static final String DATABASE_NAME = "calendar.db";
+    
+    // Note: if you update the version number, you must also update the code
+    // in upgradeDatabase() to modify the database (gracefully, if possible).
+    private static final int DATABASE_VERSION = 50;
+
+    private static final String EXPECTED_PROJECTION = "/full";
+
+    private static final String DESIRED_PROJECTION = "/full-selfattendance";
+
+    private static final String FEEDS_SUBSTRING = "/feeds/";
+
+    // Make sure we load at least two months worth of data.
+    // Client apps can load more data in a background thread.
+    private static final long MINIMUM_EXPANSION_SPAN =
+            2L * 31 * 24 * 60 * 60 * 1000;
+
+    private static final String[] sCalendarsIdProjection = new String[] { Calendars._ID };
+    private static final int CALENDARS_INDEX_ID = 0;
+    
+    // Allocate the string constant once here instead of on the heap
+    private static final String CALENDAR_ID_SELECTION = "calendar_id=?";
+
+    private static final String[] sInstancesProjection =
+        new String[] { Instances.START_DAY, Instances.END_DAY,
+        Instances.START_MINUTE, Instances.END_MINUTE, Instances.ALL_DAY };
+
+    private static final int INSTANCES_INDEX_START_DAY = 0;
+    private static final int INSTANCES_INDEX_END_DAY = 1;
+    private static final int INSTANCES_INDEX_START_MINUTE = 2;
+    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;
+
+    private CalendarSyncAdapter mSyncAdapter;
+
+    /**
+     * Listens for timezone changes and disk-no-longer-full events
+     */
+    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
+                updateTimezoneDependentFields();
+                scheduleNextAlarm();
+            } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
+                // Try to clean up if things were screwy due to a full disk
+                updateTimezoneDependentFields();
+                scheduleNextAlarm();
+            } else if (Intent.ACTION_TIME_CHANGED.equals(action)) {
+                scheduleNextAlarm();
+            }
+        }
+    };
+
+    public CalendarProvider() {
+        super(DATABASE_NAME, DATABASE_VERSION, Calendars.CONTENT_URI);
+    }
+
+    @Override
+    public boolean onCreate() {
+        super.onCreate();
+
+        // Register for Intent broadcasts
+        IntentFilter filter = new IntentFilter();
+
+        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+        filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
+        filter.addAction(Intent.ACTION_TIME_CHANGED);
+        final Context c = getContext();
+
+        // We don't ever unregister this because this thread always wants
+        // to receive notifications, even in the background.  And if this
+        // thread is killed then the whole process will be killed and the
+        // memory resources will be reclaimed.
+        c.registerReceiver(mIntentReceiver, filter);
+
+        mMetaData = new MetaData(mOpenHelper);
+        updateTimezoneDependentFields();
+
+        return true;
+    }
+
+    /**
+     * This creates a background thread to check the timezone and update
+     * the timezone dependent fields in the Instances table if the timezone
+     * has changes.
+     */
+    private void updateTimezoneDependentFields() {
+        Thread thread = new TimezoneCheckerThread();
+        thread.start();
+    }
+
+    private class TimezoneCheckerThread extends Thread {
+        @Override
+        public void run() {
+            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+            try {
+                doUpdateTimezoneDependentFields();
+            } catch (SQLException e) {
+                Log.e(TAG, "doUpdateTimezoneDependentFields() failed", e);
+                try {
+                    // Clear at least the in-memory data (and if possible the
+                    // database fields) to force a re-computation of Instances.
+                    mMetaData.clearInstanceRange();
+                } catch (SQLException e2) {
+                    Log.e(TAG, "clearInstanceRange() also failed: " + e2);
+                }
+            }
+        }
+    }
+
+    /**
+     * This method runs in a background thread.  If the timezone has changed
+     * then the Instances table will be regenerated.
+     */
+    private void doUpdateTimezoneDependentFields() {
+        MetaData.Fields fields = mMetaData.getFields();
+        String localTimezone = TimeZone.getDefault().getID();
+        if (TextUtils.equals(fields.timezone, localTimezone)) {
+            return;
+        }
+
+        // The database timezone is different from the current timezone.
+        // Regenerate the Instances table for this month.  Include events
+        // starting at the beginning of this month.
+        long now = System.currentTimeMillis();
+        Time time = new Time();
+        time.set(now);
+        time.monthDay = 1;
+        time.hour = 0;
+        time.minute = 0;
+        time.second = 0;
+        long begin = time.normalize(true);
+        long end = begin + MINIMUM_EXPANSION_SPAN;
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        handleInstanceQuery(qb, begin, end, new String[] { Instances._ID },
+                null /* selection */, null /* sort */);
+
+        // 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 */);
+    }
+
+    @Override
+    protected void onDatabaseOpened(SQLiteDatabase db) {
+        db.markTableSyncable("Events", "DeletedEvents");
+
+        if (!isTemporary()) {
+            mCalendarClient = new CalendarClient(
+                new AndroidGDataClient(getContext().getContentResolver()),
+                new XmlCalendarGDataParserFactory(
+                new AndroidXmlParserFactory()));
+        }
+
+        mCalendarsInserter = new DatabaseUtils.InsertHelper(db, "Calendars");
+        mEventsInserter = new DatabaseUtils.InsertHelper(db, "Events");
+        mEventsRawTimesInserter = new DatabaseUtils.InsertHelper(db, "EventsRawTimes");
+        mDeletedEventsInserter = new DatabaseUtils.InsertHelper(db, "DeletedEvents");
+        mInstancesInserter = new DatabaseUtils.InsertHelper(db, "Instances");
+        mAttendeesInserter = new DatabaseUtils.InsertHelper(db, "Attendees");
+        mRemindersInserter = new DatabaseUtils.InsertHelper(db, "Reminders");
+        mCalendarAlertsInserter = new DatabaseUtils.InsertHelper(db, "CalendarAlerts");
+        mExtendedPropertiesInserter =
+            new DatabaseUtils.InsertHelper(db, "ExtendedProperties");
+    }
+
+    @Override
+    protected boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
+        Log.i(TAG, "Upgrading DB from version " + oldVersion
+                    + " to " + newVersion);
+        if (oldVersion < 46) {
+            dropTables(db);
+            bootstrapDatabase(db);
+            return false; // this was lossy
+        }
+
+        if (oldVersion == 46) {
+            Log.w(TAG, "Upgrading CalendarAlerts table");
+            db.execSQL("UPDATE CalendarAlerts SET reminder_id=NULL;");
+            db.execSQL("ALTER TABLE CalendarAlerts ADD COLUMN minutes INTEGER DEFAULT 0;");
+            oldVersion += 1;
+        }
+        
+        if (oldVersion == 47) {
+            // Changing to version 48 was intended to force a data wipe
+            dropTables(db);
+            bootstrapDatabase(db);
+            return false; // this was lossy
+        }
+        
+        if (oldVersion == 48) {
+            // Changing to version 49 was intended to force a data wipe
+            dropTables(db);
+            bootstrapDatabase(db);
+            return false; // this was lossy
+        }
+
+        if (oldVersion == 49) {
+            Log.w(TAG, "Upgrading DeletedEvents table");
+
+            // We don't have enough information to fill in the correct
+            // value of the calendar_id for old rows in the DeletedEvents
+            // table, but rows in that table are transient so it is unlikely
+            // that there are any rows.  Plus, the calendar_id is used only
+            // when deleting a calendar, which is a rare event.  All new rows
+            // will have the correct calendar_id.
+            db.execSQL("ALTER TABLE DeletedEvents ADD COLUMN calendar_id INTEGER;");
+
+            // Trigger to remove a calendar's events when we delete the calendar
+            db.execSQL("DROP TRIGGER IF EXISTS calendar_cleanup");
+            db.execSQL("CREATE TRIGGER calendar_cleanup DELETE ON Calendars " +
+                        "BEGIN " +
+                            "DELETE FROM Events WHERE calendar_id = old._id;" +
+                            "DELETE FROM DeletedEvents WHERE calendar_id = old._id;" +
+                        "END");
+            oldVersion += 1;
+        }
+        return true; // this was lossless
+    }
+
+    private void dropTables(SQLiteDatabase db) {
+        db.execSQL("DROP TABLE IF EXISTS Calendars;");
+        db.execSQL("DROP TABLE IF EXISTS Events;");
+        db.execSQL("DROP TABLE IF EXISTS EventsRawTimes;");
+        db.execSQL("DROP TABLE IF EXISTS DeletedEvents;");
+        db.execSQL("DROP TABLE IF EXISTS Instances;");
+        db.execSQL("DROP TABLE IF EXISTS CalendarMetaData;");
+        db.execSQL("DROP TABLE IF EXISTS BusyBits;");
+        db.execSQL("DROP TABLE IF EXISTS Attendees;");
+        db.execSQL("DROP TABLE IF EXISTS Reminders;");
+        db.execSQL("DROP TABLE IF EXISTS CalendarAlerts;");
+        db.execSQL("DROP TABLE IF EXISTS ExtendedProperties;");
+    }
+
+    @Override
+    protected void bootstrapDatabase(SQLiteDatabase db) {
+        super.bootstrapDatabase(db);
+        db.execSQL("CREATE TABLE Calendars (" +
+                        "_id INTEGER PRIMARY KEY," +
+                        "_sync_account TEXT," +
+                        "_sync_id TEXT," +
+                        "_sync_version TEXT," +
+                        "_sync_time TEXT," +            // UTC
+                        "_sync_local_id INTEGER," +
+                        "_sync_dirty INTEGER," +
+                        "_sync_mark INTEGER," + // Used to filter out new rows
+                        "url TEXT," +
+                        "name TEXT," +
+                        "displayName TEXT," +
+                        "hidden INTEGER NOT NULL DEFAULT 0," +
+                        "color INTEGER," +
+                        "access_level INTEGER," +
+                        "selected INTEGER NOT NULL DEFAULT 1," +
+                        "sync_events INTEGER NOT NULL DEFAULT 0," +
+                        "location TEXT," +
+                        "timezone TEXT" +
+                        ");");
+
+        // Trigger to remove a calendar's events when we delete the calendar
+        db.execSQL("CREATE TRIGGER calendar_cleanup DELETE ON Calendars " +
+                    "BEGIN " +
+                        "DELETE FROM Events WHERE calendar_id = old._id;" +
+                        "DELETE FROM DeletedEvents WHERE calendar_id = old._id;" +
+                    "END");
+
+        // TODO: do we need both dtend and duration?
+        db.execSQL("CREATE TABLE Events (" +
+                        "_id INTEGER PRIMARY KEY," +
+                        "_sync_account TEXT," +
+                        "_sync_id TEXT," +
+                        "_sync_version TEXT," +
+                        "_sync_time TEXT," +            // UTC
+                        "_sync_local_id INTEGER," +
+                        "_sync_dirty INTEGER," +
+                        "_sync_mark INTEGER," + // To filter out new rows
+                        "calendar_id INTEGER," +
+                        "htmlUri TEXT," +
+                        "title TEXT," +
+                        "eventLocation TEXT," +
+                        "description TEXT," +
+                        "eventStatus INTEGER," +
+                        "selfAttendeeStatus INTEGER NOT NULL DEFAULT 0," +
+                        "commentsUri TEXT," +
+                        "dtstart INTEGER," +               // millis since epoch
+                        "dtend INTEGER," +                 // millis since epoch
+                        "eventTimezone TEXT," +         // timezone for event
+                        "duration TEXT," +
+                        "allDay INTEGER NOT NULL DEFAULT 0," +
+                        "visibility INTEGER NOT NULL DEFAULT 0," +
+                        "transparency INTEGER NOT NULL DEFAULT 0," +
+                        "hasAlarm INTEGER NOT NULL DEFAULT 0," +
+                        "hasExtendedProperties INTEGER NOT NULL DEFAULT 0," +
+                        "rrule TEXT," +
+                        "rdate TEXT," +
+                        "exrule TEXT," +
+                        "exdate TEXT," +
+                        "originalEvent TEXT," +
+                        "originalInstanceTime INTEGER," +  // millis since epoch
+                        "lastDate INTEGER" +               // millis since epoch
+                    ");");
+
+        db.execSQL("CREATE INDEX eventsCalendarIdIndex ON Events (" +
+                   Events.CALENDAR_ID +
+                   ");");
+
+        db.execSQL("CREATE TABLE EventsRawTimes (" +
+                        "_id INTEGER PRIMARY KEY," +
+                        "event_id INTEGER NOT NULL," +
+                        "dtstart2445 TEXT," +
+                        "dtend2445 TEXT," +
+                        "originalInstanceTime2445 TEXT," +
+                        "lastDate2445 TEXT," +
+                        "UNIQUE (event_id)" +
+                    ");");
+
+        // NOTE: we do not create a trigger to delete an event's instances upon update,
+        // as all rows currently get updated during a merge.
+
+        db.execSQL("CREATE TABLE DeletedEvents (" +
+                        "_sync_id TEXT," +
+                        "_sync_version TEXT," +
+                        "_sync_account TEXT," +
+                        "_sync_mark INTEGER," + // To filter out new rows
+                        "calendar_id INTEGER" +
+                    ");");
+
+        db.execSQL("CREATE TABLE Instances (" +
+                        "_id INTEGER PRIMARY KEY," +
+                        "event_id INTEGER," +
+                        "begin INTEGER," +         // UTC millis
+                        "end INTEGER," +           // UTC millis
+                        "startDay INTEGER," +      // Julian start day
+                        "endDay INTEGER," +        // Julian end day
+                        "startMinute INTEGER," +   // minutes from midnight
+                        "endMinute INTEGER," +     // minutes from midnight
+                        "UNIQUE (event_id, begin, end)" +
+                    ");");
+
+        db.execSQL("CREATE INDEX instancesStartDayIndex ON Instances (" +
+                   Instances.START_DAY +
+                   ");");
+
+        db.execSQL("CREATE TABLE CalendarMetaData (" +
+                        "_id INTEGER PRIMARY KEY," +
+                        "localTimezone TEXT," +
+                        "minInstance INTEGER," +      // UTC millis
+                        "maxInstance INTEGER," +      // UTC millis
+                        "minBusyBits INTEGER," +      // UTC millis
+                        "maxBusyBits INTEGER" +       // UTC millis
+        ");");
+
+        db.execSQL("CREATE TABLE BusyBits(" +
+                        "day INTEGER PRIMARY KEY," +  // the Julian day
+                        "busyBits INTEGER," +         // 24 bits for 60-minute intervals
+                        "allDayCount INTEGER" +       // number of all-day events
+        ");");
+
+        db.execSQL("CREATE TABLE Attendees (" +
+                        "_id INTEGER PRIMARY KEY," +
+                        "event_id INTEGER," +
+                        "attendeeName TEXT," +
+                        "attendeeEmail TEXT," +
+                        "attendeeStatus INTEGER," +
+                        "attendeeRelationship INTEGER," +
+                        "attendeeType INTEGER" +
+                   ");");
+
+        db.execSQL("CREATE INDEX attendeesEventIdIndex ON Attendees (" +
+                   Attendees.EVENT_ID +
+                   ");");
+
+        db.execSQL("CREATE TABLE Reminders (" +
+                        "_id INTEGER PRIMARY KEY," +
+                        "event_id INTEGER," +
+                        "minutes INTEGER," +
+                        "method INTEGER NOT NULL" +
+                        " DEFAULT " + Reminders.METHOD_DEFAULT +
+                   ");");
+
+        db.execSQL("CREATE INDEX remindersEventIdIndex ON Reminders (" +
+                   Reminders.EVENT_ID +
+                   ");");
+
+        // This table stores the Calendar notifications that have gone off.
+        db.execSQL("CREATE TABLE CalendarAlerts (" +
+                        "_id INTEGER PRIMARY KEY," +
+                        "event_id INTEGER," +
+                        "begin INTEGER NOT NULL," +        // UTC millis
+                        "end INTEGER NOT NULL," +          // UTC millis
+                        "alarmTime INTEGER NOT NULL," +    // UTC millis
+                        "state INTEGER NOT NULL," +
+                        "minutes INTEGER," +
+                        "UNIQUE (alarmTime, begin, event_id)" +
+                   ");");
+
+        db.execSQL("CREATE INDEX calendarAlertsEventIdIndex ON CalendarAlerts (" +
+                   CalendarAlerts.EVENT_ID +
+                   ");");
+
+        db.execSQL("CREATE TABLE ExtendedProperties (" +
+                        "_id INTEGER PRIMARY KEY," +
+                        "event_id INTEGER," +
+                        "name TEXT," +
+                        "value TEXT" +
+                   ");");
+
+        db.execSQL("CREATE INDEX extendedPropertiesEventIdIndex ON ExtendedProperties (" +
+                   ExtendedProperties.EVENT_ID +
+                   ");");
+
+        // Trigger to remove data tied to an event when we delete that event.
+        db.execSQL("CREATE TRIGGER events_cleanup_delete DELETE ON Events " +
+                    "BEGIN " +
+                        "DELETE FROM Instances WHERE event_id = old._id;" +
+                        "DELETE FROM EventsRawTimes WHERE event_id = old._id;" +
+                        "DELETE FROM Attendees WHERE event_id = old._id;" +
+                        "DELETE FROM Reminders WHERE event_id = old._id;" +
+                        "DELETE FROM CalendarAlerts WHERE event_id = old._id;" +
+                        "DELETE FROM ExtendedProperties WHERE event_id = old._id;" +
+                    "END");
+
+        // Triggers to set the _sync_dirty flag when an attendee is changed,
+        // inserted or deleted
+        db.execSQL("CREATE TRIGGER attendees_update UPDATE ON Attendees " +
+                    "BEGIN " +
+                        "UPDATE Events SET _sync_dirty=1 WHERE Events._id=old.event_id;" +
+                    "END");
+        db.execSQL("CREATE TRIGGER attendees_insert INSERT ON Attendees " +
+                    "BEGIN " +
+                        "UPDATE Events SET _sync_dirty=1 WHERE Events._id=new.event_id;" +
+                    "END");
+        db.execSQL("CREATE TRIGGER attendees_delete DELETE ON Attendees " +
+                    "BEGIN " +
+                        "UPDATE Events SET _sync_dirty=1 WHERE Events._id=old.event_id;" +
+                    "END");
+
+        // Triggers to set the _sync_dirty flag when a reminder is changed,
+        // inserted or deleted
+        db.execSQL("CREATE TRIGGER reminders_update UPDATE ON Reminders " +
+                    "BEGIN " +
+                        "UPDATE Events SET _sync_dirty=1 WHERE Events._id=old.event_id;" +
+                    "END");
+        db.execSQL("CREATE TRIGGER reminders_insert INSERT ON Reminders " +
+                    "BEGIN " +
+                        "UPDATE Events SET _sync_dirty=1 WHERE Events._id=new.event_id;" +
+                    "END");
+        db.execSQL("CREATE TRIGGER reminders_delete DELETE ON Reminders " +
+                    "BEGIN " +
+                        "UPDATE Events SET _sync_dirty=1 WHERE Events._id=old.event_id;" +
+                    "END");
+        // Triggers to set the _sync_dirty flag when an extended property is changed,
+        // inserted or deleted
+        db.execSQL("CREATE TRIGGER extended_properties_update UPDATE ON ExtendedProperties " +
+                    "BEGIN " +
+                        "UPDATE Events SET _sync_dirty=1 WHERE Events._id=old.event_id;" +
+                    "END");
+        db.execSQL("CREATE TRIGGER extended_properties_insert UPDATE ON ExtendedProperties " +
+                    "BEGIN " +
+                        "UPDATE Events SET _sync_dirty=1 WHERE Events._id=new.event_id;" +
+                    "END");
+        db.execSQL("CREATE TRIGGER extended_properties_delete UPDATE ON ExtendedProperties " +
+                    "BEGIN " +
+                        "UPDATE Events SET _sync_dirty=1 WHERE Events._id=old.event_id;" +
+                    "END");
+    }
+
+    /**
+     * Make sure that there are no entries for accounts that no longer
+     * exist. We are overriding this since we need to delete from the
+     * Calendars table, which is not syncable, which has triggers that
+     * will delete from the Events and DeletedEvents tables, which are
+     * syncable.
+     */
+    @Override
+    protected void onAccountsChanged(String[] accountsArray) {
+        super.onAccountsChanged(accountsArray);
+
+        Map<String, Boolean> accounts = new HashMap<String, Boolean>();
+        for (String account : accountsArray) {
+            accounts.put(account, false);
+        }
+
+        mDb.beginTransaction();
+        try {
+            deleteRowsForRemovedAccounts(accounts, "Calendars",
+                    SyncConstValue._SYNC_ACCOUNT);
+            mDb.setTransactionSuccessful();
+        } finally {
+            mDb.endTransaction();
+        }
+
+        if (mCalendarClient == null) {
+            return;
+        }
+
+        // If we have calendars for unknown accounts, delete them.
+        // If there are no calendars at all for a given account, add the
+        // default calendar.
+
+        for (Map.Entry<String, Boolean> entry : accounts.entrySet()) {
+            entry.setValue(false);
+            // TODO: remove this break when Calendar supports multiple accounts. Until then
+            // pretend that only the first account exists.
+            break;
+        }
+
+        Set<String> handledAccounts = Sets.newHashSet();
+        ContentResolver cr = getContext().getContentResolver();
+        if (Config.LOGV) Log.v(TAG, "querying calendars");
+        Cursor c = cr.query(Calendars.CONTENT_URI, ACCOUNTS_PROJECTION, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                String account = c.getString(0);
+                if (handledAccounts.contains(account)) {
+                    continue;
+                }
+                handledAccounts.add(account);
+                if (accounts.containsKey(account)) {
+                    if (Config.LOGV) {
+                        Log.v(TAG, "calendars for account " + account
+                                + " exist");
+                    }
+                    accounts.put(account, true /* hasCalendar */);
+                }
+            }
+        } finally {
+            c.close();
+            c = null;
+        }
+
+        if (Config.LOGV) {
+            Log.v(TAG, "scanning over " + accounts.size() + " account(s)");
+        }
+        for (Map.Entry<String, Boolean> entry : accounts.entrySet()) {
+            String account = entry.getKey();
+            boolean hasCalendar = entry.getValue();
+            if (hasCalendar) {
+                if (Config.LOGV) {
+                    Log.v(TAG, "ignoring account " + account +
+                         " since it matched an existing calendar");
+                }
+                continue;
+            }
+            String feedUrl = mCalendarClient.getDefaultCalendarUrl(account,
+                    CalendarClient.PROJECTION_PRIVATE_SELF_ATTENDANCE, null/* query params */);
+            feedUrl = CalendarSyncAdapter.rewriteUrlforAccount(account, feedUrl);
+            if (Config.LOGV) {
+                Log.v(TAG, "adding default calendar for account " + account);
+            }
+            ContentValues values = new ContentValues();
+            values.put(Calendars._SYNC_ACCOUNT, account);
+            values.put(Calendars.URL, feedUrl);
+            values.put(Calendars.DISPLAY_NAME, "Default");
+            values.put(Calendars.SYNC_EVENTS, 1);
+            values.put(Calendars.SELECTED, 1);
+            values.put(Calendars.HIDDEN, 0);
+            values.put(Calendars.COLOR, -14069085 /* blue */);
+            // this is just our best guess.  the real value will get updated
+            // when the user does a sync.
+            values.put(Calendars.TIMEZONE, Time.getCurrentTimezone());
+            values.put(Calendars.ACCESS_LEVEL, Calendars.OWNER_ACCESS);
+            cr.insert(Calendars.CONTENT_URI, values);
+
+            scheduleSync(account, false /* do a full sync */, null /* no url */);
+        }
+    }
+
+    @Override
+    public Cursor queryInternal(Uri url, String[] projectionIn,
+            String selection, String[] selectionArgs, String sort) {
+        final SQLiteDatabase db = getDatabase();
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+
+        Cursor ret;
+
+        // Generate the body of the query
+        int match = sURLMatcher.match(url);
+        switch (match)
+        {
+            case EVENTS:
+                qb.setTables("Events, Calendars");
+                qb.setProjectionMap(sEventsProjectionMap);
+                qb.appendWhere("Events.calendar_id=Calendars._id");
+                break;
+            case EVENTS_ID:
+                qb.setTables("Events, Calendars");
+                qb.setProjectionMap(sEventsProjectionMap);
+                qb.appendWhere("Events.calendar_id=Calendars._id");
+                qb.appendWhere(" AND Events._id=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                break;
+            case DELETED_EVENTS:
+                if (isTemporary()) {
+                    qb.setTables("DeletedEvents");
+                    break;
+                } else {
+                    throw new IllegalArgumentException("Unknown URL " + url);
+                }
+            case CALENDARS:
+                qb.setTables("Calendars");
+                // see if we want to update the list of calendars from the
+                // server.
+                String update = null;
+                update = url.getQueryParameter("update");
+                if ("1".equals(update)) {
+                    fetchCalendarsFromServer();
+                }
+
+                break;
+            case CALENDARS_ID:
+                qb.setTables("Calendars");
+                qb.appendWhere("_id=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                break;
+            case INSTANCES:
+                long begin;
+                long end;
+                try {
+                    begin = Long.valueOf(url.getPathSegments().get(2));
+                } catch (NumberFormatException nfe) {
+                    throw new IllegalArgumentException("Cannot parse begin "
+                            + url.getPathSegments().get(2));
+                }
+                try {
+                    end = Long.valueOf(url.getPathSegments().get(3));
+                } catch (NumberFormatException nfe) {
+                    throw new IllegalArgumentException("Cannot parse end "
+                            + url.getPathSegments().get(3));
+                }
+                return handleInstanceQuery(qb, begin, end, projectionIn,
+                                           selection, sort);
+            case BUSYBITS:
+                int startDay;
+                int endDay;
+                try {
+                    startDay = Integer.valueOf(url.getPathSegments().get(2));
+                } catch (NumberFormatException nfe) {
+                    throw new IllegalArgumentException("Cannot parse start day "
+                            + url.getPathSegments().get(2));
+                }
+                try {
+                    endDay = Integer.valueOf(url.getPathSegments().get(3));
+                } catch (NumberFormatException nfe) {
+                    throw new IllegalArgumentException("Cannot parse end day "
+                            + url.getPathSegments().get(3));
+                }
+                return handleBusyBitsQuery(qb, startDay, endDay, projectionIn,
+                                           selection, sort);
+            case ATTENDEES:
+                qb.setTables("Attendees, Events, Calendars");
+                qb.setProjectionMap(sAttendeesProjectionMap);
+                qb.appendWhere("Events.calendar_id=Calendars._id");
+                qb.appendWhere(" AND Events._id=Attendees.event_id");
+                break;
+            case ATTENDEES_ID:
+                qb.setTables("Attendees, Events, Calendars");
+                qb.setProjectionMap(sAttendeesProjectionMap);
+                qb.appendWhere("Attendees._id=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                qb.appendWhere(" AND Events.calendar_id=Calendars._id");
+                qb.appendWhere(" AND Events._id=Attendees.event_id");
+                break;
+            case REMINDERS:
+                qb.setTables("Reminders");
+                break;
+            case REMINDERS_ID:
+                qb.setTables("Reminders, Events, Calendars");
+                qb.setProjectionMap(sRemindersProjectionMap);
+                qb.appendWhere("Reminders._id=");
+                qb.appendWhere(url.getLastPathSegment());
+                qb.appendWhere(" AND Events.calendar_id=Calendars._id");
+                qb.appendWhere(" AND Events._id=Reminders.event_id");
+                break;
+            case CALENDAR_ALERTS:
+                qb.setTables("CalendarAlerts, Events, Calendars");
+                qb.setProjectionMap(sCalendarAlertsProjectionMap);
+                qb.appendWhere("Events.calendar_id=Calendars._id");
+                qb.appendWhere(" AND Events._id=CalendarAlerts.event_id");
+                break;
+            case CALENDAR_ALERTS_BY_INSTANCE:
+                qb.setTables("CalendarAlerts, Events, Calendars");
+                qb.setProjectionMap(sCalendarAlertsProjectionMap);
+                qb.appendWhere("Events.calendar_id=Calendars._id");
+                qb.appendWhere(" AND Events._id=CalendarAlerts.event_id");
+                String groupBy = CalendarAlerts.EVENT_ID + "," + CalendarAlerts.BEGIN;
+                return qb.query(db, projectionIn, selection, selectionArgs,
+                        groupBy, null, sort);
+            case CALENDAR_ALERTS_ID:
+                qb.setTables("CalendarAlerts, Events, Calendars");
+                qb.setProjectionMap(sCalendarAlertsProjectionMap);
+                qb.appendWhere("CalendarAlerts._id=");
+                qb.appendWhere(url.getLastPathSegment());
+                qb.appendWhere(" AND Events.calendar_id=Calendars._id");
+                qb.appendWhere(" AND Events._id=CalendarAlerts.event_id");
+                break;
+            case EXTENDED_PROPERTIES:
+                qb.setTables("ExtendedProperties");
+                break;
+            case EXTENDED_PROPERTIES_ID:
+                qb.setTables("ExtendedProperties, Events, Calendars");
+                // not sure if we need a projection map or a join.  see what callers want.
+//                qb.setProjectionMap(sExtendedPropertiesProjectionMap);
+                qb.appendWhere("ExtendedProperties._id=");
+                qb.appendWhere(url.getPathSegments().get(1));
+//                qb.appendWhere(" AND Events.calendar_id = Calendars._id");
+//                qb.appendWhere(" AND Events._id=ExtendedProperties.event_id");
+                break;
+
+            default:
+                throw new IllegalArgumentException("Unknown URL " + url);
+        }
+
+        // run the query
+        ret = qb.query(db, projectionIn, selection, selectionArgs, null, null, sort);
+
+        return ret;
+    }
+
+    private void fetchCalendarsFromServer() {
+        if (mCalendarClient == null) {
+            Log.w(TAG, "Cannot fetch calendars -- calendar url defined.");
+            return;
+        }
+
+        GoogleLoginServiceBlockingHelper loginHelper = null;
+        String username = null;
+        String authToken = null;
+
+        try {
+            loginHelper = new GoogleLoginServiceBlockingHelper(getContext());
+
+            // TODO: allow caller to specify which account's feeds should be updated
+            username = loginHelper.getAccount(false);
+            if (TextUtils.isEmpty(username)) {
+                Log.w(TAG, "Unable to update calendars from server -- "
+                      + "no users configured.");
+                return;
+            }
+
+            try {
+                authToken = loginHelper.getAuthToken(username,
+                                                     mCalendarClient.getServiceName());
+            } catch (GoogleLoginServiceBlockingHelper.AuthenticationException e) {
+                Log.w(TAG, "Unable to update calendars from server -- could not "
+                      + "authenticate user " + username, e);
+                return;
+            }
+        } catch (GoogleLoginServiceNotFoundException e) {
+            Log.e(TAG, "Could not find Google login service", e);
+            return;
+        } finally {
+            if (loginHelper != null) {
+                loginHelper.close();
+            }
+        }
+
+        // get the current set of calendars.  we'll need to pay attention to
+        // which calendars we get back from the server, so we can delete
+        // calendars that have been deleted from the server.
+        Set<Long> existingCalendarIds = new HashSet<Long>();
+
+        final SQLiteDatabase db = getDatabase();
+        db.beginTransaction();
+        try {
+            getCurrentCalendars(existingCalendarIds);
+
+            // get and process the calendars meta feed
+            GDataParser parser = null;
+            try {
+                String feedUrl = mCalendarClient.getUserCalendarsUrl(username);
+                feedUrl = CalendarSyncAdapter.rewriteUrlforAccount(username, feedUrl);
+                parser = mCalendarClient.getParserForUserCalendars(feedUrl, authToken);
+                // process the calendars
+                processCalendars(username, parser, existingCalendarIds);
+            } catch (AuthenticationException ae) {
+                Log.w(TAG, "Unable to process calendars from server -- could not "
+                        + "authenticate user.", ae);
+                return;
+            } catch (ParseException pe) {
+                Log.w(TAG, "Unable to process calendars from server -- could not "
+                        + "parse calendar feed.", pe);
+                return;
+            } catch (IOException ioe) {
+                Log.w(TAG, "Unable to process calendars from server -- encountered "
+                        + "i/o error", ioe);
+                return;
+            } catch (AllDeletedUnavailableException e) {
+                Log.w(TAG, "Unable to process calendars from server -- encountered "
+                        + "an AllDeletedUnavailableException, this should never happen", e);
+                return;
+            } finally {
+                if (parser != null) {
+                    parser.close();
+                }
+            }
+
+            // delete calendars that are no longer sent from the server.
+            final Uri calendarContentUri = Calendars.CONTENT_URI;
+            for (long calId : existingCalendarIds) {
+                // NOTE: triggers delete all events, instances for this calendar.
+                delete(ContentUris.withAppendedId(calendarContentUri, calId),
+                        null /* where */, null /* selectionArgs */);
+            }
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    private void getCurrentCalendars(Set<Long> calendarIds) {
+        Cursor cursor = query(Calendars.CONTENT_URI,
+                new String[] { Calendars._ID },
+                null /* selection */,
+                null /* selectionArgs */,
+                null /* sort */);
+        if (cursor != null) {
+            try {
+                while (cursor.moveToNext()) {
+                    calendarIds.add(cursor.getLong(0));
+                }
+            } finally {
+                cursor.close();
+            }
+        }
+    }
+
+    private void processCalendars(String username,
+                                  GDataParser parser,
+                                  Set<Long> existingCalendarIds)
+            throws ParseException, IOException {
+        CalendarsFeed feed = (CalendarsFeed) parser.init();
+        Entry entry = null;
+        ContentValues map = new ContentValues();
+        final Uri calendarContentUri = Calendars.CONTENT_URI;
+        while (parser.hasMoreData()) {
+            entry = parser.readNextEntry(entry);
+            if (Config.LOGV) Log.v(TAG, "Read entry: " + entry.toString());
+            CalendarEntry calendarEntry = (CalendarEntry) entry;
+            String feedUrl = calendarEntryToContentValues(username, feed, calendarEntry, map);
+            if (TextUtils.isEmpty(feedUrl)) {
+                continue;
+            }
+            long calId = -1;
+
+            Cursor c = query(calendarContentUri,
+                    new String[] { Calendars._ID },
+                    Calendars.URL + "='"
+                            + feedUrl + '\'' /* selection */,
+                    null /* selectionArgs */,
+                    null /* sort */);
+            if (c != null) {
+                try {
+                    if (c.moveToFirst()) {
+                        calId = c.getLong(0);
+                        existingCalendarIds.remove(calId);
+                    }
+                } finally {
+                    c.close();
+                }
+            }
+
+            if (calId != -1) {
+                if (Config.LOGV) Log.v(TAG, "Updating calendar " + map);
+                // don't override the existing "selected" or "hidden" settings.
+                map.remove(Calendars.SELECTED);
+                map.remove(Calendars.HIDDEN);
+                // write to db directly, so we don't send a notification.
+                updateInternal(ContentUris.withAppendedId(calendarContentUri, calId), map,
+                       null /* where */, null /* selectionArgs */);
+            } else {
+                // Select this calendar for syncing and display if it is
+                // selected and not hidden.
+                int syncAndDisplay = 0;
+                if (calendarEntry.isSelected() && !calendarEntry.isHidden()) {
+                    syncAndDisplay = 1;
+                }
+                map.put(Calendars.SYNC_EVENTS, syncAndDisplay);
+                map.put(Calendars.SELECTED, syncAndDisplay);
+                map.put(Calendars.HIDDEN, 0);
+                map.put(Calendars._SYNC_ACCOUNT, username);
+                if (Config.LOGV) Log.v(TAG, "Adding calendar " + map);
+                // write to db directly, so we don't send a notification.
+                Uri row = insertInternal(calendarContentUri, map);
+            }
+        }
+    }
+
+    // TODO: unit test.
+    protected static final String convertCalendarIdToFeedUrl(String url) {
+        // id: http://www.google.com/calendar/feeds/<username>/<cal id>
+        // desired feed:
+        //   http://www.google.com/calendar/feeds/<cal id>/<projection>
+        int start = url.indexOf(FEEDS_SUBSTRING);
+        if (start != -1) {
+            // strip out the */ in /feeds/*/
+            start += FEEDS_SUBSTRING.length();
+            int end = url.indexOf('/', start);
+            if (end != -1) {
+                url = url.replace(url.substring(start, end + 1), "");
+            }
+            url = url + "/private" + DESIRED_PROJECTION;
+        }
+        return url;
+    }
+
+    /**
+     * Convert the CalenderEntry to a Bundle that can be inserted/updated into the
+     * Calendars table.
+     */
+    private String calendarEntryToContentValues(String account, CalendarsFeed feed,
+            CalendarEntry entry,
+            ContentValues map) {
+        map.clear();
+
+        String url = entry.getAlternateLink();
+
+        // we only want to fetch the full-selfattendance calendar feeds
+        if (!TextUtils.isEmpty(url)) {
+            if (url.endsWith(EXPECTED_PROJECTION)) {
+                url = url.replace(EXPECTED_PROJECTION, DESIRED_PROJECTION);
+            }
+        } else {
+            // yuck.  the alternate link was not available.  we should
+            // reconstruct from the id.
+            url = entry.getId();
+            if (!TextUtils.isEmpty(url)) {
+                url = convertCalendarIdToFeedUrl(url);
+            } else {
+                if (Config.LOGV) {
+                    Log.v(TAG, "Cannot generate url for calendar feed.");
+                }
+                return null;
+            }
+        }
+
+        url = CalendarSyncAdapter.rewriteUrlforAccount(account, url);
+
+        map.put(Calendars.URL, url);
+        map.put(Calendars.NAME, entry.getTitle());
+
+        // TODO:
+        map.put(Calendars.DISPLAY_NAME, entry.getTitle());
+
+        map.put(Calendars.TIMEZONE, entry.getTimezone());
+
+        String colorStr = entry.getColor();
+        if (!TextUtils.isEmpty(colorStr)) {
+            int color = Color.parseColor(colorStr);
+            // Ensure the alpha is set to max
+            color |= 0xff000000;
+            map.put(Calendars.COLOR, color);
+        }
+
+        map.put(Calendars.SELECTED, entry.isSelected() ? 1 : 0);
+
+        map.put(Calendars.HIDDEN, entry.isHidden() ? 1 : 0);
+
+        int accesslevel;
+        switch (entry.getAccessLevel()) {
+        case CalendarEntry.ACCESS_NONE:
+            accesslevel = Calendars.NO_ACCESS;
+            break;
+        case CalendarEntry.ACCESS_READ:
+            accesslevel = Calendars.READ_ACCESS;
+            break;
+        case CalendarEntry.ACCESS_FREEBUSY:
+            accesslevel = Calendars.FREEBUSY_ACCESS;
+            break;
+        case CalendarEntry.ACCESS_CONTRIBUTOR:
+            accesslevel = Calendars.CONTRIBUTOR_ACCESS;
+            break;
+        case CalendarEntry.ACCESS_OWNER:
+            accesslevel = Calendars.OWNER_ACCESS;
+            break;
+        default:
+            accesslevel = Calendars.NO_ACCESS;
+        }
+        map.put(Calendars.ACCESS_LEVEL, accesslevel);
+        // TODO: use the update time, when calendar actually supports this.
+        // right now, calendar modifies the update time frequently.
+        map.put(Calendars._SYNC_TIME, System.currentTimeMillis());
+
+        return url;
+    }
+
+    /*
+     * Fills the Instances table, if necessary, for the given range and then
+     * queries the Instances table.
+     */
+    private Cursor handleInstanceQuery(SQLiteQueryBuilder qb, long rangeBegin,
+                                       long rangeEnd, String[] projectionIn,
+                                       String selection, String sort) {
+        final SQLiteDatabase db = getDatabase();
+        // will lock the database.
+        acquireInstanceRange(rangeBegin, rangeEnd, true /* use minimum expansion window */);
+        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(rangeEnd));
+        qb.appendWhere(" AND end >= ");
+        qb.appendWhere(String.valueOf(rangeBegin));
+        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) {
+        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);
+    }
+
+    /**
+     * Ensure that the date range given has all elements in the instance
+     * table.  Acquires the database lock and calls {@link #acquireInstanceRangeLocked}.
+     */
+    private void acquireInstanceRange(final long begin,
+                                      final long end,
+                                      final boolean useMinimumExpansionWindow) {
+        mDb.beginTransaction();
+        try {
+            acquireInstanceRangeLocked(begin, end, useMinimumExpansionWindow);
+            mDb.setTransactionSuccessful();
+        } finally {
+            mDb.endTransaction();
+        }
+    }
+
+    /**
+     * 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.
+     */
+    private void acquireInstanceRangeLocked(long begin, long end,
+                                            boolean useMinimumExpansionWindow) {
+        long expandBegin = begin;
+        long expandEnd = end;
+
+        if (useMinimumExpansionWindow) {
+            // if we end up having to expand events into the instances table, expand
+            // events for a minimal amount of time, so we do not have to perform
+            // expansions frequently.
+            long span = end - begin;
+            if (span < MINIMUM_EXPANSION_SPAN) {
+                long additionalRange = (MINIMUM_EXPANSION_SPAN - span) / 2;
+                expandBegin -= additionalRange;
+                expandEnd += additionalRange;
+            }
+        }
+
+        // Check if the timezone has changed.
+        // We do this check here because the database is locked and we can
+        // safely delete all the entries in the Instances table.
+        MetaData.Fields fields = mMetaData.getFieldsLocked();
+        String dbTimezone = fields.timezone;
+        long maxInstance = fields.maxInstance;
+        long minInstance = fields.minInstance;
+        String localTimezone = TimeZone.getDefault().getID();
+        boolean timezoneChanged = (dbTimezone == null) || !dbTimezone.equals(localTimezone);
+
+        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,"
+                        + " timezone changed: " + timezoneChanged);
+            }
+            expandInstanceRangeLocked(expandBegin, expandEnd, localTimezone);
+
+            mMetaData.writeLocked(localTimezone, expandBegin, expandEnd,
+                    0 /* startDay */, 0 /* endDay */);
+            return;
+        }
+
+        // If the desired range [begin, end] has already been
+        // expanded, then simply return.  The range is inclusive, that is,
+        // events that touch either endpoint are included in the expansion.
+        // This means that a zero-duration event that starts and ends at
+        // the endpoint will be included.
+        // We use [begin, end] here and not [expandBegin, expandEnd] for
+        // checking the range because a common case is for the client to
+        // request successive days or weeks, for example.  If we checked
+        // that the expanded range [expandBegin, expandEnd] then we would
+        // always be expanding because there would always be one more day
+        // or week that hasn't been expanded.
+        if ((begin >= minInstance) && (end <= maxInstance)) {
+            if (Config.LOGV) {
+                Log.v(TAG, "Canceled instance query (" + expandBegin + ", " + expandEnd
+                        + ") falls within previously expanded range.");
+            }
+            return;
+        }
+
+        // If the requested begin point has not been expanded, then include
+        // more events than requested in the expansion (use "expandBegin").
+        if (begin < minInstance) {
+            expandInstanceRangeLocked(expandBegin, minInstance, localTimezone);
+            minInstance = expandBegin;
+        }
+
+        // If the requested end point has not been expanded, then include
+        // more events than requested in the expansion (use "expandEnd").
+        if (end > maxInstance) {
+            expandInstanceRangeLocked(maxInstance, expandEnd, localTimezone);
+            maxInstance = expandEnd;
+        }
+
+        // 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");
+
+        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,
+                    Events.STATUS,
+                    Events.DTSTART,
+                    Events.DTEND,
+                    Events.EVENT_TIMEZONE,
+                    Events.RRULE,
+                    Events.RDATE,
+                    Events.EXRULE,
+                    Events.EXDATE,
+                    Events.DURATION,
+                    Events.ALL_DAY,
+                    Events.ORIGINAL_EVENT,
+                    Events.ORIGINAL_INSTANCE_TIME
+                };
+
+    private static class CanceledInstance {
+        public final long begin;
+        public final String syncId;
+
+        public CanceledInstance(long b, String id) {
+            begin = b;
+            syncId = id;
+        }
+    };
+
+    /**
+     * Make instances for the given range.
+     */
+    private void expandInstanceRangeLocked(long begin, long end, String localTimezone) {
+
+        if (PROFILE) {
+            Debug.startMethodTracing("expandInstanceRangeLocked");
+        }
+
+        final SQLiteDatabase db = getDatabase();
+        Cursor entries = null;
+
+        if (Config.LOGV) {
+            Log.v(TAG, "Expanding events between " + begin + " and " + end);
+        }
+
+        try {
+            SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+            qb.setTables("Events INNER JOIN Calendars ON (calendar_id = Calendars._id)");
+            qb.setProjectionMap(sEventsProjectionMap);
+
+            qb.appendWhere("dtstart <= ");
+            qb.appendWhere(String.valueOf(end));
+            qb.appendWhere(" AND ");
+            qb.appendWhere("(lastDate IS NULL OR lastDate >= ");
+            qb.appendWhere(String.valueOf(begin));
+            qb.appendWhere(")");
+
+            entries = qb.query(db, EXPAND_COLUMNS, null, null, null, null, null);
+
+            RecurrenceProcessor rp = new RecurrenceProcessor();
+
+            TreeSet<Long> dates = new TreeSet<Long>();
+
+            int statusColumn = entries.getColumnIndex(Events.STATUS);
+            int dtstartColumn = entries.getColumnIndex(Events.DTSTART);
+            int dtendColumn = entries.getColumnIndex(Events.DTEND);
+            int eventTimezoneColumn = entries.getColumnIndex(Events.EVENT_TIMEZONE);
+            int durationColumn = entries.getColumnIndex(Events.DURATION);
+            int rruleColumn = entries.getColumnIndex(Events.RRULE);
+            int rdateColumn = entries.getColumnIndex(Events.RDATE);
+            int exruleColumn = entries.getColumnIndex(Events.EXRULE);
+            int exdateColumn = entries.getColumnIndex(Events.EXDATE);
+            int allDayColumn = entries.getColumnIndex(Events.ALL_DAY);
+            int idColumn = entries.getColumnIndex(Events._ID);
+            int syncIdColumn = entries.getColumnIndex(Events._SYNC_ID);
+            int originalEventColumn = entries.getColumnIndex(Events.ORIGINAL_EVENT);
+            int originalInstanceTimeColumn = entries.getColumnIndex(Events.ORIGINAL_INSTANCE_TIME);
+
+            ContentValues initialValues;
+            EventInstancesMap instancesMap = new EventInstancesMap();
+            ArrayList<CanceledInstance> canceled = new ArrayList<CanceledInstance>();
+
+            Duration duration = new Duration();
+            Time eventTime = new Time();
+
+            while (entries.moveToNext()) {
+                initialValues = null;
+
+                boolean allDay = entries.getInt(allDayColumn) != 0;
+
+                String eventTimezone = entries.getString(eventTimezoneColumn);
+                if (allDay || TextUtils.isEmpty(eventTimezone)) {
+                  // in the events table, allDay events start at midnight.
+                  // this forces them to stay at midnight for all day events
+                  // TODO: check that this actually does the right thing.
+                  eventTimezone = Time.TIMEZONE_UTC;
+                }
+
+                long dtstartMillis = entries.getLong(dtstartColumn);
+                Long eventId = Long.valueOf(entries.getLong(idColumn));
+
+                String durationStr = entries.getString(durationColumn);
+                if (durationStr != null) {
+                    try {
+                        duration.parse(durationStr);
+                    }
+                    catch (DateException e) {
+                        Log.w(TAG, "error parsing duration for event "
+                                + eventId + "'" + durationStr + "'", e);
+                        duration.sign = 1;
+                        duration.weeks = 0;
+                        duration.days = 0;
+                        duration.hours = 0;
+                        duration.minutes = 0;
+                        duration.seconds = 0;
+                        durationStr = "+P0S";
+                    }
+                }
+
+                String syncId = entries.getString(syncIdColumn);
+                String originalEvent = entries.getString(originalEventColumn);
+                long originalInstanceTimeMillis = -1;
+                if (!entries.isNull(originalInstanceTimeColumn)) {
+                    originalInstanceTimeMillis= entries.getLong(originalInstanceTimeColumn);
+                }
+                int status = entries.getInt(statusColumn);
+
+                String rruleStr = entries.getString(rruleColumn);
+                String rdateStr = entries.getString(rdateColumn);
+                String exruleStr = entries.getString(exruleColumn);
+                String exdateStr = entries.getString(exdateColumn);
+
+                RecurrenceSet recur = new RecurrenceSet(rruleStr, rdateStr, exruleStr, exdateStr);
+
+                if (recur.hasRecurrence()) {
+                    // the event is repeating
+
+                    if (status == Events.STATUS_CANCELED) {
+                        // should not happen!
+                        Log.e(TAG, "Found canceled recurring event in "
+                        + "Events table.  Ignoring.");
+                        continue;
+                    }
+
+                    // need to parse the event into a local calendar.
+                    eventTime.timezone = eventTimezone;
+                    eventTime.set(dtstartMillis);
+                    eventTime.allDay = allDay;
+
+                    if (durationStr == null) {
+                        // should not happen.
+                        Log.e(TAG, "Repeating event has no duration -- "
+                                + "should not happen.");
+                        if (allDay) {
+                            // set to one day.
+                            duration.sign = 1;
+                            duration.weeks = 0;
+                            duration.days = 1;
+                            duration.hours = 0;
+                            duration.minutes = 0;
+                            duration.seconds = 0;
+                            durationStr = "+P1D";
+                        } else {
+                            // compute the duration from dtend, if we can.
+                            // otherwise, use 0s.
+                            duration.sign = 1;
+                            duration.weeks = 0;
+                            duration.days = 0;
+                            duration.hours = 0;
+                            duration.minutes = 0;
+                            if (!entries.isNull(dtendColumn)) {
+                                long dtendMillis = entries.getLong(dtendColumn);
+                                duration.seconds = (int) ((dtendMillis - dtstartMillis) / 1000);
+                                durationStr = "+P" + duration.seconds + "S";
+                            } else {
+                                duration.seconds = 0;
+                                durationStr = "+P0S";
+                            }
+                        }
+                    }
+
+                    try {
+                        rp.expand(eventTime, recur,
+                                  begin /* range start */, end /* range end */, dates);
+                    }
+                    catch (DateException e) {
+                        Log.w(TAG, "RecurrenceProcessor.expand skipping",e);
+                        continue;
+                    }
+
+                    // Initialize the "eventTime" timezone outside the loop.
+                    // This is used in computeTimezoneDependentFields().
+                    if (allDay) {
+                        eventTime.timezone = Time.TIMEZONE_UTC;
+                    } else {
+                        eventTime.timezone = localTimezone;
+                    }
+
+                    for (long date : dates) {
+                        initialValues = new ContentValues();
+                        initialValues.put(Instances.EVENT_ID, eventId);
+
+                        initialValues.put(Instances.BEGIN, date);
+                        long dtendMillis = duration.addTo(date);
+                        initialValues.put(Instances.END, dtendMillis);
+
+                        computeTimezoneDependentFields(date, dtendMillis,
+                                eventTime, initialValues);
+                        instancesMap.add(syncId, initialValues);
+                    }
+                } else {
+                    // the event is not repeating
+
+                    // if this event has an "original" field, then record
+                    // that we need to cancel the original event (we can't
+                    // do that here because the order of this loop isn't
+                    // defined)
+                    if (originalEvent != null && originalInstanceTimeMillis != -1) {
+                        canceled.add(new CanceledInstance(originalInstanceTimeMillis,
+                                     originalEvent));
+                    }
+
+                    // do not create an instance in the Instances table if this
+                    // is a canceled event/exception to a recurrence.
+                    if (status == Events.STATUS_CANCELED) {
+                        continue;
+                    }
+
+                    initialValues = new ContentValues();
+                    initialValues.put(Instances.EVENT_ID, eventId);
+                    initialValues.put(Instances.BEGIN, dtstartMillis);
+
+                    long dtendMillis = dtstartMillis;
+                    if (durationStr == null) {
+                        if (!entries.isNull(dtendColumn)) {
+                            dtendMillis = entries.getLong(dtendColumn);
+                        }
+                    } else {
+                        dtendMillis = duration.addTo(dtstartMillis);
+                    }
+                    initialValues.put(Instances.END, dtendMillis);
+
+                    if (allDay) {
+                        eventTime.timezone = Time.TIMEZONE_UTC;
+                    } else {
+                        eventTime.timezone = localTimezone;
+                    }
+                    computeTimezoneDependentFields(dtstartMillis, dtendMillis,
+                            eventTime, initialValues);
+
+                    instancesMap.add(syncId, initialValues);
+                }
+            }
+
+            // remove the ones that should be canceled
+
+            int numCanceled = canceled.size();
+            for (int i=0; i<numCanceled; i++) {
+                CanceledInstance cancellation = canceled.get(i);
+                if (TextUtils.isEmpty(cancellation.syncId)) {
+                    // should this ever happen?
+                    continue;
+                }
+                InstancesList instancesList = instancesMap.get(cancellation.syncId);
+                if (instancesList == null) {
+                    continue;
+                }
+                int numInstances = instancesList.size();
+                for (int j=numInstances-1; j>=0; j--) {
+                    ContentValues m = instancesList.get(j);
+                    if (m.get(Instances.BEGIN).equals(cancellation.begin)) {
+                        instancesList.remove(j);
+                    }
+                }
+            }
+
+            // Now do the inserts.  Since the db lock is held when this method is executed,
+            // this will be done in a transaction.
+            // NOTE: if there is lock contention (e.g., a sync is trying to merge into the db
+            // while the calendar app is trying to query the db (expanding instances)), we will
+            // not be "polite" and yield the lock until we're done.  This will favor local query
+            // operations over sync/write operations.
+            Collection<InstancesList> lists = instancesMap.values();
+            for (InstancesList list : lists) {
+                for (ContentValues m : list) {
+                    mInstancesInserter.replace(m);
+                    if (false) {
+                        // yield the lock if anyone else is trying to
+                        // perform a db operation here.
+                        db.yieldIfContended();
+                    }
+                }
+            }
+        } catch (TimeFormatException e) {
+            Log.w(TAG, "Exception in instance query preparation", e);
+        }
+        finally {
+            if (entries != null) {
+                entries.close();
+            }
+        }
+        if (PROFILE) {
+            Debug.stopMethodTracing();
+        }
+        //System.out.println("EXIT  insertInstanceRange begin=" + begin + " end=" + end);
+    }
+
+    /**
+     * Computes the timezone-dependent fields of an instance of an event and
+     * updates the "values" map to contain those fields.
+     *
+     * @param begin the start time of the instance (in UTC milliseconds)
+     * @param end the end time of the instance (in UTC milliseconds)
+     * @param local a Time object with the timezone set to the local timezone
+     * @param values a map that will contain the timezone-dependent fields
+     */
+    private void computeTimezoneDependentFields(long begin, long end,
+            Time local, ContentValues values) {
+        local.set(begin);
+        int startDay = Time.getJulianDay(begin, local.gmtoff);
+        int startMinute = local.hour * 60 + local.minute;
+
+        local.set(end);
+        int endDay = Time.getJulianDay(end, local.gmtoff);
+        int endMinute = local.hour * 60 + local.minute;
+
+        // Special case for midnight, which has endMinute == 0.  Change
+        // that to +24 hours on the previous day to make everything simpler.
+        // Exception: if start and end minute are both 0 on the same day,
+        // then leave endMinute alone.
+        if (endMinute == 0 && endDay > startDay) {
+            endMinute = 24 * 60;
+            endDay -= 1;
+        }
+
+        values.put(Instances.START_DAY, startDay);
+        values.put(Instances.END_DAY, endDay);
+        values.put(Instances.START_MINUTE, startMinute);
+        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) {
+        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) {
+                return null;
+            }
+            cursor.moveToFirst();
+            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 = sURLMatcher.match(url);
+        switch (match) {
+        case EVENTS:
+            return "vnd.android.cursor.dir/event";
+        case EVENTS_ID:
+            return "vnd.android.cursor.item/event";
+        case REMINDERS:
+            return "vnd.android.cursor.dir/reminder";
+        case REMINDERS_ID:
+            return "vnd.android.cursor.item/reminder";
+        case CALENDAR_ALERTS:
+            return "vnd.android.cursor.dir/calendar-alert";
+        case CALENDAR_ALERTS_BY_INSTANCE:
+            return "vnd.android.cursor.dir/calendar-alert-by-instance";
+        case CALENDAR_ALERTS_ID:
+            return "vnd.android.cursor.item/calendar-alert";
+        case INSTANCES:
+            return "vnd.android.cursor.dir/event-instance";
+        case BUSYBITS:
+            return "vnd.android.cursor.dir/busybits";
+        default:
+            throw new IllegalArgumentException("Unknown URL " + url);
+        }
+    }
+
+    public static boolean isRecurrenceEvent(ContentValues values) {
+        return (!TextUtils.isEmpty(values.getAsString(Events.RRULE))||
+                !TextUtils.isEmpty(values.getAsString(Events.RDATE))||
+                !TextUtils.isEmpty(values.getAsString(Events.ORIGINAL_EVENT)));
+    }
+
+    @Override
+    public Uri insertInternal(Uri url, ContentValues initialValues) {
+        final SQLiteDatabase db = getDatabase();
+        long rowID;
+
+        int match = sURLMatcher.match(url);
+        switch (match) {
+            case EVENTS:
+                if (!isTemporary()) {
+                    initialValues.put(Events._SYNC_DIRTY, 1);
+
+                    // Disallow inserting the attendee status in the Events
+                    // table because that makes it harder to keep the value
+                    // consistent with the corresponding entry in the
+                    // Attendees table.  Note that it's okay (and expected)
+                    // for the temporary table to contain the attendee status
+                    // because that comes from the server sync and the Events
+                    // table is already consistent with the Attendees table.
+                    if (initialValues.containsKey(Events.SELF_ATTENDEE_STATUS)) {
+                        throw new IllegalArgumentException("Inserting "
+                                + Events.SELF_ATTENDEE_STATUS
+                                + " in Events table is not allowed");
+                    }
+
+                    if (!initialValues.containsKey(Events.DTSTART)) {
+                        throw new RuntimeException("DTSTART field missing from event");
+                    }
+                }
+                // TODO: avoid the call to updateBundleFromEvent if this is just finding local
+                // changes.  or avoid for temp providers altogether, if we can compute this
+                // during a merge.
+                // TODO: do we really need to make a copy?
+                ContentValues updatedValues = updateContentValuesFromEvent(initialValues);
+                if (updatedValues == null) {
+                    throw new RuntimeException("Could not insert event.");
+                    // return null;
+                }
+                long rowId = mEventsInserter.insert(updatedValues);
+                Uri uri = Uri.parse("content://" + url.getAuthority() + "/events/" + rowId);
+                if (!isTemporary() && rowId != -1) {
+                    updateEventRawTimesLocked(rowId, updatedValues);
+                    updateInstancesLocked(updatedValues, rowId, true /* new event */, db);
+                    insertBusyBitsLocked(rowId, updatedValues);
+                }
+
+                return uri;
+            case CALENDARS:
+                if (!isTemporary()) {
+                    Integer syncEvents = initialValues.getAsInteger(Calendars.SYNC_EVENTS);
+                    if (syncEvents != null && syncEvents == 1) {
+                        String account = initialValues.getAsString(Calendars._SYNC_ACCOUNT);
+                        String calendarUrl = initialValues.getAsString(Calendars.URL);
+                        scheduleSync(account, false /* two-way sync */, calendarUrl);
+                    }
+                }
+                rowID = mCalendarsInserter.insert(initialValues);
+                return Uri.parse("content://calendar/calendars/" + rowID);
+            case ATTENDEES:
+                // currently, only sync may insert attendees.  we do not support
+                // inserting or removing attendees (which can only be yourself)
+                // from the app.
+                // TODO: remove this restriction when we deal with the full
+                // attendees feed.  we'll also need to put in some protection to
+                // prevent updates to the attendees that the server might reject.
+                if (!isTemporary()) {
+                    throw new IllegalArgumentException("Can only insert attendees into "
+                    + "the temporary provider.");
+                }
+                if (!initialValues.containsKey(Attendees.EVENT_ID)) {
+                    throw new IllegalArgumentException("Attendees values must "
+                        + "contain an event_id");
+                }
+                rowID = mAttendeesInserter.insert(initialValues);
+
+                // Copy the attendee status value to the Events table.
+                updateEventAttendeeStatus(db, initialValues);
+
+                return Uri.parse("content://calendars/attendees/" + rowID);
+            case REMINDERS:
+                if (!initialValues.containsKey(Reminders.EVENT_ID)) {
+                    throw new IllegalArgumentException("Reminders values must "
+                        + "contain an event_id");
+                }
+                rowID = mRemindersInserter.insert(initialValues);
+
+                if (!isTemporary()) {
+                    // Schedule another event alarm, if necessary
+                    scheduleNextAlarm();
+                }
+                return Uri.parse("content://calendars/reminders/" + rowID);
+            case CALENDAR_ALERTS:
+                if (!initialValues.containsKey(CalendarAlerts.EVENT_ID)) {
+                    throw new IllegalArgumentException("CalendarAlerts values must "
+                        + "contain an event_id");
+                }
+                rowID = mCalendarAlertsInserter.insert(initialValues);
+
+                return Uri.parse(CalendarAlerts.CONTENT_URI + "/" + rowID);
+            case EXTENDED_PROPERTIES:
+                if (!initialValues.containsKey(Calendar.ExtendedProperties.EVENT_ID)) {
+                    throw new IllegalArgumentException("ExtendedProperties values must "
+                        + "contain an event_id");
+                }
+                rowID = mExtendedPropertiesInserter.insert(initialValues);
+
+                return Uri.parse("content://calendars/extendedproperties/" + rowID);
+            case DELETED_EVENTS:
+                if (isTemporary()) {
+                    rowID = mDeletedEventsInserter.insert(initialValues);
+                    return Uri.parse("content://calendar/deleted_events/" + rowID);
+                }
+                // fallthrough
+            case EVENTS_ID:
+            case REMINDERS_ID:
+            case CALENDAR_ALERTS_ID:
+            case EXTENDED_PROPERTIES_ID:
+            case INSTANCES:
+                throw new UnsupportedOperationException("Cannot insert into that URL");
+            default:
+                throw new IllegalArgumentException("Unknown URL " + url);
+        }
+    }
+
+    /**
+     * Extracts the calendar email from a calendar feed url.
+     * @param feed the calendar feed url
+     * @return the calendar email that is in the feed url or null if it can't
+     * find the email address.
+     */
+    private String calendarEmailAddressFromFeedUrl(String feed) {
+        // Example feed url:
+        // https://www.google.com/calendar/feeds/foo%40gmail.com/private/full-noattendees
+        String[] pathComponents = feed.split("/");
+        if (pathComponents.length > 5 && "feeds".equals(pathComponents[4])) {
+            try {
+                return URLDecoder.decode(pathComponents[5], "UTF-8");
+            } catch (UnsupportedEncodingException e) {
+                Log.e(TAG, "unable to url decode the email address in calendar " + feed);
+                return null;
+            }
+        }
+
+        Log.e(TAG, "unable to find the email address in calendar " + feed);
+        return null;
+    }
+
+
+    /**
+     * Updates the attendee status in the Events table to be consistent with
+     * the value in the Attendees table.
+     *
+     * @param db the database
+     * @param attendeeValues the column values for one row in the Attendees
+     * table.
+     */
+    private void updateEventAttendeeStatus(SQLiteDatabase db, ContentValues attendeeValues) {
+        // Get the event id for this attendee
+        long eventId = attendeeValues.getAsLong(Attendees.EVENT_ID);
+
+        // Currently, we only fetch the attendee for the owner of the calendar
+        // so all the following expensive code is just wasted overhead.
+        // When we actually support multiple attendees for an event, we will
+        // have to execute this code (and perhaps tune it to make it as
+        // efficient as possible).
+        if (MULTIPLE_ATTENDEES_PER_EVENT) {
+            // Get the calendar id for this event
+            Cursor cursor = null;
+            long calId;
+            try {
+                cursor = query(ContentUris.withAppendedId(Events.CONTENT_URI, eventId),
+                        new String[] { Events.CALENDAR_ID },
+                        null /* selection */,
+                        null /* selectionArgs */,
+                        null /* sort */);
+                if (cursor == null) {
+                    return;
+                }
+                cursor.moveToFirst();
+                calId = cursor.getLong(0);
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+            }
+
+            // Get the feed for this Calendar
+            String calendarUrl = null;
+            cursor = null;
+            try {
+                cursor = query(ContentUris.withAppendedId(Calendars.CONTENT_URI, calId),
+                        new String[] { Calendars.URL },
+                        null /* selection */,
+                        null /* selectionArgs */,
+                        null /* sort */);
+                if (cursor == null) {
+                    return;
+                }
+                cursor.moveToFirst();
+                calendarUrl = cursor.getString(0);
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+            }
+
+            // Get the email address from the calendar feed
+            String calendarEmail = calendarEmailAddressFromFeedUrl(calendarUrl);
+            if (calendarEmail == null) {
+                return;
+            }
+
+            // Get the email address for this attendee
+            String attendeeEmail = null;
+            if (attendeeValues.containsKey(Attendees.ATTENDEE_EMAIL)) {
+                attendeeEmail = attendeeValues.getAsString(Attendees.ATTENDEE_EMAIL);
+            }
+
+            // If the attendee email does not match the calendar email, then this
+            // attendee is not the owner of this calendar so we don't update the
+            // selfAttendeeStatus in the event.
+            if (!calendarEmail.equals(attendeeEmail)) {
+                return;
+            }
+        }
+
+        int status = Attendees.ATTENDEE_STATUS_NONE;
+        if (attendeeValues.containsKey(Attendees.ATTENDEE_RELATIONSHIP)) {
+            int rel = attendeeValues.getAsInteger(Attendees.ATTENDEE_RELATIONSHIP);
+            if (rel == Attendees.RELATIONSHIP_ORGANIZER) {
+                status = Attendees.ATTENDEE_STATUS_ACCEPTED;
+            }
+        }
+
+        if (attendeeValues.containsKey(Attendees.ATTENDEE_STATUS)) {
+            status = attendeeValues.getAsInteger(Attendees.ATTENDEE_STATUS);
+        }
+
+        ContentValues values = new ContentValues();
+        values.put(Events.SELF_ATTENDEE_STATUS, status);
+        db.update("Events", values, "_id="+eventId, null);
+    }
+
+    private void updateInstancesLocked(ContentValues values,
+                                       long rowId,
+                                       boolean newEvent,
+                                       SQLiteDatabase db) {
+        if (isRecurrenceEvent(values))  {
+            // TODO: insert the new recurrence into the instances table.
+            mMetaData.clearInstanceRange();
+            return;
+        }
+
+        // If there are no expanded Instances, then return.
+        MetaData.Fields fields = mMetaData.getFieldsLocked();
+        if (fields.maxInstance == 0) {
+            return;
+        }
+
+        // if the event is in the expanded range, insert
+        // into the instances table.
+        // TODO: deal with durations.  currently, durations are only used in
+        // recurrences.
+
+        Long dtstartMillis = values.getAsLong(Events.DTSTART);
+
+        if (dtstartMillis == null) {
+            if (newEvent) {
+                // must be present for a new event.
+                throw new RuntimeException("DTSTART missing.");
+            }
+            if (Config.LOGV) Log.v(TAG, "Missing DTSTART.  "
+                    + "No need to update instance.");
+            return;
+        }
+
+        if (!newEvent) {
+            db.delete("Instances", "event_id=" + rowId, null /* selectionArgs */);
+        }
+
+        Long dtendMillis = values.getAsLong(Events.DTEND);
+        if (dtendMillis == null) {
+            dtendMillis = dtstartMillis;
+        }
+
+        if (dtstartMillis <= fields.maxInstance && dtendMillis >= fields.minInstance) {
+            ContentValues instanceValues = new ContentValues();
+            instanceValues.put(Instances.EVENT_ID, rowId);
+            instanceValues.put(Instances.BEGIN, dtstartMillis);
+            instanceValues.put(Instances.END, dtendMillis);
+
+            boolean allDay = false;
+            Integer allDayInteger = values.getAsInteger(Events.ALL_DAY);
+            if (allDayInteger != null) {
+                allDay = allDayInteger != 0;
+            }
+
+            // Update the timezone-dependent fields.
+            Time local = new Time();
+            if (allDay) {
+                local.timezone = Time.TIMEZONE_UTC;
+            } else {
+                local.timezone = fields.timezone;
+            }
+
+            computeTimezoneDependentFields(dtstartMillis, dtendMillis, local, instanceValues);
+            mInstancesInserter.insert(instanceValues);
+        }
+    }
+
+    long calculateLastDate(ContentValues values)
+                    throws DateException {
+        // Allow updates to some event fields like the title or hasAlarm
+        // without requiring DTSTART.
+        if (!values.containsKey(Events.DTSTART)) {
+            if (values.containsKey(Events.DTEND) || values.containsKey(Events.RRULE)
+                    || values.containsKey(Events.DURATION)
+                    || values.containsKey(Events.EVENT_TIMEZONE)
+                    || values.containsKey(Events.RDATE)
+                    || values.containsKey(Events.EXRULE)
+                    || values.containsKey(Events.EXDATE)) {
+                throw new RuntimeException("DTSTART field missing from event");
+            }
+            return -1;
+        }
+        long dtstartMillis = values.getAsLong(Events.DTSTART);
+        long lastMillis = -1;
+
+        // Can we use dtend with a repeating event?  What does that even
+        // mean?
+        // NOTE: if the repeating event has a dtend, we convert it to a
+        // duration during event processing, so this situation should not
+        // occur.
+        Long dtEnd = values.getAsLong(Events.DTEND);
+        if (dtEnd != null) {
+            lastMillis = dtEnd;
+        } else {
+            // find out how long it is
+            Duration duration = new Duration();
+            String durationStr = values.getAsString(Events.DURATION);
+            if (durationStr != null) {
+                duration.parse(durationStr);
+            }
+
+            RecurrenceSet recur = new RecurrenceSet(values);
+
+            if (recur.hasRecurrence()) {
+                // the event is repeating, so find the last date it
+                // could appear on
+
+                String tz = values.getAsString(Events.EVENT_TIMEZONE);
+
+                if (TextUtils.isEmpty(tz)) {
+                    // floating timezone
+                    tz = Time.TIMEZONE_UTC;
+                }
+                Time dtstartLocal = new Time(tz);
+
+                dtstartLocal.set(dtstartMillis);
+
+                RecurrenceProcessor rp = new RecurrenceProcessor();
+                lastMillis = rp.getLastOccurence(dtstartLocal, recur);
+                if (lastMillis == -1) {
+                    return lastMillis;  // -1
+                }
+            } else {
+                // the event is not repeating, just use dtstartMillis
+                lastMillis = dtstartMillis;
+            }
+
+            // that was the beginning of the event.  this is the end.
+            lastMillis = duration.addTo(lastMillis);
+        }
+        return lastMillis;
+    }
+
+    private ContentValues updateContentValuesFromEvent(ContentValues initialValues) {
+        try {
+            ContentValues values = new ContentValues(initialValues);
+
+            long last = calculateLastDate(values);
+            if (last != -1) {
+                values.put(Events.LAST_DATE, last);
+            }
+
+            return values;
+        } catch (DateException e) {
+            // don't add it if there was an error
+            Log.w(TAG, "Could not calculate last date.", e);
+            return null;
+        }
+    }
+
+    private void updateEventRawTimesLocked(long eventId, ContentValues values) {
+        ContentValues rawValues = new ContentValues();
+
+        rawValues.put("event_id", eventId);
+
+        String timezone = values.getAsString(Events.EVENT_TIMEZONE);
+
+        if (TextUtils.isEmpty(timezone)) {
+            // floating timezone
+            timezone = Time.TIMEZONE_UTC;
+        }
+
+        Time time = new Time(timezone);
+        Long dtstartMillis = values.getAsLong(Events.DTSTART);
+        if (dtstartMillis != null) {
+            time.set(dtstartMillis);
+            rawValues.put("dtstart2445", time.format2445());
+        }
+
+        Long dtendMillis = values.getAsLong(Events.DTEND);
+        if (dtendMillis != null) {
+            time.set(dtendMillis);
+            rawValues.put("dtend2445", time.format2445());
+        }
+
+        Long originalInstanceMillis = values.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
+        if (originalInstanceMillis != null) {
+            time.set(originalInstanceMillis);
+            rawValues.put("originalInstanceTime2445", time.format2445());
+        }
+
+        Long lastDateMillis = values.getAsLong(Events.LAST_DATE);
+        if (lastDateMillis != null) {
+            time.set(lastDateMillis);
+            rawValues.put("lastDate2445", time.format2445());
+        }
+
+        mEventsRawTimesInserter.replace(rawValues);
+    }
+
+    @Override
+    public int deleteInternal(Uri url, String where, String[] whereArgs) {
+        final SQLiteDatabase db = getDatabase();
+        int match = sURLMatcher.match(url);
+        switch (match)
+        {
+            case EVENTS_ID:
+            {
+                String id = url.getLastPathSegment();
+                if (where != null) {
+                    throw new UnsupportedOperationException("CalendarProvider "
+                            + "doesn't support where based deletion for type "
+                            + match);
+                }
+                if (!isTemporary()) {
+                    deleteBusyBitsLocked(Integer.parseInt(id));
+
+                    // Query this event to get the fields needed for inserting
+                    // a new row in the DeletedEvents table.
+                    Cursor cursor = db.query("Events", EVENTS_PROJECTION,
+                            "_id=" + id, null, null, null, null);
+                    try {
+                        if (cursor.moveToNext()) {
+                            String syncId = cursor.getString(EVENTS_SYNC_ID_INDEX);
+                            String syncVersion = cursor.getString(EVENTS_SYNC_VERSION_INDEX);
+                            String syncAccount = cursor.getString(EVENTS_SYNC_ACCOUNT_INDEX);
+                            Long calId = cursor.getLong(EVENTS_CALENDAR_ID_INDEX);
+                            
+                            ContentValues values = new ContentValues();
+                            values.put(Events._SYNC_ID, syncId);
+                            values.put(Events._SYNC_VERSION, syncVersion);
+                            values.put(Events._SYNC_ACCOUNT, syncAccount);
+                            values.put(Events.CALENDAR_ID, calId);
+                            mDeletedEventsInserter.insert(values);
+                        }
+                    } finally {
+                        cursor.close();
+                        cursor = null;
+                    }
+                }
+
+                // There is a delete trigger that will cause all instances
+                // matching this event id to get deleted as well.  In fact, all
+                // of the following tables will remove entries matching this
+                // event id: Instances, EventsRawTimes, Attendees, Reminders,
+                // CalendarAlerts, and ExtendedProperties.
+                int result = db.delete("Events", "_id=" + id, null);
+                return result;
+            }
+            case ATTENDEES_ID:
+            {
+              // we currently don't support deletions to the attendees list.
+              // TODO: remove this restriction when we handle the full attendees
+              // feed.  we'll need to put in some logic to check that the
+              // modification will be allowed by the server.
+              throw new IllegalArgumentException("Cannot delete attendees.");
+              //                String id = url.getPathSegments().get(1);
+              //                int result = db.delete("Attendees", "_id="+id, null);
+              //                return result;
+            }
+            case REMINDERS:
+            {
+                int result = db.delete("Reminders", where, whereArgs);
+                return result;
+            }
+            case REMINDERS_ID:
+            {
+                String id = url.getLastPathSegment();
+                int result = db.delete("Reminders", "_id="+id, null);
+                return result;
+            }
+            case CALENDAR_ALERTS:
+            {
+                int result = db.delete("CalendarAlerts", where, whereArgs);
+                return result;
+            }
+            case CALENDAR_ALERTS_ID:
+            {
+                String id = url.getLastPathSegment();
+                int result = db.delete("CalendarAlerts", "_id="+id, null);
+                return result;
+            }
+            case DELETED_EVENTS:
+            case EVENTS:
+                throw new UnsupportedOperationException("Cannot delete that URL");
+            case CALENDARS_ID:
+                StringBuilder whereSb = new StringBuilder("_id=");
+                whereSb.append(url.getPathSegments().get(1));
+                if (!TextUtils.isEmpty(where)) {
+                    whereSb.append(" AND (");
+                    whereSb.append(where);
+                    whereSb.append(')');
+                }
+                where = whereSb.toString();
+                // fall through to CALENDARS for the actual delete
+            case CALENDARS:
+                return deleteMatchingCalendars(where);
+            case INSTANCES:
+                throw new UnsupportedOperationException("Cannot delete that URL");
+            default:
+                throw new IllegalArgumentException("Unknown URL " + url);
+        }
+    }
+
+    private int deleteMatchingCalendars(String where) {
+        // query to find all the calendars that match, for each
+        // - delete calendar subscription
+        // - delete calendar
+
+        int numDeleted = 0;
+        final SQLiteDatabase db = getDatabase();
+        Cursor c = db.query("Calendars", sCalendarsIdProjection, where, null,
+                null, null, null);
+        if (c == null) {
+            return 0;
+        }
+        try {
+            while (c.moveToNext()) {
+                long id = c.getLong(CALENDARS_INDEX_ID);
+                if (!isTemporary()) {
+                    modifyCalendarSubscription(id, false /* not selected */);
+                }
+                c.deleteRow();
+                numDeleted++;
+            }
+        } finally {
+            c.close();
+        }
+        return numDeleted;
+    }
+
+    // TODO: call calculateLastDate()!
+    @Override
+    public int updateInternal(Uri url, ContentValues values,
+            String where, String[] selectionArgs) {
+        // TODO: remove this restriction
+        if (!TextUtils.isEmpty(where)) {
+            throw new IllegalArgumentException(
+                    "WHERE based updates not supported");
+        }
+        final SQLiteDatabase db = getDatabase();
+
+        int match = sURLMatcher.match(url);
+        switch (match) {
+            case CALENDARS_ID:
+            {
+                long id = ContentUris.parseId(url);
+                Integer syncEvents = values.getAsInteger(Calendars.SYNC_EVENTS);
+                if (syncEvents != null && !isTemporary()) {
+                    modifyCalendarSubscription(id, syncEvents == 1);
+                }
+
+                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;
+            }
+            case EVENTS_ID:
+            {
+                long id = ContentUris.parseId(url);
+                if (!isTemporary()) {
+                    values.put(Events._SYNC_DIRTY, 1);
+
+                    // Disallow updating the attendee status in the Events
+                    // table.  In the future, we could support this but we
+                    // would have to query and update the attendees table
+                    // to keep the values consistent.
+                    if (values.containsKey(Events.SELF_ATTENDEE_STATUS)) {
+                        throw new IllegalArgumentException("Updating "
+                                + Events.SELF_ATTENDEE_STATUS
+                                + " in Events table is not allowed.");
+                    }
+
+                    if (values.containsKey(Events.HTML_URI)) {
+                        throw new IllegalArgumentException("Updating "
+                                + Events.HTML_URI
+                                + " in Events table is not allowed.");
+                    }
+
+                    updateBusyBitsLocked(id, values);
+                }
+
+                ContentValues updatedValues = updateContentValuesFromEvent(values);
+                if (updatedValues == null) {
+                    Log.w(TAG, "Could not update event.");
+                    return 0;
+                }
+
+                int result = db.update("Events", updatedValues, "_id="+id, null);
+                if (!isTemporary()) {
+                    if (result > 0) {
+                        updateEventRawTimesLocked(id, updatedValues);
+                        updateInstancesLocked(updatedValues, id, false /* not a new event */, db);
+
+                        if (values.containsKey(Events.DTSTART)) {
+                            // The start time of the event changed, so run the
+                            // event alarm scheduler.
+                            scheduleNextAlarm();
+                        }
+                    }
+                }
+                return result;
+            }
+            case ATTENDEES_ID:
+            {
+                // Copy the attendee status value to the Events table.
+                updateEventAttendeeStatus(db, values);
+
+                long id = ContentUris.parseId(url);
+                return db.update("Attendees", values, "_id="+id, null);
+            }
+            case CALENDAR_ALERTS_ID:
+            {
+                long id = ContentUris.parseId(url);
+                return db.update("CalendarAlerts", values, "_id="+id, null);
+            }
+            case REMINDERS_ID:
+            {
+                long id = ContentUris.parseId(url);
+                int result = db.update("Reminders", values, "_id="+id, null);
+                if (!isTemporary()) {
+                    // Reschedule the event alarms because the
+                    // "minutes" field may have changed.
+                    scheduleNextAlarm();
+                }
+                return result;
+            }
+            case EXTENDED_PROPERTIES_ID:
+            {
+                long id = ContentUris.parseId(url);
+                return db.update("ExtendedProperties", values, "_id="+id, null);
+            }
+            default:
+                throw new IllegalArgumentException("Unknown URL " + url);
+        }
+    }
+    
+    /**
+     * Schedule a calendar sync for the account.
+     * @param account the account for which to schedule a sync
+     * @param uploadChangesOnly if set, specify that the sync should only send
+     *   up local changes
+     * @param url the url feed for the calendar to sync (may be null)
+     */
+    private void scheduleSync(String account, boolean uploadChangesOnly, String url) {
+        Bundle extras = new Bundle();
+        extras.putString(ContentResolver.SYNC_EXTRAS_ACCOUNT, account);
+        extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, uploadChangesOnly);
+        if (url != null) {
+            extras.putString("feed", url);
+            extras.putBoolean(ContentResolver.SYNC_EXTRAS_FORCE, true);
+        }
+        getContext().getContentResolver().startSync(android.provider.Calendar.CONTENT_URI, extras);
+    }
+
+    private void modifyCalendarSubscription(long id, boolean syncEvents) {
+        // get the account, url, and current selected state
+        // for this calendar.
+        Cursor cursor = query(ContentUris.withAppendedId(Calendars.CONTENT_URI, id),
+                new String[] { Calendars._SYNC_ACCOUNT,
+                               Calendars.URL,
+                               Calendars.SYNC_EVENTS},
+                null /* selection */,
+                null /* selectionArgs */,
+                null /* sort */);
+
+        String account = null;
+        String calendarUrl = null;
+        boolean oldSyncEvents = false;
+        if (cursor != null) {
+            try {
+                cursor.moveToFirst();
+                account = cursor.getString(0);
+                calendarUrl = cursor.getString(1);
+                oldSyncEvents = (cursor.getInt(2) != 0);
+            } finally {
+                cursor.close();
+            }
+        }
+
+        if (TextUtils.isEmpty(account) || TextUtils.isEmpty(calendarUrl)) {
+            // should not happen?
+            Log.w(TAG, "Cannot update subscription because account "
+            + "or calendar url empty -- should not happen.");
+            return;
+        }
+
+        if (oldSyncEvents == syncEvents) {
+            // nothing to do
+            return;
+        }
+
+        // If we are no longer syncing a calendar then make sure that the
+        // old calendar sync data is cleared.  Then if we later add this
+        // calendar back, we will sync all the events.
+        if (!syncEvents) {
+            byte[] data = readSyncDataBytes(account);
+            GDataSyncData syncData = AbstractGDataSyncAdapter.newGDataSyncDataFromBytes(data);
+            if (syncData != null) {
+                syncData.feedData.remove(calendarUrl);
+                data = AbstractGDataSyncAdapter.newBytesFromGDataSyncData(syncData);
+                writeSyncDataBytes(account, data);
+            }
+
+            // Delete all of the events in this calendar to save space.
+            // This is the closest we can come to deleting a calendar.
+            // Clients should never actually delete a calendar.  That won't
+            // work.  We need to keep the calendar entry in the Calendars table
+            // in order to know not to sync the events for that calendar from
+            // the server.
+            final SQLiteDatabase db = getDatabase();
+            String[] args = new String[] {Long.toString(id)};
+            db.delete("Events", CALENDAR_ID_SELECTION, args);
+            // Note that we do not delete the matching entries
+            // in the DeletedEvents table.  We will let those
+            // deleted events propagate to the server.
+            
+            // TODO: there is a corner case to deal with here: namely, if
+            // we edit or delete an event on the phone and then remove
+            // (that is, stop syncing) a calendar, and if we also make a
+            // change on the server to that event at about the same time,
+            // then we will never propagate the changes from the phone to
+            // the server.
+        }
+
+        // If the calendar is not selected for syncing, then don't download
+        // events.
+        scheduleSync(account, !syncEvents, calendarUrl);
+    }
+
+    @Override
+    public synchronized SyncAdapter getSyncAdapter() {
+        if (mSyncAdapter == null) {
+            mSyncAdapter = new CalendarSyncAdapter(getContext(), this);
+        }
+        return mSyncAdapter;
+    }
+
+    @Override
+    public void onSyncStop(SyncContext context, boolean success) {
+        super.onSyncStop(context, success);
+        scheduleNextAlarm();
+    }
+
+    @Override
+    protected Iterable<EventMerger> getMergers() {
+        return Collections.singletonList(new EventMerger());
+    }
+
+    /* Retrieve and cache the alarm manager */
+    private AlarmManager getAlarmManager() {
+        synchronized(mAlarmLock) {
+            if (mAlarmManager == null) {
+                Context context = getContext();
+                if (context == null) {
+                    Log.e(TAG, "getAlarmManager() cannot get Context");
+                    return null;
+                }
+                Object service = context.getSystemService(Context.ALARM_SERVICE);
+                mAlarmManager = (AlarmManager) service;
+            }
+            return mAlarmManager;
+        }
+    }
+
+    void scheduleNextAlarmCheck(long triggerTime) {
+        AlarmManager manager = getAlarmManager();
+        if (manager == null) {
+            Log.e(TAG, "scheduleNextAlarmCheck() cannot get AlarmManager");
+            return;
+        }
+        Context context = getContext();
+        Intent intent = new Intent(CalendarReceiver.SCHEDULE);
+        intent.setClass(context, CalendarReceiver.class);
+        PendingIntent pending = PendingIntent.getBroadcast(context,
+                0, intent, PendingIntent.FLAG_NO_CREATE);
+        if (pending != null) {
+            if (DEBUG_ALARMS) {
+                Log.i(TAG, "cancelling pending alarm " + pending);
+            }
+            // Cancel any previous alarms that do the same thing.
+            manager.cancel(pending);
+        }
+        pending = PendingIntent.getBroadcast(context,
+                0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+
+        if (DEBUG_ALARMS) {
+            Time time = new Time();
+            time.set(triggerTime);
+            String timeStr = time.format(" %a, %b %d, %Y %I:%M%P");
+            Log.i(TAG, "scheduleNextAlarmCheck at: " + triggerTime + timeStr);
+        }
+
+        manager.set(AlarmManager.RTC_WAKEUP, triggerTime, pending);
+    }
+
+    /*
+     * This method runs the alarm scheduler in a background thread.
+     */
+    void scheduleNextAlarm() {
+        Thread thread = new Thread(new AlarmScheduler());
+        thread.start();
+    }
+
+    /**
+     * This method runs in a background thread and schedules an alarm for
+     * the next calendar event, if necessary.
+     */
+    private void runScheduleNextAlarm() {
+        // Do not schedule any events while syncing or if this is a temporary
+        // database.
+        if (isTemporary())
+            return;
+
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            scheduleNextAlarmLocked(db);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    /**
+     * This method looks at the 24-hour window from now for any events that it
+     * needs to schedule.  This method runs within a database transaction.
+     * 
+     * @param db the database
+     */
+    private void scheduleNextAlarmLocked(SQLiteDatabase db) {
+        AlarmManager alarmManager = getAlarmManager();
+        if (alarmManager == null) {
+            Log.e(TAG, "Failed to find the AlarmManager. Could not schedule the next alarm!");
+            return;
+        }
+
+        final long currentMillis = System.currentTimeMillis();
+        final long start = currentMillis - SCHEDULE_ALARM_SLACK;
+        final long end = start + (24 * 60 * 60 * 1000);
+        ContentResolver cr = getContext().getContentResolver();
+        if (DEBUG_ALARMS) {
+            Time time = new Time();
+            time.set(start);
+            String startTimeStr = time.format(" %a, %b %d, %Y %I:%M%P");
+            Log.i(TAG, "runScheduleNextAlarm() start search: " + startTimeStr);
+        }
+
+        // Clear old alarms but keep alarms around for a while to prevent
+        // multiple alerts for the same reminder.  The "clearUpToTime'
+        // should be further in the past than the point in time where
+        // we start searching for events (the "start" variable defined above).
+        long clearUpToTime = currentMillis - CLEAR_OLD_ALARM_THRESHOLD;
+        db.delete("CalendarAlerts", CalendarAlerts.ALARM_TIME + "<" + clearUpToTime, null);
+
+        long nextAlarmTime = end;
+        long alarmTime = CalendarAlerts.findNextAlarmTime(cr, currentMillis);
+        if (alarmTime != -1 && alarmTime < nextAlarmTime) {
+            nextAlarmTime = alarmTime;
+        }
+
+        // Extract events from the database sorted by alarm time.  The
+        // alarm times are computed from Instances.begin (whose units
+        // are milliseconds) and Reminders.minutes (whose units are
+        // minutes).
+        //
+        // Also, ignore events whose end time is already in the past.
+        // Also, ignore events alarms that we have already scheduled.
+        //
+        // Note 1: we can add support for the case where Reminders.minutes
+        // equals -1 to mean use Calendars.minutes by adding a UNION for
+        // that case where the two halves restrict the WHERE clause on
+        // Reminders.minutes != -1 and Reminders.minutes = 1, respectively.
+        //
+        // Note 2: we have to name "myAlarmTime" different from the
+        // "alarmTime" column in CalendarAlerts because otherwise the
+        // query won't find multiple alarms for the same event.
+        String query = "SELECT begin-(minutes*60000) AS myAlarmTime,"
+            + " Instances.event_id AS eventId, begin, end,"
+            + " title, allDay, method, minutes"
+            + " FROM Instances INNER JOIN Events"
+            + " ON (Events._id = Instances.event_id)"
+            + " INNER JOIN Reminders"
+            + " ON (Instances.event_id = Reminders.event_id)"
+            + " WHERE method=" + Reminders.METHOD_ALERT
+            + " AND myAlarmTime>=" + start
+            + " AND myAlarmTime<=" + nextAlarmTime
+            + " AND end>=" + currentMillis
+            + " AND 0=(SELECT count(*) from CalendarAlerts CA"
+            + " where CA.event_id=Instances.event_id AND CA.begin=Instances.begin"
+            + " AND CA.alarmTime=myAlarmTime)"
+            + " ORDER BY myAlarmTime,begin,title";
+
+        acquireInstanceRange(start, end, false /* don't use minimum expansion windows */);
+        Cursor cursor = null;
+        try {
+            cursor = db.rawQuery(query, null);
+
+            int beginIndex = cursor.getColumnIndex(Instances.BEGIN);
+            int endIndex = cursor.getColumnIndex(Instances.END);
+            int eventIdIndex = cursor.getColumnIndex("eventId");
+            int alarmTimeIndex = cursor.getColumnIndex("myAlarmTime");
+            int minutesIndex = cursor.getColumnIndex(Reminders.MINUTES);
+
+            if (DEBUG_ALARMS) {
+                Time time = new Time();
+                time.set(nextAlarmTime);
+                String alarmTimeStr = time.format(" %a, %b %d, %Y %I:%M%P");
+                Log.i(TAG, "nextAlarmTime: " + alarmTimeStr
+                        + " query: " + query
+                        + " cursor results: " + cursor.getCount());
+            }
+
+            while (cursor.moveToNext()) {
+                // Schedule all alarms whose alarm time is as early as any
+                // scheduled alarm.  For example, if the earliest alarm is at
+                // 1pm, then we will schedule all alarms that occur at 1pm
+                // but no alarms that occur later than 1pm.
+                // Actually, we allow alarms up to a minute later to also
+                // be scheduled so that we don't have to check immediately
+                // again after an event alarm goes off.
+                alarmTime = cursor.getLong(alarmTimeIndex);
+                long eventId = cursor.getLong(eventIdIndex);
+                int minutes = cursor.getInt(minutesIndex);
+                long startTime = cursor.getLong(beginIndex);
+
+                if (DEBUG_ALARMS) {
+                    int titleIndex = cursor.getColumnIndex(Events.TITLE);
+                    String title = cursor.getString(titleIndex);
+                    Time time = new Time();
+                    time.set(alarmTime);
+                    String schedTime = time.format(" %a, %b %d, %Y %I:%M%P");
+                    time.set(startTime);
+                    String startTimeStr = time.format(" %a, %b %d, %Y %I:%M%P");
+                    long endTime = cursor.getLong(endIndex);
+                    time.set(endTime);
+                    String endTimeStr = time.format(" - %a, %b %d, %Y %I:%M%P");
+                    time.set(currentMillis);
+                    String currentTimeStr = time.format(" %a, %b %d, %Y %I:%M%P");
+                    Log.i(TAG, "  looking at id: " + eventId + " " + title
+                            + " " + startTime
+                            + startTimeStr + endTimeStr + " alarm: "
+                            + alarmTime + schedTime
+                            + " currentTime: " + currentTimeStr);
+                }
+
+                if (alarmTime < nextAlarmTime) {
+                    nextAlarmTime = alarmTime;
+                } else if (alarmTime > nextAlarmTime + android.pim.DateUtils.MINUTE_IN_MILLIS) {
+                    // This event alarm (and all later ones) will be scheduled
+                    // later.
+                    break;
+                }
+                
+                // Avoid an SQLiteContraintException by checking if this alarm
+                // already exists in the table.
+                if (CalendarAlerts.alarmExists(cr, eventId, startTime, alarmTime)) {
+                    continue;
+                }
+
+                // Insert this alarm into the CalendarAlerts table
+                long endTime = cursor.getLong(endIndex);
+                Uri uri = CalendarAlerts.insert(cr, eventId, startTime,
+                        endTime, alarmTime, minutes);
+                if (uri == null) {
+                    Log.e(TAG, "runScheduleNextAlarm() insert into CalendarAlerts table failed");
+                    continue;
+                }
+
+                Intent intent = new Intent(android.provider.Calendar.EVENT_REMINDER_ACTION);
+                intent.setData(uri);
+
+                // Also include the begin and end time of this event, because
+                // we cannot determine that from the Events database table.
+                intent.putExtra(android.provider.Calendar.EVENT_BEGIN_TIME, startTime);
+                intent.putExtra(android.provider.Calendar.EVENT_END_TIME, endTime);
+                if (DEBUG_ALARMS) {
+                    int titleIndex = cursor.getColumnIndex(Events.TITLE);
+                    String title = cursor.getString(titleIndex);
+                    Time time = new Time();
+                    time.set(alarmTime);
+                    String schedTime = time.format(" %a, %b %d, %Y %I:%M%P");
+                    time.set(startTime);
+                    String startTimeStr = time.format(" %a, %b %d, %Y %I:%M%P");
+                    time.set(endTime);
+                    String endTimeStr = time.format(" %a, %b %d, %Y %I:%M%P");
+                    time.set(currentMillis);
+                    String currentTimeStr = time.format(" %a, %b %d, %Y %I:%M%P");
+                    Log.i(TAG, "  scheduling " + title
+                            + startTimeStr  + " - " + endTimeStr + " alarm: " + schedTime
+                            + " currentTime: " + currentTimeStr
+                            + " uri: " + uri);
+                }
+                PendingIntent sender = PendingIntent.getBroadcast(getContext(),
+                        0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+                alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, sender);
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+
+        // If we scheduled an event alarm, then schedule the next alarm check
+        // for one minute past that alarm.  Otherwise, if there were no
+        // event alarms scheduled, then check again in 24 hours.  If a new
+        // event is inserted before the next alarm check, then this method
+        // will be run again when the new event is inserted.
+        if (nextAlarmTime != Long.MAX_VALUE) {
+            scheduleNextAlarmCheck(nextAlarmTime + android.pim.DateUtils.MINUTE_IN_MILLIS);
+        } else {
+            scheduleNextAlarmCheck(currentMillis + android.pim.DateUtils.DAY_IN_MILLIS);
+        }
+    }
+
+    private static String sEventsTable = "Events";
+    private static Uri sEventsURL =
+            Uri.parse("content://calendar/events/");
+    private static String sDeletedEventsTable = "DeletedEvents";
+    private static Uri sDeletedEventsURL =
+            Uri.parse("content://calendar/deleted_events/");
+    private static String sAttendeesTable = "Attendees";
+    private static String sRemindersTable = "Reminders";
+    private static String sCalendarAlertsTable = "CalendarAlerts";
+    private static String sExtendedPropertiesTable = "ExtendedProperties";
+
+    private class EventMerger extends AbstractTableMerger {
+
+        private ContentValues mValues = new ContentValues();
+        EventMerger() {
+            super(getDatabase(), sEventsTable, sEventsURL, sDeletedEventsTable, sDeletedEventsURL);
+        }
+
+        @Override
+        protected void notifyChanges() {
+            getContext().getContentResolver().notifyChange(Events.CONTENT_URI,
+                    null /* observer */, false /* do not sync to network */);
+        }
+
+        @Override
+        protected void cursorRowToContentValues(Cursor cursor, ContentValues map) {
+            rowToContentValues(cursor, map);
+        }
+
+        @Override
+        public void insertRow(ContentProvider diffs, Cursor diffsCursor) {
+            rowToContentValues(diffsCursor, mValues);
+            final SQLiteDatabase db = getDatabase();
+            long rowId = mEventsInserter.insert(mValues);
+            if (rowId <= 0) {
+                Log.e(TAG, "Unable to insert values into calendar db: " + mValues);
+                return;
+            }
+
+            long diffsRowId = diffsCursor.getLong(
+                diffsCursor.getColumnIndex(Events._ID));
+
+            insertAttendees(diffs, diffsRowId, rowId, db);
+            insertRemindersIfNecessary(diffs, diffsRowId, rowId, db);
+            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
+            // methods will fire a sql trigger that will cause this flag to
+            // be set.
+            clearSyncDirtyFlag(db, rowId);
+        }
+
+        private void clearSyncDirtyFlag(SQLiteDatabase db, long rowId) {
+            mValues.clear();
+            mValues.put(Events._SYNC_DIRTY, 0);
+            db.update(mTable, mValues, Events._ID + '=' + rowId, null);
+        }
+
+        private void insertAttendees(ContentProvider diffs,
+                long diffsRowId,
+                long rowId,
+                SQLiteDatabase db) {
+            // query attendees in diffs
+            Cursor attendeesCursor =
+                    diffs.query(Attendees.CONTENT_URI, null,
+                            "event_id=" + diffsRowId, null, null);
+            ContentValues attendeesValues = new ContentValues();
+            try {
+                while (attendeesCursor.moveToNext()) {
+                    attendeesValues.clear();
+                    DatabaseUtils.cursorStringToContentValues(attendeesCursor,
+                            Attendees.ATTENDEE_NAME,
+                            attendeesValues);
+                    DatabaseUtils.cursorStringToContentValues(attendeesCursor,
+                            Attendees.ATTENDEE_EMAIL,
+                            attendeesValues);
+                    DatabaseUtils.cursorIntToContentValues(attendeesCursor,
+                            Attendees.ATTENDEE_STATUS,
+                            attendeesValues);
+                    DatabaseUtils.cursorIntToContentValues(attendeesCursor,
+                            Attendees.ATTENDEE_TYPE,
+                            attendeesValues);
+                    DatabaseUtils.cursorIntToContentValues(attendeesCursor,
+                            Attendees.ATTENDEE_RELATIONSHIP,
+                            attendeesValues);
+                    attendeesValues.put(Attendees.EVENT_ID, rowId);
+                    mAttendeesInserter.insert(attendeesValues);
+                }
+            } finally {
+                if (attendeesCursor != null) {
+                    attendeesCursor.close();
+                }
+            }
+        }
+
+        private void insertRemindersIfNecessary(ContentProvider diffs,
+                                                long diffsRowId,
+                                                long rowId,
+                                                SQLiteDatabase db) {
+            // insert reminders, if necessary.
+            Integer hasAlarm = mValues.getAsInteger(Events.HAS_ALARM);
+            if (hasAlarm != null && hasAlarm.intValue() == 1) {
+                // query reminders in diffs
+                Cursor reminderCursor =
+                        diffs.query(Reminders.CONTENT_URI, null,
+                                "event_id=" + diffsRowId, null, null);
+                ContentValues reminderValues = new ContentValues();
+                try {
+                    while (reminderCursor.moveToNext()) {
+                        reminderValues.clear();
+                        DatabaseUtils.cursorIntToContentValues(reminderCursor,
+                                Reminders.METHOD,
+                                reminderValues);
+                        DatabaseUtils.cursorIntToContentValues(reminderCursor,
+                                Reminders.MINUTES,
+                                reminderValues);
+                        reminderValues.put(Reminders.EVENT_ID, rowId);
+                        mRemindersInserter.insert(reminderValues);
+                    }
+                } finally {
+                    if (reminderCursor != null) {
+                        reminderCursor.close();
+                    }
+                }
+            }
+        }
+
+        private void insertExtendedPropertiesIfNecessary(ContentProvider diffs,
+                                                         long diffsRowId,
+                                                         long rowId,
+                                                         SQLiteDatabase db) {
+            // insert extended properties, if necessary.
+            Integer hasExtendedProperties = mValues.getAsInteger(Events.HAS_EXTENDED_PROPERTIES);
+            if (hasExtendedProperties != null && hasExtendedProperties.intValue() != 0) {
+                // query reminders in diffs
+                Cursor extendedPropertiesCursor =
+                        diffs.query(Calendar.ExtendedProperties.CONTENT_URI, null,
+                                "event_id=" + diffsRowId, null, null);
+                ContentValues extendedPropertiesValues = new ContentValues();
+                try {
+                    while (extendedPropertiesCursor.moveToNext()) {
+                        extendedPropertiesValues.clear();
+                        DatabaseUtils.cursorStringToContentValues(extendedPropertiesCursor,
+                                Calendar.ExtendedProperties.NAME, extendedPropertiesValues);
+                        DatabaseUtils.cursorStringToContentValues(extendedPropertiesCursor,
+                                Calendar.ExtendedProperties.VALUE, extendedPropertiesValues);
+                        mExtendedPropertiesInserter.insert(extendedPropertiesValues);
+                    }
+                } finally {
+                    if (extendedPropertiesCursor != null) {
+                        extendedPropertiesCursor.close();
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void updateRow(long localId, ContentProvider diffs,
+                                 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) {
+                Log.e(TAG, "Unable to update calendar db: " + mValues);
+                return;
+            }
+
+            long diffsRowId = diffsCursor.getLong(
+                diffsCursor.getColumnIndex(Events._ID));
+            // TODO: only update the attendees, reminders, and extended properties if they have
+            // changed?
+            // delete the existing attendees, reminders, and extended properties
+            db.delete(sAttendeesTable, "event_id=" + localId, null /* selectionArgs */);
+            db.delete(sRemindersTable, "event_id=" + localId, null /* selectionArgs */);
+            db.delete(sExtendedPropertiesTable, "event_id=" + localId,
+                    null /* selectionArgs */);
+
+            // process attendees sent by the server.
+            insertAttendees(diffs, diffsRowId, localId, db);
+            // process reminders sent by the server.
+            insertRemindersIfNecessary(diffs, diffsRowId, localId, db);
+
+            // process extended properties sent by the server.
+            insertExtendedPropertiesIfNecessary(diffs, diffsRowId, localId, db);
+
+            updateEventRawTimesLocked(localId, mValues);
+            updateInstancesLocked(mValues, localId, false /* not a new event */, db);
+
+            // Update the _SYNC_DIRTY flag of the event. We have to do this
+            // after updating since the update of the reminders and extended properties
+            // methods will fire a sql trigger that will cause this flag to
+            // be set.
+            clearSyncDirtyFlag(db, localId);
+        }
+
+        @Override
+        public void resolveRow(long localId, String syncId,
+                                  ContentProvider diffs, Cursor diffsCursor) {
+            // server wins
+            updateRow(localId, diffs, diffsCursor);
+        }
+
+        @Override
+        public void deleteRow(Cursor localCursor) {
+            int idIndex = localCursor.getColumnIndexOrThrow(Events._ID);
+            long localId = localCursor.getLong(idIndex);
+            deleteBusyBitsLocked(localId);
+            super.deleteRow(localCursor);
+        }
+
+        private void rowToContentValues(Cursor diffsCursor, ContentValues values) {
+            values.clear();
+
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events._SYNC_ID, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events._SYNC_TIME, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events._SYNC_VERSION, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events._SYNC_DIRTY, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events._SYNC_ACCOUNT, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.HTML_URI, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.TITLE, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.EVENT_LOCATION, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.DESCRIPTION, values);
+            DatabaseUtils.cursorLongToContentValues(diffsCursor, Events.STATUS, values);
+            DatabaseUtils.cursorIntToContentValues(diffsCursor, Events.SELF_ATTENDEE_STATUS,
+                    values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.COMMENTS_URI, values);
+            DatabaseUtils.cursorLongToContentValues(diffsCursor, Events.DTSTART, values);
+            DatabaseUtils.cursorLongToContentValues(diffsCursor, Events.DTEND, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.EVENT_TIMEZONE, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.DURATION, values);
+            DatabaseUtils.cursorIntToContentValues(diffsCursor, Events.ALL_DAY, values);
+            DatabaseUtils.cursorIntToContentValues(diffsCursor, Events.VISIBILITY, values);
+            DatabaseUtils.cursorIntToContentValues(diffsCursor, Events.TRANSPARENCY, values);
+            DatabaseUtils.cursorIntToContentValues(diffsCursor, Events.HAS_ALARM, values);
+            DatabaseUtils.cursorIntToContentValues(diffsCursor, Events.HAS_EXTENDED_PROPERTIES,
+                    values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.RRULE, values);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, Events.ORIGINAL_EVENT, values);
+            DatabaseUtils.cursorLongToContentValues(diffsCursor, Events.ORIGINAL_INSTANCE_TIME,
+                    values);
+            DatabaseUtils.cursorLongToContentValues(diffsCursor, Events.LAST_DATE, values);
+            DatabaseUtils.cursorLongToContentValues(diffsCursor, Events.CALENDAR_ID, values);
+        }
+    }
+
+    private static final int EVENTS = 1;
+    private static final int EVENTS_ID = 2;
+    private static final int INSTANCES = 3;
+    private static final int DELETED_EVENTS = 4;
+    private static final int CALENDARS = 5;
+    private static final int CALENDARS_ID = 6;
+    private static final int ATTENDEES = 7;
+    private static final int ATTENDEES_ID = 8;
+    private static final int REMINDERS = 9;
+    private static final int REMINDERS_ID = 10;
+    private static final int EXTENDED_PROPERTIES = 11;
+    private static final int EXTENDED_PROPERTIES_ID = 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 UriMatcher sURLMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+    private static final HashMap<String, String> sInstancesProjectionMap;
+    private static final HashMap<String, String> sEventsProjectionMap;
+    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", "events", EVENTS);
+        sURLMatcher.addURI("calendar", "events/#", EVENTS_ID);
+        sURLMatcher.addURI("calendar", "calendars", CALENDARS);
+        sURLMatcher.addURI("calendar", "calendars/#", CALENDARS_ID);
+        sURLMatcher.addURI("calendar", "deleted_events", DELETED_EVENTS);
+        sURLMatcher.addURI("calendar", "attendees", ATTENDEES);
+        sURLMatcher.addURI("calendar", "attendees/#", ATTENDEES_ID);
+        sURLMatcher.addURI("calendar", "reminders", REMINDERS);
+        sURLMatcher.addURI("calendar", "reminders/#", REMINDERS_ID);
+        sURLMatcher.addURI("calendar", "extendedproperties", EXTENDED_PROPERTIES);
+        sURLMatcher.addURI("calendar", "extendedproperties/#", EXTENDED_PROPERTIES_ID);
+        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>();
+        // Events columns
+        sEventsProjectionMap.put(Events.HTML_URI, "htmlUri");
+        sEventsProjectionMap.put(Events.TITLE, "title");
+        sEventsProjectionMap.put(Events.EVENT_LOCATION, "eventLocation");
+        sEventsProjectionMap.put(Events.DESCRIPTION, "description");
+        sEventsProjectionMap.put(Events.STATUS, "eventStatus");
+        sEventsProjectionMap.put(Events.SELF_ATTENDEE_STATUS, "selfAttendeeStatus");
+        sEventsProjectionMap.put(Events.COMMENTS_URI, "commentsUri");
+        sEventsProjectionMap.put(Events.DTSTART, "dtstart");
+        sEventsProjectionMap.put(Events.DTEND, "dtend");
+        sEventsProjectionMap.put(Events.EVENT_TIMEZONE, "eventTimezone");
+        sEventsProjectionMap.put(Events.DURATION, "duration");
+        sEventsProjectionMap.put(Events.ALL_DAY, "allDay");
+        sEventsProjectionMap.put(Events.VISIBILITY, "visibility");
+        sEventsProjectionMap.put(Events.TRANSPARENCY, "transparency");
+        sEventsProjectionMap.put(Events.HAS_ALARM, "hasAlarm");
+        sEventsProjectionMap.put(Events.HAS_EXTENDED_PROPERTIES, "hasExtendedProperties");
+        sEventsProjectionMap.put(Events.RRULE, "rrule");
+        sEventsProjectionMap.put(Events.RDATE, "rdate");
+        sEventsProjectionMap.put(Events.EXRULE, "exrule");
+        sEventsProjectionMap.put(Events.EXDATE, "exdate");
+        sEventsProjectionMap.put(Events.ORIGINAL_EVENT, "originalEvent");
+        sEventsProjectionMap.put(Events.ORIGINAL_INSTANCE_TIME, "originalInstanceTime");
+        sEventsProjectionMap.put(Events.LAST_DATE, "lastDate");
+        sEventsProjectionMap.put(Events.CALENDAR_ID, "calendar_id");
+        // Calendar columns
+        sEventsProjectionMap.put(Events.COLOR, "color");
+        sEventsProjectionMap.put(Events.ACCESS_LEVEL, "access_level");
+        sEventsProjectionMap.put(Events.SELECTED, "selected");
+        sEventsProjectionMap.put(Calendars.URL, "url");
+        sEventsProjectionMap.put(Calendars.TIMEZONE, "timezone");
+
+        // Put the shared items into the Instances projection map
+        sInstancesProjectionMap = new HashMap<String, String>(sEventsProjectionMap);
+        sAttendeesProjectionMap = new HashMap<String, String>(sEventsProjectionMap);
+        sRemindersProjectionMap = new HashMap<String, String>(sEventsProjectionMap);
+        sCalendarAlertsProjectionMap = new HashMap<String, String>(sEventsProjectionMap);
+
+        sEventsProjectionMap.put(Events._ID, "Events._id AS _id");
+        sEventsProjectionMap.put(Events._SYNC_ID, "Events._sync_id AS _sync_id");
+        sEventsProjectionMap.put(Events._SYNC_VERSION, "Events._sync_version AS _sync_version");
+        sEventsProjectionMap.put(Events._SYNC_TIME, "Events._sync_time AS _sync_time");
+        sEventsProjectionMap.put(Events._SYNC_LOCAL_ID, "Events._sync_local_id AS _sync_local_id");
+        sEventsProjectionMap.put(Events._SYNC_DIRTY, "Events._sync_dirty AS _sync_dirty");
+        sEventsProjectionMap.put(Events._SYNC_ACCOUNT, "Events._sync_account AS _sync_account");
+
+        // Instances columns
+        sInstancesProjectionMap.put(Instances.BEGIN, "begin");
+        sInstancesProjectionMap.put(Instances.END, "end");
+        sInstancesProjectionMap.put(Instances.EVENT_ID, "Instances.event_id AS event_id");
+        sInstancesProjectionMap.put(Instances._ID, "Instances._id AS _id");
+        sInstancesProjectionMap.put(Instances.START_DAY, "startDay");
+        sInstancesProjectionMap.put(Instances.END_DAY, "endDay");
+        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");
+        sAttendeesProjectionMap.put(Attendees.ATTENDEE_NAME, "attendeeName");
+        sAttendeesProjectionMap.put(Attendees.ATTENDEE_EMAIL, "attendeeEmail");
+        sAttendeesProjectionMap.put(Attendees.ATTENDEE_STATUS, "attendeeStatus");
+        sAttendeesProjectionMap.put(Attendees.ATTENDEE_RELATIONSHIP, "attendeeRelationship");
+        sAttendeesProjectionMap.put(Attendees.ATTENDEE_TYPE, "attendeeType");
+
+        // Reminders columns
+        sRemindersProjectionMap.put(Reminders.EVENT_ID, "event_id");
+        sRemindersProjectionMap.put(Reminders._ID, "Reminders._id AS _id");
+        sRemindersProjectionMap.put(Reminders.MINUTES, "minutes");
+        sRemindersProjectionMap.put(Reminders.METHOD, "method");
+
+        // CalendarAlerts columns
+        sCalendarAlertsProjectionMap.put(CalendarAlerts.EVENT_ID, "event_id");
+        sCalendarAlertsProjectionMap.put(CalendarAlerts._ID, "CalendarAlerts._id AS _id");
+        sCalendarAlertsProjectionMap.put(CalendarAlerts.BEGIN, "begin");
+        sCalendarAlertsProjectionMap.put(CalendarAlerts.END, "end");
+        sCalendarAlertsProjectionMap.put(CalendarAlerts.ALARM_TIME, "alarmTime");
+        sCalendarAlertsProjectionMap.put(CalendarAlerts.STATE, "state");
+        sCalendarAlertsProjectionMap.put(CalendarAlerts.MINUTES, "minutes");
+    }
+}
diff --git a/src/com/android/providers/calendar/CalendarReceiver.java b/src/com/android/providers/calendar/CalendarReceiver.java
new file mode 100644
index 0000000..f3bef8f
--- /dev/null
+++ b/src/com/android/providers/calendar/CalendarReceiver.java
@@ -0,0 +1,52 @@
+/*
+** Copyright 2006, 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,
+** See the License for the specific language governing permissions and
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** limitations under the License.
+*/
+
+package com.android.providers.calendar;
+
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.IContentProvider;
+import android.content.Intent;
+import android.content.BroadcastReceiver;
+
+/**
+ * This IntentReceiver executes when the boot completes and ensures that
+ * the Calendar provider has started and then initializes the alarm
+ * scheduler for the Calendar provider.  This needs to be done after
+ * the boot completes because the alarm manager may not have been started
+ * yet.
+ */
+public class CalendarReceiver extends BroadcastReceiver {
+    
+    static final String SCHEDULE = "com.android.providers.calendar.SCHEDULE_ALARM";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        ContentResolver cr = context.getContentResolver();
+        CalendarProvider provider;
+        IContentProvider icp = cr.acquireProvider("calendar");
+        provider = (CalendarProvider) ContentProvider.
+                coerceToLocalContentProvider(icp);
+        if (action.equals(SCHEDULE)) {
+            provider.scheduleNextAlarm();
+        } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
+            provider.scheduleNextAlarm();
+        }
+        cr.releaseProvider(icp);
+    }
+}
diff --git a/src/com/android/providers/calendar/CalendarSyncAdapter.java b/src/com/android/providers/calendar/CalendarSyncAdapter.java
new file mode 100644
index 0000000..e368915
--- /dev/null
+++ b/src/com/android/providers/calendar/CalendarSyncAdapter.java
@@ -0,0 +1,1252 @@
+/*
+**
+** Copyright 2006, 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,
+** See the License for the specific language governing permissions and
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** limitations under the License.
+*/
+
+package com.android.providers.calendar;
+
+import com.google.android.gdata.client.AndroidXmlParserFactory;
+import com.google.android.gdata.client.AndroidGDataClient;
+import com.google.android.providers.AbstractGDataSyncAdapter;
+import com.google.wireless.gdata.calendar.client.CalendarClient;
+import com.google.wireless.gdata.calendar.data.EventEntry;
+import com.google.wireless.gdata.calendar.data.EventsFeed;
+import com.google.wireless.gdata.calendar.data.Reminder;
+import com.google.wireless.gdata.calendar.data.When;
+import com.google.wireless.gdata.calendar.data.Who;
+import com.google.wireless.gdata.calendar.parser.xml.XmlCalendarGDataParserFactory;
+import com.google.wireless.gdata.client.GDataServiceClient;
+import com.google.wireless.gdata.client.QueryParams;
+import com.google.wireless.gdata.data.Entry;
+import com.google.wireless.gdata.data.Feed;
+import com.google.wireless.gdata.data.StringUtils;
+import com.google.wireless.gdata.parser.ParseException;
+
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SyncContext;
+import android.content.SyncableContentProvider;
+import android.content.SyncResult;
+import android.database.Cursor;
+import android.database.CursorJoiner;
+import android.net.Uri;
+import android.os.SystemProperties;
+import android.os.Bundle;
+import android.pim.ICalendar;
+import android.pim.RecurrenceSet;
+import android.pim.Time;
+import android.provider.Calendar;
+import android.provider.Calendar.Calendars;
+import android.provider.Calendar.Events;
+import android.provider.SubscribedFeeds;
+import android.provider.SyncConstValue;
+import android.text.TextUtils;
+import android.util.Config;
+import android.util.Log;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * SyncAdapter for Google Calendar.  Fetches the list of the user's calendars,
+ * and for each calendar that is marked as &quot;selected&quot; in the web
+ * interface, syncs that calendar.
+ */
+public final class CalendarSyncAdapter extends AbstractGDataSyncAdapter {
+
+    private static final String SELECT_BY_ACCOUNT = Calendars._SYNC_ACCOUNT + "=?";
+    private static final String SELECT_BY_ACCOUNT_AND_FEED =
+            SELECT_BY_ACCOUNT + " AND " + Calendars.URL + "=?";
+
+    private static final String[] CALENDAR_KEY_COLUMNS =
+            new String[]{Calendars._SYNC_ACCOUNT, Calendars.URL};
+    private static final String CALENDAR_KEY_SORT_ORDER =
+            Calendars._SYNC_ACCOUNT + "," + Calendars.URL;
+    private static final String[] FEEDS_KEY_COLUMNS =
+            new String[]{SubscribedFeeds.Feeds._SYNC_ACCOUNT, SubscribedFeeds.Feeds.FEED};
+    private static final String FEEDS_KEY_SORT_ORDER =
+            SubscribedFeeds.Feeds._SYNC_ACCOUNT + ", " + SubscribedFeeds.Feeds.FEED;
+
+    public static class SyncInfo {
+        // public String feedUrl;
+        public long calendarId;
+        public String calendarTimezone;
+    }
+
+    private static final String TAG = "Sync";
+    private static final Integer sTentativeStatus = Events.STATUS_TENTATIVE;
+    private static final Integer sConfirmedStatus = Events.STATUS_CONFIRMED;
+    private static final Integer sCanceledStatus = Events.STATUS_CANCELED;
+
+    private final CalendarClient mCalendarClient;
+
+    private ContentResolver mContentResolver;
+
+    private static final String[] CALENDARS_PROJECTION = new String[] {
+            Calendars._ID,            // 0
+            Calendars.SELECTED,       // 1
+            Calendars._SYNC_TIME,     // 2
+            Calendars.URL,            // 3
+            Calendars.DISPLAY_NAME,   // 4
+            Calendars.TIMEZONE,       // 5
+            Calendars.SYNC_EVENTS     // 6
+    };
+
+    // Counters for sync event logging
+    private static int mServerDiffs;
+    private static int mRefresh;
+
+    protected CalendarSyncAdapter(Context context, SyncableContentProvider provider) {
+        super(context, provider);
+        mCalendarClient = new CalendarClient(
+                new AndroidGDataClient(context.getContentResolver()),
+                new XmlCalendarGDataParserFactory(new AndroidXmlParserFactory()));
+    }
+
+    @Override
+    protected Object createSyncInfo() {
+        return new SyncInfo();
+    }
+
+    @Override
+    protected Entry newEntry() {
+        return new EventEntry();
+    }
+
+    @Override
+    protected Cursor getCursorForTable(ContentProvider cp, Class entryClass) {
+        if (entryClass != EventEntry.class) {
+            throw new IllegalArgumentException("unexpected entry class, " + entryClass.getName());
+        }
+        return cp.query(Calendar.Events.CONTENT_URI, null, null, null, null);
+    }
+
+    @Override
+    protected Cursor getCursorForDeletedTable(ContentProvider cp, Class entryClass) {
+        if (entryClass != EventEntry.class) {
+            throw new IllegalArgumentException("unexpected entry class, " + entryClass.getName());
+        }
+        return cp.query(Calendar.Events.DELETED_CONTENT_URI, null, null, null, null);
+    }
+
+    @Override
+    protected String cursorToEntry(SyncContext context, Cursor c, Entry entry,
+            Object info) throws ParseException {
+        EventEntry event = (EventEntry) entry;
+        SyncInfo syncInfo = (SyncInfo) info;
+
+        String feedUrl = c.getString(c.getColumnIndex(Calendars.URL));
+
+        // update the sync info.  this will be used later when we update the
+        // provider with the results of sending this entry to the calendar
+        // server.
+        syncInfo.calendarId = c.getLong(c.getColumnIndex(Events.CALENDAR_ID));
+        syncInfo.calendarTimezone =
+                c.getString(c.getColumnIndex(Events.EVENT_TIMEZONE));
+        if (TextUtils.isEmpty(syncInfo.calendarTimezone)) {
+            // if the event timezone is not set -- e.g., when we're creating an
+            // event on the device -- we will use the timezone for the calendar.
+            syncInfo.calendarTimezone =
+                    c.getString(c.getColumnIndex(Events.TIMEZONE));
+        }
+
+        // id
+        event.setId(c.getString(c.getColumnIndex(Events._SYNC_ID)));
+        event.setEditUri(c.getString(c.getColumnIndex(Events._SYNC_VERSION)));
+
+        // status
+        byte status;
+        int localStatus = c.getInt(c.getColumnIndex(Events.STATUS));
+        switch (localStatus) {
+            case Events.STATUS_CANCELED:
+                status = EventEntry.STATUS_CANCELED;
+                break;
+            case Events.STATUS_CONFIRMED:
+                status = EventEntry.STATUS_CONFIRMED;
+                break;
+            case Events.STATUS_TENTATIVE:
+                status = EventEntry.STATUS_TENTATIVE;
+                break;
+            default:
+                // should not happen
+                status = EventEntry.STATUS_TENTATIVE;
+                break;
+        }
+        event.setStatus(status);
+
+        // visibility
+        byte visibility;
+        int localVisibility = c.getInt(c.getColumnIndex(Events.VISIBILITY));
+        switch (localVisibility) {
+            case Events.VISIBILITY_DEFAULT:
+                visibility = EventEntry.VISIBILITY_DEFAULT;
+                break;
+            case Events.VISIBILITY_CONFIDENTIAL:
+                visibility = EventEntry.VISIBILITY_CONFIDENTIAL;
+                break;
+            case Events.VISIBILITY_PRIVATE:
+                visibility = EventEntry.VISIBILITY_PRIVATE;
+                break;
+            case Events.VISIBILITY_PUBLIC:
+                visibility = EventEntry.VISIBILITY_PUBLIC;
+                break;
+            default:
+                // should not happen
+                Log.e(TAG, "Unexpected value for visibility: " + localVisibility
+                        + "; using default visibility.");
+                visibility = EventEntry.VISIBILITY_DEFAULT;
+                break;
+        }
+        event.setVisibility(visibility);
+
+        byte transparency;
+        int localTransparency = c.getInt(c.getColumnIndex(Events.TRANSPARENCY));
+        switch (localTransparency) {
+            case Events.TRANSPARENCY_OPAQUE:
+                transparency = EventEntry.TRANSPARENCY_OPAQUE;
+                break;
+            case Events.TRANSPARENCY_TRANSPARENT:
+                transparency = EventEntry.TRANSPARENCY_TRANSPARENT;
+                break;
+            default:
+                // should not happen
+                Log.e(TAG, "Unexpected value for transparency: " + localTransparency
+                        + "; using opaque transparency.");
+                transparency = EventEntry.TRANSPARENCY_OPAQUE;
+                break;
+        }
+        event.setTransparency(transparency);
+
+        // could set the html uri, but there's no need to, since it should not be edited.
+
+        // title
+        event.setTitle(c.getString(c.getColumnIndex(Events.TITLE)));
+
+        // description
+        event.setContent(c.getString(c.getColumnIndex(Events.DESCRIPTION)));
+
+        // where
+        event.setWhere(c.getString(c.getColumnIndex(Events.EVENT_LOCATION)));
+
+        // attendees
+        long eventId = c.getInt(c.getColumnIndex(Events._SYNC_LOCAL_ID));
+        addAttendeesToEntry(eventId, event);
+
+        // comment uri
+        event.setCommentsUri(c.getString(c.getColumnIndexOrThrow(Events.COMMENTS_URI)));
+
+        Time utc = new Time(Time.TIMEZONE_UTC);
+
+        boolean allDay = c.getInt(c.getColumnIndex(Events.ALL_DAY)) != 0;
+
+        String startTime = null;
+        String endTime = null;
+        // start time
+        int dtstartColumn = c.getColumnIndex(Events.DTSTART);
+        if (!c.isNull(dtstartColumn)) {
+            long dtstart = c.getLong(dtstartColumn);
+            utc.set(dtstart);
+            startTime = utc.format3339(allDay);
+        }
+
+        // end time
+        int dtendColumn = c.getColumnIndex(Events.DTEND);
+        if (!c.isNull(dtendColumn)) {
+            long dtend = c.getLong(dtendColumn);
+            utc.set(dtend);
+            endTime = utc.format3339(allDay);
+        }
+
+        When when = new When(startTime, endTime);
+        event.addWhen(when);
+
+        // reminders
+        Integer hasReminder = c.getInt(c.getColumnIndex(Events.HAS_ALARM));
+        if (hasReminder != null && hasReminder.intValue() != 0) {
+            addRemindersToEntry(eventId, event);
+        }
+
+        // extendedProperties
+        Integer hasExtendedProperties = c.getInt(c.getColumnIndex(Events.HAS_EXTENDED_PROPERTIES));
+        if (hasExtendedProperties != null && hasExtendedProperties.intValue() != 0) {
+            addExtendedPropertiesToEntry(eventId, event);
+        }
+
+        long originalStartTime = -1;
+        String originalId = c.getString(c.getColumnIndex(Events.ORIGINAL_EVENT));
+        int originalStartTimeIndex = c.getColumnIndex(Events.ORIGINAL_INSTANCE_TIME);
+        if (!c.isNull(originalStartTimeIndex)) {
+            originalStartTime = c.getLong(originalStartTimeIndex);
+        }
+        if ((originalStartTime != -1) &&
+                !TextUtils.isEmpty(originalId)) {
+
+            Time originalTime = new Time(c.getString(c.getColumnIndex(Events.EVENT_TIMEZONE)));
+            originalTime.set(originalStartTime);
+
+            utc.set(originalStartTime);
+            event.setOriginalEventStartTime(utc.format3339(allDay));
+            event.setOriginalEventId(originalId);
+        }
+
+        // recurrences.
+        ICalendar.Component component = new ICalendar.Component("DUMMY",
+                null /* parent */);
+        if (RecurrenceSet.populateComponent(c, component)) {
+            addRecurrenceToEntry(component, event);
+        }
+
+        // if this is a new entry, return the feed url.  otherwise, return null; the edit url is
+        // already in the entry.
+        if (event.getEditUri() == null) {
+            return feedUrl;
+        } else {
+            return null;
+        }
+    }
+
+    private void addAttendeesToEntry(long eventId, EventEntry event)
+            throws ParseException {
+        Cursor c = getContext().getContentResolver().query(
+                Calendar.Attendees.CONTENT_URI, null, "event_id=" + eventId, null, null);
+
+        try {
+            int nameIndex = c.getColumnIndexOrThrow(Calendar.Attendees.ATTENDEE_NAME);
+            int emailIndex = c.getColumnIndexOrThrow(Calendar.Attendees.ATTENDEE_EMAIL);
+            int statusIndex = c.getColumnIndexOrThrow(Calendar.Attendees.ATTENDEE_STATUS);
+            int typeIndex = c.getColumnIndexOrThrow(Calendar.Attendees.ATTENDEE_TYPE);
+            int relIndex = c.getColumnIndexOrThrow(Calendar.Attendees.ATTENDEE_RELATIONSHIP);
+
+
+
+            while (c.moveToNext()) {
+                Who who = new Who();
+                who.setValue(c.getString(nameIndex));
+                who.setEmail(c.getString(emailIndex));
+                int status = c.getInt(statusIndex);
+                switch (status) {
+                    case Calendar.Attendees.ATTENDEE_STATUS_NONE:
+                        who.setStatus(Who.STATUS_NONE);
+                        break;
+                    case Calendar.Attendees.ATTENDEE_STATUS_ACCEPTED:
+                        who.setStatus(Who.STATUS_ACCEPTED);
+                        break;
+                    case Calendar.Attendees.ATTENDEE_STATUS_DECLINED:
+                        who.setStatus(Who.STATUS_DECLINED);
+                        break;
+                    case Calendar.Attendees.ATTENDEE_STATUS_INVITED:
+                        who.setStatus(Who.STATUS_INVITED);
+                        break;
+                    case Calendar.Attendees.ATTENDEE_STATUS_TENTATIVE:
+                        who.setStatus(Who.STATUS_TENTATIVE);
+                        break;
+                    default:
+                        Log.e(TAG, "Unknown attendee status: " + status);
+                        who.setStatus(Who.STATUS_NONE);
+                        break;
+                }
+                int type = c.getInt(typeIndex);
+                switch (type) {
+                    case Calendar.Attendees.TYPE_NONE:
+                        who.setType(Who.TYPE_NONE);
+                        break;
+                    case Calendar.Attendees.TYPE_REQUIRED:
+                        who.setType(Who.TYPE_REQUIRED);
+                        break;
+                    case Calendar.Attendees.TYPE_OPTIONAL:
+                        who.setType(Who.TYPE_OPTIONAL);
+                        break;
+                    default:
+                        Log.e(TAG, "Unknown attendee type: " + type);
+                        who.setType(Who.TYPE_NONE);
+                        break;
+                }
+                int rel = c.getInt(relIndex);
+                switch (rel) {
+                    case Calendar.Attendees.RELATIONSHIP_NONE:
+                        who.setRelationship(Who.RELATIONSHIP_NONE);
+                        break;
+                    case Calendar.Attendees.RELATIONSHIP_ATTENDEE:
+                        who.setRelationship(Who.RELATIONSHIP_ATTENDEE);
+                        break;
+                    case Calendar.Attendees.RELATIONSHIP_ORGANIZER:
+                        who.setRelationship(Who.RELATIONSHIP_ORGANIZER);
+                        break;
+                    case Calendar.Attendees.RELATIONSHIP_SPEAKER:
+                        who.setRelationship(Who.RELATIONSHIP_SPEAKER);
+                        break;
+                    case Calendar.Attendees.RELATIONSHIP_PERFORMER:
+                        who.setRelationship(Who.RELATIONSHIP_PERFORMER);
+                        break;
+                    default:
+                        Log.e(TAG, "Unknown attendee relationship: " + rel);
+                        who.setRelationship(Who.RELATIONSHIP_NONE);
+                        break;
+                }
+                event.addAttendee(who);
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    private void addRemindersToEntry(long eventId, EventEntry event)
+            throws ParseException {
+        Cursor c = getContext().getContentResolver().query(
+                Calendar.Reminders.CONTENT_URI, null,
+                "event_id=" + eventId, null, null);
+
+        try {
+            int methodIndex = c.getColumnIndex(Calendar.Reminders.METHOD);
+            int minutesIndex = c.getColumnIndex(Calendar.Reminders.MINUTES);
+
+            while (c.moveToNext()) {
+                Reminder reminder = new Reminder();
+                reminder.setMinutes(c.getInt(minutesIndex));
+                int method = c.getInt(methodIndex);
+                switch(method) {
+                    case Calendar.Reminders.METHOD_DEFAULT:
+                        reminder.setMethod(Reminder.METHOD_DEFAULT);
+                        break;
+                    case Calendar.Reminders.METHOD_ALERT:
+                        reminder.setMethod(Reminder.METHOD_ALERT);
+                        break;
+                    case Calendar.Reminders.METHOD_EMAIL:
+                        reminder.setMethod(Reminder.METHOD_EMAIL);
+                        break;
+                    case Calendar.Reminders.METHOD_SMS:
+                        reminder.setMethod(Reminder.METHOD_SMS);
+                        break;
+                    default:
+                        throw new ParseException("illegal method, " + method);
+                }
+                event.addReminder(reminder);
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    private void addExtendedPropertiesToEntry(long eventId, EventEntry event)
+            throws ParseException {
+        Cursor c = getContext().getContentResolver().query(
+                Calendar.ExtendedProperties.CONTENT_URI, null,
+                "event_id=" + eventId, null, null);
+
+        try {
+            int nameIndex = c.getColumnIndex(Calendar.ExtendedProperties.NAME);
+            int valueIndex = c.getColumnIndex(Calendar.ExtendedProperties.VALUE);
+
+            while (c.moveToNext()) {
+                String name = c.getString(nameIndex);
+                String value = c.getString(valueIndex);
+                event.addExtendedProperty(name, value);
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    private void addRecurrenceToEntry(ICalendar.Component component,
+            EventEntry event) {
+        // serialize the component into a Google Calendar recurrence string
+        // we don't serialize the entire component, since we have a dummy
+        // wrapper (BEGIN:DUMMY, END:DUMMY).
+        StringBuilder sb = new StringBuilder();
+
+        // append the properties
+        boolean first = true;
+        for (String propertyName : component.getPropertyNames()) {
+            for (ICalendar.Property property :
+                    component.getProperties(propertyName)) {
+                if (first) {
+                    first = false;
+                } else {
+                    sb.append("\n");
+                }
+                property.toString(sb);
+            }
+        }
+
+        // append the sub-components
+        List<ICalendar.Component> children = component.getComponents();
+        if (children != null) {
+            for (ICalendar.Component child : children) {
+                if (first) {
+                    first = false;
+                } else {
+                    sb.append("\n");
+                }
+                child.toString(sb);
+            }
+        }
+        event.setRecurrence(sb.toString());
+    }
+
+    @Override
+    protected void deletedCursorToEntry(SyncContext context, Cursor c, Entry entry) {
+        EventEntry event = (EventEntry) entry;
+        event.setId(c.getString(c.getColumnIndex(Events._SYNC_ID)));
+        event.setEditUri(c.getString(c.getColumnIndex(Events._SYNC_VERSION)));
+        event.setStatus(EventEntry.STATUS_CANCELED);
+    }
+
+    protected boolean handleAllDeletedUnavailable(GDataSyncData syncData, String feed) {
+        syncData.feedData.remove(feed);
+        getContext().getContentResolver().delete(Calendar.Calendars.CONTENT_URI,
+                Calendar.Calendars._SYNC_ACCOUNT + "=? AND " + Calendar.Calendars.URL + "=?",
+                new String[]{getAccount(), feed});
+        return true;
+    }
+
+    @Override
+    public void onSyncStarting(SyncContext context, String account, boolean forced,
+            SyncResult result) {
+        mContentResolver = getContext().getContentResolver();
+        mServerDiffs = 0;
+        mRefresh = 0;
+        super.onSyncStarting(context, account, forced, result);
+    }
+
+    private void deletedEntryToContentValues(EventEntry event, ContentValues values) {
+        // see #deletedCursorToEntry.  this deletion cannot be an exception to a recurrence (e.g.,
+        // deleting an instance of a repeating event) -- new recurrence exceptions would be
+        // insertions.
+        values.clear();
+
+        // Base sync info
+        values.put(Events._SYNC_ID, event.getId());
+        values.put(Events._SYNC_VERSION, event.getEditUri());
+    }
+
+    /**
+     * Clear out the map and stuff an Entry into it in a format that can
+     * be inserted into a content provider.
+     *
+     * @return ENTRY_OK, ENTRY_DELETED, or ENTRY_INVALID
+     */
+    private int entryToContentValues(EventEntry event, long syncLocalId,
+            ContentValues map, Object info) {
+        SyncInfo syncInfo = (SyncInfo) info;
+
+        // There are 3 cases for parsing a date-time string:
+        //
+        // 1. The date-time string specifies a date and time with a time offset.
+        //    (The "normal" format.)
+        // 2. The date-time string is just a date, used for all-day events,
+        //    with no time or time offset fields. (The "all-day" format.)
+        // 3. The date-time string specifies a date and time, but no time
+        //    offset.  (The "floating" format, not supported yet.)
+        //
+        // Case 1: Time.parse3339() converts the date-time string to UTC and
+        // sets the Time.timezone to UTC.  It does not matter what the initial
+        // Time.timezone field was set to.  The initial timezone is ignored.
+        //
+        // Case 2: The date-time string doesn't specify the time.
+        // Time.parse3339() just sets the date but not the time (hour, minute,
+        // second) fields.  (The time fields should be zero, meaning midnight.)
+        // This code then sets the timezone to UTC (because this is an all-day
+        // event).  It does not matter in this case either what the initial
+        // Time.timezone field was set to.
+        //
+        // Case 3: This is a "floating time" (which we do not support yet).
+        // In this case, it will matter what the initial Time.timezone is set
+        // to.  It should use UTC.  If I specify a floating time of 1pm then I
+        // want that event displayed at 1pm in every timezone.  The easiest way
+        // to support this would be store it as 1pm in UTC and mark the event
+        // as "isFloating" (with a new database column).  Then when displaying
+        // the event, the code checks "isFloating" and just leaves the time at
+        // 1pm without doing any conversion to the local timezone.
+        //
+        // So in all cases, it is correct to set the Time.timezone to UTC.
+        Time time = new Time(Time.TIMEZONE_UTC);
+
+        map.clear();
+
+        // Base sync info
+        map.put(Events._SYNC_ID, event.getId());
+        String version = event.getEditUri();
+        if (!StringUtils.isEmpty(version)) {
+            // Always rewrite the edit URL to https for dasher account to avoid
+            // redirection.
+            map.put(Events._SYNC_VERSION, rewriteUrlforAccount(getAccount(), version));
+        }
+
+        // see if this is an exception to an existing event/recurrence.
+        String originalId = event.getOriginalEventId();
+        String originalStartTime = event.getOriginalEventStartTime();
+        boolean isRecurrenceException = false;
+        if (!StringUtils.isEmpty(originalId) &&
+                !StringUtils.isEmpty(originalStartTime)) {
+            isRecurrenceException = true;
+            time.parse3339(originalStartTime);
+            map.put(Events.ORIGINAL_EVENT, originalId);
+            map.put(Events.ORIGINAL_INSTANCE_TIME, time.toMillis(false /* use isDst */));
+        }
+
+        // Event status
+        byte status = event.getStatus();
+        switch (status) {
+            case EventEntry.STATUS_CANCELED:
+                if (!isRecurrenceException) {
+                    return ENTRY_DELETED;
+                }
+                map.put(Events.STATUS, sCanceledStatus);
+                break;
+            case EventEntry.STATUS_TENTATIVE:
+                map.put(Events.STATUS, sTentativeStatus);
+                break;
+            case EventEntry.STATUS_CONFIRMED:
+                map.put(Events.STATUS, sConfirmedStatus);
+                break;
+            default:
+                // should not happen
+                return ENTRY_INVALID;
+        }
+
+        map.put(Events._SYNC_LOCAL_ID, syncLocalId);
+
+        // Updated time, only needed for non-deleted items
+        String updated = event.getUpdateDate();
+        map.put(Events._SYNC_TIME, updated);
+        map.put(Events._SYNC_DIRTY, 0);
+
+        // visibility
+        switch (event.getVisibility()) {
+            case EventEntry.VISIBILITY_DEFAULT:
+                map.put(Events.VISIBILITY,  Events.VISIBILITY_DEFAULT);
+                break;
+            case EventEntry.VISIBILITY_CONFIDENTIAL:
+                map.put(Events.VISIBILITY,  Events.VISIBILITY_CONFIDENTIAL);
+                break;
+            case EventEntry.VISIBILITY_PRIVATE:
+                map.put(Events.VISIBILITY,  Events.VISIBILITY_PRIVATE);
+                break;
+            case EventEntry.VISIBILITY_PUBLIC:
+                map.put(Events.VISIBILITY,  Events.VISIBILITY_PUBLIC);
+                break;
+            default:
+                // should not happen
+                Log.e(TAG, "Unexpected visibility " + event.getVisibility());
+                return ENTRY_INVALID;
+        }
+
+        // transparency
+        switch (event.getTransparency()) {
+            case EventEntry.TRANSPARENCY_OPAQUE:
+                map.put(Events.TRANSPARENCY,  Events.TRANSPARENCY_OPAQUE);
+                break;
+            case EventEntry.TRANSPARENCY_TRANSPARENT:
+                map.put(Events.TRANSPARENCY,  Events.TRANSPARENCY_TRANSPARENT);
+                break;
+            default:
+                // should not happen
+                Log.e(TAG, "Unexpected transparency " + event.getTransparency());
+                return ENTRY_INVALID;
+        }
+
+        // html uri
+        String htmlUri = event.getHtmlUri();
+        if (!StringUtils.isEmpty(htmlUri)) {
+            // TODO: convert this desktop url into a mobile one?
+            // htmlUri = htmlUri.replace("/event?", "/mevent?"); // but a little more robust
+            map.put(Events.HTML_URI, htmlUri);
+        }
+
+        // title
+        String title = event.getTitle();
+        if (!StringUtils.isEmpty(title)) {
+            map.put(Events.TITLE, title);
+        }
+
+        // content
+        String content = event.getContent();
+        if (!StringUtils.isEmpty(content)) {
+            map.put(Events.DESCRIPTION, content);
+        }
+
+        // where
+        String where = event.getWhere();
+        if (!StringUtils.isEmpty(where)) {
+            map.put(Events.EVENT_LOCATION, where);
+        }
+
+        // Calendar ID
+        map.put(Events.CALENDAR_ID, syncInfo.calendarId);
+
+        // comments uri
+        String commentsUri = event.getCommentsUri();
+        if (commentsUri != null) {
+            map.put(Events.COMMENTS_URI, commentsUri);
+        }
+
+        boolean timesSet = false;
+
+        // see if there are any reminders for this event
+        if (event.getReminders() != null) {
+            // just store that we have reminders.  the caller will have
+            // to update the reminders table separately.
+            map.put(Events.HAS_ALARM, 1);
+        }
+
+        // see if there are any extended properties for this event
+        if (event.getExtendedProperties() != null) {
+            // just store that we have extended properties.  the caller will have
+            // to update the extendedproperties table separately.
+            map.put(Events.HAS_EXTENDED_PROPERTIES, 1);
+        }
+
+        // dtstart & dtend
+        When when = event.getFirstWhen();
+        if (when != null) {
+            String startTime = when.getStartTime();
+            if (!StringUtils.isEmpty(startTime)) {
+                time.parse3339(startTime);
+
+                // we also stash away the event's timezone.
+                // this timezone might get overwritten below, if this event is
+                // a recurrence (recurrences are defined in terms of the
+                // timezone of the creator of the event).
+                // note that we treat all day events as occurring in the UTC timezone, so
+                // an event on 05/08/2007 occurs on 05/08/2007, no matter what timezone the device
+                // is in.
+                // TODO: handle the "floating" timezone.
+                if (time.allDay) {
+                    map.put(Events.ALL_DAY, 1);
+                    map.put(Events.EVENT_TIMEZONE, Time.TIMEZONE_UTC);
+                } else {
+                    map.put(Events.EVENT_TIMEZONE, syncInfo.calendarTimezone);
+                }
+
+                map.put(Events.DTSTART, time.toMillis(false /* use isDst */));
+
+                timesSet = true;
+            }
+
+            String endTime = when.getEndTime();
+            if (!StringUtils.isEmpty(endTime)) {
+                time.parse3339(endTime);
+                map.put(Events.DTEND, time.toMillis(false /* use isDst */));
+            }
+        }
+
+        // rrule
+        String recurrence = event.getRecurrence();
+        if (!TextUtils.isEmpty(recurrence)) {
+            ICalendar.Component recurrenceComponent =
+                    new ICalendar.Component("DUMMY", null /* parent */);
+            ICalendar ical = null;
+            try {
+                ICalendar.parseComponent(recurrenceComponent, recurrence);
+            } catch (ICalendar.FormatException fe) {
+                if (Config.LOGD) {
+                    Log.d(TAG, "Unable to parse recurrence: " + recurrence);
+                }
+                return ENTRY_INVALID;
+            }
+
+            if (!RecurrenceSet.populateContentValues(recurrenceComponent, map)) {
+                return ENTRY_INVALID;
+            }
+
+            timesSet = true;
+        }
+
+        if (!timesSet) {
+            return ENTRY_INVALID;
+        }
+
+        map.put(SyncConstValue._SYNC_ACCOUNT, getAccount());
+        return ENTRY_OK;
+    }
+
+    @Override
+    public void updateProvider(Feed feed,
+            long syncLocalId, boolean forceDelete, Entry entry,
+            ContentProvider provider, Object info) throws ParseException {
+        SyncInfo syncInfo = (SyncInfo) info;
+        EventEntry event = (EventEntry) entry;
+
+        ContentValues map = new ContentValues();
+
+        // use the calendar's timezone, if provided in the feed.
+        // this overwrites whatever was in the db.
+        if ((feed != null) && (feed instanceof EventsFeed)) {
+            EventsFeed eventsFeed = (EventsFeed) feed;
+            syncInfo.calendarTimezone = eventsFeed.getTimezone();
+        }
+
+        if (forceDelete) {
+            deletedEntryToContentValues(event, map);
+            if (Config.LOGV) {
+                Log.v(TAG, "Deleting entry: " + map);
+            }
+            provider.insert(Events.DELETED_CONTENT_URI, map);
+            return;
+        }
+
+        int entryState = entryToContentValues(event, syncLocalId, map, syncInfo);
+
+        if (entryState == ENTRY_DELETED) {
+            if (Config.LOGV) {
+                Log.v(TAG, "Got deleted entry from server: "
+                        + map);
+            }
+            provider.insert(Events.DELETED_CONTENT_URI, map);
+        } else if (entryState == ENTRY_OK) {
+            if (Config.LOGV) {
+                Log.v(TAG, "Got entry from server: " + map);
+            }
+            Uri result = provider.insert(Events.CONTENT_URI, map);
+            long rowId = ContentUris.parseId(result);
+            // handle the reminders for the event
+            Integer hasAlarm = map.getAsInteger(Events.HAS_ALARM);
+            if (hasAlarm != null && hasAlarm == 1) {
+                // reminders should not be null
+                Vector alarms = event.getReminders();
+                if (alarms == null) {
+                    Log.e(TAG, "Have an alarm but do not have any reminders "
+                            + "-- should not happen.");
+                    throw new IllegalStateException("Have an alarm but do not have any reminders");
+                }
+                Enumeration reminders = alarms.elements();
+                while (reminders.hasMoreElements()) {
+                    ContentValues reminderValues = new ContentValues();
+                    reminderValues.put(Calendar.Reminders.EVENT_ID, rowId);
+
+                    Reminder reminder = (Reminder) reminders.nextElement();
+                    byte method = reminder.getMethod();
+                    switch (method) {
+                        case Reminder.METHOD_DEFAULT:
+                            reminderValues.put(Calendar.Reminders.METHOD,
+                                    Calendar.Reminders.METHOD_DEFAULT);
+                            break;
+                        case Reminder.METHOD_ALERT:
+                            reminderValues.put(Calendar.Reminders.METHOD,
+                                    Calendar.Reminders.METHOD_ALERT);
+                            break;
+                        case Reminder.METHOD_EMAIL:
+                            reminderValues.put(Calendar.Reminders.METHOD,
+                                    Calendar.Reminders.METHOD_EMAIL);
+                            break;
+                        case Reminder.METHOD_SMS:
+                            reminderValues.put(Calendar.Reminders.METHOD,
+                                    Calendar.Reminders.METHOD_SMS);
+                            break;
+                        default:
+                            // should not happen.  return false?  we'd have to
+                            // roll back the event.
+                            Log.e(TAG, "Unknown reminder method: " + method
+                                    + " should not happen!");
+                    }
+
+                    int minutes = reminder.getMinutes();
+                    reminderValues.put(Calendar.Reminders.MINUTES,
+                            minutes == Reminder.MINUTES_DEFAULT ?
+                                    Calendar.Reminders.MINUTES_DEFAULT :
+                                    minutes);
+
+                    if (provider.insert(Calendar.Reminders.CONTENT_URI,
+                            reminderValues) == null) {
+                        throw new ParseException("Unable to insert reminders.");
+                    }
+                }
+            }
+
+            // handle attendees for the event
+            Vector attendees = event.getAttendees();
+            Enumeration attendeesEnum = attendees.elements();
+            while (attendeesEnum.hasMoreElements()) {
+                Who who = (Who) attendeesEnum.nextElement();
+                ContentValues attendeesValues = new ContentValues();
+                attendeesValues.put(Calendar.Attendees.EVENT_ID, rowId);
+                attendeesValues.put(Calendar.Attendees.ATTENDEE_NAME, who.getValue());
+                attendeesValues.put(Calendar.Attendees.ATTENDEE_EMAIL, who.getEmail());
+
+                byte status;
+                switch (who.getStatus()) {
+                    case Who.STATUS_NONE:
+                        status = Calendar.Attendees.ATTENDEE_STATUS_NONE;
+                        break;
+                    case Who.STATUS_INVITED:
+                        status = Calendar.Attendees.ATTENDEE_STATUS_INVITED;
+                        break;
+                    case Who.STATUS_ACCEPTED:
+                        status = Calendar.Attendees.ATTENDEE_STATUS_ACCEPTED;
+                        break;
+                    case Who.STATUS_TENTATIVE:
+                        status = Calendar.Attendees.ATTENDEE_STATUS_TENTATIVE;
+                        break;
+                    case Who.STATUS_DECLINED:
+                        status = Calendar.Attendees.ATTENDEE_STATUS_DECLINED;
+                        break;
+                    default:
+                        Log.w(TAG, "Unknown attendee status " + who.getStatus());
+                        status = Calendar.Attendees.ATTENDEE_STATUS_NONE;
+                }
+                attendeesValues.put(Calendar.Attendees.ATTENDEE_STATUS, status);
+                byte rel;
+                switch (who.getRelationship()) {
+                    case Who.RELATIONSHIP_NONE:
+                        rel = Calendar.Attendees.RELATIONSHIP_NONE;
+                        break;
+                    case Who.RELATIONSHIP_ORGANIZER:
+                        rel = Calendar.Attendees.RELATIONSHIP_ORGANIZER;
+                        break;
+                    case Who.RELATIONSHIP_ATTENDEE:
+                        rel = Calendar.Attendees.RELATIONSHIP_ATTENDEE;
+                        break;
+                    case Who.RELATIONSHIP_PERFORMER:
+                        rel = Calendar.Attendees.RELATIONSHIP_PERFORMER;
+                        break;
+                    case Who.RELATIONSHIP_SPEAKER:
+                        rel = Calendar.Attendees.RELATIONSHIP_SPEAKER;
+                        break;
+                    default:
+                        Log.w(TAG, "Unknown attendee relationship " + who.getRelationship());
+                        rel = Calendar.Attendees.RELATIONSHIP_NONE;
+                }
+
+                attendeesValues.put(Calendar.Attendees.ATTENDEE_RELATIONSHIP, rel);
+
+                byte type;
+                switch (who.getType()) {
+                    case Who.TYPE_NONE:
+                        type = Calendar.Attendees.TYPE_NONE;
+                        break;
+                    case Who.TYPE_REQUIRED:
+                        type = Calendar.Attendees.TYPE_REQUIRED;
+                        break;
+                    case Who.TYPE_OPTIONAL:
+                        type = Calendar.Attendees.TYPE_OPTIONAL;
+                        break;
+                    default:
+                        Log.w(TAG, "Unknown attendee type " + who.getType());
+                        type = Calendar.Attendees.TYPE_NONE;
+                }
+                attendeesValues.put(Calendar.Attendees.ATTENDEE_TYPE, type);
+                if (provider.insert(Calendar.Attendees.CONTENT_URI, attendeesValues) == null) {
+                    throw new ParseException("Unable to insert attendees.");
+                }
+            }
+
+            // handle the extended properties for the event
+            Integer hasExtendedProperties = map.getAsInteger(Events.HAS_EXTENDED_PROPERTIES);
+            if (hasExtendedProperties != null && hasExtendedProperties.intValue() != 0) {
+                // extended properties should not be null
+                // TODO: make the extended properties a bit more OO?
+                Hashtable extendedProperties = event.getExtendedProperties();
+                if (extendedProperties == null) {
+                    Log.e(TAG, "Have extendedProperties but do not have any properties"
+                            + "-- should not happen.");
+                    throw new IllegalStateException(
+                            "Have extendedProperties but do not have any properties");
+                }
+                Enumeration propertyNames = extendedProperties.keys();
+                while (propertyNames.hasMoreElements()) {
+                    String propertyName = (String) propertyNames.nextElement();
+                    String propertyValue = (String) extendedProperties.get(propertyName);
+                    ContentValues extendedPropertyValues = new ContentValues();
+                    extendedPropertyValues.put(Calendar.ExtendedProperties.EVENT_ID, rowId);
+                    extendedPropertyValues.put(Calendar.ExtendedProperties.NAME,
+                            propertyName);
+                    extendedPropertyValues.put(Calendar.ExtendedProperties.VALUE,
+                            propertyValue);
+                    if (provider.insert(Calendar.ExtendedProperties.CONTENT_URI,
+                            extendedPropertyValues) == null) {
+                        throw new ParseException("Unable to insert extended properties.");
+                    }
+                }
+            }
+        } else {
+            // If the DTSTART == -1, then the date was out of range.  We don't
+            // need to throw a ParseException because the user can create
+            // dates on the web that we can't handle on the phone.  For
+            // example, events with dates before Dec 13, 1901 can be created
+            // on the web but cannot be handled on the phone.
+            Long dtstart = map.getAsLong(Events.DTSTART);
+            if (dtstart != null && dtstart == -1) {
+                return;
+            }
+
+            if (Config.LOGV) {
+                Log.v(TAG, "Got invalid entry from server: " + map);
+            }
+            throw new ParseException("Got invalid entry from server: " + map);
+        }
+    }
+
+    @Override
+    public void getServerDiffs(SyncContext context,
+            SyncData baseSyncData, SyncableContentProvider tempProvider,
+            Bundle extras, Object baseSyncInfo, SyncResult syncResult) {
+        final ContentResolver cr = getContext().getContentResolver();
+        mServerDiffs++;
+        final boolean syncingSingleFeed = (extras != null) && extras.containsKey("feed");
+        if (syncingSingleFeed) {
+            String feedUrl = extras.getString("feed");
+            getServerDiffsForFeed(context, baseSyncData, tempProvider, feedUrl,
+                    baseSyncInfo, syncResult);
+            return;
+        }
+
+        // select the set of calendars for this account.
+        Cursor cursor = cr.query(Calendar.Calendars.CONTENT_URI,
+                CALENDARS_PROJECTION, SELECT_BY_ACCOUNT,
+                new String[] { getAccount() }, null /* sort order */);
+
+        Bundle syncExtras = new Bundle();
+
+        boolean refreshCalendars = true;
+
+        try {
+            while (cursor.moveToNext()) {
+                boolean syncEvents = (cursor.getInt(6) == 1);
+                String feedUrl = cursor.getString(3);
+
+                if (!syncEvents) {
+                    continue;
+                }
+
+                // since this is a poll (no specific feed selected), refresh the list of calendars.
+                // we can move away from this when we move to the new allcalendars feed, which is
+                // syncable.  until then, we'll rely on the daily poll to keep the list of calendars
+                // up to date.
+                if (refreshCalendars) {
+                    mRefresh++;
+                    context.setStatusText("Fetching list of calendars");
+                    // get rid of the current cursor and fetch from the server.
+                    cursor.close();
+                    final String[] accountSelectionArgs = new String[]{getAccount()};
+                    cursor = cr.query(
+                        Calendar.Calendars.LIVE_CONTENT_URI, CALENDARS_PROJECTION,
+                        SELECT_BY_ACCOUNT, accountSelectionArgs, null /* sort order */);
+                    // start over with the loop
+                    refreshCalendars = false;
+                    continue;
+                }
+
+                // schedule syncs for each of these feeds.
+                syncExtras.clear();
+                syncExtras.putAll(extras);
+                syncExtras.putString("feed", feedUrl);
+                cr.startSync(Calendar.CONTENT_URI, syncExtras);
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+
+    private void getServerDiffsForFeed(SyncContext context, SyncData baseSyncData,
+            SyncableContentProvider tempProvider,
+            String feed, Object baseSyncInfo, SyncResult syncResult) {
+        final SyncInfo syncInfo = (SyncInfo) baseSyncInfo;
+        final GDataSyncData syncData = (GDataSyncData) baseSyncData;
+
+        Cursor cursor = getContext().getContentResolver().query(Calendar.Calendars.CONTENT_URI,
+                CALENDARS_PROJECTION, SELECT_BY_ACCOUNT_AND_FEED,
+                new String[] { getAccount(), feed }, null /* sort order */);
+
+        ContentValues map = new ContentValues();
+        int maxResults = getMaxEntriesPerSync();
+
+        try {
+            if (!cursor.moveToFirst()) {
+                return;
+            }
+            // TODO: refactor all of this, so we don't have to rely on
+            // member variables getting updated here in order for the
+            // base class hooks to work.
+
+            syncInfo.calendarId = cursor.getLong(0);
+            boolean syncEvents = (cursor.getInt(6) == 1);
+            long syncTime = cursor.getLong(2);
+            String feedUrl = cursor.getString(3);
+            String name = cursor.getString(4);
+            String origCalendarTimezone =
+                    syncInfo.calendarTimezone = cursor.getString(5);
+
+            if (!syncEvents) {
+                // should not happen.  non-syncable feeds should not be scheduled for syncs nor
+                // should they get tickled.
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "Ignoring sync request for non-syncable feed.");
+                }
+                return;
+            }
+
+            context.setStatusText("Syncing " + name);
+
+            // call the superclass implementation to sync the current
+            // calendar from the server.
+            getServerDiffsImpl(context, tempProvider, getFeedEntryClass(), feedUrl, syncInfo,
+                    maxResults, syncData, syncResult);
+            if (mSyncCanceled || syncResult.hasError()) {
+                return;
+            }
+
+            // update the timezone for this calendar if it changed
+            if (!TextUtils.equals(syncInfo.calendarTimezone,
+                    origCalendarTimezone)) {
+                map.clear();
+                map.put(Calendars.TIMEZONE, syncInfo.calendarTimezone);
+                mContentResolver.update(
+                        ContentUris.withAppendedId(Calendars.CONTENT_URI, syncInfo.calendarId),
+                        map, null, null);
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+    @Override
+    protected void initTempProvider(SyncableContentProvider cp) {
+        // TODO: don't use the real db's calendar id's.  create new ones locally and translate
+        // during CalendarProvider's merge.
+        
+        // populate temp provider with calendar ids, so joins work.
+        ContentValues map = new ContentValues();
+        Cursor c = getContext().getContentResolver().query(
+                Calendar.Calendars.CONTENT_URI,
+                CALENDARS_PROJECTION,
+                SELECT_BY_ACCOUNT, new String[]{getAccount()}, null /* sort order */);
+        final int idIndex = c.getColumnIndexOrThrow(Calendars._ID);
+        final int urlIndex = c.getColumnIndexOrThrow(Calendars.URL);
+        final int timezoneIndex = c.getColumnIndexOrThrow(Calendars.TIMEZONE);
+        while (c.moveToNext()) {
+            map.clear();
+            map.put(Calendars._ID, c.getLong(idIndex));
+            map.put(Calendars.URL, c.getString(urlIndex));
+            map.put(Calendars.TIMEZONE, c.getString(timezoneIndex));
+            cp.insert(Calendar.Calendars.CONTENT_URI, map);
+        }
+        c.close();
+    }
+
+    public void onAccountsChanged(String[] accountsArray) {
+        if (!"yes".equals(SystemProperties.get("ro.config.sync"))) {
+            return;
+        }
+
+        // - Get a cursor (A) over all selected calendars over all accounts
+        // - Get a cursor (B) over all subscribed feeds for calendar
+        // - If an item is in A but not B then add a subscription
+        // - If an item is in B but not A then remove the subscription
+
+        ContentResolver cr = getContext().getContentResolver();
+        Cursor cursorA = null;
+        Cursor cursorB = null;
+        try {
+            cursorA = Calendar.Calendars.query(cr, null /* projection */,
+                    Calendar.Calendars.SELECTED + "=1", CALENDAR_KEY_SORT_ORDER);
+            int urlIndexA = cursorA.getColumnIndexOrThrow(Calendar.Calendars.URL);
+            int accountIndexA = cursorA.getColumnIndexOrThrow(Calendar.Calendars._SYNC_ACCOUNT);
+            cursorB = SubscribedFeeds.Feeds.query(cr, FEEDS_KEY_COLUMNS,
+                    SubscribedFeeds.Feeds.AUTHORITY + "=?", new String[]{Calendar.AUTHORITY},
+                    FEEDS_KEY_SORT_ORDER);
+            int urlIndexB = cursorB.getColumnIndexOrThrow(SubscribedFeeds.Feeds.FEED);
+            int accountIndexB = cursorB.getColumnIndexOrThrow(SubscribedFeeds.Feeds._SYNC_ACCOUNT);
+            for (CursorJoiner.Result joinerResult :
+                    new CursorJoiner(cursorA, CALENDAR_KEY_COLUMNS, cursorB, FEEDS_KEY_COLUMNS)) {
+                switch (joinerResult) {
+                    case LEFT:
+                        SubscribedFeeds.addFeed(
+                                cr,
+                                cursorA.getString(urlIndexA),
+                                cursorA.getString(accountIndexA),
+                                Calendar.AUTHORITY,
+                                CalendarClient.SERVICE);
+                        break;
+                    case RIGHT:
+                        SubscribedFeeds.deleteFeed(
+                                cr,
+                                cursorB.getString(urlIndexB),
+                                cursorB.getString(accountIndexB),
+                                Calendar.AUTHORITY);
+                        break;
+                    case BOTH:
+                        // do nothing, since the subscription already exists
+                        break;
+                }
+            }
+        } finally {
+            // check for null in case an exception occurred before the cursors got created
+            if (cursorA != null) cursorA.close();
+            if (cursorB != null) cursorB.close();
+        }
+    }
+
+    /**
+     * Should not get called.  The feed url changes depending on which calendar is being sync'd
+     * to/from the device, and thus is determined and passed around as a local variable, where
+     * appropriate.
+     */
+    protected String getFeedUrl(String account) {
+        throw new UnsupportedOperationException("getFeedUrl() should not get called.");
+    }
+
+    protected Class getFeedEntryClass() {
+        return EventEntry.class;
+    }
+
+    @Override
+    protected void updateQueryParameters(QueryParams params) {
+        if (params.getUpdatedMin() == null) {
+            // if this is the first sync, only bother syncing starting from
+            // one month ago.
+            // TODO: remove this restriction -- we may want all of
+            // historical calendar events.
+            Time lastMonth = new Time(Time.TIMEZONE_UTC);
+            lastMonth.setToNow();
+            --lastMonth.month;
+            lastMonth.normalize(true /* ignore isDst */);
+            String startMin = lastMonth.format("%Y-%m-%dT%H:%M:%S.000Z");
+            // TODO: move start-min to CalendarClient?
+            // or create CalendarQueryParams subclass (extra class)?
+            params.setParamValue("start-min", startMin);
+            // HACK: specify that we want to expand recurrences ijn the past,
+            // so the server does not expand any recurrences.  we do this to
+            // avoid a large number of gd:when elements that we do not need,
+            // since we process gd:recurrence elements instead.
+            params.setParamValue("recurrence-expansion-start", "1970-01-01");
+            params.setParamValue("recurrence-expansion-end", "1970-01-01");
+        }
+        // we want to get the events ordered by last modified, so we can
+        // recover in case we cannot process the entire feed.
+        params.setParamValue("orderby", "lastmodified");
+        params.setParamValue("sortorder", "ascending");
+    }
+
+    @Override
+    protected GDataServiceClient getGDataServiceClient() {
+        return mCalendarClient;
+    }
+
+    protected void getStatsString(StringBuffer sb, SyncResult result) {
+        super.getStatsString(sb, result);
+        if (mRefresh > 0) {
+            sb.append("F").append(mRefresh);
+        }
+        if (mServerDiffs > 0) {
+            sb.append("s").append(mServerDiffs);
+        }
+    }
+}
diff --git a/src/com/android/providers/calendar/Duration.java b/src/com/android/providers/calendar/Duration.java
new file mode 100644
index 0000000..b5dad4b
--- /dev/null
+++ b/src/com/android/providers/calendar/Duration.java
@@ -0,0 +1,145 @@
+/* //device/content/providers/pim/Duration.java
+**
+** Copyright 2006, 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.pim.DateException;
+
+import java.util.Calendar;
+
+/**
+ * According to RFC2445, durations are like this:
+ *       WEEKS
+ *     | DAYS [ HOURS [ MINUTES [ SECONDS ] ] ]
+ *     | HOURS [ MINUTES [ SECONDS ] ]
+ * it doesn't specifically, say, but this sort of implies that you can't have
+ * 70 seconds.
+ */
+public class Duration
+{
+    public int sign; // 1 or -1
+    public int weeks;
+    public int days;
+    public int hours;
+    public int minutes;
+    public int seconds;
+
+    public Duration()
+    {
+        sign = 1;
+    }
+
+    /**
+     * Parse according to RFC2445 ss4.3.6.  (It's actually a little loose with
+     * its parsing, for better or for worse)
+     */
+    public void parse(String str) throws DateException 
+    {
+        sign = 1;
+        weeks = 0;
+        days = 0;
+        hours = 0;
+        minutes = 0;
+        seconds = 0;
+
+        int len = str.length();
+        int index = 0;
+        char c;
+
+        if (len < 1) {
+            return ;
+        }
+
+        c = str.charAt(0);
+        if (c == '-') {
+            sign = -1;
+            index++;
+        }
+        else if (c == '+') {
+            index++;
+        }
+
+        if (len < index) {
+            return ;
+        }
+
+        c = str.charAt(index);
+        if (c != 'P') {
+            throw new DateException (
+                    "Duration.parse(str='" + str + "') expected 'P' at index="
+                    + index);
+        }
+        index++;
+
+        int n = 0;
+        for (; index < len; index++) {
+            c = str.charAt(index);
+            if (c >= '0' && c <= '9') {
+                n *= 10;
+                n += ((int)(c-'0'));
+            }
+            else if (c == 'W') {
+                weeks = n;
+                n = 0;
+            }
+            else if (c == 'H') {
+                hours = n;
+                n = 0;
+            }
+            else if (c == 'M') {
+                minutes = n;
+                n = 0;
+            }
+            else if (c == 'S') {
+                seconds = n;
+                n = 0;
+            }
+            else if (c == 'D') {
+                days = n;
+                n = 0;
+            }
+            else if (c == 'T') {
+            }
+            else {
+                throw new DateException (
+                        "Duration.parse(str='" + str + "') unexpected char '"
+                        + c + "' at index=" + index);
+            }
+        }
+    }
+
+    /**
+     * Add this to the calendar provided, in place, in the calendar.
+     */
+    public void addTo(Calendar cal)
+    {
+        cal.add(Calendar.DAY_OF_MONTH, sign*weeks*7);
+        cal.add(Calendar.DAY_OF_MONTH, sign*days);
+        cal.add(Calendar.HOUR, sign*hours);
+        cal.add(Calendar.MINUTE, sign*minutes);
+        cal.add(Calendar.SECOND, sign*seconds);
+    }
+
+    public long addTo(long dt) {
+        long factor = 1000*sign;
+        return dt + (7*24*60*60*factor*weeks)
+                  + (24*60*60*factor*days)
+                  + (60*60*factor*hours)
+                  + (60*factor*minutes)
+                  + (factor*seconds);
+    }
+}
diff --git a/src/com/android/providers/calendar/MetaData.java b/src/com/android/providers/calendar/MetaData.java
new file mode 100644
index 0000000..ed7f9d9
--- /dev/null
+++ b/src/com/android/providers/calendar/MetaData.java
@@ -0,0 +1,282 @@
+/*
+**
+** Copyright 2008, 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,
+** See the License for the specific language governing permissions and
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** limitations under the License.
+*/
+
+package com.android.providers.calendar;
+
+
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.provider.Calendar.CalendarMetaData;
+
+/**
+ * The global meta-data used for expanding the Instances table is stored in one
+ * row of the "CalendarMetaData" table.  This class is used for caching those
+ * values to avoid repeatedly banging on the database.  It is also used
+ * for writing the values back to the database, while maintaining the
+ * consistency of the cache.
+ */
+public class MetaData {
+    /**
+     * These fields are updated atomically with the database.
+     * If fields are added or removed from the CalendarMetaData table, those
+     * changes must also be reflected here.
+     */
+    public class Fields {
+        public String timezone;     // local timezone used for Instance expansion
+        public long minInstance;    // UTC millis
+        public long maxInstance;    // UTC millis
+        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;
+
+    /**
+     * The column names in the CalendarMetaData table.  This projection
+     * must contain all of the columns.
+     */
+    private static final String[] sCalendarMetaDataProjection = {
+        CalendarMetaData.LOCAL_TIMEZONE,
+        CalendarMetaData.MIN_INSTANCE,
+        CalendarMetaData.MAX_INSTANCE,
+        CalendarMetaData.MIN_BUSYBITS,
+        CalendarMetaData.MAX_BUSYBITS };
+    
+    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() {
+        Fields fields = new Fields();
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        db.beginTransaction();
+        try {
+            // If the fields have not been initialized from the database,
+            // then read the database.
+            if (!mInitialized) {
+                readLocked(db);
+            }
+            fields.timezone = mFields.timezone;
+            fields.minInstance = mFields.minInstance;
+            fields.maxInstance = mFields.maxInstance;
+            fields.minBusyBit = mFields.minBusyBit;
+            fields.maxBusyBit = mFields.maxBusyBit;
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+        return fields;
+    }
+
+    /**
+     * 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() {
+        Fields fields = new Fields();
+
+        // If the fields have not been initialized from the database,
+        // then read the database.
+        if (!mInitialized) {
+            SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+            readLocked(db);
+        }
+        fields.timezone = mFields.timezone;
+        fields.minInstance = mFields.minInstance;
+        fields.maxInstance = mFields.maxInstance;
+        fields.minBusyBit = mFields.minBusyBit;
+        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
+     * lock is held.  If there were no exceptions reading the database,
+     * mInitialized is set to true.
+     */
+    private void readLocked(SQLiteDatabase db) {
+        String timezone = null;
+        long minInstance = 0, maxInstance = 0;
+        int minBusyBit = 0, maxBusyBit = 0;
+
+        // Read the database directly.  We only do this once to initialize
+        // the members of this class.
+        Cursor cursor = db.query("CalendarMetaData", sCalendarMetaDataProjection,
+                null, null, null, null, null);
+        try {
+            if (cursor.moveToNext()) {
+                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) {
+                cursor.close();
+            }
+        }
+
+        // Cache the result of reading the database
+        mFields.timezone = timezone;
+        mFields.minInstance = minInstance;
+        mFields.maxInstance = maxInstance;
+        mFields.minBusyBit = minBusyBit;
+        mFields.maxBusyBit = maxBusyBit;
+        
+        // Mark the fields as initialized
+        mInitialized = true;
+    }
+
+    /**
+     * 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
+     * @param startDay the start of the BusyBit expansion (the start Julian day)
+     * @param endDay the end of the BusyBit expansion (the end Julian day)
+     */
+    public void write(String timezone, long begin, long end, int startDay, int endDay) {
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        db.beginTransaction();
+        try {
+            writeLocked(timezone, begin, end, startDay, endDay);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    /**
+     * 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
+     * @param startDay the start of the BusyBit expansion (the start Julian day)
+     * @param endDay the end of the BusyBit expansion (the end Julian day)
+     */
+    public void writeLocked(String timezone, long begin, long end, int startDay, int endDay) {
+        ContentValues values = new ContentValues();
+        values.put("_id", 1);
+        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 {
+            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+            db.replace("CalendarMetaData", null, values);
+        } catch (RuntimeException e) {
+            // Failed: zero the in-memory fields to force recomputation.
+            mFields.timezone = null;
+            mFields.minInstance = mFields.maxInstance = 0;
+            mFields.minBusyBit = mFields.maxBusyBit = 0;
+            throw e;
+        }
+
+        // Update the cached members last in case the database update fails
+        mFields.timezone = timezone;
+        mFields.minInstance = begin;
+        mFields.maxInstance = end;
+        mFields.minBusyBit = startDay;
+        mFields.maxBusyBit = endDay;
+    }
+
+    /**
+     * 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.
+     */
+    public void clearInstanceRange() {
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        db.beginTransaction();
+        try {
+            // If the fields have not been initialized from the database,
+            // then read the database.
+            if (!mInitialized) {
+                readLocked(db);
+            }
+            writeLocked(mFields.timezone, 0 /* begin */, 0 /* end */,
+                    0 /* startDay */, 0 /* endDay */);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    /**
+     * Clears the time range for the BusyBits table.
+     */
+    public void clearBusyBitRange() {
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        db.beginTransaction();
+        try {
+            // If the fields have not been initialized from the database,
+            // then read the database.
+            if (!mInitialized) {
+                readLocked(db);
+            }
+            writeLocked(mFields.timezone, mFields.minInstance, mFields.maxInstance,
+                    0 /* startDay */, 0 /* endDay */);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+}
diff --git a/src/com/android/providers/calendar/RecurrenceProcessor.java b/src/com/android/providers/calendar/RecurrenceProcessor.java
new file mode 100644
index 0000000..c04a538
--- /dev/null
+++ b/src/com/android/providers/calendar/RecurrenceProcessor.java
@@ -0,0 +1,890 @@
+/* //device/content/providers/pim/RecurrenceProcessor.java
+**
+** Copyright 2006, 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.pim.DateException;
+import android.pim.EventRecurrence;
+import android.pim.RecurrenceSet;
+import android.pim.Time;
+import android.util.Log;
+
+import java.util.TreeSet;
+
+public class RecurrenceProcessor
+{
+    // these are created once and reused.
+    private Time mIterator = new Time(Time.TIMEZONE_UTC);
+    private Time mUntil = new Time(Time.TIMEZONE_UTC);
+    private StringBuilder mStringBuilder = new StringBuilder();
+    private Time mGenerated = new Time(Time.TIMEZONE_UTC);
+    private DaySet mDays = new DaySet(false);
+
+    public RecurrenceProcessor()
+    {
+    }
+
+    private static final String TAG = "RecurrenceProcessor";
+
+    private static final boolean SPEW = false;
+
+    /**
+     * Returns the time (millis since epoch) of the last occurrence, -1 if the event repeats
+     * forever.
+     */
+    public long getLastOccurence(Time dtstart,
+                                 RecurrenceSet recur) throws DateException {
+
+        long lastTime = -1;
+        boolean hasCount = false;
+
+        // first see if there are any "until"s specified.  if so, use the latest
+        // until / rdate.
+        if (recur.rrules != null) {
+            for (EventRecurrence rrule : recur.rrules) {
+                if (rrule.count != 0) {
+                    hasCount = true;
+                }
+                    
+                if (rrule.until != null) {
+                    // according to RFC 2445, until must be in UTC.
+                    mIterator.parse2445(rrule.until);
+                    long untilTime = mIterator.toMillis(false /* use isDst */);
+                    if (untilTime > lastTime) {
+                        lastTime = untilTime;
+                    }
+                }
+            }
+            if ((lastTime != -1) && recur.rdates != null) {
+                for (long dt : recur.rdates) {
+                    if (dt > lastTime) {
+                        lastTime = dt;
+                    }
+                }
+            }
+            if (lastTime != -1) {
+                return lastTime;
+            }
+        } else if ((recur.rdates != null) &&
+                   ((recur.exrules == null) && (recur.exdates == null))) {
+            // if there are only rdates, we can just pick the last one.
+            for (long dt : recur.rdates) {
+                if (dt > lastTime) {
+                    lastTime = dt;
+                }
+            }
+            return lastTime;
+        }
+
+        // expand the complete recurrence if there were any counts specified,
+        // or if there were rdates specified.
+        if ((recur.rrules != null && hasCount) || (recur.rdates != null)) {
+            // could return 0 if the recurrence only occurs before dtstart?
+            // i don't think we would have been called in that case.
+            // TODO: check this!
+            return expand(dtstart, recur,
+                    dtstart.toMillis(false /* use isDst */) /* range start */,
+                    -1 /* range end */, null /* output */);
+        }
+        return -1;
+    }
+
+    /**
+     * a -- list of values
+     * N -- number of values to use in a
+     * v -- value to check for
+     */
+    private static boolean listContains(int[] a, int N, int v)
+    {
+        for (int i=0; i<N; i++) {
+            if (a[i] == v) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * a -- list of values
+     * N -- number of values to use in a
+     * v -- value to check for
+     * max -- if a value in a is negative, add that negative value
+     *        to max and compare that instead; this is how we deal with
+     *        negative numbers being offsets from the end value
+     */
+    private static boolean listContains(int[] a, int N, int v, int max)
+    {
+        for (int i=0; i<N; i++) {
+            int w = a[i];
+            if (w > 0) {
+                if (w == v) {
+                    return true;
+                }
+            } else {
+                max += w; // w is negative
+                if (max == v) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Filter out the ones for events whose BYxxx rule is for
+     * a period greater than or equal to the period of the FREQ.
+     *
+     * Returns 0 if the event should not be filtered out
+     * Returns something else (a rule number which is useful for debugging)
+     * if the event should not be returned
+     */
+    private static int filter(EventRecurrence r, Time iterator)
+    {
+        boolean found;
+        int freq = r.freq;
+
+        if (EventRecurrence.MONTHLY >= freq) {
+            // BYMONTH
+            if (r.bymonthCount > 0) {
+                found = listContains(r.bymonth, r.bymonthCount,
+                        iterator.month + 1);
+                if (!found) {
+                    return 1;
+                }
+            }
+        }
+        if (EventRecurrence.WEEKLY >= freq) {
+            // BYWEEK -- this is just a guess.  I wonder how many events
+            // acutally use BYWEEKNO.
+            if (r.byweeknoCount > 0) {
+                found = listContains(r.byweekno, r.byweeknoCount,
+                                iterator.getWeekNumber(),
+                                iterator.getActualMaximum(Time.WEEK_NUM));
+                if (!found) {
+                    return 2;
+                }
+            }
+        }
+        if (EventRecurrence.DAILY >= freq) {
+            // BYYEARDAY
+            if (r.byyeardayCount > 0) {
+                found = listContains(r.byyearday, r.byyeardayCount,
+                                iterator.yearDay, iterator.getActualMaximum(Time.YEAR_DAY));
+                if (!found) {
+                    return 3;
+                }
+            }
+            // BYMONTHDAY
+            if (r.bymonthdayCount > 0 ) {
+                found = listContains(r.bymonthday, r.bymonthdayCount,
+                                iterator.monthDay,
+                                iterator.getActualMaximum(Time.MONTH_DAY));
+                if (!found) {
+                    return 4;
+                }
+            }
+            // BYDAY -- when filtering, we ignore the number field, because it
+            // only is meaningful when creating more events.
+byday:
+            if (r.bydayCount > 0) {
+                int a[] = r.byday;
+                int N = r.bydayCount;
+                int v = EventRecurrence.timeDay2Day(iterator.weekDay);
+                for (int i=0; i<N; i++) {
+                    if (a[i] == v) {
+                        break byday;
+                    }
+                }
+                return 5;
+            }
+        }
+        if (EventRecurrence.HOURLY >= freq) {
+            // BYHOUR
+            found = listContains(r.byhour, r.byhourCount,
+                            iterator.hour,
+                            iterator.getActualMaximum(Time.HOUR));
+            if (!found) {
+                return 6;
+            }
+        }
+        if (EventRecurrence.MINUTELY >= freq) {
+            // BYMINUTE
+            found = listContains(r.byminute, r.byminuteCount,
+                            iterator.minute,
+                            iterator.getActualMaximum(Time.MINUTE));
+            if (!found) {
+                return 7;
+            }
+        }
+        if (EventRecurrence.SECONDLY >= freq) {
+            // BYSECOND
+            found = listContains(r.bysecond, r.bysecondCount,
+                            iterator.second,
+                            iterator.getActualMaximum(Time.SECOND));
+            if (!found) {
+                return 8;
+            }
+        }
+        // BYSETPOS -- we might have to do this by postprocessing
+        // the list
+
+        // if we got to here, we didn't filter it out
+        return 0;
+    }
+
+    private static final int USE_ITERATOR = 0;
+    private static final int USE_BYLIST = 1;
+
+    /**
+     * Return whether we should make this list from the BYxxx list or
+     * from the component of the iterator.
+     */
+    int generateByList(int count, int freq, int byFreq)
+    {
+        if (byFreq >= freq) {
+            return USE_ITERATOR;
+        } else {
+            if (count == 0) {
+                return USE_ITERATOR;
+            } else {
+                return USE_BYLIST;
+            }
+        }
+    }
+
+    private static boolean useBYX(int freq, int freqConstant, int count)
+    {
+        return freq > freqConstant && count > 0;
+    }
+
+    public static class DaySet
+    {
+        public DaySet(boolean zulu)
+        {
+            mTime = new Time(Time.TIMEZONE_UTC);
+        }
+
+        void setRecurrence(EventRecurrence r)
+        {
+            mYear = 0;
+            mMonth = -1;
+            mR = r;
+        }
+
+        boolean get(Time iterator, int day)
+        {
+            int realYear = iterator.year;
+            int realMonth = iterator.month;
+
+            Time t = null;
+
+            if (SPEW) {
+                Log.i(TAG, "get called with iterator=" + iterator
+                        + " " + iterator.month
+                        + "/" + iterator.monthDay
+                        + "/" + iterator.year + " day=" + day);
+            }
+            if (day < 1 || day > 28) {
+                // if might be past the end of the month, we need to normalize it
+                t = mTime;
+                t.set(day, realMonth, realYear);
+                t.normalize(true /* ignore isDst */);
+                realYear = t.year;
+                realMonth = t.month;
+                day = t.monthDay;
+                if (SPEW) {
+                    Log.i(TAG, "normalized t=" + t + " " + t.month
+                            + "/" + t.monthDay
+                            + "/" + t.year);
+                }
+            }
+
+            /*
+            if (true || SPEW) {
+                Log.i(TAG, "set t=" + t + " " + realMonth + "/" + day + "/" + realYear);
+            }
+            */
+            if (realYear != mYear || realMonth != mMonth) {
+                if (t == null) {
+                    t = mTime;
+                    t.set(day, realMonth, realYear);
+                    t.normalize(true /* ignore isDst */);
+                    if (SPEW) {
+                        Log.i(TAG, "set t=" + t + " " + t.month
+                                + "/" + t.monthDay
+                                + "/" + t.year
+                                + " realMonth=" + realMonth + " mMonth=" + mMonth);
+                    }
+                }
+                mYear = realYear;
+                mMonth = realMonth;
+                mDays = generateDaysList(t, mR);
+                if (SPEW) {
+                    Log.i(TAG, "generated days list");
+                }
+            }
+            return (mDays & (1<<day)) != 0;
+        }
+
+        /**
+         * Fill in a bit set containing the days of the month on which this
+         * will occur.
+         *
+         * Only call this if the r.freq > DAILY.  Otherwise, we should be
+         * processing the BYDAY, BYMONTHDAY, etc. as filters instead.
+         *
+         * monthOffset may be -1, 0 or 1
+         */
+        private static int generateDaysList(Time generated, EventRecurrence r)
+        {
+            int days = 0;
+
+            int i, count, v;
+            int[] byday, bydayNum, bymonthday;
+            int j, lastDayThisMonth;
+            int first; // Time.SUNDAY, etc
+            int k;
+
+            lastDayThisMonth = generated.getActualMaximum(Time.MONTH_DAY);
+
+            // BYDAY
+            count = r.bydayCount;
+            if (count > 0) {
+                // calculate the day of week for the first of this month (first)
+                j = generated.monthDay;
+                while (j >= 8) {
+                    j -= 7;
+                }
+                first = generated.weekDay;
+                if (first >= j) {
+                    first = first - j + 1;
+                } else {
+                    first = first - j + 8;
+                }
+
+                // What to do if the event is weekly:
+                // This isn't ideal, but we'll generate a month's worth of events
+                // and the code that calls this will only use the ones that matter
+                // for the current week.
+                byday = r.byday;
+                bydayNum = r.bydayNum;
+                for (i=0; i<count; i++) {
+                    v = bydayNum[i];
+                    j = EventRecurrence.day2TimeDay(byday[i]) - first + 1;
+                    if (j <= 0) {
+                        j += 7;
+                    }
+                    if (v == 0) {
+                        // v is 0, each day in the month/week
+                        for (; j<=lastDayThisMonth; j+=7) {
+                            if (SPEW) Log.i(TAG, "setting " + j + " for rule "
+                                    + v + "/" + EventRecurrence.day2TimeDay(byday[i]));
+                            days |= 1 << j;
+                        }
+                    }
+                    else if (v > 0) {
+                        // v is positive, count from the beginning of the month
+                        // -1 b/c the first one should add 0
+                        j += 7*(v-1);
+                        if (j <= lastDayThisMonth) {
+                            if (SPEW) Log.i(TAG, "setting " + j + " for rule "
+                                    + v + "/" + EventRecurrence.day2TimeDay(byday[i]));
+                            // if it's impossible, we drop it
+                            days |= 1 << j;
+                        }
+                    }
+                    else {
+                        // v is negative, count from the end of the month
+                        // find the last one
+                        for (; j<=lastDayThisMonth; j+=7) {
+                        }
+                        // v is negative
+                        // should do +1 b/c the last one should add 0, but we also
+                        // skipped the j -= 7 b/c the loop to find the last one
+                        // overshot by one week
+                        j += 7*v;
+                        if (j >= 1) {
+                            if (SPEW) Log.i(TAG, "setting " + j + " for rule "
+                                    + v + "/" + EventRecurrence.day2TimeDay(byday[i]));
+                            days |= 1 << j;
+                        }
+                    }
+                }
+            }
+
+            // BYMONTHDAY
+            // Q: What happens if we have BYMONTHDAY and BYDAY?
+            // A: I didn't see it in the spec, so in lieu of that, we'll
+            // intersect the two.  That seems reasonable to me.
+            if (r.freq > EventRecurrence.WEEKLY) {
+                count = r.bymonthdayCount;
+                if (count != 0) {
+                    bymonthday = r.bymonthday;
+                    if (r.bydayCount == 0) {
+                        for (i=0; i<count; i++) {
+                            v = bymonthday[i];
+                            if (v >= 0) {
+                                days |= 1 << v;
+                            } else {
+                                j = lastDayThisMonth + v + 1; // v is negative
+                                if (j >= 1 && j <= lastDayThisMonth) {
+                                    days |= 1 << j;
+                                }
+                            }
+                        }
+                    } else {
+                        // This is O(lastDayThisMonth*count), which is really
+                        // O(count) with a decent sized constant.
+                        for (j=1; j<=lastDayThisMonth; j++) {
+                            next_day : { 
+                                if ((days&(1<<j)) != 0) {
+                                    for (i=0; i<count; i++) {
+                                        if (bymonthday[i] == j) {
+                                            break next_day;
+                                        }
+                                    }
+                                    days &= ~(1<<j);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            return days;
+        }
+
+        private EventRecurrence mR;
+        private int mDays;
+        private Time mTime;
+        private int mYear;
+        private int mMonth;
+    }
+
+
+    // TODO: document, clean up these return codes.  currently, the return value
+    // is the last occurrence of the recurrence within the expansion window.
+    // 0 is returned if there are no instances within the expansion window.
+    public long expand(Time dtstart,
+                       RecurrenceSet recur,
+                       long rangeStartMillis,
+                       long rangeEndMillis,
+                       TreeSet<Long> dtSet) throws DateException {
+        if (dtSet != null) {
+            dtSet.clear();
+        } else {
+            // create the set locally, for book-keeping.
+            dtSet = new TreeSet<Long>();
+        }
+
+        if (recur.rrules != null) {
+            for (EventRecurrence rrule : recur.rrules) {
+                expand(dtstart, rrule, rangeStartMillis,
+                       rangeEndMillis, true /* add */, dtSet);
+            }
+        }
+        if (recur.rdates != null) {
+            for (long dt : recur.rdates) {
+                dtSet.add(dt);
+            }
+        }
+        if (recur.exrules != null) {
+            for (EventRecurrence exrule : recur.exrules) {
+                expand(dtstart, exrule, rangeStartMillis,
+                       rangeEndMillis, false /* remove */, dtSet);
+            }
+        }
+        if (recur.exdates != null) {
+            for (long dt : recur.exdates) {
+                dtSet.remove(dt);
+            }
+        }
+        if (dtSet.isEmpty()) {
+            // this can happen if the recurrence does not occur within the
+            // expansion window.
+            return 0;
+        }
+        return dtSet.last();
+    }
+
+    /**
+     * Run the recurrence algorithm.  Processes events defined in the local
+     * timezone of the event.  Return a list of iCalendar DATETIME
+     * strings containing the start date/times of the occurrences; the output
+     * times are defined in the local timezone of the event.
+     *
+     * If you want all of the events, pass null for rangeEnd.  If you pass
+     * null for rangeEnd, and the event doesn't have a COUNT or UNTIL field,
+     * you'll get a DateException.
+     *
+     * @param dtstart the dtstart date as defined in RFC2445.  This
+     * {@link Time} should be in the timezone of the event.
+     * @param r the parsed recurrence, as defiend in RFC2445
+     * @param rangeStartMillis the first date-time you care about, inclusive
+     * @param rangeEndMillis the last date-time you care about, not inclusive (so
+     *                  if you care about everything up through and including
+     *                  Dec 22 1995, set last to Dec 23, 1995 00:00:00
+     * @param add Whether or not we should add to out, or remove from out.
+     * @param out the ArrayList you'd like to fill with the events
+     */
+    public void expand(Time dtstart,
+                       EventRecurrence r,
+                       long rangeStartMillis,
+                       long rangeEndMillis,
+                       boolean add,
+                       TreeSet<Long> out) throws DateException {
+        String timezone = dtstart.timezone;
+        long dtstartMillis = dtstart.toMillis(false /* use isDst */);
+        int count = 0;
+
+        // add the dtstart instance to the recurrence, if within range.
+        if (add) {
+            if (dtstartMillis >= rangeStartMillis) {
+                if ((rangeEndMillis != -1 && (dtstartMillis <= rangeEndMillis))
+                    || r.count > 0) {
+                        out.add(dtstartMillis);
+                        ++count;
+                }
+            }
+        }
+
+        // reset the Time objects to the new timezone.
+        // (we want to avoid creating new objects here)
+        // we do NOT clear the until -- untils *must* be specified in UTC.
+        mIterator.clear(timezone);
+        mGenerated.clear(timezone);
+        
+        Time iterator = mIterator;
+        Time until = mUntil;
+        StringBuilder sb = mStringBuilder;
+        Time generated = mGenerated;
+        DaySet days = mDays;
+
+        try {
+
+            days.setRecurrence(r);
+
+            if (rangeEndMillis == -1 && r.until == null && r.count == 0) {
+                throw new DateException(
+                        "No range end provided for a recurrence that has no UNTIL or COUNT.");
+            }
+
+            // the top-level frequency
+            int freqField;
+            int freqAmount = r.interval;
+            int freq = r.freq;
+            switch (freq)
+            {
+                case EventRecurrence.SECONDLY:
+                    freqField = Time.SECOND;
+                    break;
+                case EventRecurrence.MINUTELY:
+                    freqField = Time.MINUTE;
+                    break;
+                case EventRecurrence.HOURLY:
+                    freqField = Time.HOUR;
+                    break;
+                case EventRecurrence.DAILY:
+                    freqField = Time.MONTH_DAY;
+                    break;
+                case EventRecurrence.WEEKLY:
+                    freqField = Time.MONTH_DAY;
+                    freqAmount = 7 * r.interval;
+                    if (freqAmount <= 0) {
+                        freqAmount = 7;
+                    }
+                    break;
+                case EventRecurrence.MONTHLY:
+                    freqField = Time.MONTH;
+                    break;
+                case EventRecurrence.YEARLY:
+                    freqField = Time.YEAR;
+                    break;
+                default:
+                    throw new DateException("bad freq=" + freq);
+            }
+            if (freqAmount <= 0) {
+                freqAmount = 1;
+            }
+
+            int bymonthCount = r.bymonthCount;
+            boolean usebymonth = useBYX(freq, EventRecurrence.MONTHLY, bymonthCount);
+            boolean useDays = freq >= EventRecurrence.WEEKLY &&
+                                 (r.bydayCount > 0 || r.bymonthdayCount > 0);
+            int byhourCount = r.byhourCount;
+            boolean usebyhour = useBYX(freq, EventRecurrence.HOURLY, byhourCount);
+            int byminuteCount = r.byminuteCount;
+            boolean usebyminute = useBYX(freq, EventRecurrence.MINUTELY, byminuteCount);
+            int bysecondCount = r.bysecondCount;
+            boolean usebysecond = useBYX(freq, EventRecurrence.SECONDLY, bysecondCount);
+
+            // initialize the iterator
+            iterator.set(dtstart);
+            if (freqField == Time.MONTH) {
+                if (useDays) {
+                    // if it's monthly, and we're going to be generating
+                    // days, set the iterator day field to 1 because sometimes
+                    // we'll skip months if it's greater than 28.
+                    // XXX Do we generate days for MONTHLY w/ BYHOUR?  If so,
+                    // we need to do this then too.
+                    iterator.monthDay = 1;
+                }
+            }
+
+            if (r.until != null) {
+                until.parse(r.until);
+            }
+            long untilMillis = until.toMillis(false /* use isDst */);
+
+            sb.ensureCapacity(15);
+            sb.setLength(15); // TODO: pay attention to whether or not the event
+            // is an all-day one.
+
+            if (SPEW) {
+                Log.i(TAG, "expand called w/ rangeStart=" + rangeStartMillis
+                        + " rangeEnd=" + rangeEndMillis);
+            }
+
+            // go until the end of the range or we're done with this event
+            boolean eventEnded = false;
+            int N, i, v;
+            int a[];
+            events: {
+                while (true) {
+                    int monthIndex = 0;
+
+                    iterator.normalize(true /* ignore isDst */);
+
+                    int iteratorYear = iterator.year;
+                    int iteratorMonth = iterator.month + 1;
+                    int iteratorDay = iterator.monthDay;
+                    int iteratorHour = iterator.hour;
+                    int iteratorMinute = iterator.minute;
+                    int iteratorSecond = iterator.second;
+
+                    // year is never expanded -- there is no BYYEAR
+                    generated.set(iterator);
+
+                    if (SPEW) Log.i(TAG, "year=" + generated.year);
+
+                    do { // month
+                        int month = usebymonth
+                                        ? r.bymonth[monthIndex]
+                                        : iteratorMonth;
+                        month--;
+                        if (SPEW) Log.i(TAG, "  month=" + month);
+
+                        int dayIndex = 1;
+                        int lastDayToExamine = 0;
+
+                        // Use this to handle weeks that overlap the end of the month.
+                        // Keep the year and month that days is for, and generate it
+                        // when needed in the loop
+                        if (useDays) {
+                            // Determine where to start and end, don't worry if this happens
+                            // to be before dtstart or after the end, because that will be
+                            // filtered in the inner loop
+                            if (freq == EventRecurrence.WEEKLY) {
+                                int dow = iterator.weekDay;
+                                dayIndex = iterator.monthDay - dow;
+                                lastDayToExamine = dayIndex + 6;
+                            } else {
+                                lastDayToExamine = generated
+                                    .getActualMaximum(Time.MONTH_DAY);
+                            }
+                            if (SPEW) Log.i(TAG, "dayIndex=" + dayIndex
+                                    + " lastDayToExamine=" + lastDayToExamine
+                                    + " days=" + days);
+                        }
+
+                        do { // day
+                            int day;
+                            if (useDays) {
+                                if (!days.get(iterator, dayIndex)) {
+                                    dayIndex++;
+                                    continue;
+                                } else {
+                                    day = dayIndex;
+                                }
+                            } else {
+                                day = iteratorDay;
+                            }
+                            if (SPEW) Log.i(TAG, "    day=" + day);
+
+                            // hour
+                            int hourIndex = 0;
+                            do {
+                                int hour = usebyhour
+                                                ? r.byhour[hourIndex]
+                                                : iteratorHour;
+                                if (SPEW) Log.i(TAG, "      hour=" + hour + " usebyhour=" + usebyhour);
+
+                                // minute
+                                int minuteIndex = 0;
+                                do {
+                                    int minute = usebyminute
+                                                    ? r.byminute[minuteIndex]
+                                                    : iteratorMinute;
+                                    if (SPEW) Log.i(TAG, "        minute=" + minute);
+
+                                    // second
+                                    int secondIndex = 0;
+                                    do {
+                                        int second = usebysecond
+                                                        ? r.bysecond[secondIndex]
+                                                        : iteratorSecond;
+                                        if (SPEW) Log.i(TAG, "          second=" + second);
+
+                                        // we do this here each time, because if we distribute it, we find the
+                                        // month advancing extra times, as we set the month to the 32nd, 33rd, etc.
+                                        // days.
+                                        generated.set(second, minute, hour, day, month, iteratorYear);
+
+                                        long genMillis = generated.normalize(true /* ignore DST */);
+                                        // sometimes events get generated (BYDAY, BYHOUR, etc.) that
+                                        // are before dtstart.  Filter these.  I believe this is correct,
+                                        // but Google Calendar doesn't seem to always do this.
+                                        if (genMillis >= dtstartMillis) {
+                                            // filter and then add
+                                            int filtered = filter(r, generated);
+                                            if (0 == filtered) {
+
+                                                // increase the count as long
+                                                // as this isn't the same
+                                                // as the first instance
+                                                // specified by the DTSTART
+                                                // (for RRULEs -- additive).
+                                                if (!add) {
+                                                    ++count;
+                                                } else if (dtstartMillis !=
+                                                               genMillis) {
+                                                    ++count;
+                                                }
+                                                // one reason we can stop is that we're past the until date
+                                                if (r.until != null &&
+                                                    genMillis > untilMillis) {
+                                                    if (SPEW) {
+                                                        Log.i(TAG, "stopping b/c until="
+                                                            + untilMillis
+                                                            + " generated="
+                                                            + genMillis);
+                                                    }
+                                                    break events;
+                                                }
+                                                // or we're past rangeEnd
+                                                if (rangeEndMillis != -1 &&
+                                                    genMillis >= rangeEndMillis) {
+                                                    if (SPEW) {
+                                                        Log.i(TAG, "stopping b/c rangeEnd="
+                                                                + rangeEndMillis
+                                                                + " generated=" + generated);
+                                                    }
+                                                    break events;
+                                                }
+
+                                                if (out != null &&
+                                                    genMillis >= rangeStartMillis) {
+                                                    if (SPEW) {
+                                                        Log.i(TAG, "adding date=" + generated + " filtered=" + filtered);
+                                                    }
+                                                    if (add) {
+                                                        out.add(genMillis);
+                                                    } else {
+                                                        out.remove(genMillis);
+                                                    }
+                                                }
+                                                // another is that count is high enough
+                                                if (r.count > 0 && r.count == count) {
+                                                    //Log.i(TAG, "stopping b/c count=" + count);
+                                                    break events;
+                                                }
+                                            }
+                                        }
+                                        secondIndex++;
+                                    } while (usebysecond && secondIndex < bysecondCount);
+                                    minuteIndex++;
+                                } while (usebyminute && minuteIndex < byminuteCount);
+                                hourIndex++;
+                            } while (usebyhour && hourIndex < byhourCount);
+                            dayIndex++;
+                        } while (useDays && dayIndex <= lastDayToExamine);
+                        monthIndex++;
+                    } while (usebymonth && monthIndex < bymonthCount);
+
+                    // Add freqAmount to freqField until we get another date that we want.
+                    // We don't want to "generate" dates with the iterator.
+                    // XXX: We do this for days, because there is a varying number of days
+                    // per month
+                    int oldDay = iterator.monthDay;
+                    generated.set(iterator);  // just using generated as a temporary.
+                    int n = 1;
+                    while (true) {
+                        int value = freqAmount * n;
+                        switch (freqField) {
+                            case Time.SECOND:
+                                iterator.second += value;
+                                break;
+                            case Time.MINUTE:
+                                iterator.minute += value;
+                                break;
+                            case Time.HOUR:
+                                iterator.hour += value;
+                                break;
+                            case Time.MONTH_DAY:
+                                iterator.monthDay += value;
+                                break;
+                            case Time.MONTH:
+                                iterator.month += value;
+                                break;
+                            case Time.YEAR:
+                                iterator.year += value;
+                                break;
+                            case Time.WEEK_DAY:
+                                iterator.monthDay += value;
+                                break;
+                            case Time.YEAR_DAY:
+                                iterator.monthDay += value;
+                                break;
+                            default:
+                                throw new RuntimeException("bad field=" + freqField);
+                        }
+
+                        iterator.normalize(true /* ignore isDst */);
+                        if (freqField != Time.YEAR && freqField != Time.MONTH) {
+                            break;
+                        }
+                        if (iterator.monthDay == oldDay) {
+                            break;
+                        }
+                        n++;
+                        iterator.set(generated);
+                    }
+                }
+            }
+        }
+        catch (DateException e) {
+            Log.w(TAG, "DateException with r=" + r + " rangeStart=" + rangeStartMillis
+                    + " rangeEnd=" + rangeEndMillis);
+            throw e;
+        }
+        catch (RuntimeException t) {
+            Log.w(TAG, "RuntimeException with r=" + r + " rangeStart=" + rangeStartMillis
+                    + " rangeEnd=" + rangeEndMillis);
+            throw t;
+        }
+    }
+}
+
diff --git a/src/com/android/providers/calendar/VCal.java b/src/com/android/providers/calendar/VCal.java
new file mode 100644
index 0000000..e49c83a
--- /dev/null
+++ b/src/com/android/providers/calendar/VCal.java
@@ -0,0 +1,275 @@
+/* //device/apps/Calendar/MonthView.java
+**
+** Copyright 2006, 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.pim.DateException;
+import android.pim.DateUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+import java.util.regex.Pattern;
+
+public class VCal
+{
+    public static final Pattern LINE = Pattern.compile(
+            "([^:;]+)([^:]*):(.*)");
+
+    public ArrayList<Property> properties = new ArrayList<Property>();
+    public String dtstart;
+    public String tzid;
+    public String duration;
+    public String rrule;
+    public boolean allDay;
+
+    public void dump()
+    {
+        System.out.println("-----------------------");
+        dump(properties, "");
+        System.out.println("dtstart='" + this.dtstart + "'");
+        System.out.println("tzid='" + this.tzid + "'");
+        System.out.println("duration='" + this.duration + "'");
+        System.out.println("rrule='" + this.rrule + "'");
+        System.out.println("-----------------------");
+    }
+
+    public static void dump(ArrayList<Property> props, String prefix)
+    {
+        int count = props.size();
+        for (int i=0; i<count; i++) {
+            Property prop = props.get(i);
+            System.out.println(prefix + prop.name);
+            if (prop instanceof Begin) {
+                Begin b = (Begin)prop;
+                dump(b.properties, prefix + "  ");
+            }
+        }
+   }
+
+    public static class Parameter
+    {
+        public String name;
+        public String value;
+    }
+
+    public static class Property
+    {
+        public String name;
+        public Parameter[] parameters;
+        public String value;
+        public String[] values;
+    }
+
+    public static class Begin extends Property
+    {
+        public Begin parent;
+        public ArrayList<Property> properties = new ArrayList<Property>();
+    }
+
+
+    public static Property make(String name)
+    {
+        Property p;
+        if (name.equals("BEGIN")) {
+            p = new Begin();
+        }
+        else {
+            p = new Property();
+        }
+        p.name = name;
+        return p;
+    }
+
+    public static VCal parse(String str)
+    {
+        VCal vc = new VCal();
+
+        int i, j, start;
+        int N, M;
+
+        // first we deal with line folding, by replacing all "\r\n " strings
+        // with nothing
+        str = str.replaceAll("\r\n ", "");
+
+        // it's supposed to be \r\n, but not everyone does that
+        str = str.replaceAll("\r\n", "\n");
+        str = str.replaceAll("\r", "\n");
+
+        ArrayList<Parameter> params = new ArrayList<Parameter>();
+        ArrayList<Property> props = vc.properties;
+
+        // then we split into lines
+        String[] lines = str.split("\n");
+
+        Begin begin = null;
+        //System.out.println("lines.length=" + lines);
+        N = lines.length;
+        for (j=0; j<N; j++) {
+            //System.out.println("===[" + lines[j] + "]===");
+            String line = lines[j];
+            int len = line.length();
+            if (len > 0) {
+                i = 0;
+                char c;
+                do {
+                    c = line.charAt(i);
+                    i++;
+                } while (c != ';' && c != ':');
+
+                String n = line.substring(0, i-1);
+                Property prop = make(n);
+                props.add(prop);
+                if (n.equals("BEGIN")) {
+                    Begin b = (Begin)prop;
+                    b.parent = begin;
+                    begin = b;
+                    props = begin.properties;
+                }
+                else if (n.equals("END")) {
+                    begin = begin.parent;
+                    if (begin != null) {
+                        props = begin.properties;
+                    } else {
+                        props = vc.properties;
+                    }
+                }
+
+                //System.out.println("name=[" + prop.name + "]");
+                params.clear();
+                while (c == ';') {
+                    Parameter param = new Parameter();
+                    start = i;
+                    i++;
+                    // param name
+                    do {
+                        c = line.charAt(i);
+                        i++;
+                    } while (c != '=');
+                    param.name = line.substring(start, i-1);
+                    //System.out.println(" param.name=[" + param.name + "]");
+                    start = i;
+                    if (line.charAt(start) == '"') {
+                        i++;
+                        start++;
+                        do {
+                            c = line.charAt(i);
+                            i++;
+                        } while (c != '"');
+                        param.value = line.substring(start, i-1);
+                        c = line.charAt(i);
+                        i++;
+                        //System.out.println(" param.valueA=[" + param.value
+                        //                              + "]");
+                    } else {
+                        do {
+                            c = line.charAt(i);
+                            i++;
+                        } while (c != ';' && c != ':');
+                        param.value = line.substring(start, i-1);
+                        //System.out.println(" param.valueB=["
+                        //                              + param.value + "]");
+                    }
+                    params.add(param);
+                }
+                Object[] array = params.toArray();
+                prop.parameters = new Parameter[array.length];
+                System.arraycopy(array, 0, prop.parameters, 0, array.length);
+                if (c != ':') {
+                    throw new RuntimeException("error finding ':' c=" + c);
+                }
+                prop.value = line.substring(i);
+                prop.values = line.split(",");
+            }
+        }
+
+        N = vc.properties.size();
+        Calendar calStart = null;
+        for (i=0; i<N; i++) {
+            Property prop = vc.properties.get(i);
+            String n = prop.name;
+            if (n.equals("DTSTART")) {
+                try {
+                    calStart = parseDateTime(prop, vc);
+                    vc.dtstart = prop.value;
+                } catch (DateException de) {
+                    Log.w("CalendarProvider", "Unable to parse DTSTART=" + n, de);
+                    return null;
+                }
+            } else if (n.equals("DTEND")) {
+                // TODO: store the dtend, compute when expanding instances?
+                // will we ever need to deal with seeing the DTEND before the
+                // DTSTART?
+                try {
+                    if (calStart == null) {
+                        vc.duration = "+P0S";
+                    } else {
+                        Calendar calEnd =
+                                parseDateTime(prop, vc);
+                        long durationMillis =
+                                calEnd.getTimeInMillis() -
+                                        calStart.getTimeInMillis();
+                        long durationSeconds = (durationMillis / 1000);
+                        vc.duration = "+P" + durationSeconds + "S";
+                    }
+                } catch (DateException de) {
+                    Log.w("CalendarProvider", "Unable to parse DTEND=" + n, de);
+                    return null;
+                }
+            } else if (n.equals("DURATION")) {
+                vc.duration = prop.value;
+            } else if (n.equals("RRULE")) {
+                vc.rrule = prop.value;
+            }
+        }
+        return vc;
+    }
+
+    private static Calendar parseDateTime(Property prop, VCal vc) throws DateException {
+        int M;
+        int j;
+        String dt = prop.value;
+        M = prop.parameters.length;
+        for (j=0; j<M; j++) {
+            Parameter param = prop.parameters[j];
+            if (param.name.equals("TZID")) {
+                vc.tzid = param.value;
+            }
+        }
+
+        TimeZone tz = TimeZone.getTimeZone(vc.tzid);
+        if (tz == null) {
+            tz = TimeZone.getTimeZone("UTC");
+        }
+        GregorianCalendar somewhere = new GregorianCalendar(tz);
+        DateUtils.parseDateTime(dt, somewhere);
+        if (dt.length() == 8) {
+            // this seems to work.
+            vc.allDay = true;
+        }
+        return somewhere;
+        /*GregorianCalendar zulu = new GregorianCalendar(
+                                       TimeZone.getTimeZone("GMT"));
+        zulu.setTimeInMillis(somewhere.getTimeInMillis());
+        return zulu;*/
+        // System.out.println("DTSTART=" + dtstart
+        //         + " somewhere=" + somewhere
+        //         + " vc.dtstart=" + vc.dtstart);
+    }
+}
