/*
**
** 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.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.OnAccountsUpdateListener;
import android.app.AppOpsManager;
import android.content.BroadcastReceiver;
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.UriMatcher;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.provider.BaseColumns;
import android.provider.CalendarContract;
import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.CalendarAlerts;
import android.provider.CalendarContract.Calendars;
import android.provider.CalendarContract.Colors;
import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Instances;
import android.provider.CalendarContract.Reminders;
import android.provider.CalendarContract.SyncState;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.Log;
import android.util.TimeFormatException;
import android.util.TimeUtils;

import com.android.calendarcommon2.DateException;
import com.android.calendarcommon2.Duration;
import com.android.calendarcommon2.EventRecurrence;
import com.android.calendarcommon2.RecurrenceProcessor;
import com.android.calendarcommon2.RecurrenceSet;
import com.android.providers.calendar.CalendarDatabaseHelper.Tables;
import com.android.providers.calendar.CalendarDatabaseHelper.Views;
import com.google.android.collect.Sets;
import com.google.common.annotations.VisibleForTesting;

import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Calendar content provider. The contract between this provider and applications
 * is defined in {@link android.provider.CalendarContract}.
 */
public class CalendarProvider2 extends SQLiteContentProvider implements OnAccountsUpdateListener {


    protected static final String TAG = "CalendarProvider2";
    // Turn on for b/22449592
    static final boolean DEBUG_INSTANCES = Log.isLoggable(TAG, Log.DEBUG);

    private static final String TIMEZONE_GMT = "GMT";
    private static final String ACCOUNT_SELECTION_PREFIX = Calendars.ACCOUNT_NAME + "=? AND "
            + Calendars.ACCOUNT_TYPE + "=?";

    protected static final boolean PROFILE = false;
    private static final boolean MULTIPLE_ATTENDEES_PER_EVENT = true;

    private static final String[] ID_ONLY_PROJECTION =
            new String[] {Events._ID};

    private static final String[] EVENTS_PROJECTION = new String[] {
            Events._SYNC_ID,
            Events.RRULE,
            Events.RDATE,
            Events.ORIGINAL_ID,
            Events.ORIGINAL_SYNC_ID,
    };

    private static final int EVENTS_SYNC_ID_INDEX = 0;
    private static final int EVENTS_RRULE_INDEX = 1;
    private static final int EVENTS_RDATE_INDEX = 2;
    private static final int EVENTS_ORIGINAL_ID_INDEX = 3;
    private static final int EVENTS_ORIGINAL_SYNC_ID_INDEX = 4;

    private static final String[] COLORS_PROJECTION = new String[] {
        Colors.ACCOUNT_NAME,
        Colors.ACCOUNT_TYPE,
        Colors.COLOR_TYPE,
        Colors.COLOR_KEY,
        Colors.COLOR,
    };
    private static final int COLORS_ACCOUNT_NAME_INDEX = 0;
    private static final int COLORS_ACCOUNT_TYPE_INDEX = 1;
    private static final int COLORS_COLOR_TYPE_INDEX = 2;
    private static final int COLORS_COLOR_INDEX_INDEX = 3;
    private static final int COLORS_COLOR_INDEX = 4;

    private static final String COLOR_FULL_SELECTION = Colors.ACCOUNT_NAME + "=? AND "
            + Colors.ACCOUNT_TYPE + "=? AND " + Colors.COLOR_TYPE + "=? AND " + Colors.COLOR_KEY
            + "=?";

    private static final String GENERIC_ACCOUNT_NAME = Calendars.ACCOUNT_NAME;
    private static final String GENERIC_ACCOUNT_TYPE = Calendars.ACCOUNT_TYPE;
    private static final String[] ACCOUNT_PROJECTION = new String[] {
        GENERIC_ACCOUNT_NAME,
        GENERIC_ACCOUNT_TYPE,
    };
    private static final int ACCOUNT_NAME_INDEX = 0;
    private static final int ACCOUNT_TYPE_INDEX = 1;

    // many tables have _id and event_id; pick a representative version to use as our generic
    private static final String GENERIC_ID = Attendees._ID;
    private static final String GENERIC_EVENT_ID = Attendees.EVENT_ID;

    private static final String[] ID_PROJECTION = new String[] {
            GENERIC_ID,
            GENERIC_EVENT_ID,
    };
    private static final int ID_INDEX = 0;
    private static final int EVENT_ID_INDEX = 1;

    /**
     * Projection to query for correcting times in allDay events.
     */
    private static final String[] ALLDAY_TIME_PROJECTION = new String[] {
        Events._ID,
        Events.DTSTART,
        Events.DTEND,
        Events.DURATION
    };
    private static final int ALLDAY_ID_INDEX = 0;
    private static final int ALLDAY_DTSTART_INDEX = 1;
    private static final int ALLDAY_DTEND_INDEX = 2;
    private static final int ALLDAY_DURATION_INDEX = 3;

    private static final int DAY_IN_SECONDS = 24 * 60 * 60;

    /**
     * The cached copy of the CalendarMetaData database table.
     * Make this "package private" instead of "private" so that test code
     * can access it.
     */
    MetaData mMetaData;
    CalendarCache mCalendarCache;

    private CalendarDatabaseHelper mDbHelper;
    private CalendarInstancesHelper mInstancesHelper;

    private static final String SQL_SELECT_EVENTSRAWTIMES = "SELECT " +
            CalendarContract.EventsRawTimes.EVENT_ID + ", " +
            CalendarContract.EventsRawTimes.DTSTART_2445 + ", " +
            CalendarContract.EventsRawTimes.DTEND_2445 + ", " +
            Events.EVENT_TIMEZONE +
            " FROM " +
            Tables.EVENTS_RAW_TIMES + ", " +
            Tables.EVENTS +
            " WHERE " +
            CalendarContract.EventsRawTimes.EVENT_ID + " = " + Tables.EVENTS + "." + Events._ID;

    private static final String SQL_UPDATE_EVENT_SET_DIRTY_AND_MUTATORS = "UPDATE " +
            Tables.EVENTS + " SET " +
            Events.DIRTY + "=1," +
            Events.MUTATORS + "=? " +
            " WHERE " + Events._ID + "=?";

    private static final String SQL_QUERY_EVENT_MUTATORS = "SELECT " + Events.MUTATORS +
            " FROM " + Tables.EVENTS +
            " WHERE " + Events._ID + "=?";

    private static final String SQL_WHERE_CALENDAR_COLOR = Calendars.ACCOUNT_NAME + "=? AND "
            + Calendars.ACCOUNT_TYPE + "=? AND " + Calendars.CALENDAR_COLOR_KEY + "=?";

    private static final String SQL_WHERE_EVENT_COLOR = "calendar_id in (SELECT _id from "
            + Tables.CALENDARS + " WHERE " + Events.ACCOUNT_NAME + "=? AND " + Events.ACCOUNT_TYPE
            + "=?) AND " + Events.EVENT_COLOR_KEY + "=?";

    protected static final String SQL_WHERE_ID = GENERIC_ID + "=?";
    private static final String SQL_WHERE_EVENT_ID = GENERIC_EVENT_ID + "=?";
    private static final String SQL_WHERE_ORIGINAL_ID = Events.ORIGINAL_ID + "=?";
    private static final String SQL_WHERE_ORIGINAL_ID_NO_SYNC_ID = Events.ORIGINAL_ID +
            "=? AND " + Events._SYNC_ID + " IS NULL";

    private static final String SQL_WHERE_ATTENDEE_BASE =
            Tables.EVENTS + "." + Events._ID + "=" + Tables.ATTENDEES + "." + Attendees.EVENT_ID
            + " AND " +
            Tables.EVENTS + "." + Events.CALENDAR_ID + "=" + Tables.CALENDARS + "." + Calendars._ID;

    private static final String SQL_WHERE_ATTENDEES_ID =
            Tables.ATTENDEES + "." + Attendees._ID + "=? AND " + SQL_WHERE_ATTENDEE_BASE;

    private static final String SQL_WHERE_REMINDERS_ID =
            Tables.REMINDERS + "." + Reminders._ID + "=? AND " +
            Tables.EVENTS + "." + Events._ID + "=" + Tables.REMINDERS + "." + Reminders.EVENT_ID +
            " AND " +
            Tables.EVENTS + "." + Events.CALENDAR_ID + "=" + Tables.CALENDARS + "." + Calendars._ID;

    private static final String SQL_WHERE_CALENDAR_ALERT =
            Views.EVENTS + "." + Events._ID + "=" +
                    Tables.CALENDAR_ALERTS + "." + CalendarAlerts.EVENT_ID;

    private static final String SQL_WHERE_CALENDAR_ALERT_ID =
            Views.EVENTS + "." + Events._ID + "=" +
                    Tables.CALENDAR_ALERTS + "." + CalendarAlerts.EVENT_ID +
            " AND " +
            Tables.CALENDAR_ALERTS + "." + CalendarAlerts._ID + "=?";

    private static final String SQL_WHERE_EXTENDED_PROPERTIES_ID =
            Tables.EXTENDED_PROPERTIES + "." + CalendarContract.ExtendedProperties._ID + "=?";

    private static final String SQL_DELETE_FROM_CALENDARS = "DELETE FROM " + Tables.CALENDARS +
                " WHERE " + Calendars.ACCOUNT_NAME + "=? AND " +
                    Calendars.ACCOUNT_TYPE + "=?";

    private static final String SQL_DELETE_FROM_COLORS = "DELETE FROM " + Tables.COLORS + " WHERE "
            + Calendars.ACCOUNT_NAME + "=? AND " + Calendars.ACCOUNT_TYPE + "=?";

    private static final String SQL_SELECT_COUNT_FOR_SYNC_ID =
            "SELECT COUNT(*) FROM " + Tables.EVENTS + " WHERE " + Events._SYNC_ID + "=?";

    // 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;

    private static final String INSTANCE_QUERY_TABLES =
        CalendarDatabaseHelper.Tables.INSTANCES + " INNER JOIN " +
        CalendarDatabaseHelper.Views.EVENTS + " AS " +
        CalendarDatabaseHelper.Tables.EVENTS +
        " ON (" + CalendarDatabaseHelper.Tables.INSTANCES + "."
        + CalendarContract.Instances.EVENT_ID + "=" +
        CalendarDatabaseHelper.Tables.EVENTS + "."
        + CalendarContract.Events._ID + ")";

    private static final String INSTANCE_SEARCH_QUERY_TABLES = "(" +
        CalendarDatabaseHelper.Tables.INSTANCES + " INNER JOIN " +
        CalendarDatabaseHelper.Views.EVENTS + " AS " +
        CalendarDatabaseHelper.Tables.EVENTS +
        " ON (" + CalendarDatabaseHelper.Tables.INSTANCES + "."
        + CalendarContract.Instances.EVENT_ID + "=" +
        CalendarDatabaseHelper.Tables.EVENTS + "."
        + CalendarContract.Events._ID + ")" + ") LEFT OUTER JOIN " +
        CalendarDatabaseHelper.Tables.ATTENDEES +
        " ON (" + CalendarDatabaseHelper.Tables.ATTENDEES + "."
        + CalendarContract.Attendees.EVENT_ID + "=" +
        CalendarDatabaseHelper.Tables.EVENTS + "."
        + CalendarContract.Events._ID + ")";

    private static final String SQL_WHERE_INSTANCES_BETWEEN_DAY =
        CalendarContract.Instances.START_DAY + "<=? AND " +
        CalendarContract.Instances.END_DAY + ">=?";

    private static final String SQL_WHERE_INSTANCES_BETWEEN =
        CalendarContract.Instances.BEGIN + "<=? AND " +
        CalendarContract.Instances.END + ">=?";

    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;

    /**
     * The sort order is: events with an earlier start time occur first and if
     * the start times are the same, then events with a later end time occur
     * first. The later end time is ordered first so that long-running events in
     * the calendar views appear first. If the start and end times of two events
     * are the same then we sort alphabetically on the title. This isn't
     * required for correctness, it just adds a nice touch.
     */
    public static final String SORT_CALENDAR_VIEW = "begin ASC, end DESC, title ASC";

    /**
     * A regex for describing how we split search queries into tokens. Keeps
     * quoted phrases as one token. "one \"two three\"" ==> ["one" "two three"]
     */
    private static final Pattern SEARCH_TOKEN_PATTERN =
        Pattern.compile("[^\\s\"'.?!,]+|" // first part matches unquoted words
                      + "\"([^\"]*)\"");  // second part matches quoted phrases
    /**
     * A special character that was use to escape potentially problematic
     * characters in search queries.
     *
     * Note: do not use backslash for this, as it interferes with the regex
     * escaping mechanism.
     */
    private static final String SEARCH_ESCAPE_CHAR = "#";

    /**
     * A regex for matching any characters in an incoming search query that we
     * need to escape with {@link #SEARCH_ESCAPE_CHAR}, including the escape
     * character itself.
     */
    private static final Pattern SEARCH_ESCAPE_PATTERN =
        Pattern.compile("([%_" + SEARCH_ESCAPE_CHAR + "])");

    /**
     * Alias used for aggregate concatenation of attendee e-mails when grouping
     * attendees by instance.
     */
    private static final String ATTENDEES_EMAIL_CONCAT =
        "group_concat(" + CalendarContract.Attendees.ATTENDEE_EMAIL + ")";

    /**
     * Alias used for aggregate concatenation of attendee names when grouping
     * attendees by instance.
     */
    private static final String ATTENDEES_NAME_CONCAT =
        "group_concat(" + CalendarContract.Attendees.ATTENDEE_NAME + ")";

    private static final String[] SEARCH_COLUMNS = new String[] {
        CalendarContract.Events.TITLE,
        CalendarContract.Events.DESCRIPTION,
        CalendarContract.Events.EVENT_LOCATION,
        ATTENDEES_EMAIL_CONCAT,
        ATTENDEES_NAME_CONCAT
    };

    /**
     * Arbitrary integer that we assign to the messages that we send to this
     * thread's handler, indicating that these are requests to send an update
     * notification intent.
     */
    private static final int UPDATE_BROADCAST_MSG = 1;

    /**
     * Any requests to send a PROVIDER_CHANGED intent will be collapsed over
     * this window, to prevent spamming too many intents at once.
     */
    private static final long UPDATE_BROADCAST_TIMEOUT_MILLIS =
        DateUtils.SECOND_IN_MILLIS;

    private static final long SYNC_UPDATE_BROADCAST_TIMEOUT_MILLIS =
        30 * DateUtils.SECOND_IN_MILLIS;

    private static final HashSet<String> ALLOWED_URI_PARAMETERS = Sets.newHashSet(
            CalendarContract.CALLER_IS_SYNCADAPTER,
            CalendarContract.EventsEntity.ACCOUNT_NAME,
            CalendarContract.EventsEntity.ACCOUNT_TYPE);

    /** Set of columns allowed to be altered when creating an exception to a recurring event. */
    private static final HashSet<String> ALLOWED_IN_EXCEPTION = new HashSet<String>();
    static {
        // _id, _sync_account, _sync_account_type, dirty, _sync_mark, calendar_id
        ALLOWED_IN_EXCEPTION.add(Events._SYNC_ID);
        ALLOWED_IN_EXCEPTION.add(Events.SYNC_DATA1);
        ALLOWED_IN_EXCEPTION.add(Events.SYNC_DATA7);
        ALLOWED_IN_EXCEPTION.add(Events.SYNC_DATA3);
        ALLOWED_IN_EXCEPTION.add(Events.TITLE);
        ALLOWED_IN_EXCEPTION.add(Events.EVENT_LOCATION);
        ALLOWED_IN_EXCEPTION.add(Events.DESCRIPTION);
        ALLOWED_IN_EXCEPTION.add(Events.EVENT_COLOR);
        ALLOWED_IN_EXCEPTION.add(Events.EVENT_COLOR_KEY);
        ALLOWED_IN_EXCEPTION.add(Events.STATUS);
        ALLOWED_IN_EXCEPTION.add(Events.SELF_ATTENDEE_STATUS);
        ALLOWED_IN_EXCEPTION.add(Events.SYNC_DATA6);
        ALLOWED_IN_EXCEPTION.add(Events.DTSTART);
        // dtend -- set from duration as part of creating the exception
        ALLOWED_IN_EXCEPTION.add(Events.EVENT_TIMEZONE);
        ALLOWED_IN_EXCEPTION.add(Events.EVENT_END_TIMEZONE);
        ALLOWED_IN_EXCEPTION.add(Events.DURATION);
        ALLOWED_IN_EXCEPTION.add(Events.ALL_DAY);
        ALLOWED_IN_EXCEPTION.add(Events.ACCESS_LEVEL);
        ALLOWED_IN_EXCEPTION.add(Events.AVAILABILITY);
        ALLOWED_IN_EXCEPTION.add(Events.HAS_ALARM);
        ALLOWED_IN_EXCEPTION.add(Events.HAS_EXTENDED_PROPERTIES);
        ALLOWED_IN_EXCEPTION.add(Events.RRULE);
        ALLOWED_IN_EXCEPTION.add(Events.RDATE);
        ALLOWED_IN_EXCEPTION.add(Events.EXRULE);
        ALLOWED_IN_EXCEPTION.add(Events.EXDATE);
        ALLOWED_IN_EXCEPTION.add(Events.ORIGINAL_SYNC_ID);
        ALLOWED_IN_EXCEPTION.add(Events.ORIGINAL_INSTANCE_TIME);
        // originalAllDay, lastDate
        ALLOWED_IN_EXCEPTION.add(Events.HAS_ATTENDEE_DATA);
        ALLOWED_IN_EXCEPTION.add(Events.GUESTS_CAN_MODIFY);
        ALLOWED_IN_EXCEPTION.add(Events.GUESTS_CAN_INVITE_OTHERS);
        ALLOWED_IN_EXCEPTION.add(Events.GUESTS_CAN_SEE_GUESTS);
        ALLOWED_IN_EXCEPTION.add(Events.ORGANIZER);
        ALLOWED_IN_EXCEPTION.add(Events.CUSTOM_APP_PACKAGE);
        ALLOWED_IN_EXCEPTION.add(Events.CUSTOM_APP_URI);
        ALLOWED_IN_EXCEPTION.add(Events.UID_2445);
        // deleted, original_id, alerts
    }

    /** Don't clone these from the base event into the exception event. */
    private static final String[] DONT_CLONE_INTO_EXCEPTION = {
        Events._SYNC_ID,
        Events.SYNC_DATA1,
        Events.SYNC_DATA2,
        Events.SYNC_DATA3,
        Events.SYNC_DATA4,
        Events.SYNC_DATA5,
        Events.SYNC_DATA6,
        Events.SYNC_DATA7,
        Events.SYNC_DATA8,
        Events.SYNC_DATA9,
        Events.SYNC_DATA10,
    };

    /** set to 'true' to enable debug logging for recurrence exception code */
    private static final boolean DEBUG_EXCEPTION = false;

    private Context mContext;
    private ContentResolver mContentResolver;

    private static CalendarProvider2 mInstance;

    @VisibleForTesting
    protected CalendarAlarmManager mCalendarAlarm;

    private final Handler mBroadcastHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Context context = CalendarProvider2.this.mContext;
            if (msg.what == UPDATE_BROADCAST_MSG) {
                // Broadcast a provider changed intent
                doSendUpdateNotification();
                // Because the handler does not guarantee message delivery in
                // the case that the provider is killed, we need to make sure
                // that the provider stays alive long enough to deliver the
                // notification. This empty service is sufficient to "wedge" the
                // process until we stop it here.
                context.stopService(new Intent(context, EmptyService.class));
            }
        }
    };

    /**
     * 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 (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "onReceive() " + action);
            }
            if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
                updateTimezoneDependentFields();
                mCalendarAlarm.checkNextAlarm(false /* do not remove alarms */);
            } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
                // Try to clean up if things were screwy due to a full disk
                updateTimezoneDependentFields();
                mCalendarAlarm.checkNextAlarm(false /* do not remove alarms */);
            } else if (Intent.ACTION_TIME_CHANGED.equals(action)) {
                mCalendarAlarm.checkNextAlarm(false /* do not remove alarms */);
            }
        }
    };

    /* Visible for testing */
    @Override
    protected CalendarDatabaseHelper getDatabaseHelper(final Context context) {
        return CalendarDatabaseHelper.getInstance(context);
    }

    protected static CalendarProvider2 getInstance() {
        return mInstance;
    }

    @Override
    public void shutdown() {
        if (mDbHelper != null) {
            mDbHelper.close();
            mDbHelper = null;
            mDb = null;
        }
    }

    @Override
    public boolean onCreate() {
        super.onCreate();
        setAppOps(AppOpsManager.OP_READ_CALENDAR, AppOpsManager.OP_WRITE_CALENDAR);
        try {
            return initialize();
        } catch (RuntimeException e) {
            if (Log.isLoggable(TAG, Log.ERROR)) {
                Log.e(TAG, "Cannot start provider", e);
            }
            return false;
        }
    }

    private boolean initialize() {
        mInstance = this;

        mContext = getContext();
        mContentResolver = mContext.getContentResolver();

        mDbHelper = (CalendarDatabaseHelper)getDatabaseHelper();
        mDb = mDbHelper.getWritableDatabase();

        mMetaData = new MetaData(mDbHelper);
        mInstancesHelper = new CalendarInstancesHelper(mDbHelper, mMetaData);

        // 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);

        // 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.
        mContext.registerReceiver(mIntentReceiver, filter);

        mCalendarCache = new CalendarCache(mDbHelper);

        // This is pulled out for testing
        initCalendarAlarm();

        postInitialize();

        return true;
    }

    protected void initCalendarAlarm() {
        mCalendarAlarm = getOrCreateCalendarAlarmManager();
    }

    synchronized CalendarAlarmManager getOrCreateCalendarAlarmManager() {
        if (mCalendarAlarm == null) {
            mCalendarAlarm = new CalendarAlarmManager(mContext);
            Log.i(TAG, "Created " + mCalendarAlarm + "(" + this + ")");
        }
        return mCalendarAlarm;
    }

    protected void postInitialize() {
        Thread thread = new PostInitializeThread();
        thread.start();
    }

    private class PostInitializeThread extends Thread {
        @Override
        public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

            verifyAccounts();

            try {
                doUpdateTimezoneDependentFields();
            } catch (IllegalStateException e) {
                // Added this because tests would fail if the provider is
                // closed by the time this is executed

                // Nothing actionable here anyways.
            }
        }
    }

    private void verifyAccounts() {
        AccountManager.get(getContext()).addOnAccountsUpdatedListener(this, null, false);
        removeStaleAccounts(AccountManager.get(getContext()).getAccounts());
    }


    /**
     * This creates a background thread to check the timezone and update
     * the timezone dependent fields in the Instances table if the timezone
     * has changed.
     */
    protected void updateTimezoneDependentFields() {
        Thread thread = new TimezoneCheckerThread();
        thread.start();
    }

    private class TimezoneCheckerThread extends Thread {
        @Override
        public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            doUpdateTimezoneDependentFields();
        }
    }

    /**
     * Check if we are in the same time zone
     */
    private boolean isLocalSameAsInstancesTimezone() {
        String localTimezone = TimeZone.getDefault().getID();
        return TextUtils.equals(mCalendarCache.readTimezoneInstances(), localTimezone);
    }

    /**
     * This method runs in a background thread.  If the timezone has changed
     * then the Instances table will be regenerated.
     */
    protected void doUpdateTimezoneDependentFields() {
        try {
            String timezoneType = mCalendarCache.readTimezoneType();
            // Nothing to do if we have the "home" timezone type (timezone is sticky)
            if (timezoneType != null && timezoneType.equals(CalendarCache.TIMEZONE_TYPE_HOME)) {
                return;
            }
            // We are here in "auto" mode, the timezone is coming from the device
            if (! isSameTimezoneDatabaseVersion()) {
                String localTimezone = TimeZone.getDefault().getID();
                doProcessEventRawTimes(localTimezone, TimeUtils.getTimeZoneDatabaseVersion());
            }
            if (isLocalSameAsInstancesTimezone()) {
                // Even if the timezone hasn't changed, check for missed alarms.
                // This code executes when the CalendarProvider2 is created and
                // helps to catch missed alarms when the Calendar process is
                // killed (because of low-memory conditions) and then restarted.
                mCalendarAlarm.rescheduleMissedAlarms();
            }
        } catch (SQLException e) {
            if (Log.isLoggable(TAG, Log.ERROR)) {
                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) {
                if (Log.isLoggable(TAG, Log.ERROR)) {
                    Log.e(TAG, "clearInstanceRange() also failed: " + e2);
                }
            }
        }
    }

    protected void doProcessEventRawTimes(String localTimezone, String timeZoneDatabaseVersion) {
        mDb.beginTransaction();
        try {
            updateEventsStartEndFromEventRawTimesLocked();
            updateTimezoneDatabaseVersion(timeZoneDatabaseVersion);
            mCalendarCache.writeTimezoneInstances(localTimezone);
            regenerateInstancesTable();
            mDb.setTransactionSuccessful();
        } finally {
            mDb.endTransaction();
        }
    }

    private void updateEventsStartEndFromEventRawTimesLocked() {
        Cursor cursor = mDb.rawQuery(SQL_SELECT_EVENTSRAWTIMES, null /* selection args */);
        try {
            while (cursor.moveToNext()) {
                long eventId = cursor.getLong(0);
                String dtStart2445 = cursor.getString(1);
                String dtEnd2445 = cursor.getString(2);
                String eventTimezone = cursor.getString(3);
                if (dtStart2445 == null && dtEnd2445 == null) {
                    if (Log.isLoggable(TAG, Log.ERROR)) {
                        Log.e(TAG, "Event " + eventId + " has dtStart2445 and dtEnd2445 null "
                                + "at the same time in EventsRawTimes!");
                    }
                    continue;
                }
                updateEventsStartEndLocked(eventId,
                        eventTimezone,
                        dtStart2445,
                        dtEnd2445);
            }
        } finally {
            cursor.close();
            cursor = null;
        }
    }

    private long get2445ToMillis(String timezone, String dt2445) {
        if (null == dt2445) {
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "Cannot parse null RFC2445 date");
            }
            return 0;
        }
        Time time = (timezone != null) ? new Time(timezone) : new Time();
        try {
            time.parse(dt2445);
        } catch (TimeFormatException e) {
            if (Log.isLoggable(TAG, Log.ERROR)) {
                Log.e(TAG, "Cannot parse RFC2445 date " + dt2445);
            }
            return 0;
        }
        return time.toMillis(true /* ignore DST */);
    }

    private void updateEventsStartEndLocked(long eventId,
            String timezone, String dtStart2445, String dtEnd2445) {

        ContentValues values = new ContentValues();
        values.put(Events.DTSTART, get2445ToMillis(timezone, dtStart2445));
        values.put(Events.DTEND, get2445ToMillis(timezone, dtEnd2445));

        int result = mDb.update(Tables.EVENTS, values, SQL_WHERE_ID,
                new String[] {String.valueOf(eventId)});
        if (0 == result) {
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "Could not update Events table with values " + values);
            }
        }
    }

    private void updateTimezoneDatabaseVersion(String timeZoneDatabaseVersion) {
        try {
            mCalendarCache.writeTimezoneDatabaseVersion(timeZoneDatabaseVersion);
        } catch (CalendarCache.CacheException e) {
            if (Log.isLoggable(TAG, Log.ERROR)) {
                Log.e(TAG, "Could not write timezone database version in the cache");
            }
        }
    }

    /**
     * Check if the time zone database version is the same as the cached one
     */
    protected boolean isSameTimezoneDatabaseVersion() {
        String timezoneDatabaseVersion = mCalendarCache.readTimezoneDatabaseVersion();
        if (timezoneDatabaseVersion == null) {
            return false;
        }
        return TextUtils.equals(timezoneDatabaseVersion, TimeUtils.getTimeZoneDatabaseVersion());
    }

    @VisibleForTesting
    protected String getTimezoneDatabaseVersion() {
        String timezoneDatabaseVersion = mCalendarCache.readTimezoneDatabaseVersion();
        if (timezoneDatabaseVersion == null) {
            return "";
        }
        if (Log.isLoggable(TAG, Log.INFO)) {
            Log.i(TAG, "timezoneDatabaseVersion = " + timezoneDatabaseVersion);
        }
        return timezoneDatabaseVersion;
    }

    private boolean isHomeTimezone() {
        final String type = mCalendarCache.readTimezoneType();
        return CalendarCache.TIMEZONE_TYPE_HOME.equals(type);
    }

    private void regenerateInstancesTable() {
        // 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();
        String instancesTimezone = mCalendarCache.readTimezoneInstances();
        Time time = new Time(instancesTimezone);
        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;

        Cursor cursor = null;
        try {
            cursor = handleInstanceQuery(new SQLiteQueryBuilder(),
                    begin, end,
                    new String[] { Instances._ID },
                    null /* selection */, null,
                    null /* sort */,
                    false /* searchByDayInsteadOfMillis */,
                    true /* force Instances deletion and expansion */,
                    instancesTimezone, isHomeTimezone());
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        mCalendarAlarm.rescheduleMissedAlarms();
    }


    @Override
    protected void notifyChange(boolean syncToNetwork) {
        // Note that semantics are changed: notification is for CONTENT_URI, not the specific
        // Uri that was modified.
        mContentResolver.notifyChange(CalendarContract.CONTENT_URI, null, syncToNetwork);
    }

    /**
     * ALERT table is maintained locally so don't request a sync for changes in it
     */
    @Override
    protected boolean shouldSyncFor(Uri uri) {
        final int match = sUriMatcher.match(uri);
        return !(match == CALENDAR_ALERTS ||
                match == CALENDAR_ALERTS_ID ||
                match == CALENDAR_ALERTS_BY_INSTANCE);
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        final long identity = clearCallingIdentityInternal();
        try {
            return queryInternal(uri, projection, selection, selectionArgs, sortOrder);
        } finally {
            restoreCallingIdentityInternal(identity);
        }
    }

    private Cursor queryInternal(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "query uri - " + uri);
        }
        validateUriParameters(uri.getQueryParameterNames());
        final SQLiteDatabase db = mDbHelper.getReadableDatabase();

        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        String groupBy = null;
        String limit = null; // Not currently implemented
        String instancesTimezone;

        final int match = sUriMatcher.match(uri);
        switch (match) {
            case SYNCSTATE:
                return mDbHelper.getSyncState().query(db, projection, selection, selectionArgs,
                        sortOrder);
            case SYNCSTATE_ID:
                String selectionWithId = (SyncState._ID + "=?")
                    + (selection == null ? "" : " AND (" + selection + ")");
                // Prepend id to selectionArgs
                selectionArgs = insertSelectionArg(selectionArgs,
                        String.valueOf(ContentUris.parseId(uri)));
                return mDbHelper.getSyncState().query(db, projection, selectionWithId,
                        selectionArgs, sortOrder);

            case EVENTS:
                qb.setTables(CalendarDatabaseHelper.Views.EVENTS);
                qb.setProjectionMap(sEventsProjectionMap);
                selection = appendAccountToSelection(uri, selection, Calendars.ACCOUNT_NAME,
                        Calendars.ACCOUNT_TYPE);
                selection = appendLastSyncedColumnToSelection(selection, uri);
                break;
            case EVENTS_ID:
                qb.setTables(CalendarDatabaseHelper.Views.EVENTS);
                qb.setProjectionMap(sEventsProjectionMap);
                selectionArgs = insertSelectionArg(selectionArgs, uri.getPathSegments().get(1));
                qb.appendWhere(SQL_WHERE_ID);
                break;

            case EVENT_ENTITIES:
                qb.setTables(CalendarDatabaseHelper.Views.EVENTS);
                qb.setProjectionMap(sEventEntitiesProjectionMap);
                selection = appendAccountToSelection(uri, selection, Calendars.ACCOUNT_NAME,
                        Calendars.ACCOUNT_TYPE);
                selection = appendLastSyncedColumnToSelection(selection, uri);
                break;
            case EVENT_ENTITIES_ID:
                qb.setTables(CalendarDatabaseHelper.Views.EVENTS);
                qb.setProjectionMap(sEventEntitiesProjectionMap);
                selectionArgs = insertSelectionArg(selectionArgs, uri.getPathSegments().get(1));
                qb.appendWhere(SQL_WHERE_ID);
                break;

            case COLORS:
                qb.setTables(Tables.COLORS);
                qb.setProjectionMap(sColorsProjectionMap);
                selection = appendAccountToSelection(uri, selection, Calendars.ACCOUNT_NAME,
                        Calendars.ACCOUNT_TYPE);
                break;

            case CALENDARS:
            case CALENDAR_ENTITIES:
                qb.setTables(Tables.CALENDARS);
                qb.setProjectionMap(sCalendarsProjectionMap);
                selection = appendAccountToSelection(uri, selection, Calendars.ACCOUNT_NAME,
                        Calendars.ACCOUNT_TYPE);
                break;
            case CALENDARS_ID:
            case CALENDAR_ENTITIES_ID:
                qb.setTables(Tables.CALENDARS);
                qb.setProjectionMap(sCalendarsProjectionMap);
                selectionArgs = insertSelectionArg(selectionArgs, uri.getPathSegments().get(1));
                qb.appendWhere(SQL_WHERE_ID);
                break;
            case INSTANCES:
            case INSTANCES_BY_DAY:
                long begin;
                long end;
                try {
                    begin = Long.valueOf(uri.getPathSegments().get(2));
                } catch (NumberFormatException nfe) {
                    throw new IllegalArgumentException("Cannot parse begin "
                            + uri.getPathSegments().get(2));
                }
                try {
                    end = Long.valueOf(uri.getPathSegments().get(3));
                } catch (NumberFormatException nfe) {
                    throw new IllegalArgumentException("Cannot parse end "
                            + uri.getPathSegments().get(3));
                }
                instancesTimezone = mCalendarCache.readTimezoneInstances();
                return handleInstanceQuery(qb, begin, end, projection, selection, selectionArgs,
                        sortOrder, match == INSTANCES_BY_DAY, false /* don't force an expansion */,
                        instancesTimezone, isHomeTimezone());
            case INSTANCES_SEARCH:
            case INSTANCES_SEARCH_BY_DAY:
                try {
                    begin = Long.valueOf(uri.getPathSegments().get(2));
                } catch (NumberFormatException nfe) {
                    throw new IllegalArgumentException("Cannot parse begin "
                            + uri.getPathSegments().get(2));
                }
                try {
                    end = Long.valueOf(uri.getPathSegments().get(3));
                } catch (NumberFormatException nfe) {
                    throw new IllegalArgumentException("Cannot parse end "
                            + uri.getPathSegments().get(3));
                }
                instancesTimezone = mCalendarCache.readTimezoneInstances();
                // this is already decoded
                String query = uri.getPathSegments().get(4);
                return handleInstanceSearchQuery(qb, begin, end, query, projection, selection,
                        selectionArgs, sortOrder, match == INSTANCES_SEARCH_BY_DAY,
                        instancesTimezone, isHomeTimezone());
            case EVENT_DAYS:
                int startDay;
                int endDay;
                try {
                    startDay = Integer.parseInt(uri.getPathSegments().get(2));
                } catch (NumberFormatException nfe) {
                    throw new IllegalArgumentException("Cannot parse start day "
                            + uri.getPathSegments().get(2));
                }
                try {
                    endDay = Integer.parseInt(uri.getPathSegments().get(3));
                } catch (NumberFormatException nfe) {
                    throw new IllegalArgumentException("Cannot parse end day "
                            + uri.getPathSegments().get(3));
                }
                instancesTimezone = mCalendarCache.readTimezoneInstances();
                return handleEventDayQuery(qb, startDay, endDay, projection, selection,
                        instancesTimezone, isHomeTimezone());
            case ATTENDEES:
                qb.setTables(Tables.ATTENDEES + ", " + Tables.EVENTS + ", " + Tables.CALENDARS);
                qb.setProjectionMap(sAttendeesProjectionMap);
                qb.appendWhere(SQL_WHERE_ATTENDEE_BASE);
                break;
            case ATTENDEES_ID:
                qb.setTables(Tables.ATTENDEES + ", " + Tables.EVENTS + ", " + Tables.CALENDARS);
                qb.setProjectionMap(sAttendeesProjectionMap);
                selectionArgs = insertSelectionArg(selectionArgs, uri.getPathSegments().get(1));
                qb.appendWhere(SQL_WHERE_ATTENDEES_ID);
                break;
            case REMINDERS:
                qb.setTables(Tables.REMINDERS);
                break;
            case REMINDERS_ID:
                qb.setTables(Tables.REMINDERS + ", " + Tables.EVENTS + ", " + Tables.CALENDARS);
                qb.setProjectionMap(sRemindersProjectionMap);
                selectionArgs = insertSelectionArg(selectionArgs, uri.getLastPathSegment());
                qb.appendWhere(SQL_WHERE_REMINDERS_ID);
                break;
            case CALENDAR_ALERTS:
                qb.setTables(Tables.CALENDAR_ALERTS + ", " + CalendarDatabaseHelper.Views.EVENTS);
                qb.setProjectionMap(sCalendarAlertsProjectionMap);
                qb.appendWhere(SQL_WHERE_CALENDAR_ALERT);
                break;
            case CALENDAR_ALERTS_BY_INSTANCE:
                qb.setTables(Tables.CALENDAR_ALERTS + ", " + CalendarDatabaseHelper.Views.EVENTS);
                qb.setProjectionMap(sCalendarAlertsProjectionMap);
                qb.appendWhere(SQL_WHERE_CALENDAR_ALERT);
                groupBy = CalendarAlerts.EVENT_ID + "," + CalendarAlerts.BEGIN;
                break;
            case CALENDAR_ALERTS_ID:
                qb.setTables(Tables.CALENDAR_ALERTS + ", " + CalendarDatabaseHelper.Views.EVENTS);
                qb.setProjectionMap(sCalendarAlertsProjectionMap);
                selectionArgs = insertSelectionArg(selectionArgs, uri.getLastPathSegment());
                qb.appendWhere(SQL_WHERE_CALENDAR_ALERT_ID);
                break;
            case EXTENDED_PROPERTIES:
                qb.setTables(Tables.EXTENDED_PROPERTIES);
                break;
            case EXTENDED_PROPERTIES_ID:
                qb.setTables(Tables.EXTENDED_PROPERTIES);
                selectionArgs = insertSelectionArg(selectionArgs, uri.getPathSegments().get(1));
                qb.appendWhere(SQL_WHERE_EXTENDED_PROPERTIES_ID);
                break;
            case PROVIDER_PROPERTIES:
                qb.setTables(Tables.CALENDAR_CACHE);
                qb.setProjectionMap(sCalendarCacheProjectionMap);
                break;
            default:
                throw new IllegalArgumentException("Unknown URL " + uri);
        }

        // run the query
        return query(db, qb, projection, selection, selectionArgs, sortOrder, groupBy, limit);
    }

    private void validateUriParameters(Set<String> queryParameterNames) {
        final Set<String> parameterNames = queryParameterNames;
        for (String parameterName : parameterNames) {
            if (!ALLOWED_URI_PARAMETERS.contains(parameterName)) {
                throw new IllegalArgumentException("Invalid URI parameter: " + parameterName);
            }
        }
    }

    private Cursor query(final SQLiteDatabase db, SQLiteQueryBuilder qb, String[] projection,
            String selection, String[] selectionArgs, String sortOrder, String groupBy,
            String limit) {

        if (projection != null && projection.length == 1
                && BaseColumns._COUNT.equals(projection[0])) {
            qb.setProjectionMap(sCountProjectionMap);
        }

        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "query sql - projection: " + Arrays.toString(projection) +
                    " selection: " + selection +
                    " selectionArgs: " + Arrays.toString(selectionArgs) +
                    " sortOrder: " + sortOrder +
                    " groupBy: " + groupBy +
                    " limit: " + limit);
        }
        final Cursor c = qb.query(db, projection, selection, selectionArgs, groupBy, null,
                sortOrder, limit);
        if (c != null) {
            // TODO: is this the right notification Uri?
            c.setNotificationUri(mContentResolver, CalendarContract.Events.CONTENT_URI);
        }
        return c;
    }

    /*
     * Fills the Instances table, if necessary, for the given range and then
     * queries the Instances table.
     *
     * @param qb The query
     * @param rangeBegin start of range (Julian days or ms)
     * @param rangeEnd end of range (Julian days or ms)
     * @param projection The projection
     * @param selection The selection
     * @param sort How to sort
     * @param searchByDay if true, range is in Julian days, if false, range is in ms
     * @param forceExpansion force the Instance deletion and expansion if set to true
     * @param instancesTimezone timezone we need to use for computing the instances
     * @param isHomeTimezone if true, we are in the "home" timezone
     * @return
     */
    private Cursor handleInstanceQuery(SQLiteQueryBuilder qb, long rangeBegin,
            long rangeEnd, String[] projection, String selection, String[] selectionArgs,
            String sort, boolean searchByDay, boolean forceExpansion,
            String instancesTimezone, boolean isHomeTimezone) {
        mDb = mDbHelper.getWritableDatabase();
        qb.setTables(INSTANCE_QUERY_TABLES);
        qb.setProjectionMap(sInstancesProjectionMap);
        if (searchByDay) {
            // Convert the first and last Julian day range to a range that uses
            // UTC milliseconds.
            Time time = new Time(instancesTimezone);
            long beginMs = time.setJulianDay((int) rangeBegin);
            // 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 endMs = time.setJulianDay((int) rangeEnd + 1);
            // will lock the database.
            acquireInstanceRange(beginMs, endMs, true /* use minimum expansion window */,
                    forceExpansion, instancesTimezone, isHomeTimezone);
            qb.appendWhere(SQL_WHERE_INSTANCES_BETWEEN_DAY);
        } else {
            // will lock the database.
            acquireInstanceRange(rangeBegin, rangeEnd, true /* use minimum expansion window */,
                    forceExpansion, instancesTimezone, isHomeTimezone);
            qb.appendWhere(SQL_WHERE_INSTANCES_BETWEEN);
        }

        String[] newSelectionArgs = new String[] {String.valueOf(rangeEnd),
                String.valueOf(rangeBegin)};
        if (selectionArgs == null) {
            selectionArgs = newSelectionArgs;
        } else {
            selectionArgs = combine(newSelectionArgs, selectionArgs);
        }
        return qb.query(mDb, projection, selection, selectionArgs, null /* groupBy */,
                null /* having */, sort);
    }

    /**
     * Combine a set of arrays in the order they are passed in. All arrays must
     * be of the same type.
     */
    private static <T> T[] combine(T[]... arrays) {
        if (arrays.length == 0) {
            throw new IllegalArgumentException("Must supply at least 1 array to combine");
        }

        int totalSize = 0;
        for (T[] array : arrays) {
            totalSize += array.length;
        }

        T[] finalArray = (T[]) (Array.newInstance(arrays[0].getClass().getComponentType(),
                totalSize));

        int currentPos = 0;
        for (T[] array : arrays) {
            int length = array.length;
            System.arraycopy(array, 0, finalArray, currentPos, length);
            currentPos += array.length;
        }
        return finalArray;
    }

    /**
     * Escape any special characters in the search token
     * @param token the token to escape
     * @return the escaped token
     */
    @VisibleForTesting
    String escapeSearchToken(String token) {
        Matcher matcher = SEARCH_ESCAPE_PATTERN.matcher(token);
        return matcher.replaceAll(SEARCH_ESCAPE_CHAR + "$1");
    }

    /**
     * Splits the search query into individual search tokens based on whitespace
     * and punctuation. Leaves both single quoted and double quoted strings
     * intact.
     *
     * @param query the search query
     * @return an array of tokens from the search query
     */
    @VisibleForTesting
    String[] tokenizeSearchQuery(String query) {
        List<String> matchList = new ArrayList<String>();
        Matcher matcher = SEARCH_TOKEN_PATTERN.matcher(query);
        String token;
        while (matcher.find()) {
            if (matcher.group(1) != null) {
                // double quoted string
                token = matcher.group(1);
            } else {
                // unquoted token
                token = matcher.group();
            }
            matchList.add(escapeSearchToken(token));
        }
        return matchList.toArray(new String[matchList.size()]);
    }

    /**
     * In order to support what most people would consider a reasonable
     * search behavior, we have to do some interesting things here. We
     * assume that when a user searches for something like "lunch meeting",
     * they really want any event that matches both "lunch" and "meeting",
     * not events that match the string "lunch meeting" itself. In order to
     * do this across multiple columns, we have to construct a WHERE clause
     * that looks like:
     * <code>
     *   WHERE (title LIKE "%lunch%"
     *      OR description LIKE "%lunch%"
     *      OR eventLocation LIKE "%lunch%")
     *     AND (title LIKE "%meeting%"
     *      OR description LIKE "%meeting%"
     *      OR eventLocation LIKE "%meeting%")
     * </code>
     * This "product of clauses" is a bit ugly, but produced a fairly good
     * approximation of full-text search across multiple columns.  The set
     * of columns is specified by the SEARCH_COLUMNS constant.
     * <p>
     * Note the "WHERE" token isn't part of the returned string.  The value
     * may be passed into a query as the "HAVING" clause.
     */
    @VisibleForTesting
    String constructSearchWhere(String[] tokens) {
        if (tokens.length == 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        String column, token;
        for (int j = 0; j < tokens.length; j++) {
            sb.append("(");
            for (int i = 0; i < SEARCH_COLUMNS.length; i++) {
                sb.append(SEARCH_COLUMNS[i]);
                sb.append(" LIKE ? ESCAPE \"");
                sb.append(SEARCH_ESCAPE_CHAR);
                sb.append("\" ");
                if (i < SEARCH_COLUMNS.length - 1) {
                    sb.append("OR ");
                }
            }
            sb.append(")");
            if (j < tokens.length - 1) {
                sb.append(" AND ");
            }
        }
        return sb.toString();
    }

    @VisibleForTesting
    String[] constructSearchArgs(String[] tokens) {
        int numCols = SEARCH_COLUMNS.length;
        int numArgs = tokens.length * numCols;
        String[] selectionArgs = new String[numArgs];
        for (int j = 0; j < tokens.length; j++) {
            int start = numCols * j;
            for (int i = start; i < start + numCols; i++) {
                selectionArgs[i] = "%" + tokens[j] + "%";
            }
        }
        return selectionArgs;
    }

    private Cursor handleInstanceSearchQuery(SQLiteQueryBuilder qb,
            long rangeBegin, long rangeEnd, String query, String[] projection,
            String selection, String[] selectionArgs, String sort, boolean searchByDay,
            String instancesTimezone, boolean isHomeTimezone) {
        mDb = mDbHelper.getWritableDatabase();
        qb.setTables(INSTANCE_SEARCH_QUERY_TABLES);
        qb.setProjectionMap(sInstancesProjectionMap);

        String[] tokens = tokenizeSearchQuery(query);
        String[] searchArgs = constructSearchArgs(tokens);
        String[] timeRange = new String[] {String.valueOf(rangeEnd), String.valueOf(rangeBegin)};
        if (selectionArgs == null) {
            selectionArgs = combine(timeRange, searchArgs);
        } else {
            // where clause comes first, so put selectionArgs before searchArgs.
            selectionArgs = combine(timeRange, selectionArgs, searchArgs);
        }
        // we pass this in as a HAVING instead of a WHERE so the filtering
        // happens after the grouping
        String searchWhere = constructSearchWhere(tokens);

        if (searchByDay) {
            // Convert the first and last Julian day range to a range that uses
            // UTC milliseconds.
            Time time = new Time(instancesTimezone);
            long beginMs = time.setJulianDay((int) rangeBegin);
            // 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 endMs = time.setJulianDay((int) rangeEnd + 1);
            // will lock the database.
            // we expand the instances here because we might be searching over
            // a range where instance expansion has not occurred yet
            acquireInstanceRange(beginMs, endMs,
                    true /* use minimum expansion window */,
                    false /* do not force Instances deletion and expansion */,
                    instancesTimezone,
                    isHomeTimezone
            );
            qb.appendWhere(SQL_WHERE_INSTANCES_BETWEEN_DAY);
        } else {
            // will lock the database.
            // we expand the instances here because we might be searching over
            // a range where instance expansion has not occurred yet
            acquireInstanceRange(rangeBegin, rangeEnd,
                    true /* use minimum expansion window */,
                    false /* do not force Instances deletion and expansion */,
                    instancesTimezone,
                    isHomeTimezone
            );
            qb.appendWhere(SQL_WHERE_INSTANCES_BETWEEN);
        }
        return qb.query(mDb, projection, selection, selectionArgs,
                Tables.INSTANCES + "." + Instances._ID /* groupBy */,
                searchWhere /* having */, sort);
    }

    private Cursor handleEventDayQuery(SQLiteQueryBuilder qb, int begin, int end,
            String[] projection, String selection, String instancesTimezone,
            boolean isHomeTimezone) {
        mDb = mDbHelper.getWritableDatabase();
        qb.setTables(INSTANCE_QUERY_TABLES);
        qb.setProjectionMap(sInstancesProjectionMap);
        // Convert the first and last Julian day range to a range that uses
        // UTC milliseconds.
        Time time = new Time(instancesTimezone);
        long beginMs = time.setJulianDay(begin);
        // 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 endMs = time.setJulianDay(end + 1);

        acquireInstanceRange(beginMs, endMs, true,
                false /* do not force Instances expansion */, instancesTimezone, isHomeTimezone);
        qb.appendWhere(SQL_WHERE_INSTANCES_BETWEEN_DAY);
        String selectionArgs[] = new String[] {String.valueOf(end), String.valueOf(begin)};

        return qb.query(mDb, projection, selection, selectionArgs,
                Instances.START_DAY /* groupBy */, null /* having */, null);
    }

    /**
     * Ensure that the date range given has all elements in the instance
     * table.  Acquires the database lock and calls
     * {@link #acquireInstanceRangeLocked(long, long, boolean, boolean, String, boolean)}.
     *
     * @param begin start of range (ms)
     * @param end end of range (ms)
     * @param useMinimumExpansionWindow expand by at least MINIMUM_EXPANSION_SPAN
     * @param forceExpansion force the Instance deletion and expansion if set to true
     * @param instancesTimezone timezone we need to use for computing the instances
     * @param isHomeTimezone if true, we are in the "home" timezone
     */
    private void acquireInstanceRange(final long begin, final long end,
            final boolean useMinimumExpansionWindow, final boolean forceExpansion,
            final String instancesTimezone, final boolean isHomeTimezone) {
        mDb.beginTransaction();
        try {
            acquireInstanceRangeLocked(begin, end, useMinimumExpansionWindow,
                    forceExpansion, instancesTimezone, isHomeTimezone);
            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.
     *
     * @param begin start of range (ms)
     * @param end end of range (ms)
     * @param useMinimumExpansionWindow expand by at least MINIMUM_EXPANSION_SPAN
     * @param forceExpansion force the Instance deletion and expansion if set to true
     * @param instancesTimezone timezone we need to use for computing the instances
     * @param isHomeTimezone if true, we are in the "home" timezone
     */
    void acquireInstanceRangeLocked(long begin, long end, boolean useMinimumExpansionWindow,
            boolean forceExpansion, String instancesTimezone, boolean isHomeTimezone) {
        long expandBegin = begin;
        long expandEnd = end;

        if (DEBUG_INSTANCES) {
            Log.d(TAG + "-i", "acquireInstanceRange begin=" + begin + " end=" + end +
                    " useMin=" + useMinimumExpansionWindow + " force=" + forceExpansion);
        }

        if (instancesTimezone == null) {
            Log.e(TAG, "Cannot run acquireInstanceRangeLocked() because instancesTimezone is null");
            return;
        }

        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();
        long maxInstance = fields.maxInstance;
        long minInstance = fields.minInstance;
        boolean timezoneChanged;
        if (isHomeTimezone) {
            String previousTimezone = mCalendarCache.readTimezoneInstancesPrevious();
            timezoneChanged = !instancesTimezone.equals(previousTimezone);
        } else {
            String localTimezone = TimeZone.getDefault().getID();
            timezoneChanged = !instancesTimezone.equals(localTimezone);
            // if we're in auto make sure we are using the device time zone
            if (timezoneChanged) {
                instancesTimezone = localTimezone;
            }
        }
        // if "home", then timezoneChanged only if current != previous
        // if "auto", then timezoneChanged, if !instancesTimezone.equals(localTimezone);
        if (maxInstance == 0 || timezoneChanged || forceExpansion) {
            if (DEBUG_INSTANCES) {
                Log.d(TAG + "-i", "Wiping instances and expanding from scratch");
            }

            // Empty the Instances table and expand from scratch.
            mDb.execSQL("DELETE FROM " + Tables.INSTANCES + ";");
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "acquireInstanceRangeLocked() deleted Instances,"
                        + " timezone changed: " + timezoneChanged);
            }
            mInstancesHelper.expandInstanceRangeLocked(expandBegin, expandEnd, instancesTimezone);

            mMetaData.writeLocked(instancesTimezone, expandBegin, expandEnd);

            final String timezoneType = mCalendarCache.readTimezoneType();
            // This may cause some double writes but guarantees the time zone in
            // the db and the time zone the instances are in is the same, which
            // future changes may affect.
            mCalendarCache.writeTimezoneInstances(instancesTimezone);

            // If we're in auto check if we need to fix the previous tz value
            if (CalendarCache.TIMEZONE_TYPE_AUTO.equals(timezoneType)) {
                String prevTZ = mCalendarCache.readTimezoneInstancesPrevious();
                if (TextUtils.equals(TIMEZONE_GMT, prevTZ)) {
                    mCalendarCache.writeTimezoneInstancesPrevious(instancesTimezone);
                }
            }
            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 (DEBUG_INSTANCES) {
                Log.d(TAG + "-i", "instances are already expanded");
            }
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                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) {
            mInstancesHelper.expandInstanceRangeLocked(expandBegin, minInstance, instancesTimezone);
            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) {
            mInstancesHelper.expandInstanceRangeLocked(maxInstance, expandEnd, instancesTimezone);
            maxInstance = expandEnd;
        }

        // Update the bounds on the Instances table.
        mMetaData.writeLocked(instancesTimezone, minInstance, maxInstance);
    }

    @Override
    public String getType(Uri url) {
        int match = sUriMatcher.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:
            case INSTANCES_BY_DAY:
            case EVENT_DAYS:
                return "vnd.android.cursor.dir/event-instance";
            case TIME:
                return "time/epoch";
            case PROVIDER_PROPERTIES:
                return "vnd.android.cursor.dir/property";
            default:
                throw new IllegalArgumentException("Unknown URL " + url);
        }
    }

    /**
     * Determines if the event is recurrent, based on the provided values.
     */
    public static boolean isRecurrenceEvent(String rrule, String rdate, String originalId,
            String originalSyncId) {
        return (!TextUtils.isEmpty(rrule) ||
                !TextUtils.isEmpty(rdate) ||
                !TextUtils.isEmpty(originalId) ||
                !TextUtils.isEmpty(originalSyncId));
    }

    /**
     * Takes an event and corrects the hrs, mins, secs if it is an allDay event.
     * <p>
     * AllDay events should have hrs, mins, secs set to zero. This checks if this is true and
     * corrects the fields DTSTART, DTEND, and DURATION if necessary.
     *
     * @param values The values to check and correct
     * @param modValues Any updates will be stored here.  This may be the same object as
     *   <strong>values</strong>.
     * @return Returns true if a correction was necessary, false otherwise
     */
    private boolean fixAllDayTime(ContentValues values, ContentValues modValues) {
        Integer allDayObj = values.getAsInteger(Events.ALL_DAY);
        if (allDayObj == null || allDayObj == 0) {
            return false;
        }

        boolean neededCorrection = false;

        Long dtstart = values.getAsLong(Events.DTSTART);
        Long dtend = values.getAsLong(Events.DTEND);
        String duration = values.getAsString(Events.DURATION);
        Time time = new Time();
        String tempValue;

        // Change dtstart so h,m,s are 0 if necessary.
        time.clear(Time.TIMEZONE_UTC);
        time.set(dtstart.longValue());
        if (time.hour != 0 || time.minute != 0 || time.second != 0) {
            time.hour = 0;
            time.minute = 0;
            time.second = 0;
            modValues.put(Events.DTSTART, time.toMillis(true));
            neededCorrection = true;
        }

        // If dtend exists for this event make sure it's h,m,s are 0.
        if (dtend != null) {
            time.clear(Time.TIMEZONE_UTC);
            time.set(dtend.longValue());
            if (time.hour != 0 || time.minute != 0 || time.second != 0) {
                time.hour = 0;
                time.minute = 0;
                time.second = 0;
                dtend = time.toMillis(true);
                modValues.put(Events.DTEND, dtend);
                neededCorrection = true;
            }
        }

        if (duration != null) {
            int len = duration.length();
            /* duration is stored as either "P<seconds>S" or "P<days>D". This checks if it's
             * in the seconds format, and if so converts it to days.
             */
            if (len == 0) {
                duration = null;
            } else if (duration.charAt(0) == 'P' &&
                    duration.charAt(len - 1) == 'S') {
                int seconds = Integer.parseInt(duration.substring(1, len - 1));
                int days = (seconds + DAY_IN_SECONDS - 1) / DAY_IN_SECONDS;
                duration = "P" + days + "D";
                modValues.put(Events.DURATION, duration);
                neededCorrection = true;
            }
        }

        return neededCorrection;
    }


    /**
     * Determines whether the strings in the set name columns that may be overridden
     * when creating a recurring event exception.
     * <p>
     * This uses a white list because it screens out unknown columns and is a bit safer to
     * maintain than a black list.
     */
    private void checkAllowedInException(Set<String> keys) {
        for (String str : keys) {
            if (!ALLOWED_IN_EXCEPTION.contains(str.intern())) {
                throw new IllegalArgumentException("Exceptions can't overwrite " + str);
            }
        }
    }

    /**
     * Splits a recurrent event at a specified instance.  This is useful when modifying "this
     * and all future events".
     *<p>
     * If the recurrence rule has a COUNT specified, we need to split that at the point of the
     * exception.  If the exception is instance N (0-based), the original COUNT is reduced
     * to N, and the exception's COUNT is set to (COUNT - N).
     *<p>
     * If the recurrence doesn't have a COUNT, we need to update or introduce an UNTIL value,
     * so that the original recurrence will end just before the exception instance.  (Note
     * that UNTIL dates are inclusive.)
     *<p>
     * This should not be used to update the first instance ("update all events" action).
     *
     * @param values The original event values; must include EVENT_TIMEZONE and DTSTART.
     *        The RRULE value may be modified (with the expectation that this will propagate
     *        into the exception event).
     * @param endTimeMillis The time before which the event must end (i.e. the start time of the
     *        exception event instance).
     * @return Values to apply to the original event.
     */
    private static ContentValues setRecurrenceEnd(ContentValues values, long endTimeMillis) {
        boolean origAllDay = values.getAsBoolean(Events.ALL_DAY);
        String origRrule = values.getAsString(Events.RRULE);

        EventRecurrence origRecurrence = new EventRecurrence();
        origRecurrence.parse(origRrule);

        // Get the start time of the first instance in the original recurrence.
        long startTimeMillis = values.getAsLong(Events.DTSTART);
        Time dtstart = new Time();
        dtstart.timezone = values.getAsString(Events.EVENT_TIMEZONE);
        dtstart.set(startTimeMillis);

        ContentValues updateValues = new ContentValues();

        if (origRecurrence.count > 0) {
            /*
             * Generate the full set of instances for this recurrence, from the first to the
             * one just before endTimeMillis.  The list should never be empty, because this method
             * should not be called for the first instance.  All we're really interested in is
             * the *number* of instances found.
             */
            RecurrenceSet recurSet = new RecurrenceSet(values);
            RecurrenceProcessor recurProc = new RecurrenceProcessor();
            long[] recurrences;
            try {
                recurrences = recurProc.expand(dtstart, recurSet, startTimeMillis, endTimeMillis);
            } catch (DateException de) {
                throw new RuntimeException(de);
            }

            if (recurrences.length == 0) {
                throw new RuntimeException("can't use this method on first instance");
            }

            EventRecurrence excepRecurrence = new EventRecurrence();
            excepRecurrence.parse(origRrule); // TODO: add/use a copy constructor to EventRecurrence
            excepRecurrence.count -= recurrences.length;
            values.put(Events.RRULE, excepRecurrence.toString());

            origRecurrence.count = recurrences.length;

        } else {
            Time untilTime = new Time();

            // The "until" time must be in UTC time in order for Google calendar
            // to display it properly. For all-day events, the "until" time string
            // must include just the date field, and not the time field. The
            // repeating events repeat up to and including the "until" time.
            untilTime.timezone = Time.TIMEZONE_UTC;

            // Subtract one second from the exception begin time to get the "until" time.
            untilTime.set(endTimeMillis - 1000); // subtract one second (1000 millis)
            if (origAllDay) {
                untilTime.hour = untilTime.minute = untilTime.second = 0;
                untilTime.allDay = true;
                untilTime.normalize(false);

                // This should no longer be necessary -- DTSTART should already be in the correct
                // format for an all-day event.
                dtstart.hour = dtstart.minute = dtstart.second = 0;
                dtstart.allDay = true;
                dtstart.timezone = Time.TIMEZONE_UTC;
            }
            origRecurrence.until = untilTime.format2445();
        }

        updateValues.put(Events.RRULE, origRecurrence.toString());
        updateValues.put(Events.DTSTART, dtstart.normalize(true));
        return updateValues;
    }

    /**
     * Handles insertion of an exception to a recurring event.
     * <p>
     * There are two modes, selected based on the presence of "rrule" in modValues:
     * <ol>
     * <li> Create a single instance exception ("modify current event only").
     * <li> Cap the original event, and create a new recurring event ("modify this and all
     * future events").
     * </ol>
     * This may be used for "modify all instances of the event" by simply selecting the
     * very first instance as the exception target.  In that case, the ID of the "new"
     * exception event will be the same as the originalEventId.
     *
     * @param originalEventId The _id of the event to be modified
     * @param modValues Event columns to update
     * @param callerIsSyncAdapter Set if the content provider client is the sync adapter
     * @return the ID of the new "exception" event, or -1 on failure
     */
    private long handleInsertException(long originalEventId, ContentValues modValues,
            boolean callerIsSyncAdapter) {
        if (DEBUG_EXCEPTION) {
            Log.i(TAG, "RE: values: " + modValues.toString());
        }

        // Make sure they have specified an instance via originalInstanceTime.
        Long originalInstanceTime = modValues.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
        if (originalInstanceTime == null) {
            throw new IllegalArgumentException("Exceptions must specify " +
                    Events.ORIGINAL_INSTANCE_TIME);
        }

        // Check for attempts to override values that shouldn't be touched.
        checkAllowedInException(modValues.keySet());

        // If this isn't the sync adapter, set the "dirty" flag in any Event we modify.
        if (!callerIsSyncAdapter) {
            modValues.put(Events.DIRTY, true);
            addMutator(modValues, Events.MUTATORS);
        }

        // Wrap all database accesses in a transaction.
        mDb.beginTransaction();
        Cursor cursor = null;
        try {
            // TODO: verify that there's an instance corresponding to the specified time
            //       (does this matter? it's weird, but not fatal?)

            // Grab the full set of columns for this event.
            cursor = mDb.query(Tables.EVENTS, null /* columns */,
                    SQL_WHERE_ID, new String[] { String.valueOf(originalEventId) },
                    null /* groupBy */, null /* having */, null /* sortOrder */);
            if (cursor.getCount() != 1) {
                Log.e(TAG, "Original event ID " + originalEventId + " lookup failed (count is " +
                        cursor.getCount() + ")");
                return -1;
            }
            //DatabaseUtils.dumpCursor(cursor);

            // If there's a color index check that it's valid
            String color_index = modValues.getAsString(Events.EVENT_COLOR_KEY);
            if (!TextUtils.isEmpty(color_index)) {
                int calIdCol = cursor.getColumnIndex(Events.CALENDAR_ID);
                Long calId = cursor.getLong(calIdCol);
                String accountName = null;
                String accountType = null;
                if (calId != null) {
                    Account account = getAccount(calId);
                    if (account != null) {
                        accountName = account.name;
                        accountType = account.type;
                    }
                }
                verifyColorExists(accountName, accountType, color_index, Colors.TYPE_EVENT);
            }

            /*
             * Verify that the original event is in fact a recurring event by checking for the
             * presence of an RRULE.  If it's there, we assume that the event is otherwise
             * properly constructed (e.g. no DTEND).
             */
            cursor.moveToFirst();
            int rruleCol = cursor.getColumnIndex(Events.RRULE);
            if (TextUtils.isEmpty(cursor.getString(rruleCol))) {
                Log.e(TAG, "Original event has no rrule");
                return -1;
            }
            if (DEBUG_EXCEPTION) {
                Log.d(TAG, "RE: old RRULE is " + cursor.getString(rruleCol));
            }

            // Verify that the original event is not itself a (single-instance) exception.
            int originalIdCol = cursor.getColumnIndex(Events.ORIGINAL_ID);
            if (!TextUtils.isEmpty(cursor.getString(originalIdCol))) {
                Log.e(TAG, "Original event is an exception");
                return -1;
            }

            boolean createSingleException = TextUtils.isEmpty(modValues.getAsString(Events.RRULE));

            // TODO: check for the presence of an existing exception on this event+instance?
            //       The caller should be modifying that, not creating another exception.
            //       (Alternatively, we could do that for them.)

            // Create a new ContentValues for the new event.  Start with the original event,
            // and drop in the new caller-supplied values.  This will set originalInstanceTime.
            ContentValues values = new ContentValues();
            DatabaseUtils.cursorRowToContentValues(cursor, values);
            cursor.close();
            cursor = null;

            // TODO: if we're changing this to an all-day event, we should ensure that
            //       hours/mins/secs on DTSTART are zeroed out (before computing DTEND).
            //       See fixAllDayTime().

            boolean createNewEvent = true;
            if (createSingleException) {
                /*
                 * Save a copy of a few fields that will migrate to new places.
                 */
                String _id = values.getAsString(Events._ID);
                String _sync_id = values.getAsString(Events._SYNC_ID);
                boolean allDay = values.getAsBoolean(Events.ALL_DAY);

                /*
                 * Wipe out some fields that we don't want to clone into the exception event.
                 */
                for (String str : DONT_CLONE_INTO_EXCEPTION) {
                    values.remove(str);
                }

                /*
                 * Merge the new values on top of the existing values.  Note this sets
                 * originalInstanceTime.
                 */
                values.putAll(modValues);

                /*
                 * Copy some fields to their "original" counterparts:
                 *   _id --> original_id
                 *   _sync_id --> original_sync_id
                 *   allDay --> originalAllDay
                 *
                 * If this event hasn't been sync'ed with the server yet, the _sync_id field will
                 * be null.  We will need to fill original_sync_id in later.  (May not be able to
                 * do it right when our own _sync_id field gets populated, because the order of
                 * events from the server may not be what we want -- could update the exception
                 * before updating the original event.)
                 *
                 * _id is removed later (right before we write the event).
                 */
                values.put(Events.ORIGINAL_ID, _id);
                values.put(Events.ORIGINAL_SYNC_ID, _sync_id);
                values.put(Events.ORIGINAL_ALL_DAY, allDay);

                // Mark the exception event status as "tentative", unless the caller has some
                // other value in mind (like STATUS_CANCELED).
                if (!values.containsKey(Events.STATUS)) {
                    values.put(Events.STATUS, Events.STATUS_TENTATIVE);
                }

                // We're converting from recurring to non-recurring.
                // Clear out RRULE, RDATE, EXRULE & EXDATE
                // Replace DURATION with DTEND.
                values.remove(Events.RRULE);
                values.remove(Events.RDATE);
                values.remove(Events.EXRULE);
                values.remove(Events.EXDATE);

                Duration duration = new Duration();
                String durationStr = values.getAsString(Events.DURATION);
                try {
                    duration.parse(durationStr);
                } catch (Exception ex) {
                    // NullPointerException if the original event had no duration.
                    // DateException if the duration was malformed.
                    Log.w(TAG, "Bad duration in recurring event: " + durationStr, ex);
                    return -1;
                }

                /*
                 * We want to compute DTEND as an offset from the start time of the instance.
                 * If the caller specified a new value for DTSTART, we want to use that; if not,
                 * the DTSTART in "values" will be the start time of the first instance in the
                 * recurrence, so we want to replace it with ORIGINAL_INSTANCE_TIME.
                 */
                long start;
                if (modValues.containsKey(Events.DTSTART)) {
                    start = values.getAsLong(Events.DTSTART);
                } else {
                    start = values.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
                    values.put(Events.DTSTART, start);
                }
                values.put(Events.DTEND, start + duration.getMillis());
                if (DEBUG_EXCEPTION) {
                    Log.d(TAG, "RE: ORIG_INST_TIME=" + start +
                            ", duration=" + duration.getMillis() +
                            ", generated DTEND=" + values.getAsLong(Events.DTEND));
                }
                values.remove(Events.DURATION);
            } else {
                /*
                 * We're going to "split" the recurring event, making the old one stop before
                 * this instance, and creating a new recurring event that starts here.
                 *
                 * No need to fill out the "original" fields -- the new event is not tied to
                 * the previous event in any way.
                 *
                 * If this is the first event in the series, we can just update the existing
                 * event with the values.
                 */
                boolean canceling = (values.getAsInteger(Events.STATUS) == Events.STATUS_CANCELED);

                if (originalInstanceTime.equals(values.getAsLong(Events.DTSTART))) {
                    /*
                     * Update fields in the existing event.  Rather than use the merged data
                     * from the cursor, we just do the update with the new value set after
                     * removing the ORIGINAL_INSTANCE_TIME entry.
                     */
                    if (canceling) {
                        // TODO: should we just call deleteEventInternal?
                        Log.d(TAG, "Note: canceling entire event via exception call");
                    }
                    if (DEBUG_EXCEPTION) {
                        Log.d(TAG, "RE: updating full event");
                    }
                    if (!validateRecurrenceRule(modValues)) {
                        throw new IllegalArgumentException("Invalid recurrence rule: " +
                                values.getAsString(Events.RRULE));
                    }
                    modValues.remove(Events.ORIGINAL_INSTANCE_TIME);
                    mDb.update(Tables.EVENTS, modValues, SQL_WHERE_ID,
                            new String[] { Long.toString(originalEventId) });
                    createNewEvent = false; // skip event creation and related-table cloning
                } else {
                    if (DEBUG_EXCEPTION) {
                        Log.d(TAG, "RE: splitting event");
                    }

                    /*
                     * Cap the original event so it ends just before the target instance.  In
                     * some cases (nonzero COUNT) this will also update the RRULE in "values",
                     * so that the exception we're creating terminates appropriately.  If a
                     * new RRULE was specified by the caller, the new rule will overwrite our
                     * changes when we merge the new values in below (which is the desired
                     * behavior).
                     */
                    ContentValues splitValues = setRecurrenceEnd(values, originalInstanceTime);
                    mDb.update(Tables.EVENTS, splitValues, SQL_WHERE_ID,
                            new String[] { Long.toString(originalEventId) });

                    /*
                     * Prepare the new event.  We remove originalInstanceTime, because we're now
                     * creating a new event rather than an exception.
                     *
                     * We're always cloning a non-exception event (we tested to make sure the
                     * event doesn't specify original_id, and we don't allow original_id in the
                     * modValues), so we shouldn't end up creating a new event that looks like
                     * an exception.
                     */
                    values.putAll(modValues);
                    values.remove(Events.ORIGINAL_INSTANCE_TIME);
                }
            }

            long newEventId;
            if (createNewEvent) {
                values.remove(Events._ID);      // don't try to set this explicitly
                if (callerIsSyncAdapter) {
                    scrubEventData(values, null);
                } else {
                    validateEventData(values);
                }

                newEventId = mDb.insert(Tables.EVENTS, null, values);
                if (newEventId < 0) {
                    Log.w(TAG, "Unable to add exception to recurring event");
                    Log.w(TAG, "Values: " + values);
                    return -1;
                }
                if (DEBUG_EXCEPTION) {
                    Log.d(TAG, "RE: new ID is " + newEventId);
                }

                // TODO: do we need to do something like this?
                //updateEventRawTimesLocked(id, updatedValues);

                /*
                 * Force re-computation of the Instances associated with the recurrence event.
                 */
                mInstancesHelper.updateInstancesLocked(values, newEventId, true, mDb);

                /*
                 * Some of the other tables (Attendees, Reminders, ExtendedProperties) reference
                 * the Event ID.  We need to copy the entries from the old event, filling in the
                 * new event ID, so that somebody doing a SELECT on those tables will find
                 * matching entries.
                 */
                CalendarDatabaseHelper.copyEventRelatedTables(mDb, newEventId, originalEventId);

                /*
                 * If we modified Event.selfAttendeeStatus, we need to keep the corresponding
                 * entry in the Attendees table in sync.
                 */
                if (modValues.containsKey(Events.SELF_ATTENDEE_STATUS)) {
                    /*
                     * Each Attendee is identified by email address.  To find the entry that
                     * corresponds to "self", we want to compare that address to the owner of
                     * the Calendar.  We're expecting to find one matching entry in Attendees.
                     */
                    long calendarId = values.getAsLong(Events.CALENDAR_ID);
                    String accountName = getOwner(calendarId);

                    if (accountName != null) {
                        ContentValues attValues = new ContentValues();
                        attValues.put(Attendees.ATTENDEE_STATUS,
                                modValues.getAsString(Events.SELF_ATTENDEE_STATUS));

                        if (DEBUG_EXCEPTION) {
                            Log.d(TAG, "Updating attendee status for event=" + newEventId +
                                    " name=" + accountName + " to " +
                                    attValues.getAsString(Attendees.ATTENDEE_STATUS));
                        }
                        int count = mDb.update(Tables.ATTENDEES, attValues,
                                Attendees.EVENT_ID + "=? AND " + Attendees.ATTENDEE_EMAIL + "=?",
                                new String[] { String.valueOf(newEventId), accountName });
                        if (count != 1 && count != 2) {
                            // We're only expecting one matching entry.  We might briefly see
                            // two during a server sync.
                            Log.e(TAG, "Attendee status update on event=" + newEventId
                                    + " touched " + count + " rows. Expected one or two rows.");
                            if (false) {
                                // This dumps PII in the log, don't ship with it enabled.
                                Cursor debugCursor = mDb.query(Tables.ATTENDEES, null,
                                        Attendees.EVENT_ID + "=? AND " +
                                            Attendees.ATTENDEE_EMAIL + "=?",
                                        new String[] { String.valueOf(newEventId), accountName },
                                        null, null, null);
                                DatabaseUtils.dumpCursor(debugCursor);
                                if (debugCursor != null) {
                                    debugCursor.close();
                                }
                            }
                            throw new RuntimeException("Status update WTF");
                        }
                    }
                }
            } else {
                /*
                 * Update any Instances changed by the update to this Event.
                 */
                mInstancesHelper.updateInstancesLocked(values, originalEventId, false, mDb);
                newEventId = originalEventId;
            }

            mDb.setTransactionSuccessful();
            return newEventId;
        } finally {
            if (cursor != null) {
                cursor.close();
            }
            mDb.endTransaction();
        }
    }

    /**
     * Fills in the originalId column for previously-created exceptions to this event.  If
     * this event is not recurring or does not have a _sync_id, this does nothing.
     * <p>
     * The server might send exceptions before the event they refer to.  When
     * this happens, the originalId field will not have been set in the
     * exception events (it's the recurrence events' _id field, so it can't be
     * known until the recurrence event is created).  When we add a recurrence
     * event with a non-empty _sync_id field, we write that event's _id to the
     * originalId field of any events whose originalSyncId matches _sync_id.
     * <p>
     * Note _sync_id is only expected to be unique within a particular calendar.
     *
     * @param id The ID of the Event
     * @param values Values for the Event being inserted
     */
    private void backfillExceptionOriginalIds(long id, ContentValues values) {
        String syncId = values.getAsString(Events._SYNC_ID);
        String rrule = values.getAsString(Events.RRULE);
        String rdate = values.getAsString(Events.RDATE);
        String calendarId = values.getAsString(Events.CALENDAR_ID);

        if (TextUtils.isEmpty(syncId) || TextUtils.isEmpty(calendarId) ||
                (TextUtils.isEmpty(rrule) && TextUtils.isEmpty(rdate))) {
            // Not a recurring event, or doesn't have a server-provided sync ID.
            return;
        }

        ContentValues originalValues = new ContentValues();
        originalValues.put(Events.ORIGINAL_ID, id);
        mDb.update(Tables.EVENTS, originalValues,
                Events.ORIGINAL_SYNC_ID + "=? AND " + Events.CALENDAR_ID + "=?",
                new String[] { syncId, calendarId });
    }

    @Override
    protected Uri insertInTransaction(Uri uri, ContentValues values, boolean callerIsSyncAdapter) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "insertInTransaction: " + uri);
        }
        validateUriParameters(uri.getQueryParameterNames());
        final int match = sUriMatcher.match(uri);
        verifyTransactionAllowed(TRANSACTION_INSERT, uri, values, callerIsSyncAdapter, match,
                null /* selection */, null /* selection args */);
        mDb = mDbHelper.getWritableDatabase();

        long id = 0;

        switch (match) {
            case SYNCSTATE:
                id = mDbHelper.getSyncState().insert(mDb, values);
                break;
            case EVENTS:
                if (!callerIsSyncAdapter) {
                    values.put(Events.DIRTY, 1);
                    addMutator(values, Events.MUTATORS);
                }
                if (!values.containsKey(Events.DTSTART)) {
                    if (values.containsKey(Events.ORIGINAL_SYNC_ID)
                            && values.containsKey(Events.ORIGINAL_INSTANCE_TIME)
                            && Events.STATUS_CANCELED == values.getAsInteger(Events.STATUS)) {
                        // event is a canceled instance of a recurring event, it doesn't these
                        // values but lets fake some to satisfy curious consumers.
                        final long origStart = values.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
                        values.put(Events.DTSTART, origStart);
                        values.put(Events.DTEND, origStart);
                        values.put(Events.EVENT_TIMEZONE, Time.TIMEZONE_UTC);
                    } else {
                        throw new RuntimeException("DTSTART field missing from event");
                    }
                }
                // TODO: do we really need to make a copy?
                ContentValues updatedValues = new ContentValues(values);
                if (callerIsSyncAdapter) {
                    scrubEventData(updatedValues, null);
                } else {
                    validateEventData(updatedValues);
                }
                // updateLastDate must be after validation, to ensure proper last date computation
                updatedValues = updateLastDate(updatedValues);
                if (updatedValues == null) {
                    throw new RuntimeException("Could not insert event.");
                    // return null;
                }
                Long calendar_id = updatedValues.getAsLong(Events.CALENDAR_ID);
                if (calendar_id == null) {
                    // validateEventData checks this for non-sync adapter
                    // inserts
                    throw new IllegalArgumentException("New events must specify a calendar id");
                }
                // Verify the color is valid if it is being set
                String color_id = updatedValues.getAsString(Events.EVENT_COLOR_KEY);
                if (!TextUtils.isEmpty(color_id)) {
                    Account account = getAccount(calendar_id);
                    String accountName = null;
                    String accountType = null;
                    if (account != null) {
                        accountName = account.name;
                        accountType = account.type;
                    }
                    int color = verifyColorExists(accountName, accountType, color_id,
                            Colors.TYPE_EVENT);
                    updatedValues.put(Events.EVENT_COLOR, color);
                }
                String owner = null;
                if (!updatedValues.containsKey(Events.ORGANIZER)) {
                    owner = getOwner(calendar_id);
                    // TODO: This isn't entirely correct.  If a guest is adding a recurrence
                    // exception to an event, the organizer should stay the original organizer.
                    // This value doesn't go to the server and it will get fixed on sync,
                    // so it shouldn't really matter.
                    if (owner != null) {
                        updatedValues.put(Events.ORGANIZER, owner);
                    }
                }
                if (updatedValues.containsKey(Events.ORIGINAL_SYNC_ID)
                        && !updatedValues.containsKey(Events.ORIGINAL_ID)) {
                    long originalId = getOriginalId(updatedValues
                            .getAsString(Events.ORIGINAL_SYNC_ID),
                            updatedValues.getAsString(Events.CALENDAR_ID));
                    if (originalId != -1) {
                        updatedValues.put(Events.ORIGINAL_ID, originalId);
                    }
                } else if (!updatedValues.containsKey(Events.ORIGINAL_SYNC_ID)
                        && updatedValues.containsKey(Events.ORIGINAL_ID)) {
                    String originalSyncId = getOriginalSyncId(updatedValues
                            .getAsLong(Events.ORIGINAL_ID));
                    if (!TextUtils.isEmpty(originalSyncId)) {
                        updatedValues.put(Events.ORIGINAL_SYNC_ID, originalSyncId);
                    }
                }
                if (fixAllDayTime(updatedValues, updatedValues)) {
                    if (Log.isLoggable(TAG, Log.WARN)) {
                        Log.w(TAG, "insertInTransaction: " +
                                "allDay is true but sec, min, hour were not 0.");
                    }
                }
                updatedValues.remove(Events.HAS_ALARM);     // should not be set by caller
                // Insert the row
                id = mDbHelper.eventsInsert(updatedValues);
                if (id != -1) {
                    updateEventRawTimesLocked(id, updatedValues);
                    mInstancesHelper.updateInstancesLocked(updatedValues, id,
                            true /* new event */, mDb);

                    // If we inserted a new event that specified the self-attendee
                    // status, then we need to add an entry to the attendees table.
                    if (values.containsKey(Events.SELF_ATTENDEE_STATUS)) {
                        int status = values.getAsInteger(Events.SELF_ATTENDEE_STATUS);
                        if (owner == null) {
                            owner = getOwner(calendar_id);
                        }
                        createAttendeeEntry(id, status, owner);
                    }

                    backfillExceptionOriginalIds(id, values);

                    sendUpdateNotification(id, callerIsSyncAdapter);
                }
                break;
            case EXCEPTION_ID:
                long originalEventId = ContentUris.parseId(uri);
                id = handleInsertException(originalEventId, values, callerIsSyncAdapter);
                break;
            case CALENDARS:
                // TODO: verify that all required fields are present
                Integer syncEvents = values.getAsInteger(Calendars.SYNC_EVENTS);
                if (syncEvents != null && syncEvents == 1) {
                    String accountName = values.getAsString(Calendars.ACCOUNT_NAME);
                    String accountType = values.getAsString(
                            Calendars.ACCOUNT_TYPE);
                    final Account account = new Account(accountName, accountType);
                    String eventsUrl = values.getAsString(Calendars.CAL_SYNC1);
                    mDbHelper.scheduleSync(account, false /* two-way sync */, eventsUrl);
                }
                String cal_color_id = values.getAsString(Calendars.CALENDAR_COLOR_KEY);
                if (!TextUtils.isEmpty(cal_color_id)) {
                    String accountName = values.getAsString(Calendars.ACCOUNT_NAME);
                    String accountType = values.getAsString(Calendars.ACCOUNT_TYPE);
                    int color = verifyColorExists(accountName, accountType, cal_color_id,
                            Colors.TYPE_CALENDAR);
                    values.put(Calendars.CALENDAR_COLOR, color);
                }
                id = mDbHelper.calendarsInsert(values);
                sendUpdateNotification(id, callerIsSyncAdapter);
                break;
            case COLORS:
                // verifyTransactionAllowed requires this be from a sync
                // adapter, all of the required fields are marked NOT NULL in
                // the db. TODO Do we need explicit checks here or should we
                // just let sqlite throw if something isn't specified?
                String accountName = uri.getQueryParameter(Colors.ACCOUNT_NAME);
                String accountType = uri.getQueryParameter(Colors.ACCOUNT_TYPE);
                String colorIndex = values.getAsString(Colors.COLOR_KEY);
                if (TextUtils.isEmpty(accountName) || TextUtils.isEmpty(accountType)) {
                    throw new IllegalArgumentException("Account name and type must be non"
                            + " empty parameters for " + uri);
                }
                if (TextUtils.isEmpty(colorIndex)) {
                    throw new IllegalArgumentException("COLOR_INDEX must be non empty for " + uri);
                }
                if (!values.containsKey(Colors.COLOR_TYPE) || !values.containsKey(Colors.COLOR)) {
                    throw new IllegalArgumentException(
                            "New colors must contain COLOR_TYPE and COLOR");
                }
                // Make sure the account we're inserting for is the same one the
                // adapter is claiming to be. TODO should we throw if they
                // aren't the same?
                values.put(Colors.ACCOUNT_NAME, accountName);
                values.put(Colors.ACCOUNT_TYPE, accountType);

                // Verify the color doesn't already exist
                Cursor c = null;
                try {
                    final long colorType = values.getAsLong(Colors.COLOR_TYPE);
                    c = getColorByTypeIndex(accountName, accountType, colorType, colorIndex);
                    if (c.getCount() != 0) {
                        throw new IllegalArgumentException("color type " + colorType
                                + " and index " + colorIndex
                                + " already exists for account and type provided");
                    }
                } finally {
                    if (c != null)
                        c.close();
                }
                id = mDbHelper.colorsInsert(values);
                break;
            case ATTENDEES: {
                if (!values.containsKey(Attendees.EVENT_ID)) {
                    throw new IllegalArgumentException("Attendees values must "
                            + "contain an event_id");
                }
                Long eventIdObj = values.getAsLong(Reminders.EVENT_ID);
                if (!doesEventExist(eventIdObj)) {
                    Log.i(TAG, "Trying to insert a attendee to a non-existent event");
                    return null;
                }
                if (!callerIsSyncAdapter) {
                    final Long eventId = values.getAsLong(Attendees.EVENT_ID);
                    mDbHelper.duplicateEvent(eventId);
                    setEventDirty(eventId);
                }
                id = mDbHelper.attendeesInsert(values);

                // Copy the attendee status value to the Events table.
                updateEventAttendeeStatus(mDb, values);
                break;
            }
            case REMINDERS: {
                Long eventIdObj = values.getAsLong(Reminders.EVENT_ID);
                if (eventIdObj == null) {
                    throw new IllegalArgumentException("Reminders values must "
                            + "contain a numeric event_id");
                }
                if (!doesEventExist(eventIdObj)) {
                    Log.i(TAG, "Trying to insert a reminder to a non-existent event");
                    return null;
                }

                if (!callerIsSyncAdapter) {
                    mDbHelper.duplicateEvent(eventIdObj);
                    setEventDirty(eventIdObj);
                }
                id = mDbHelper.remindersInsert(values);

                // We know this event has at least one reminder, so make sure "hasAlarm" is 1.
                setHasAlarm(eventIdObj, 1);

                // Schedule another event alarm, if necessary
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "insertInternal() changing reminder");
                }
                mCalendarAlarm.checkNextAlarm(false /* do not remove alarms */);
                break;
            }
            case CALENDAR_ALERTS: {
                Long eventIdObj = values.getAsLong(Reminders.EVENT_ID);
                if (eventIdObj == null) {
                    throw new IllegalArgumentException("CalendarAlerts values must "
                            + "contain a numeric event_id");
                }
                if (!doesEventExist(eventIdObj)) {
                    Log.i(TAG, "Trying to insert an alert to a non-existent event");
                    return null;
                }
                id = mDbHelper.calendarAlertsInsert(values);
                // Note: dirty bit is not set for Alerts because it is not synced.
                // It is generated from Reminders, which is synced.
                break;
            }
            case EXTENDED_PROPERTIES: {
                Long eventIdObj = values.getAsLong(Reminders.EVENT_ID);
                if (eventIdObj == null) {
                    throw new IllegalArgumentException("ExtendedProperties values must "
                            + "contain a numeric event_id");
                }
                if (!doesEventExist(eventIdObj)) {
                    Log.i(TAG, "Trying to insert extended properties to a non-existent event id = "
                            + eventIdObj);
                    return null;
                }
                if (!callerIsSyncAdapter) {
                    final Long eventId = values
                            .getAsLong(CalendarContract.ExtendedProperties.EVENT_ID);
                    mDbHelper.duplicateEvent(eventId);
                    setEventDirty(eventId);
                }
                id = mDbHelper.extendedPropertiesInsert(values);
                break;
            }
            case EMMA:
                // Special target used during code-coverage evaluation.
                handleEmmaRequest(values);
                break;
            case EVENTS_ID:
            case REMINDERS_ID:
            case CALENDAR_ALERTS_ID:
            case EXTENDED_PROPERTIES_ID:
            case INSTANCES:
            case INSTANCES_BY_DAY:
            case EVENT_DAYS:
            case PROVIDER_PROPERTIES:
                throw new UnsupportedOperationException("Cannot insert into that URL: " + uri);
            default:
                throw new IllegalArgumentException("Unknown URL " + uri);
        }

        if (id < 0) {
            return null;
        }
        return ContentUris.withAppendedId(uri, id);
    }

    private boolean doesEventExist(long eventId) {
        return DatabaseUtils.queryNumEntries(mDb, Tables.EVENTS, Events._ID + "=?",
                new String[]{String.valueOf(eventId)}) > 0;
    }

    /**
     * Handles special commands related to EMMA code-coverage testing.
     *
     * @param values Parameters from the caller.
     */
    private static void handleEmmaRequest(ContentValues values) {
        /*
         * This is not part of the public API, so we can't share constants with the CTS
         * test code.
         *
         * Bad requests, or attempting to request EMMA coverage data when the coverage libs
         * aren't linked in, will cause an exception.
         */
        String cmd = values.getAsString("cmd");
        if (cmd.equals("start")) {
            // We'd like to reset the coverage data, but according to FAQ item 3.14 at
            // http://emma.sourceforge.net/faq.html, this isn't possible in 2.0.
            Log.d(TAG, "Emma coverage testing started");
        } else if (cmd.equals("stop")) {
            // Call com.vladium.emma.rt.RT.dumpCoverageData() to cause a data dump.  We
            // may not have been built with EMMA, so we need to do this through reflection.
            String filename = values.getAsString("outputFileName");

            File coverageFile = new File(filename);
            try {
                Class<?> emmaRTClass = Class.forName("com.vladium.emma.rt.RT");
                Method dumpCoverageMethod = emmaRTClass.getMethod("dumpCoverageData",
                        coverageFile.getClass(), boolean.class, boolean.class);

                dumpCoverageMethod.invoke(null, coverageFile, false /*merge*/,
                        false /*stopDataCollection*/);
                Log.d(TAG, "Emma coverage data written to " + filename);
            } catch (Exception e) {
                throw new RuntimeException("Emma coverage dump failed", e);
            }
        }
    }

    /**
     * Validates the recurrence rule, if any.  We allow single- and multi-rule RRULEs.
     * <p>
     * TODO: Validate RDATE, EXRULE, EXDATE (possibly passing in an indication of whether we
     * believe we have the full set, so we can reject EXRULE when not accompanied by RRULE).
     *
     * @return A boolean indicating successful validation.
     */
    private boolean validateRecurrenceRule(ContentValues values) {
        String rrule = values.getAsString(Events.RRULE);

        if (!TextUtils.isEmpty(rrule)) {
            String[] ruleList = rrule.split("\n");
            for (String recur : ruleList) {
                EventRecurrence er = new EventRecurrence();
                try {
                    er.parse(recur);
                } catch (EventRecurrence.InvalidFormatException ife) {
                    Log.w(TAG, "Invalid recurrence rule: " + recur);
                    dumpEventNoPII(values);
                    return false;
                }
            }
        }

        return true;
    }

    private void dumpEventNoPII(ContentValues values) {
        if (values == null) {
            return;
        }

        StringBuilder bob = new StringBuilder();
        bob.append("dtStart:       ").append(values.getAsLong(Events.DTSTART));
        bob.append("\ndtEnd:         ").append(values.getAsLong(Events.DTEND));
        bob.append("\nall_day:       ").append(values.getAsInteger(Events.ALL_DAY));
        bob.append("\ntz:            ").append(values.getAsString(Events.EVENT_TIMEZONE));
        bob.append("\ndur:           ").append(values.getAsString(Events.DURATION));
        bob.append("\nrrule:         ").append(values.getAsString(Events.RRULE));
        bob.append("\nrdate:         ").append(values.getAsString(Events.RDATE));
        bob.append("\nlast_date:     ").append(values.getAsLong(Events.LAST_DATE));

        bob.append("\nid:            ").append(values.getAsLong(Events._ID));
        bob.append("\nsync_id:       ").append(values.getAsString(Events._SYNC_ID));
        bob.append("\nori_id:        ").append(values.getAsLong(Events.ORIGINAL_ID));
        bob.append("\nori_sync_id:   ").append(values.getAsString(Events.ORIGINAL_SYNC_ID));
        bob.append("\nori_inst_time: ").append(values.getAsLong(Events.ORIGINAL_INSTANCE_TIME));
        bob.append("\nori_all_day:   ").append(values.getAsInteger(Events.ORIGINAL_ALL_DAY));

        Log.i(TAG, bob.toString());
    }

    /**
     * Do some scrubbing on event data before inserting or updating. In particular make
     * dtend, duration, etc make sense for the type of event (regular, recurrence, exception).
     * Remove any unexpected fields.
     *
     * @param values the ContentValues to insert.
     * @param modValues if non-null, explicit null entries will be added here whenever something
     *   is removed from <strong>values</strong>.
     */
    private void scrubEventData(ContentValues values, ContentValues modValues) {
        boolean hasDtend = values.getAsLong(Events.DTEND) != null;
        boolean hasDuration = !TextUtils.isEmpty(values.getAsString(Events.DURATION));
        boolean hasRrule = !TextUtils.isEmpty(values.getAsString(Events.RRULE));
        boolean hasRdate = !TextUtils.isEmpty(values.getAsString(Events.RDATE));
        boolean hasOriginalEvent = !TextUtils.isEmpty(values.getAsString(Events.ORIGINAL_SYNC_ID));
        boolean hasOriginalInstanceTime = values.getAsLong(Events.ORIGINAL_INSTANCE_TIME) != null;
        if (hasRrule || hasRdate) {
            // Recurrence:
            // dtstart is start time of first event
            // dtend is null
            // duration is the duration of the event
            // rrule is a valid recurrence rule
            // lastDate is the end of the last event or null if it repeats forever
            // originalEvent is null
            // originalInstanceTime is null
            if (!validateRecurrenceRule(values)) {
                throw new IllegalArgumentException("Invalid recurrence rule: " +
                        values.getAsString(Events.RRULE));
            }
            if (hasDtend || !hasDuration || hasOriginalEvent || hasOriginalInstanceTime) {
                Log.d(TAG, "Scrubbing DTEND, ORIGINAL_SYNC_ID, ORIGINAL_INSTANCE_TIME");
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "Invalid values for recurrence: " + values);
                }
                values.remove(Events.DTEND);
                values.remove(Events.ORIGINAL_SYNC_ID);
                values.remove(Events.ORIGINAL_INSTANCE_TIME);
                if (modValues != null) {
                    modValues.putNull(Events.DTEND);
                    modValues.putNull(Events.ORIGINAL_SYNC_ID);
                    modValues.putNull(Events.ORIGINAL_INSTANCE_TIME);
                }
            }
        } else if (hasOriginalEvent || hasOriginalInstanceTime) {
            // Recurrence exception
            // dtstart is start time of exception event
            // dtend is end time of exception event
            // duration is null
            // rrule is null
            // lastdate is same as dtend
            // originalEvent is the _sync_id of the recurrence
            // originalInstanceTime is the start time of the event being replaced
            if (!hasDtend || hasDuration || !hasOriginalEvent || !hasOriginalInstanceTime) {
                Log.d(TAG, "Scrubbing DURATION");
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "Invalid values for recurrence exception: " + values);
                }
                values.remove(Events.DURATION);
                if (modValues != null) {
                    modValues.putNull(Events.DURATION);
                }
            }
        } else {
            // Regular event
            // dtstart is the start time
            // dtend is the end time
            // duration is null
            // rrule is null
            // lastDate is the same as dtend
            // originalEvent is null
            // originalInstanceTime is null
            if (!hasDtend || hasDuration) {
                Log.d(TAG, "Scrubbing DURATION");
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "Invalid values for event: " + values);
                }
                values.remove(Events.DURATION);
                if (modValues != null) {
                    modValues.putNull(Events.DURATION);
                }
            }
        }
    }

    /**
     * Validates event data.  Pass in the full set of values for the event (i.e. not just
     * a part that's being updated).
     *
     * @param values Event data.
     * @throws IllegalArgumentException if bad data is found.
     */
    private void validateEventData(ContentValues values) {
        if (TextUtils.isEmpty(values.getAsString(Events.CALENDAR_ID))) {
            throw new IllegalArgumentException("Event values must include a calendar_id");
        }
        if (TextUtils.isEmpty(values.getAsString(Events.EVENT_TIMEZONE))) {
            throw new IllegalArgumentException("Event values must include an eventTimezone");
        }

        boolean hasDtstart = values.getAsLong(Events.DTSTART) != null;
        boolean hasDtend = values.getAsLong(Events.DTEND) != null;
        boolean hasDuration = !TextUtils.isEmpty(values.getAsString(Events.DURATION));
        boolean hasRrule = !TextUtils.isEmpty(values.getAsString(Events.RRULE));
        boolean hasRdate = !TextUtils.isEmpty(values.getAsString(Events.RDATE));
        if (hasRrule || hasRdate) {
            if (!validateRecurrenceRule(values)) {
                throw new IllegalArgumentException("Invalid recurrence rule: " +
                        values.getAsString(Events.RRULE));
            }
        }

        if (!hasDtstart) {
            dumpEventNoPII(values);
            throw new IllegalArgumentException("DTSTART cannot be empty.");
        }
        if (!hasDuration && !hasDtend) {
            dumpEventNoPII(values);
            throw new IllegalArgumentException("DTEND and DURATION cannot both be null for " +
                    "an event.");
        }
        if (hasDuration && hasDtend) {
            dumpEventNoPII(values);
            throw new IllegalArgumentException("Cannot have both DTEND and DURATION in an event");
        }
    }

    private void setEventDirty(long eventId) {
        final String mutators = DatabaseUtils.stringForQuery(
                mDb,
                SQL_QUERY_EVENT_MUTATORS,
                new String[]{String.valueOf(eventId)});
        final String packageName = getCallingPackageName();
        final String newMutators;
        if (TextUtils.isEmpty(mutators)) {
            newMutators = packageName;
        } else  {
            final String[] strings = mutators.split(",");
            boolean found = false;
            for (String string : strings) {
                if (string.equals(packageName)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                newMutators = mutators + "," + packageName;
            } else {
                newMutators = mutators;
            }
        }
        mDb.execSQL(SQL_UPDATE_EVENT_SET_DIRTY_AND_MUTATORS,
                new Object[] {newMutators, eventId});
    }

    private long getOriginalId(String originalSyncId, String calendarId) {
        if (TextUtils.isEmpty(originalSyncId) || TextUtils.isEmpty(calendarId)) {
            return -1;
        }
        // Get the original id for this event
        long originalId = -1;
        Cursor c = null;
        try {
            c = query(Events.CONTENT_URI, ID_ONLY_PROJECTION,
                    Events._SYNC_ID + "=?"  + " AND " + Events.CALENDAR_ID + "=?",
                    new String[] {originalSyncId, calendarId}, null);
            if (c != null && c.moveToFirst()) {
                originalId = c.getLong(0);
            }
        } finally {
            if (c != null) {
                c.close();
            }
        }
        return originalId;
    }

    private String getOriginalSyncId(long originalId) {
        if (originalId == -1) {
            return null;
        }
        // Get the original id for this event
        String originalSyncId = null;
        Cursor c = null;
        try {
            c = query(Events.CONTENT_URI, new String[] {Events._SYNC_ID},
                    Events._ID + "=?", new String[] {Long.toString(originalId)}, null);
            if (c != null && c.moveToFirst()) {
                originalSyncId = c.getString(0);
            }
        } finally {
            if (c != null) {
                c.close();
            }
        }
        return originalSyncId;
    }

    private Cursor getColorByTypeIndex(String accountName, String accountType, long colorType,
            String colorIndex) {
        return mDb.query(Tables.COLORS, COLORS_PROJECTION, COLOR_FULL_SELECTION, new String[] {
                accountName, accountType, Long.toString(colorType), colorIndex
        }, null, null, null);
    }

    /**
     * Gets a calendar's "owner account", i.e. the e-mail address of the owner of the calendar.
     *
     * @param calId The calendar ID.
     * @return email of owner or null
     */
    private String getOwner(long calId) {
        if (calId < 0) {
            if (Log.isLoggable(TAG, Log.ERROR)) {
                Log.e(TAG, "Calendar Id is not valid: " + calId);
            }
            return null;
        }
        // Get the email address of this user from this Calendar
        String emailAddress = null;
        Cursor cursor = null;
        try {
            cursor = query(ContentUris.withAppendedId(Calendars.CONTENT_URI, calId),
                    new String[] { Calendars.OWNER_ACCOUNT },
                    null /* selection */,
                    null /* selectionArgs */,
                    null /* sort */);
            if (cursor == null || !cursor.moveToFirst()) {
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "Couldn't find " + calId + " in Calendars table");
                }
                return null;
            }
            emailAddress = cursor.getString(0);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return emailAddress;
    }

    private Account getAccount(long calId) {
        Account account = null;
        Cursor cursor = null;
        try {
            cursor = query(ContentUris.withAppendedId(Calendars.CONTENT_URI, calId),
                    ACCOUNT_PROJECTION, null /* selection */, null /* selectionArgs */,
                    null /* sort */);
            if (cursor == null || !cursor.moveToFirst()) {
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "Couldn't find " + calId + " in Calendars table");
                }
                return null;
            }
            account = new Account(cursor.getString(ACCOUNT_NAME_INDEX),
                    cursor.getString(ACCOUNT_TYPE_INDEX));
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return account;
    }

    /**
     * Creates an entry in the Attendees table that refers to the given event
     * and that has the given response status.
     *
     * @param eventId the event id that the new entry in the Attendees table
     * should refer to
     * @param status the response status
     * @param emailAddress the email of the attendee
     */
    private void createAttendeeEntry(long eventId, int status, String emailAddress) {
        ContentValues values = new ContentValues();
        values.put(Attendees.EVENT_ID, eventId);
        values.put(Attendees.ATTENDEE_STATUS, status);
        values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_NONE);
        // TODO: The relationship could actually be ORGANIZER, but it will get straightened out
        // on sync.
        values.put(Attendees.ATTENDEE_RELATIONSHIP,
                Attendees.RELATIONSHIP_ATTENDEE);
        values.put(Attendees.ATTENDEE_EMAIL, emailAddress);

        // We don't know the ATTENDEE_NAME but that will be filled in by the
        // server and sent back to us.
        mDbHelper.attendeesInsert(values);
    }

    /**
     * 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 eventIdObj = attendeeValues.getAsLong(Attendees.EVENT_ID);
        if (eventIdObj == null) {
            Log.w(TAG, "Attendee update values don't include an event_id");
            return;
        }
        long eventId = eventIdObj;

        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 || !cursor.moveToFirst()) {
                    if (Log.isLoggable(TAG, Log.DEBUG)) {
                        Log.d(TAG, "Couldn't find " + eventId + " in Events table");
                    }
                    return;
                }
                calId = cursor.getLong(0);
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }

            // Get the owner email for this Calendar
            String calendarEmail = null;
            cursor = null;
            try {
                cursor = query(ContentUris.withAppendedId(Calendars.CONTENT_URI, calId),
                        new String[] { Calendars.OWNER_ACCOUNT },
                        null /* selection */,
                        null /* selectionArgs */,
                        null /* sort */);
                if (cursor == null || !cursor.moveToFirst()) {
                    if (Log.isLoggable(TAG, Log.DEBUG)) {
                        Log.d(TAG, "Couldn't find " + calId + " in Calendars table");
                    }
                    return;
                }
                calendarEmail = cursor.getString(0);
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }

            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;
            }
        }

        // Select a default value for "status" based on the relationship.
        int status = Attendees.ATTENDEE_STATUS_NONE;
        Integer relationObj = attendeeValues.getAsInteger(Attendees.ATTENDEE_RELATIONSHIP);
        if (relationObj != null) {
            int rel = relationObj;
            if (rel == Attendees.RELATIONSHIP_ORGANIZER) {
                status = Attendees.ATTENDEE_STATUS_ACCEPTED;
            }
        }

        // If the status is specified, use that.
        Integer statusObj = attendeeValues.getAsInteger(Attendees.ATTENDEE_STATUS);
        if (statusObj != null) {
            status = statusObj;
        }

        ContentValues values = new ContentValues();
        values.put(Events.SELF_ATTENDEE_STATUS, status);
        db.update(Tables.EVENTS, values, SQL_WHERE_ID,
                new String[] {String.valueOf(eventId)});
    }

    /**
     * Set the "hasAlarm" column in the database.
     *
     * @param eventId The _id of the Event to update.
     * @param val The value to set it to (0 or 1).
     */
    private void setHasAlarm(long eventId, int val) {
        ContentValues values = new ContentValues();
        values.put(Events.HAS_ALARM, val);
        int count = mDb.update(Tables.EVENTS, values, SQL_WHERE_ID,
                new String[] { String.valueOf(eventId) });
        if (count != 1) {
            Log.w(TAG, "setHasAlarm on event " + eventId + " updated " + count +
                    " rows (expected 1)");
        }
    }

    /**
     * Calculates the "last date" of the event.  For a regular event this is the start time
     * plus the duration.  For a recurring event this is the start date of the last event in
     * the recurrence, plus the duration.  The event recurs forever, this returns -1.  If
     * the recurrence rule can't be parsed, this returns -1.
     *
     * @param values
     * @return the date, in milliseconds, since the start of the epoch (UTC), or -1 if an
     *   exceptional condition exists.
     * @throws DateException
     */
    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 = null;
            try {
                recur = new RecurrenceSet(values);
            } catch (EventRecurrence.InvalidFormatException e) {
                if (Log.isLoggable(TAG, Log.WARN)) {
                    Log.w(TAG, "Could not parse RRULE recurrence string: " +
                            values.get(CalendarContract.Events.RRULE), e);
                }
                // TODO: this should throw an exception or return a distinct error code
                return lastMillis; // -1
            }

            if (null != recur && 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) {
                    // repeats forever
                    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;
    }

    /**
     * Add LAST_DATE to values.
     * @param values the ContentValues (in/out); must include DTSTART and, if the event is
     *   recurring, the columns necessary to process a recurrence rule (RRULE, DURATION,
     *   EVENT_TIMEZONE, etc).
     * @return values on success, null on failure
     */
    private ContentValues updateLastDate(ContentValues values) {
        try {
            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
            if (Log.isLoggable(TAG, Log.WARN)) {
                Log.w(TAG, "Could not calculate last date.", e);
            }
            return null;
        }
    }

    /**
     * Creates or updates an entry in the EventsRawTimes table.
     *
     * @param eventId The ID of the event that was just created or is being updated.
     * @param values For a new event, the full set of event values; for an updated event,
     *   the set of values that are being changed.
     */
    private void updateEventRawTimesLocked(long eventId, ContentValues values) {
        ContentValues rawValues = new ContentValues();

        rawValues.put(CalendarContract.EventsRawTimes.EVENT_ID, eventId);

        String timezone = values.getAsString(Events.EVENT_TIMEZONE);

        boolean allDay = false;
        Integer allDayInteger = values.getAsInteger(Events.ALL_DAY);
        if (allDayInteger != null) {
            allDay = allDayInteger != 0;
        }

        if (allDay || TextUtils.isEmpty(timezone)) {
            // floating timezone
            timezone = Time.TIMEZONE_UTC;
        }

        Time time = new Time(timezone);
        time.allDay = allDay;
        Long dtstartMillis = values.getAsLong(Events.DTSTART);
        if (dtstartMillis != null) {
            time.set(dtstartMillis);
            rawValues.put(CalendarContract.EventsRawTimes.DTSTART_2445, time.format2445());
        }

        Long dtendMillis = values.getAsLong(Events.DTEND);
        if (dtendMillis != null) {
            time.set(dtendMillis);
            rawValues.put(CalendarContract.EventsRawTimes.DTEND_2445, time.format2445());
        }

        Long originalInstanceMillis = values.getAsLong(Events.ORIGINAL_INSTANCE_TIME);
        if (originalInstanceMillis != null) {
            // This is a recurrence exception so we need to get the all-day
            // status of the original recurring event in order to format the
            // date correctly.
            allDayInteger = values.getAsInteger(Events.ORIGINAL_ALL_DAY);
            if (allDayInteger != null) {
                time.allDay = allDayInteger != 0;
            }
            time.set(originalInstanceMillis);
            rawValues.put(CalendarContract.EventsRawTimes.ORIGINAL_INSTANCE_TIME_2445,
                    time.format2445());
        }

        Long lastDateMillis = values.getAsLong(Events.LAST_DATE);
        if (lastDateMillis != null) {
            time.allDay = allDay;
            time.set(lastDateMillis);
            rawValues.put(CalendarContract.EventsRawTimes.LAST_DATE_2445, time.format2445());
        }

        mDbHelper.eventsRawTimesReplace(rawValues);
    }

    @Override
    protected int deleteInTransaction(Uri uri, String selection, String[] selectionArgs,
            boolean callerIsSyncAdapter) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "deleteInTransaction: " + uri);
        }
        validateUriParameters(uri.getQueryParameterNames());
        final int match = sUriMatcher.match(uri);
        verifyTransactionAllowed(TRANSACTION_DELETE, uri, null, callerIsSyncAdapter, match,
                selection, selectionArgs);
        mDb = mDbHelper.getWritableDatabase();

        switch (match) {
            case SYNCSTATE:
                return mDbHelper.getSyncState().delete(mDb, selection, selectionArgs);

            case SYNCSTATE_ID:
                String selectionWithId = (SyncState._ID + "=?")
                        + (selection == null ? "" : " AND (" + selection + ")");
                // Prepend id to selectionArgs
                selectionArgs = insertSelectionArg(selectionArgs,
                        String.valueOf(ContentUris.parseId(uri)));
                return mDbHelper.getSyncState().delete(mDb, selectionWithId,
                        selectionArgs);

            case COLORS:
                return deleteMatchingColors(appendAccountToSelection(uri, selection,
                        Calendars.ACCOUNT_NAME, Calendars.ACCOUNT_TYPE),
                        selectionArgs);

            case EVENTS:
            {
                int result = 0;
                selection = appendAccountToSelection(
                        uri, selection, Events.ACCOUNT_NAME, Events.ACCOUNT_TYPE);

                // Query this event to get the ids to delete.
                Cursor cursor = mDb.query(Views.EVENTS, ID_ONLY_PROJECTION,
                        selection, selectionArgs, null /* groupBy */,
                        null /* having */, null /* sortOrder */);
                try {
                    while (cursor.moveToNext()) {
                        long id = cursor.getLong(0);
                        result += deleteEventInternal(id, callerIsSyncAdapter, true /* isBatch */);
                    }
                    mCalendarAlarm.checkNextAlarm(false /* do not remove alarms */);
                    sendUpdateNotification(callerIsSyncAdapter);
                } finally {
                    cursor.close();
                    cursor = null;
                }
                return result;
            }
            case EVENTS_ID:
            {
                long id = ContentUris.parseId(uri);
                return deleteEventInternal(id, callerIsSyncAdapter, false /* isBatch */);
            }
            case EXCEPTION_ID2:
            {
                // This will throw NumberFormatException on missing or malformed input.
                List<String> segments = uri.getPathSegments();
                long eventId = Long.parseLong(segments.get(1));
                long excepId = Long.parseLong(segments.get(2));
                // TODO: verify that this is an exception instance (has an ORIGINAL_ID field
                //       that matches the supplied eventId)
                return deleteEventInternal(excepId, callerIsSyncAdapter, false /* isBatch */);
            }
            case ATTENDEES:
            {
                if (callerIsSyncAdapter) {
                    return mDb.delete(Tables.ATTENDEES, selection, selectionArgs);
                } else {
                    return deleteFromEventRelatedTable(Tables.ATTENDEES, uri, selection,
                            selectionArgs);
                }
            }
            case ATTENDEES_ID:
            {
                if (callerIsSyncAdapter) {
                    long id = ContentUris.parseId(uri);
                    return mDb.delete(Tables.ATTENDEES, SQL_WHERE_ID,
                            new String[] {String.valueOf(id)});
                } else {
                    return deleteFromEventRelatedTable(Tables.ATTENDEES, uri, null /* selection */,
                                           null /* selectionArgs */);
                }
            }
            case REMINDERS:
            {
                return deleteReminders(uri, false, selection, selectionArgs, callerIsSyncAdapter);
            }
            case REMINDERS_ID:
            {
                return deleteReminders(uri, true, null /*selection*/, null /*selectionArgs*/,
                        callerIsSyncAdapter);
            }
            case EXTENDED_PROPERTIES:
            {
                if (callerIsSyncAdapter) {
                    return mDb.delete(Tables.EXTENDED_PROPERTIES, selection, selectionArgs);
                } else {
                    return deleteFromEventRelatedTable(Tables.EXTENDED_PROPERTIES, uri, selection,
                            selectionArgs);
                }
            }
            case EXTENDED_PROPERTIES_ID:
            {
                if (callerIsSyncAdapter) {
                    long id = ContentUris.parseId(uri);
                    return mDb.delete(Tables.EXTENDED_PROPERTIES, SQL_WHERE_ID,
                            new String[] {String.valueOf(id)});
                } else {
                    return deleteFromEventRelatedTable(Tables.EXTENDED_PROPERTIES, uri,
                            null /* selection */, null /* selectionArgs */);
                }
            }
            case CALENDAR_ALERTS:
            {
                if (callerIsSyncAdapter) {
                    return mDb.delete(Tables.CALENDAR_ALERTS, selection, selectionArgs);
                } else {
                    return deleteFromEventRelatedTable(Tables.CALENDAR_ALERTS, uri, selection,
                            selectionArgs);
                }
            }
            case CALENDAR_ALERTS_ID:
            {
                // Note: dirty bit is not set for Alerts because it is not synced.
                // It is generated from Reminders, which is synced.
                long id = ContentUris.parseId(uri);
                return mDb.delete(Tables.CALENDAR_ALERTS, SQL_WHERE_ID,
                        new String[] {String.valueOf(id)});
            }
            case CALENDARS_ID:
                StringBuilder selectionSb = new StringBuilder(Calendars._ID + "=");
                selectionSb.append(uri.getPathSegments().get(1));
                if (!TextUtils.isEmpty(selection)) {
                    selectionSb.append(" AND (");
                    selectionSb.append(selection);
                    selectionSb.append(')');
                }
                selection = selectionSb.toString();
                // $FALL-THROUGH$ - fall through to CALENDARS for the actual delete
            case CALENDARS:
                selection = appendAccountToSelection(uri, selection, Calendars.ACCOUNT_NAME,
                        Calendars.ACCOUNT_TYPE);
                return deleteMatchingCalendars(selection, selectionArgs);
            case INSTANCES:
            case INSTANCES_BY_DAY:
            case EVENT_DAYS:
            case PROVIDER_PROPERTIES:
                throw new UnsupportedOperationException("Cannot delete that URL");
            default:
                throw new IllegalArgumentException("Unknown URL " + uri);
        }
    }

    private int deleteEventInternal(long id, boolean callerIsSyncAdapter, boolean isBatch) {
        int result = 0;
        String selectionArgs[] = new String[] {String.valueOf(id)};

        // Query this event to get the fields needed for deleting.
        Cursor cursor = mDb.query(Tables.EVENTS, EVENTS_PROJECTION,
                SQL_WHERE_ID, selectionArgs,
                null /* groupBy */,
                null /* having */, null /* sortOrder */);
        try {
            if (cursor.moveToNext()) {
                result = 1;
                String syncId = cursor.getString(EVENTS_SYNC_ID_INDEX);
                boolean emptySyncId = TextUtils.isEmpty(syncId);

                // If this was a recurring event or a recurrence
                // exception, then force a recalculation of the
                // instances.
                String rrule = cursor.getString(EVENTS_RRULE_INDEX);
                String rdate = cursor.getString(EVENTS_RDATE_INDEX);
                String origId = cursor.getString(EVENTS_ORIGINAL_ID_INDEX);
                String origSyncId = cursor.getString(EVENTS_ORIGINAL_SYNC_ID_INDEX);
                if (isRecurrenceEvent(rrule, rdate, origId, origSyncId)) {
                    mMetaData.clearInstanceRange();
                }
                boolean isRecurrence = !TextUtils.isEmpty(rrule) || !TextUtils.isEmpty(rdate);

                // we clean the Events and Attendees table if the caller is CalendarSyncAdapter
                // or if the event is local (no syncId)
                //
                // The EVENTS_CLEANUP_TRIGGER_SQL trigger will remove all associated data
                // (Attendees, Instances, Reminders, etc).
                if (callerIsSyncAdapter || emptySyncId) {
                    mDb.delete(Tables.EVENTS, SQL_WHERE_ID, selectionArgs);

                    // If this is a recurrence, and the event was never synced with the server,
                    // we want to delete any exceptions as well.  (If it has been to the server,
                    // we'll let the sync adapter delete the events explicitly.)  We assume that,
                    // if the recurrence hasn't been synced, the exceptions haven't either.
                    if (isRecurrence && emptySyncId) {
                        mDb.delete(Tables.EVENTS, SQL_WHERE_ORIGINAL_ID, selectionArgs);
                    }
                } else {
                    // Event is on the server, so we "soft delete", i.e. mark as deleted so that
                    // the sync adapter has a chance to tell the server about the deletion.  After
                    // the server sees the change, the sync adapter will do the "hard delete"
                    // (above).
                    ContentValues values = new ContentValues();
                    values.put(Events.DELETED, 1);
                    values.put(Events.DIRTY, 1);
                    addMutator(values, Events.MUTATORS);
                    mDb.update(Tables.EVENTS, values, SQL_WHERE_ID, selectionArgs);

                    // Exceptions that have been synced shouldn't be deleted -- the sync
                    // adapter will take care of that -- but we want to "soft delete" them so
                    // that they will be removed from the instances list.
                    // TODO: this seems to confuse the sync adapter, and leaves you with an
                    //       invisible "ghost" event after the server sync.  Maybe we can fix
                    //       this by making instance generation smarter?  Not vital, since the
                    //       exception instances disappear after the server sync.
                    //mDb.update(Tables.EVENTS, values, SQL_WHERE_ORIGINAL_ID_HAS_SYNC_ID,
                    //        selectionArgs);

                    // It's possible for the original event to be on the server but have
                    // exceptions that aren't.  We want to remove all events with a matching
                    // original_id and an empty _sync_id.
                    mDb.delete(Tables.EVENTS, SQL_WHERE_ORIGINAL_ID_NO_SYNC_ID,
                            selectionArgs);

                    // Delete associated data; attendees, however, are deleted with the actual event
                    //  so that the sync adapter is able to notify attendees of the cancellation.
                    mDb.delete(Tables.INSTANCES, SQL_WHERE_EVENT_ID, selectionArgs);
                    mDb.delete(Tables.EVENTS_RAW_TIMES, SQL_WHERE_EVENT_ID, selectionArgs);
                    mDb.delete(Tables.REMINDERS, SQL_WHERE_EVENT_ID, selectionArgs);
                    mDb.delete(Tables.CALENDAR_ALERTS, SQL_WHERE_EVENT_ID, selectionArgs);
                    mDb.delete(Tables.EXTENDED_PROPERTIES, SQL_WHERE_EVENT_ID,
                            selectionArgs);
                }
            }
        } finally {
            cursor.close();
            cursor = null;
        }

        if (!isBatch) {
            mCalendarAlarm.checkNextAlarm(false /* do not remove alarms */);
            sendUpdateNotification(callerIsSyncAdapter);
        }
        return result;
    }

    /**
     * Delete rows from an Event-related table (e.g. Attendees) and mark corresponding events
     * as dirty.
     *
     * @param table The table to delete from
     * @param uri The URI specifying the rows
     * @param selection for the query
     * @param selectionArgs for the query
     */
    private int deleteFromEventRelatedTable(String table, Uri uri, String selection,
            String[] selectionArgs) {
        if (table.equals(Tables.EVENTS)) {
            throw new IllegalArgumentException("Don't delete Events with this method "
                    + "(use deleteEventInternal)");
        }

        ContentValues dirtyValues = new ContentValues();
        dirtyValues.put(Events.DIRTY, "1");
        addMutator(dirtyValues, Events.MUTATORS);

        /*
         * Re-issue the delete URI as a query.  Note that, if this is a by-ID request, the ID
         * will be in the URI, not selection/selectionArgs.
         *
         * Note that the query will return data according to the access restrictions,
         * so we don't need to worry about deleting data we don't have permission to read.
         */
        Cursor c = query(uri, ID_PROJECTION, selection, selectionArgs, GENERIC_EVENT_ID);
        int count = 0;
        try {
            long prevEventId = -1;
            while (c.moveToNext()) {
                long id = c.getLong(ID_INDEX);
                long eventId = c.getLong(EVENT_ID_INDEX);
                // Duplicate the event.  As a minor optimization, don't try to duplicate an
                // event that we just duplicated on the previous iteration.
                if (eventId != prevEventId) {
                    mDbHelper.duplicateEvent(eventId);
                }
                mDb.delete(table, SQL_WHERE_ID, new String[]{String.valueOf(id)});
                if (eventId != prevEventId) {
                    mDb.update(Tables.EVENTS, dirtyValues, SQL_WHERE_ID,
                            new String[] { String.valueOf(eventId)} );
                }
                prevEventId = eventId;
                count++;
            }
        } finally {
            c.close();
        }
        return count;
    }

    /**
     * Deletes rows from the Reminders table and marks the corresponding events as dirty.
     * Ensures the hasAlarm column in the Event is updated.
     *
     * @return The number of rows deleted.
     */
    private int deleteReminders(Uri uri, boolean byId, String selection, String[] selectionArgs,
            boolean callerIsSyncAdapter) {
        /*
         * If this is a by-ID URI, make sure we have a good ID.  Also, confirm that the
         * selection is null, since we will be ignoring it.
         */
        long rowId = -1;
        if (byId) {
            if (!TextUtils.isEmpty(selection)) {
                throw new UnsupportedOperationException("Selection not allowed for " + uri);
            }
            rowId = ContentUris.parseId(uri);
            if (rowId < 0) {
                throw new IllegalArgumentException("ID expected but not found in " + uri);
            }
        }

        /*
         * Determine the set of events affected by this operation.  There can be multiple
         * reminders with the same event_id, so to avoid beating up the database with "how many
         * reminders are left" and "duplicate this event" requests, we want to generate a list
         * of affected event IDs and work off that.
         *
         * TODO: use GROUP BY to reduce the number of rows returned in the cursor.  (The content
         * provider query() doesn't take it as an argument.)
         */
        HashSet<Long> eventIdSet = new HashSet<Long>();
        Cursor c = query(uri, new String[] { Attendees.EVENT_ID }, selection, selectionArgs, null);
        try {
            while (c.moveToNext()) {
                eventIdSet.add(c.getLong(0));
            }
        } finally {
            c.close();
        }

        /*
         * If this isn't a sync adapter, duplicate each event (along with its associated tables),
         * and mark each as "dirty".  This is for the benefit of partial-update sync.
         */
        if (!callerIsSyncAdapter) {
            ContentValues dirtyValues = new ContentValues();
            dirtyValues.put(Events.DIRTY, "1");
            addMutator(dirtyValues, Events.MUTATORS);

            Iterator<Long> iter = eventIdSet.iterator();
            while (iter.hasNext()) {
                long eventId = iter.next();
                mDbHelper.duplicateEvent(eventId);
                mDb.update(Tables.EVENTS, dirtyValues, SQL_WHERE_ID,
                        new String[] { String.valueOf(eventId) });
            }
        }

        /*
         * Issue the original deletion request.  If we were called with a by-ID URI, generate
         * a selection.
         */
        if (byId) {
            selection = SQL_WHERE_ID;
            selectionArgs = new String[] { String.valueOf(rowId) };
        }
        int delCount = mDb.delete(Tables.REMINDERS, selection, selectionArgs);

        /*
         * For each event, set "hasAlarm" to zero if we've deleted the last of the reminders.
         * (If the event still has reminders, hasAlarm should already be 1.)  Because we're
         * executing in an exclusive transaction there's no risk of racing against other
         * database updates.
         */
        ContentValues noAlarmValues = new ContentValues();
        noAlarmValues.put(Events.HAS_ALARM, 0);
        Iterator<Long> iter = eventIdSet.iterator();
        while (iter.hasNext()) {
            long eventId = iter.next();

            // Count up the number of reminders still associated with this event.
            Cursor reminders = mDb.query(Tables.REMINDERS, new String[] { GENERIC_ID },
                    SQL_WHERE_EVENT_ID, new String[] { String.valueOf(eventId) },
                    null, null, null);
            int reminderCount = reminders.getCount();
            reminders.close();

            if (reminderCount == 0) {
                mDb.update(Tables.EVENTS, noAlarmValues, SQL_WHERE_ID,
                        new String[] { String.valueOf(eventId) });
            }
        }

        return delCount;
    }

    /**
     * Update rows in a table and, if this is a non-sync-adapter update, mark the corresponding
     * events as dirty.
     * <p>
     * This only works for tables that are associated with an event.  It is assumed that the
     * link to the Event row is a numeric identifier in a column called "event_id".
     *
     * @param uri The original request URI.
     * @param byId Set to true if the URI is expected to include an ID.
     * @param updateValues The new values to apply.  Not all columns need be represented.
     * @param selection For non-by-ID operations, the "where" clause to use.
     * @param selectionArgs For non-by-ID operations, arguments to apply to the "where" clause.
     * @param callerIsSyncAdapter Set to true if the caller is a sync adapter.
     * @return The number of rows updated.
     */
    private int updateEventRelatedTable(Uri uri, String table, boolean byId,
            ContentValues updateValues, String selection, String[] selectionArgs,
            boolean callerIsSyncAdapter)
    {
        /*
         * Confirm that the request has either an ID or a selection, but not both.  It's not
         * actually "wrong" to have both, but it's not useful, and having neither is likely
         * a mistake.
         *
         * If they provided an ID in the URI, convert it to an ID selection.
         */
        if (byId) {
            if (!TextUtils.isEmpty(selection)) {
                throw new UnsupportedOperationException("Selection not allowed for " + uri);
            }
            long rowId = ContentUris.parseId(uri);
            if (rowId < 0) {
                throw new IllegalArgumentException("ID expected but not found in " + uri);
            }
            selection = SQL_WHERE_ID;
            selectionArgs = new String[] { String.valueOf(rowId) };
        } else {
            if (TextUtils.isEmpty(selection)) {
                throw new UnsupportedOperationException("Selection is required for " + uri);
            }
        }

        /*
         * Query the events to update.  We want all the columns from the table, so we us a
         * null projection.
         */
        Cursor c = mDb.query(table, null /*projection*/, selection, selectionArgs,
                null, null, null);
        int count = 0;
        try {
            if (c.getCount() == 0) {
                Log.d(TAG, "No query results for " + uri + ", selection=" + selection +
                        " selectionArgs=" + Arrays.toString(selectionArgs));
                return 0;
            }

            ContentValues dirtyValues = null;
            if (!callerIsSyncAdapter) {
                dirtyValues = new ContentValues();
                dirtyValues.put(Events.DIRTY, "1");
                addMutator(dirtyValues, Events.MUTATORS);
            }

            final int idIndex = c.getColumnIndex(GENERIC_ID);
            final int eventIdIndex = c.getColumnIndex(GENERIC_EVENT_ID);
            if (idIndex < 0 || eventIdIndex < 0) {
                throw new RuntimeException("Lookup on _id/event_id failed for " + uri);
            }

            /*
             * For each row found:
             * - merge original values with update values
             * - update database
             * - if not sync adapter, set "dirty" flag in corresponding event to 1
             * - update Event attendee status
             */
            while (c.moveToNext()) {
                /* copy the original values into a ContentValues, then merge the changes in */
                ContentValues values = new ContentValues();
                DatabaseUtils.cursorRowToContentValues(c, values);
                values.putAll(updateValues);

                long id = c.getLong(idIndex);
                long eventId = c.getLong(eventIdIndex);
                if (!callerIsSyncAdapter) {
                    // Make a copy of the original, so partial-update code can see diff.
                    mDbHelper.duplicateEvent(eventId);
                }
                mDb.update(table, values, SQL_WHERE_ID, new String[] { String.valueOf(id) });
                if (!callerIsSyncAdapter) {
                    mDb.update(Tables.EVENTS, dirtyValues, SQL_WHERE_ID,
                            new String[] { String.valueOf(eventId) });
                }
                count++;

                /*
                 * The Events table has a "selfAttendeeStatus" field that usually mirrors the
                 * "attendeeStatus" column of one row in the Attendees table.  It's the provider's
                 * job to keep these in sync, so we have to check for changes here.  (We have
                 * to do it way down here because this is the only point where we have the
                 * merged Attendees values.)
                 *
                 * It's possible, but not expected, to have multiple Attendees entries with
                 * matching attendeeEmail.  The behavior in this case is not defined.
                 *
                 * We could do this more efficiently for "bulk" updates by caching the Calendar
                 * owner email and checking it here.
                 */
                if (table.equals(Tables.ATTENDEES)) {
                    updateEventAttendeeStatus(mDb, values);
                    sendUpdateNotification(eventId, callerIsSyncAdapter);
                }
            }
        } finally {
            c.close();
        }
        return count;
    }

    private int deleteMatchingColors(String selection, String[] selectionArgs) {
        // query to find all the colors that match, for each
        // - verify no one references it
        // - delete color
        Cursor c = mDb.query(Tables.COLORS, COLORS_PROJECTION, selection, selectionArgs, null,
                null, null);
        if (c == null) {
            return 0;
        }
        try {
            Cursor c2 = null;
            while (c.moveToNext()) {
                String index = c.getString(COLORS_COLOR_INDEX_INDEX);
                String accountName = c.getString(COLORS_ACCOUNT_NAME_INDEX);
                String accountType = c.getString(COLORS_ACCOUNT_TYPE_INDEX);
                boolean isCalendarColor = c.getInt(COLORS_COLOR_TYPE_INDEX) == Colors.TYPE_CALENDAR;
                try {
                    if (isCalendarColor) {
                        c2 = mDb.query(Tables.CALENDARS, ID_ONLY_PROJECTION,
                                SQL_WHERE_CALENDAR_COLOR, new String[] {
                                        accountName, accountType, index
                                }, null, null, null);
                        if (c2.getCount() != 0) {
                            throw new UnsupportedOperationException("Cannot delete color " + index
                                    + ". Referenced by " + c2.getCount() + " calendars.");

                        }
                    } else {
                        c2 = query(Events.CONTENT_URI, ID_ONLY_PROJECTION, SQL_WHERE_EVENT_COLOR,
                                new String[] {accountName, accountType, index}, null);
                        if (c2.getCount() != 0) {
                            throw new UnsupportedOperationException("Cannot delete color " + index
                                    + ". Referenced by " + c2.getCount() + " events.");

                        }
                    }
                } finally {
                    if (c2 != null) {
                        c2.close();
                    }
                }
            }
        } finally {
            if (c != null) {
                c.close();
            }
        }
        return mDb.delete(Tables.COLORS, selection, selectionArgs);
    }

    private int deleteMatchingCalendars(String selection, String[] selectionArgs) {
        // query to find all the calendars that match, for each
        // - delete calendar subscription
        // - delete calendar
        Cursor c = mDb.query(Tables.CALENDARS, sCalendarsIdProjection, selection,
                selectionArgs,
                null /* groupBy */,
                null /* having */,
                null /* sortOrder */);
        if (c == null) {
            return 0;
        }
        try {
            while (c.moveToNext()) {
                long id = c.getLong(CALENDARS_INDEX_ID);
                modifyCalendarSubscription(id, false /* not selected */);
            }
        } finally {
            c.close();
        }
        return mDb.delete(Tables.CALENDARS, selection, selectionArgs);
    }

    private boolean doesEventExistForSyncId(String syncId) {
        if (syncId == null) {
            if (Log.isLoggable(TAG, Log.WARN)) {
                Log.w(TAG, "SyncID cannot be null: " + syncId);
            }
            return false;
        }
        long count = DatabaseUtils.longForQuery(mDb, SQL_SELECT_COUNT_FOR_SYNC_ID,
                new String[] { syncId });
        return (count > 0);
    }

    // Check if an UPDATE with STATUS_CANCEL means that we will need to do an Update (instead of
    // a Deletion)
    //
    // Deletion will be done only and only if:
    // - event status = canceled
    // - event is a recurrence exception that does not have its original (parent) event anymore
    //
    // This is due to the Server semantics that generate STATUS_CANCELED for both creation
    // and deletion of a recurrence exception
    // See bug #3218104
    private boolean doesStatusCancelUpdateMeanUpdate(ContentValues values,
            ContentValues modValues) {
        boolean isStatusCanceled = modValues.containsKey(Events.STATUS) &&
                (modValues.getAsInteger(Events.STATUS) == Events.STATUS_CANCELED);
        if (isStatusCanceled) {
            String originalSyncId = values.getAsString(Events.ORIGINAL_SYNC_ID);

            if (!TextUtils.isEmpty(originalSyncId)) {
                // This event is an exception.  See if the recurring event still exists.
                return doesEventExistForSyncId(originalSyncId);
            }
        }
        // This is the normal case, we just want an UPDATE
        return true;
    }

    private int handleUpdateColors(ContentValues values, String selection, String[] selectionArgs) {
        Cursor c = null;
        int result = mDb.update(Tables.COLORS, values, selection, selectionArgs);
        if (values.containsKey(Colors.COLOR)) {
            try {
                c = mDb.query(Tables.COLORS, COLORS_PROJECTION, selection, selectionArgs,
                        null /* groupBy */, null /* having */, null /* orderBy */);
                while (c.moveToNext()) {
                    boolean calendarColor =
                            c.getInt(COLORS_COLOR_TYPE_INDEX) == Colors.TYPE_CALENDAR;
                    int color = c.getInt(COLORS_COLOR_INDEX);
                    String[] args = {
                            c.getString(COLORS_ACCOUNT_NAME_INDEX),
                            c.getString(COLORS_ACCOUNT_TYPE_INDEX),
                            c.getString(COLORS_COLOR_INDEX_INDEX)
                    };
                    ContentValues colorValue = new ContentValues();
                    if (calendarColor) {
                        colorValue.put(Calendars.CALENDAR_COLOR, color);
                        mDb.update(Tables.CALENDARS, colorValue, SQL_WHERE_CALENDAR_COLOR, args);
                    } else {
                        colorValue.put(Events.EVENT_COLOR, color);
                        mDb.update(Tables.EVENTS, colorValue, SQL_WHERE_EVENT_COLOR, args);
                    }
                }
            } finally {
                if (c != null) {
                    c.close();
                }
            }
        }
        return result;
    }


    /**
     * Handles a request to update one or more events.
     * <p>
     * The original event(s) will be loaded from the database, merged with the new values,
     * and the result checked for validity.  In some cases this will alter the supplied
     * arguments (e.g. zeroing out the times on all-day events), change additional fields (e.g.
     * update LAST_DATE when DTSTART changes), or cause modifications to other tables (e.g. reset
     * Instances when a recurrence rule changes).
     *
     * @param cursor The set of events to update.
     * @param updateValues The changes to apply to each event.
     * @param callerIsSyncAdapter Indicates if the request comes from the sync adapter.
     * @return the number of rows updated
     */
    private int handleUpdateEvents(Cursor cursor, ContentValues updateValues,
            boolean callerIsSyncAdapter) {
        /*
         * This field is considered read-only.  It should not be modified by applications or
         * by the sync adapter.
         */
        updateValues.remove(Events.HAS_ALARM);

        /*
         * For a single event, we can just load the event, merge modValues in, perform any
         * fix-ups (putting changes into modValues), check validity, and then update().  We have
         * to be careful that our fix-ups don't confuse the sync adapter.
         *
         * For multiple events, we need to load, merge, and validate each event individually.
         * If no single-event-specific changes need to be made, we could just issue the original
         * bulk update, which would be more efficient than a series of individual updates.
         * However, doing so would prevent us from taking advantage of the partial-update
         * mechanism.
         */
        if (cursor.getCount() > 1) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Performing update on " + cursor.getCount() + " events");
            }
        }
        while (cursor.moveToNext()) {
            // Make a copy of updateValues so we can make some local changes.
            ContentValues modValues = new ContentValues(updateValues);

            // Load the event into a ContentValues object.
            ContentValues values = new ContentValues();
            DatabaseUtils.cursorRowToContentValues(cursor, values);
            boolean doValidate = false;
            if (!callerIsSyncAdapter) {
                try {
                    // Check to see if the data in the database is valid.  If not, we will skip
                    // validation of the update, so that we don't blow up on attempts to
                    // modify existing badly-formed events.
                    validateEventData(values);
                    doValidate = true;
                } catch (IllegalArgumentException iae) {
                    Log.d(TAG, "Event " + values.getAsString(Events._ID) +
                            " malformed, not validating update (" +
                            iae.getMessage() + ")");
                }
            }

            // Merge the modifications in.
            values.putAll(modValues);

            // If a color_index is being set make sure it's valid
            String color_id = modValues.getAsString(Events.EVENT_COLOR_KEY);
            if (!TextUtils.isEmpty(color_id)) {
                String accountName = null;
                String accountType = null;
                Cursor c = mDb.query(Tables.CALENDARS, ACCOUNT_PROJECTION, SQL_WHERE_ID,
                        new String[] { values.getAsString(Events.CALENDAR_ID) }, null, null, null);
                try {
                    if (c.moveToFirst()) {
                        accountName = c.getString(ACCOUNT_NAME_INDEX);
                        accountType = c.getString(ACCOUNT_TYPE_INDEX);
                    }
                } finally {
                    if (c != null) {
                        c.close();
                    }
                }
                verifyColorExists(accountName, accountType, color_id, Colors.TYPE_EVENT);
            }

            // Scrub and/or validate the combined event.
            if (callerIsSyncAdapter) {
                scrubEventData(values, modValues);
            }
            if (doValidate) {
                validateEventData(values);
            }

            // Look for any updates that could affect LAST_DATE.  It's defined as the end of
            // the last meeting, so we need to pay attention to DURATION.
            if (modValues.containsKey(Events.DTSTART) ||
                    modValues.containsKey(Events.DTEND) ||
                    modValues.containsKey(Events.DURATION) ||
                    modValues.containsKey(Events.EVENT_TIMEZONE) ||
                    modValues.containsKey(Events.RRULE) ||
                    modValues.containsKey(Events.RDATE) ||
                    modValues.containsKey(Events.EXRULE) ||
                    modValues.containsKey(Events.EXDATE)) {
                long newLastDate;
                try {
                    newLastDate = calculateLastDate(values);
                } catch (DateException de) {
                    throw new IllegalArgumentException("Unable to compute LAST_DATE", de);
                }
                Long oldLastDateObj = values.getAsLong(Events.LAST_DATE);
                long oldLastDate = (oldLastDateObj == null) ? -1 : oldLastDateObj;
                if (oldLastDate != newLastDate) {
                    // This overwrites any caller-supplied LAST_DATE.  This is okay, because the
                    // caller isn't supposed to be messing with the LAST_DATE field.
                    if (newLastDate < 0) {
                        modValues.putNull(Events.LAST_DATE);
                    } else {
                        modValues.put(Events.LAST_DATE, newLastDate);
                    }
                }
            }

            if (!callerIsSyncAdapter) {
                modValues.put(Events.DIRTY, 1);
                addMutator(modValues, Events.MUTATORS);
            }

            // 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 (modValues.containsKey(Events.SELF_ATTENDEE_STATUS)) {
                throw new IllegalArgumentException("Updating "
                        + Events.SELF_ATTENDEE_STATUS
                        + " in Events table is not allowed.");
            }

            if (fixAllDayTime(values, modValues)) {
                if (Log.isLoggable(TAG, Log.WARN)) {
                    Log.w(TAG, "handleUpdateEvents: " +
                            "allDay is true but sec, min, hour were not 0.");
                }
            }

            // For taking care about recurrences exceptions cancelations, check if this needs
            //  to be an UPDATE or a DELETE
            boolean isUpdate = doesStatusCancelUpdateMeanUpdate(values, modValues);

            long id = values.getAsLong(Events._ID);

            if (isUpdate) {
                // If a user made a change, possibly duplicate the event so we can do a partial
                // update. If a sync adapter made a change and that change marks an event as
                // un-dirty, remove any duplicates that may have been created earlier.
                if (!callerIsSyncAdapter) {
                    mDbHelper.duplicateEvent(id);
                } else {
                    if (modValues.containsKey(Events.DIRTY)
                            && modValues.getAsInteger(Events.DIRTY) == 0) {
                        modValues.put(Events.MUTATORS, (String) null);
                        mDbHelper.removeDuplicateEvent(id);
                    }
                }
                int result = mDb.update(Tables.EVENTS, modValues, SQL_WHERE_ID,
                        new String[] { String.valueOf(id) });
                if (result > 0) {
                    updateEventRawTimesLocked(id, modValues);
                    mInstancesHelper.updateInstancesLocked(modValues, id,
                            false /* not a new event */, mDb);

                    // XXX: should we also be doing this when RRULE changes (e.g. instances
                    //      are introduced or removed?)
                    if (modValues.containsKey(Events.DTSTART) ||
                            modValues.containsKey(Events.STATUS)) {
                        // If this is a cancellation knock it out
                        // of the instances table
                        if (modValues.containsKey(Events.STATUS) &&
                                modValues.getAsInteger(Events.STATUS) == Events.STATUS_CANCELED) {
                            String[] args = new String[] {String.valueOf(id)};
                            mDb.delete(Tables.INSTANCES, SQL_WHERE_EVENT_ID, args);
                        }

                        // The start time or status of the event changed, so run the
                        // event alarm scheduler.
                        if (Log.isLoggable(TAG, Log.DEBUG)) {
                            Log.d(TAG, "updateInternal() changing event");
                        }
                        mCalendarAlarm.checkNextAlarm(false /* do not remove alarms */);
                    }

                    sendUpdateNotification(id, callerIsSyncAdapter);
                }
            } else {
                deleteEventInternal(id, callerIsSyncAdapter, true /* isBatch */);
                mCalendarAlarm.checkNextAlarm(false /* do not remove alarms */);
                sendUpdateNotification(callerIsSyncAdapter);
            }
        }

        return cursor.getCount();
    }

    @Override
    protected int updateInTransaction(Uri uri, ContentValues values, String selection,
            String[] selectionArgs, boolean callerIsSyncAdapter) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "updateInTransaction: " + uri);
        }
        validateUriParameters(uri.getQueryParameterNames());
        final int match = sUriMatcher.match(uri);
        verifyTransactionAllowed(TRANSACTION_UPDATE, uri, values, callerIsSyncAdapter, match,
                selection, selectionArgs);
        mDb = mDbHelper.getWritableDatabase();

        switch (match) {
            case SYNCSTATE:
                return mDbHelper.getSyncState().update(mDb, values,
                        appendAccountToSelection(uri, selection, Calendars.ACCOUNT_NAME,
                                Calendars.ACCOUNT_TYPE), selectionArgs);

            case SYNCSTATE_ID: {
                selection = appendAccountToSelection(uri, selection, Calendars.ACCOUNT_NAME,
                        Calendars.ACCOUNT_TYPE);
                String selectionWithId = (SyncState._ID + "=?")
                        + (selection == null ? "" : " AND (" + selection + ")");
                // Prepend id to selectionArgs
                selectionArgs = insertSelectionArg(selectionArgs,
                        String.valueOf(ContentUris.parseId(uri)));
                return mDbHelper.getSyncState().update(mDb, values, selectionWithId, selectionArgs);
            }

            case COLORS:
                int validValues = 0;
                if (values.getAsInteger(Colors.COLOR) != null) {
                    validValues++;
                }
                if (values.getAsString(Colors.DATA) != null) {
                    validValues++;
                }

                if (values.size() != validValues) {
                    throw new UnsupportedOperationException("You may only change the COLOR and"
                            + " DATA columns for an existing Colors entry.");
                }
                return handleUpdateColors(values, appendAccountToSelection(uri, selection,
                        Calendars.ACCOUNT_NAME, Calendars.ACCOUNT_TYPE),
                        selectionArgs);

            case CALENDARS:
            case CALENDARS_ID:
            {
                long id;
                if (match == CALENDARS_ID) {
                    id = ContentUris.parseId(uri);
                } else {
                    // TODO: for supporting other sync adapters, we will need to
                    // be able to deal with the following cases:
                    // 1) selection to "_id=?" and pass in a selectionArgs
                    // 2) selection to "_id IN (1, 2, 3)"
                    // 3) selection to "delete=0 AND _id=1"
                    if (selection != null && TextUtils.equals(selection,"_id=?")) {
                        id = Long.parseLong(selectionArgs[0]);
                    } else if (selection != null && selection.startsWith("_id=")) {
                        // The ContentProviderOperation generates an _id=n string instead of
                        // adding the id to the URL, so parse that out here.
                        id = Long.parseLong(selection.substring(4));
                    } else {
                        return mDb.update(Tables.CALENDARS, values, selection, selectionArgs);
                    }
                }
                if (!callerIsSyncAdapter) {
                    values.put(Calendars.DIRTY, 1);
                    addMutator(values, Calendars.MUTATORS);
                } else {
                    if (values.containsKey(Calendars.DIRTY)
                            && values.getAsInteger(Calendars.DIRTY) == 0) {
                        values.put(Calendars.MUTATORS, (String) null);
                    }
                }
                Integer syncEvents = values.getAsInteger(Calendars.SYNC_EVENTS);
                if (syncEvents != null) {
                    modifyCalendarSubscription(id, syncEvents == 1);
                }
                String color_id = values.getAsString(Calendars.CALENDAR_COLOR_KEY);
                if (!TextUtils.isEmpty(color_id)) {
                    String accountName = values.getAsString(Calendars.ACCOUNT_NAME);
                    String accountType = values.getAsString(Calendars.ACCOUNT_TYPE);
                    if (TextUtils.isEmpty(accountName) || TextUtils.isEmpty(accountType)) {
                        Account account = getAccount(id);
                        if (account != null) {
                            accountName = account.name;
                            accountType = account.type;
                        }
                    }
                    verifyColorExists(accountName, accountType, color_id, Colors.TYPE_CALENDAR);
                }

                int result = mDb.update(Tables.CALENDARS, values, SQL_WHERE_ID,
                        new String[] {String.valueOf(id)});

                if (result > 0) {
                    // if visibility was toggled, we need to update alarms
                    if (values.containsKey(Calendars.VISIBLE)) {
                        // pass false for removeAlarms since the call to
                        // scheduleNextAlarmLocked will remove any alarms for
                        // non-visible events anyways. removeScheduledAlarmsLocked
                        // does not actually have the effect we want
                        mCalendarAlarm.checkNextAlarm(false);
                    }
                    // update the widget
                    sendUpdateNotification(callerIsSyncAdapter);
                }

                return result;
            }
            case EVENTS:
            case EVENTS_ID:
            {
                Cursor events = null;

                // Grab the full set of columns for each selected event.
                // TODO: define a projection with just the data we need (e.g. we don't need to
                //       validate the SYNC_* columns)

                try {
                    if (match == EVENTS_ID) {
                        // Single event, identified by ID.
                        long id = ContentUris.parseId(uri);
                        events = mDb.query(Tables.EVENTS, null /* columns */,
                                SQL_WHERE_ID, new String[] { String.valueOf(id) },
                                null /* groupBy */, null /* having */, null /* sortOrder */);
                    } else {
                        // One or more events, identified by the selection / selectionArgs.
                        events = mDb.query(Tables.EVENTS, null /* columns */,
                                selection, selectionArgs,
                                null /* groupBy */, null /* having */, null /* sortOrder */);
                    }

                    if (events.getCount() == 0) {
                        Log.i(TAG, "No events to update: uri=" + uri + " selection=" + selection +
                                " selectionArgs=" + Arrays.toString(selectionArgs));
                        return 0;
                    }

                    return handleUpdateEvents(events, values, callerIsSyncAdapter);
                } finally {
                    if (events != null) {
                        events.close();
                    }
                }
            }
            case ATTENDEES:
                return updateEventRelatedTable(uri, Tables.ATTENDEES, false, values, selection,
                        selectionArgs, callerIsSyncAdapter);
            case ATTENDEES_ID:
                return updateEventRelatedTable(uri, Tables.ATTENDEES, true, values, null, null,
                        callerIsSyncAdapter);

            case CALENDAR_ALERTS_ID: {
                // Note: dirty bit is not set for Alerts because it is not synced.
                // It is generated from Reminders, which is synced.
                long id = ContentUris.parseId(uri);
                return mDb.update(Tables.CALENDAR_ALERTS, values, SQL_WHERE_ID,
                        new String[] {String.valueOf(id)});
            }
            case CALENDAR_ALERTS: {
                // Note: dirty bit is not set for Alerts because it is not synced.
                // It is generated from Reminders, which is synced.
                return mDb.update(Tables.CALENDAR_ALERTS, values, selection, selectionArgs);
            }

            case REMINDERS:
                return updateEventRelatedTable(uri, Tables.REMINDERS, false, values, selection,
                        selectionArgs, callerIsSyncAdapter);
            case REMINDERS_ID: {
                int count = updateEventRelatedTable(uri, Tables.REMINDERS, true, values, null, null,
                        callerIsSyncAdapter);

                // Reschedule the event alarms because the
                // "minutes" field may have changed.
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "updateInternal() changing reminder");
                }
                mCalendarAlarm.checkNextAlarm(false /* do not remove alarms */);
                return count;
            }

            case EXTENDED_PROPERTIES_ID:
                return updateEventRelatedTable(uri, Tables.EXTENDED_PROPERTIES, true, values,
                        null, null, callerIsSyncAdapter);
            case SCHEDULE_ALARM_REMOVE: {
                mCalendarAlarm.checkNextAlarm(true);
                return 0;
            }

            case PROVIDER_PROPERTIES: {
                if (!selection.equals("key=?")) {
                    throw new UnsupportedOperationException("Selection should be key=? for " + uri);
                }

                List<String> list = Arrays.asList(selectionArgs);

                if (list.contains(CalendarCache.KEY_TIMEZONE_INSTANCES_PREVIOUS)) {
                    throw new UnsupportedOperationException("Invalid selection key: " +
                            CalendarCache.KEY_TIMEZONE_INSTANCES_PREVIOUS + " for " + uri);
                }

                // Before it may be changed, save current Instances timezone for later use
                String timezoneInstancesBeforeUpdate = mCalendarCache.readTimezoneInstances();

                // Update the database with the provided values (this call may change the value
                // of timezone Instances)
                int result = mDb.update(Tables.CALENDAR_CACHE, values, selection, selectionArgs);

                // if successful, do some house cleaning:
                // if the timezone type is set to "home", set the Instances
                // timezone to the previous
                // if the timezone type is set to "auto", set the Instances
                // timezone to the current
                // device one
                // if the timezone Instances is set AND if we are in "home"
                // timezone type, then save the timezone Instance into
                // "previous" too
                if (result > 0) {
                    // If we are changing timezone type...
                    if (list.contains(CalendarCache.KEY_TIMEZONE_TYPE)) {
                        String value = values.getAsString(CalendarCache.COLUMN_NAME_VALUE);
                        if (value != null) {
                            // if we are setting timezone type to "home"
                            if (value.equals(CalendarCache.TIMEZONE_TYPE_HOME)) {
                                String previousTimezone =
                                        mCalendarCache.readTimezoneInstancesPrevious();
                                if (previousTimezone != null) {
                                    mCalendarCache.writeTimezoneInstances(previousTimezone);
                                }
                                // Regenerate Instances if the "home" timezone has changed
                                // and notify widgets
                                if (!timezoneInstancesBeforeUpdate.equals(previousTimezone) ) {
                                    regenerateInstancesTable();
                                    sendUpdateNotification(callerIsSyncAdapter);
                                }
                            }
                            // if we are setting timezone type to "auto"
                            else if (value.equals(CalendarCache.TIMEZONE_TYPE_AUTO)) {
                                String localTimezone = TimeZone.getDefault().getID();
                                mCalendarCache.writeTimezoneInstances(localTimezone);
                                if (!timezoneInstancesBeforeUpdate.equals(localTimezone)) {
                                    regenerateInstancesTable();
                                    sendUpdateNotification(callerIsSyncAdapter);
                                }
                            }
                        }
                    }
                    // If we are changing timezone Instances...
                    else if (list.contains(CalendarCache.KEY_TIMEZONE_INSTANCES)) {
                        // if we are in "home" timezone type...
                        if (isHomeTimezone()) {
                            String timezoneInstances = mCalendarCache.readTimezoneInstances();
                            // Update the previous value
                            mCalendarCache.writeTimezoneInstancesPrevious(timezoneInstances);
                            // Recompute Instances if the "home" timezone has changed
                            // and send notifications to any widgets
                            if (timezoneInstancesBeforeUpdate != null &&
                                    !timezoneInstancesBeforeUpdate.equals(timezoneInstances)) {
                                regenerateInstancesTable();
                                sendUpdateNotification(callerIsSyncAdapter);
                            }
                        }
                    }
                }
                return result;
            }

            default:
                throw new IllegalArgumentException("Unknown URL " + uri);
        }
    }

    /**
     * Verifies that a color with the given index exists for the given Calendar
     * entry.
     *
     * @param accountName The email of the account the color is for
     * @param accountType The type of account the color is for
     * @param colorIndex The color_index being set for the calendar
     * @param colorType The type of color expected (Calendar/Event)
     * @return The color specified by the index
     */
    private int verifyColorExists(String accountName, String accountType, String colorIndex,
            int colorType) {
        if (TextUtils.isEmpty(accountName) || TextUtils.isEmpty(accountType)) {
            throw new IllegalArgumentException("Cannot set color. A valid account does"
                    + " not exist for this calendar.");
        }
        int color;
        Cursor c = null;
        try {
            c = getColorByTypeIndex(accountName, accountType, colorType, colorIndex);
            if (!c.moveToFirst()) {
                throw new IllegalArgumentException("Color type: " + colorType + " and index "
                        + colorIndex + " does not exist for account.");
            }
            color = c.getInt(COLORS_COLOR_INDEX);
        } finally {
            if (c != null) {
                c.close();
            }
        }
        return color;
    }

    private String appendLastSyncedColumnToSelection(String selection, Uri uri) {
        if (getIsCallerSyncAdapter(uri)) {
            return selection;
        }
        final StringBuilder sb = new StringBuilder();
        sb.append(CalendarContract.Events.LAST_SYNCED).append(" = 0");
        return appendSelection(sb, selection);
    }

    private String appendAccountToSelection(
            Uri uri,
            String selection,
            String accountNameColumn,
            String accountTypeColumn) {
        final String accountName = QueryParameterUtils.getQueryParameter(uri,
                CalendarContract.EventsEntity.ACCOUNT_NAME);
        final String accountType = QueryParameterUtils.getQueryParameter(uri,
                CalendarContract.EventsEntity.ACCOUNT_TYPE);
        if (!TextUtils.isEmpty(accountName)) {
            final StringBuilder sb = new StringBuilder()
                    .append(accountNameColumn)
                    .append("=")
                    .append(DatabaseUtils.sqlEscapeString(accountName))
                    .append(" AND ")
                    .append(accountTypeColumn)
                    .append("=")
                    .append(DatabaseUtils.sqlEscapeString(accountType));
            return appendSelection(sb, selection);
        } else {
            return selection;
        }
    }

    private String appendSelection(StringBuilder sb, String selection) {
        if (!TextUtils.isEmpty(selection)) {
            sb.append(" AND (");
            sb.append(selection);
            sb.append(')');
        }
        return sb.toString();
    }

    /**
     * Verifies that the operation is allowed and throws an exception if it
     * isn't. This defines the limits of a sync adapter call vs an app call.
     * <p>
     * Also rejects calls that have a selection but shouldn't, or that don't have a selection
     * but should.
     *
     * @param type The type of call, {@link #TRANSACTION_QUERY},
     *            {@link #TRANSACTION_INSERT}, {@link #TRANSACTION_UPDATE}, or
     *            {@link #TRANSACTION_DELETE}
     * @param uri
     * @param values
     * @param isSyncAdapter
     */
    private void verifyTransactionAllowed(int type, Uri uri, ContentValues values,
            boolean isSyncAdapter, int uriMatch, String selection, String[] selectionArgs) {
        // Queries are never restricted to app- or sync-adapter-only, and we don't
        // restrict the set of columns that may be accessed.
        if (type == TRANSACTION_QUERY) {
            return;
        }

        if (type == TRANSACTION_UPDATE || type == TRANSACTION_DELETE) {
            // TODO review this list, document in contract.
            if (!TextUtils.isEmpty(selection)) {
                // Only allow selections for the URIs that can reasonably use them.
                // Whitelist of URIs allowed selections
                switch (uriMatch) {
                    case SYNCSTATE:
                    case CALENDARS:
                    case EVENTS:
                    case ATTENDEES:
                    case CALENDAR_ALERTS:
                    case REMINDERS:
                    case EXTENDED_PROPERTIES:
                    case PROVIDER_PROPERTIES:
                    case COLORS:
                        break;
                    default:
                        throw new IllegalArgumentException("Selection not permitted for " + uri);
                }
            } else {
                // Disallow empty selections for some URIs.
                // Blacklist of URIs _not_ allowed empty selections
                switch (uriMatch) {
                    case EVENTS:
                    case ATTENDEES:
                    case REMINDERS:
                    case PROVIDER_PROPERTIES:
                        throw new IllegalArgumentException("Selection must be specified for "
                                + uri);
                    default:
                        break;
                }
            }
        }

        // Only the sync adapter can use these to make changes.
        if (!isSyncAdapter) {
            switch (uriMatch) {
                case SYNCSTATE:
                case SYNCSTATE_ID:
                case EXTENDED_PROPERTIES:
                case EXTENDED_PROPERTIES_ID:
                case COLORS:
                    throw new IllegalArgumentException("Only sync adapters may write using " + uri);
                default:
                    break;
            }
        }

        switch (type) {
            case TRANSACTION_INSERT:
                if (uriMatch == INSTANCES) {
                    throw new UnsupportedOperationException(
                            "Inserting into instances not supported");
                }
                // Check there are no columns restricted to the provider
                verifyColumns(values, uriMatch);
                if (isSyncAdapter) {
                    // check that account and account type are specified
                    verifyHasAccount(uri, selection, selectionArgs);
                } else {
                    // check that sync only columns aren't included
                    verifyNoSyncColumns(values, uriMatch);
                }
                return;
            case TRANSACTION_UPDATE:
                if (uriMatch == INSTANCES) {
                    throw new UnsupportedOperationException("Updating instances not supported");
                }
                // Check there are no columns restricted to the provider
                verifyColumns(values, uriMatch);
                if (isSyncAdapter) {
                    // check that account and account type are specified
                    verifyHasAccount(uri, selection, selectionArgs);
                } else {
                    // check that sync only columns aren't included
                    verifyNoSyncColumns(values, uriMatch);
                }
                return;
            case TRANSACTION_DELETE:
                if (uriMatch == INSTANCES) {
                    throw new UnsupportedOperationException("Deleting instances not supported");
                }
                if (isSyncAdapter) {
                    // check that account and account type are specified
                    verifyHasAccount(uri, selection, selectionArgs);
                }
                return;
        }
    }

    private void verifyHasAccount(Uri uri, String selection, String[] selectionArgs) {
        String accountName = QueryParameterUtils.getQueryParameter(uri, Calendars.ACCOUNT_NAME);
        String accountType = QueryParameterUtils.getQueryParameter(uri,
                Calendars.ACCOUNT_TYPE);
        if (TextUtils.isEmpty(accountName) || TextUtils.isEmpty(accountType)) {
            if (selection != null && selection.startsWith(ACCOUNT_SELECTION_PREFIX)) {
                accountName = selectionArgs[0];
                accountType = selectionArgs[1];
            }
        }
        if (TextUtils.isEmpty(accountName) || TextUtils.isEmpty(accountType)) {
            throw new IllegalArgumentException(
                    "Sync adapters must specify an account and account type: " + uri);
        }
    }

    private void verifyColumns(ContentValues values, int uriMatch) {
        if (values == null || values.size() == 0) {
            return;
        }
        String[] columns;
        switch (uriMatch) {
            case EVENTS:
            case EVENTS_ID:
            case EVENT_ENTITIES:
            case EVENT_ENTITIES_ID:
                columns = Events.PROVIDER_WRITABLE_COLUMNS;
                break;
            default:
                columns = PROVIDER_WRITABLE_DEFAULT_COLUMNS;
                break;
        }

        for (int i = 0; i < columns.length; i++) {
            if (values.containsKey(columns[i])) {
                throw new IllegalArgumentException("Only the provider may write to " + columns[i]);
            }
        }
    }

    private void verifyNoSyncColumns(ContentValues values, int uriMatch) {
        if (values == null || values.size() == 0) {
            return;
        }
        String[] syncColumns;
        switch (uriMatch) {
            case CALENDARS:
            case CALENDARS_ID:
            case CALENDAR_ENTITIES:
            case CALENDAR_ENTITIES_ID:
                syncColumns = Calendars.SYNC_WRITABLE_COLUMNS;
                break;
            case EVENTS:
            case EVENTS_ID:
            case EVENT_ENTITIES:
            case EVENT_ENTITIES_ID:
                syncColumns = Events.SYNC_WRITABLE_COLUMNS;
                break;
            default:
                syncColumns = SYNC_WRITABLE_DEFAULT_COLUMNS;
                break;

        }
        for (int i = 0; i < syncColumns.length; i++) {
            if (values.containsKey(syncColumns[i])) {
                throw new IllegalArgumentException("Only sync adapters may write to "
                        + syncColumns[i]);
            }
        }
    }

    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.ACCOUNT_NAME, Calendars.ACCOUNT_TYPE,
                        Calendars.CAL_SYNC1, Calendars.SYNC_EVENTS},
                null /* selection */,
                null /* selectionArgs */,
                null /* sort */);

        Account account = null;
        String calendarUrl = null;
        boolean oldSyncEvents = false;
        if (cursor != null) {
            try {
                if (cursor.moveToFirst()) {
                    final String accountName = cursor.getString(0);
                    final String accountType = cursor.getString(1);
                    account = new Account(accountName, accountType);
                    calendarUrl = cursor.getString(2);
                    oldSyncEvents = (cursor.getInt(3) != 0);
                }
            } finally {
                if (cursor != null)
                    cursor.close();
            }
        }

        if (account == null) {
            // should not happen?
            if (Log.isLoggable(TAG, Log.WARN)) {
                Log.w(TAG, "Cannot update subscription because account "
                        + "is empty -- should not happen.");
            }
            return;
        }

        if (TextUtils.isEmpty(calendarUrl)) {
            // Passing in a null Url will cause it to not add any extras
            // Should only happen for non-google calendars.
            calendarUrl = null;
        }

        if (oldSyncEvents == syncEvents) {
            // nothing to do
            return;
        }

        // If the calendar is not selected for syncing, then don't download
        // events.
        mDbHelper.scheduleSync(account, !syncEvents, calendarUrl);
    }

    /**
     * Call this to trigger a broadcast of the ACTION_PROVIDER_CHANGED intent.
     * This also provides a timeout, so any calls to this method will be batched
     * over a period of BROADCAST_TIMEOUT_MILLIS defined in this class.
     *
     * @param callerIsSyncAdapter whether or not the update is being triggered by a sync
     */
    private void sendUpdateNotification(boolean callerIsSyncAdapter) {
        // We use -1 to represent an update to all events
        sendUpdateNotification(-1, callerIsSyncAdapter);
    }

    /**
     * Call this to trigger a broadcast of the ACTION_PROVIDER_CHANGED intent.
     * This also provides a timeout, so any calls to this method will be batched
     * over a period of BROADCAST_TIMEOUT_MILLIS defined in this class.  The
     * actual sending of the intent is done in
     * {@link #doSendUpdateNotification()}.
     *
     * TODO add support for eventId
     *
     * @param eventId the ID of the event that changed, or -1 for no specific event
     * @param callerIsSyncAdapter whether or not the update is being triggered by a sync
     */
    private void sendUpdateNotification(long eventId,
            boolean callerIsSyncAdapter) {
        // Are there any pending broadcast requests?
        if (mBroadcastHandler.hasMessages(UPDATE_BROADCAST_MSG)) {
            // Delete any pending requests, before requeuing a fresh one
            mBroadcastHandler.removeMessages(UPDATE_BROADCAST_MSG);
        } else {
            // Because the handler does not guarantee message delivery in
            // the case that the provider is killed, we need to make sure
            // that the provider stays alive long enough to deliver the
            // notification. This empty service is sufficient to "wedge" the
            // process until we stop it here.
            mContext.startService(new Intent(mContext, EmptyService.class));
        }
        // We use a much longer delay for sync-related updates, to prevent any
        // receivers from slowing down the sync
        long delay = callerIsSyncAdapter ?
                SYNC_UPDATE_BROADCAST_TIMEOUT_MILLIS :
                UPDATE_BROADCAST_TIMEOUT_MILLIS;
        // Despite the fact that we actually only ever use one message at a time
        // for now, it is really important to call obtainMessage() to get a
        // clean instance.  This avoids potentially infinite loops resulting
        // adding the same instance to the message queue twice, since the
        // message queue implements its linked list using a field from Message.
        Message msg = mBroadcastHandler.obtainMessage(UPDATE_BROADCAST_MSG);
        mBroadcastHandler.sendMessageDelayed(msg, delay);
    }

    /**
     * This method should not ever be called directly, to prevent sending too
     * many potentially expensive broadcasts.  Instead, call
     * {@link #sendUpdateNotification(boolean)} instead.
     *
     * @see #sendUpdateNotification(boolean)
     */
    private void doSendUpdateNotification() {
        Intent intent = new Intent(Intent.ACTION_PROVIDER_CHANGED,
                CalendarContract.CONTENT_URI);
        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
        if (Log.isLoggable(TAG, Log.INFO)) {
            Log.i(TAG, "Sending notification intent: " + intent);
        }
        mContext.sendBroadcast(intent, null);
    }

    private static final int TRANSACTION_QUERY = 0;
    private static final int TRANSACTION_INSERT = 1;
    private static final int TRANSACTION_UPDATE = 2;
    private static final int TRANSACTION_DELETE = 3;

    // @formatter:off
    private static final String[] SYNC_WRITABLE_DEFAULT_COLUMNS = new String[] {
        CalendarContract.Calendars.DIRTY,
        CalendarContract.Calendars._SYNC_ID
    };
    private static final String[] PROVIDER_WRITABLE_DEFAULT_COLUMNS = new String[] {
    };
    // @formatter:on

    private static final int EVENTS = 1;
    private static final int EVENTS_ID = 2;
    private static final int INSTANCES = 3;
    private static final int CALENDARS = 4;
    private static final int CALENDARS_ID = 5;
    private static final int ATTENDEES = 6;
    private static final int ATTENDEES_ID = 7;
    private static final int REMINDERS = 8;
    private static final int REMINDERS_ID = 9;
    private static final int EXTENDED_PROPERTIES = 10;
    private static final int EXTENDED_PROPERTIES_ID = 11;
    private static final int CALENDAR_ALERTS = 12;
    private static final int CALENDAR_ALERTS_ID = 13;
    private static final int CALENDAR_ALERTS_BY_INSTANCE = 14;
    private static final int INSTANCES_BY_DAY = 15;
    private static final int SYNCSTATE = 16;
    private static final int SYNCSTATE_ID = 17;
    private static final int EVENT_ENTITIES = 18;
    private static final int EVENT_ENTITIES_ID = 19;
    private static final int EVENT_DAYS = 20;
    private static final int SCHEDULE_ALARM_REMOVE = 22;
    private static final int TIME = 23;
    private static final int CALENDAR_ENTITIES = 24;
    private static final int CALENDAR_ENTITIES_ID = 25;
    private static final int INSTANCES_SEARCH = 26;
    private static final int INSTANCES_SEARCH_BY_DAY = 27;
    private static final int PROVIDER_PROPERTIES = 28;
    private static final int EXCEPTION_ID = 29;
    private static final int EXCEPTION_ID2 = 30;
    private static final int EMMA = 31;
    private static final int COLORS = 32;

    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    private static final HashMap<String, String> sInstancesProjectionMap;
    private static final HashMap<String, String> sColorsProjectionMap;
    protected static final HashMap<String, String> sCalendarsProjectionMap;
    protected static final HashMap<String, String> sEventsProjectionMap;
    private static final HashMap<String, String> sEventEntitiesProjectionMap;
    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> sCalendarCacheProjectionMap;
    private static final HashMap<String, String> sCountProjectionMap;

    static {
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "instances/when/*/*", INSTANCES);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "instances/whenbyday/*/*", INSTANCES_BY_DAY);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "instances/search/*/*/*", INSTANCES_SEARCH);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "instances/searchbyday/*/*/*",
                INSTANCES_SEARCH_BY_DAY);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "instances/groupbyday/*/*", EVENT_DAYS);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "events", EVENTS);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "events/#", EVENTS_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "event_entities", EVENT_ENTITIES);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "event_entities/#", EVENT_ENTITIES_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "calendars", CALENDARS);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "calendars/#", CALENDARS_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "calendar_entities", CALENDAR_ENTITIES);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "calendar_entities/#", CALENDAR_ENTITIES_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "attendees", ATTENDEES);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "attendees/#", ATTENDEES_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "reminders", REMINDERS);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "reminders/#", REMINDERS_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "extendedproperties", EXTENDED_PROPERTIES);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "extendedproperties/#",
                EXTENDED_PROPERTIES_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "calendar_alerts", CALENDAR_ALERTS);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "calendar_alerts/#", CALENDAR_ALERTS_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "calendar_alerts/by_instance",
                           CALENDAR_ALERTS_BY_INSTANCE);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "syncstate", SYNCSTATE);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "syncstate/#", SYNCSTATE_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY,
                CalendarAlarmManager.SCHEDULE_ALARM_REMOVE_PATH, SCHEDULE_ALARM_REMOVE);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "time/#", TIME);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "time", TIME);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "properties", PROVIDER_PROPERTIES);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "exception/#", EXCEPTION_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "exception/#/#", EXCEPTION_ID2);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "emma", EMMA);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "colors", COLORS);

        /** Contains just BaseColumns._COUNT */
        sCountProjectionMap = new HashMap<String, String>();
        sCountProjectionMap.put(BaseColumns._COUNT, "COUNT(*) AS " + BaseColumns._COUNT);

        sColorsProjectionMap = new HashMap<String, String>();
        sColorsProjectionMap.put(Colors._ID, Colors._ID);
        sColorsProjectionMap.put(Colors.DATA, Colors.DATA);
        sColorsProjectionMap.put(Colors.ACCOUNT_NAME, Colors.ACCOUNT_NAME);
        sColorsProjectionMap.put(Colors.ACCOUNT_TYPE, Colors.ACCOUNT_TYPE);
        sColorsProjectionMap.put(Colors.COLOR_KEY, Colors.COLOR_KEY);
        sColorsProjectionMap.put(Colors.COLOR_TYPE, Colors.COLOR_TYPE);
        sColorsProjectionMap.put(Colors.COLOR, Colors.COLOR);

        sCalendarsProjectionMap = new HashMap<String, String>();
        sCalendarsProjectionMap.put(Calendars._ID, Calendars._ID);
        sCalendarsProjectionMap.put(Calendars.ACCOUNT_NAME, Calendars.ACCOUNT_NAME);
        sCalendarsProjectionMap.put(Calendars.ACCOUNT_TYPE, Calendars.ACCOUNT_TYPE);
        sCalendarsProjectionMap.put(Calendars._SYNC_ID, Calendars._SYNC_ID);
        sCalendarsProjectionMap.put(Calendars.DIRTY, Calendars.DIRTY);
        sCalendarsProjectionMap.put(Calendars.MUTATORS, Calendars.MUTATORS);
        sCalendarsProjectionMap.put(Calendars.NAME, Calendars.NAME);
        sCalendarsProjectionMap.put(
                Calendars.CALENDAR_DISPLAY_NAME, Calendars.CALENDAR_DISPLAY_NAME);
        sCalendarsProjectionMap.put(Calendars.CALENDAR_COLOR, Calendars.CALENDAR_COLOR);
        sCalendarsProjectionMap.put(Calendars.CALENDAR_COLOR_KEY, Calendars.CALENDAR_COLOR_KEY);
        sCalendarsProjectionMap.put(Calendars.CALENDAR_ACCESS_LEVEL,
                Calendars.CALENDAR_ACCESS_LEVEL);
        sCalendarsProjectionMap.put(Calendars.VISIBLE, Calendars.VISIBLE);
        sCalendarsProjectionMap.put(Calendars.SYNC_EVENTS, Calendars.SYNC_EVENTS);
        sCalendarsProjectionMap.put(Calendars.CALENDAR_LOCATION, Calendars.CALENDAR_LOCATION);
        sCalendarsProjectionMap.put(Calendars.CALENDAR_TIME_ZONE, Calendars.CALENDAR_TIME_ZONE);
        sCalendarsProjectionMap.put(Calendars.OWNER_ACCOUNT, Calendars.OWNER_ACCOUNT);
        sCalendarsProjectionMap.put(Calendars.IS_PRIMARY,
                "COALESCE(" + Events.IS_PRIMARY + ", "
                        + Calendars.OWNER_ACCOUNT + " = " + Calendars.ACCOUNT_NAME + ") AS "
                        + Calendars.IS_PRIMARY);
        sCalendarsProjectionMap.put(Calendars.CAN_ORGANIZER_RESPOND,
                Calendars.CAN_ORGANIZER_RESPOND);
        sCalendarsProjectionMap.put(Calendars.CAN_MODIFY_TIME_ZONE, Calendars.CAN_MODIFY_TIME_ZONE);
        sCalendarsProjectionMap.put(Calendars.CAN_PARTIALLY_UPDATE, Calendars.CAN_PARTIALLY_UPDATE);
        sCalendarsProjectionMap.put(Calendars.MAX_REMINDERS, Calendars.MAX_REMINDERS);
        sCalendarsProjectionMap.put(Calendars.ALLOWED_REMINDERS, Calendars.ALLOWED_REMINDERS);
        sCalendarsProjectionMap.put(Calendars.ALLOWED_AVAILABILITY, Calendars.ALLOWED_AVAILABILITY);
        sCalendarsProjectionMap.put(Calendars.ALLOWED_ATTENDEE_TYPES,
                Calendars.ALLOWED_ATTENDEE_TYPES);
        sCalendarsProjectionMap.put(Calendars.DELETED, Calendars.DELETED);
        sCalendarsProjectionMap.put(Calendars.CAL_SYNC1, Calendars.CAL_SYNC1);
        sCalendarsProjectionMap.put(Calendars.CAL_SYNC2, Calendars.CAL_SYNC2);
        sCalendarsProjectionMap.put(Calendars.CAL_SYNC3, Calendars.CAL_SYNC3);
        sCalendarsProjectionMap.put(Calendars.CAL_SYNC4, Calendars.CAL_SYNC4);
        sCalendarsProjectionMap.put(Calendars.CAL_SYNC5, Calendars.CAL_SYNC5);
        sCalendarsProjectionMap.put(Calendars.CAL_SYNC6, Calendars.CAL_SYNC6);
        sCalendarsProjectionMap.put(Calendars.CAL_SYNC7, Calendars.CAL_SYNC7);
        sCalendarsProjectionMap.put(Calendars.CAL_SYNC8, Calendars.CAL_SYNC8);
        sCalendarsProjectionMap.put(Calendars.CAL_SYNC9, Calendars.CAL_SYNC9);
        sCalendarsProjectionMap.put(Calendars.CAL_SYNC10, Calendars.CAL_SYNC10);

        sEventsProjectionMap = new HashMap<String, String>();
        // Events columns
        sEventsProjectionMap.put(Events.ACCOUNT_NAME, Events.ACCOUNT_NAME);
        sEventsProjectionMap.put(Events.ACCOUNT_TYPE, Events.ACCOUNT_TYPE);
        sEventsProjectionMap.put(Events.TITLE, Events.TITLE);
        sEventsProjectionMap.put(Events.EVENT_LOCATION, Events.EVENT_LOCATION);
        sEventsProjectionMap.put(Events.DESCRIPTION, Events.DESCRIPTION);
        sEventsProjectionMap.put(Events.STATUS, Events.STATUS);
        sEventsProjectionMap.put(Events.EVENT_COLOR, Events.EVENT_COLOR);
        sEventsProjectionMap.put(Events.EVENT_COLOR_KEY, Events.EVENT_COLOR_KEY);
        sEventsProjectionMap.put(Events.SELF_ATTENDEE_STATUS, Events.SELF_ATTENDEE_STATUS);
        sEventsProjectionMap.put(Events.DTSTART, Events.DTSTART);
        sEventsProjectionMap.put(Events.DTEND, Events.DTEND);
        sEventsProjectionMap.put(Events.EVENT_TIMEZONE, Events.EVENT_TIMEZONE);
        sEventsProjectionMap.put(Events.EVENT_END_TIMEZONE, Events.EVENT_END_TIMEZONE);
        sEventsProjectionMap.put(Events.DURATION, Events.DURATION);
        sEventsProjectionMap.put(Events.ALL_DAY, Events.ALL_DAY);
        sEventsProjectionMap.put(Events.ACCESS_LEVEL, Events.ACCESS_LEVEL);
        sEventsProjectionMap.put(Events.AVAILABILITY, Events.AVAILABILITY);
        sEventsProjectionMap.put(Events.HAS_ALARM, Events.HAS_ALARM);
        sEventsProjectionMap.put(Events.HAS_EXTENDED_PROPERTIES, Events.HAS_EXTENDED_PROPERTIES);
        sEventsProjectionMap.put(Events.RRULE, Events.RRULE);
        sEventsProjectionMap.put(Events.RDATE, Events.RDATE);
        sEventsProjectionMap.put(Events.EXRULE, Events.EXRULE);
        sEventsProjectionMap.put(Events.EXDATE, Events.EXDATE);
        sEventsProjectionMap.put(Events.ORIGINAL_SYNC_ID, Events.ORIGINAL_SYNC_ID);
        sEventsProjectionMap.put(Events.ORIGINAL_ID, Events.ORIGINAL_ID);
        sEventsProjectionMap.put(Events.ORIGINAL_INSTANCE_TIME, Events.ORIGINAL_INSTANCE_TIME);
        sEventsProjectionMap.put(Events.ORIGINAL_ALL_DAY, Events.ORIGINAL_ALL_DAY);
        sEventsProjectionMap.put(Events.LAST_DATE, Events.LAST_DATE);
        sEventsProjectionMap.put(Events.HAS_ATTENDEE_DATA, Events.HAS_ATTENDEE_DATA);
        sEventsProjectionMap.put(Events.CALENDAR_ID, Events.CALENDAR_ID);
        sEventsProjectionMap.put(Events.GUESTS_CAN_INVITE_OTHERS, Events.GUESTS_CAN_INVITE_OTHERS);
        sEventsProjectionMap.put(Events.GUESTS_CAN_MODIFY, Events.GUESTS_CAN_MODIFY);
        sEventsProjectionMap.put(Events.GUESTS_CAN_SEE_GUESTS, Events.GUESTS_CAN_SEE_GUESTS);
        sEventsProjectionMap.put(Events.ORGANIZER, Events.ORGANIZER);
        sEventsProjectionMap.put(Events.IS_ORGANIZER, Events.IS_ORGANIZER);
        sEventsProjectionMap.put(Events.CUSTOM_APP_PACKAGE, Events.CUSTOM_APP_PACKAGE);
        sEventsProjectionMap.put(Events.CUSTOM_APP_URI, Events.CUSTOM_APP_URI);
        sEventsProjectionMap.put(Events.UID_2445, Events.UID_2445);
        sEventsProjectionMap.put(Events.DELETED, Events.DELETED);
        sEventsProjectionMap.put(Events._SYNC_ID, Events._SYNC_ID);

        // Put the shared items into the Attendees, Reminders projection map
        sAttendeesProjectionMap = new HashMap<String, String>(sEventsProjectionMap);
        sRemindersProjectionMap = new HashMap<String, String>(sEventsProjectionMap);

        // Calendar columns
        sEventsProjectionMap.put(Calendars.CALENDAR_COLOR, Calendars.CALENDAR_COLOR);
        sEventsProjectionMap.put(Calendars.CALENDAR_COLOR_KEY, Calendars.CALENDAR_COLOR_KEY);
        sEventsProjectionMap.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CALENDAR_ACCESS_LEVEL);
        sEventsProjectionMap.put(Calendars.VISIBLE, Calendars.VISIBLE);
        sEventsProjectionMap.put(Calendars.CALENDAR_TIME_ZONE, Calendars.CALENDAR_TIME_ZONE);
        sEventsProjectionMap.put(Calendars.OWNER_ACCOUNT, Calendars.OWNER_ACCOUNT);
        sEventsProjectionMap.put(Calendars.CALENDAR_DISPLAY_NAME, Calendars.CALENDAR_DISPLAY_NAME);
        sEventsProjectionMap.put(Calendars.ALLOWED_REMINDERS, Calendars.ALLOWED_REMINDERS);
        sEventsProjectionMap
                .put(Calendars.ALLOWED_ATTENDEE_TYPES, Calendars.ALLOWED_ATTENDEE_TYPES);
        sEventsProjectionMap.put(Calendars.ALLOWED_AVAILABILITY, Calendars.ALLOWED_AVAILABILITY);
        sEventsProjectionMap.put(Calendars.MAX_REMINDERS, Calendars.MAX_REMINDERS);
        sEventsProjectionMap.put(Calendars.CAN_ORGANIZER_RESPOND, Calendars.CAN_ORGANIZER_RESPOND);
        sEventsProjectionMap.put(Calendars.CAN_MODIFY_TIME_ZONE, Calendars.CAN_MODIFY_TIME_ZONE);
        sEventsProjectionMap.put(Events.DISPLAY_COLOR, Events.DISPLAY_COLOR);

        // Put the shared items into the Instances projection map
        // The Instances and CalendarAlerts are joined with Calendars, so the projections include
        // the above Calendar columns.
        sInstancesProjectionMap = new HashMap<String, String>(sEventsProjectionMap);
        sCalendarAlertsProjectionMap = new HashMap<String, String>(sEventsProjectionMap);

        sEventsProjectionMap.put(Events._ID, Events._ID);
        sEventsProjectionMap.put(Events.SYNC_DATA1, Events.SYNC_DATA1);
        sEventsProjectionMap.put(Events.SYNC_DATA2, Events.SYNC_DATA2);
        sEventsProjectionMap.put(Events.SYNC_DATA3, Events.SYNC_DATA3);
        sEventsProjectionMap.put(Events.SYNC_DATA4, Events.SYNC_DATA4);
        sEventsProjectionMap.put(Events.SYNC_DATA5, Events.SYNC_DATA5);
        sEventsProjectionMap.put(Events.SYNC_DATA6, Events.SYNC_DATA6);
        sEventsProjectionMap.put(Events.SYNC_DATA7, Events.SYNC_DATA7);
        sEventsProjectionMap.put(Events.SYNC_DATA8, Events.SYNC_DATA8);
        sEventsProjectionMap.put(Events.SYNC_DATA9, Events.SYNC_DATA9);
        sEventsProjectionMap.put(Events.SYNC_DATA10, Events.SYNC_DATA10);
        sEventsProjectionMap.put(Calendars.CAL_SYNC1, Calendars.CAL_SYNC1);
        sEventsProjectionMap.put(Calendars.CAL_SYNC2, Calendars.CAL_SYNC2);
        sEventsProjectionMap.put(Calendars.CAL_SYNC3, Calendars.CAL_SYNC3);
        sEventsProjectionMap.put(Calendars.CAL_SYNC4, Calendars.CAL_SYNC4);
        sEventsProjectionMap.put(Calendars.CAL_SYNC5, Calendars.CAL_SYNC5);
        sEventsProjectionMap.put(Calendars.CAL_SYNC6, Calendars.CAL_SYNC6);
        sEventsProjectionMap.put(Calendars.CAL_SYNC7, Calendars.CAL_SYNC7);
        sEventsProjectionMap.put(Calendars.CAL_SYNC8, Calendars.CAL_SYNC8);
        sEventsProjectionMap.put(Calendars.CAL_SYNC9, Calendars.CAL_SYNC9);
        sEventsProjectionMap.put(Calendars.CAL_SYNC10, Calendars.CAL_SYNC10);
        sEventsProjectionMap.put(Events.DIRTY, Events.DIRTY);
        sEventsProjectionMap.put(Events.MUTATORS, Events.MUTATORS);
        sEventsProjectionMap.put(Events.LAST_SYNCED, Events.LAST_SYNCED);

        sEventEntitiesProjectionMap = new HashMap<String, String>();
        sEventEntitiesProjectionMap.put(Events.TITLE, Events.TITLE);
        sEventEntitiesProjectionMap.put(Events.EVENT_LOCATION, Events.EVENT_LOCATION);
        sEventEntitiesProjectionMap.put(Events.DESCRIPTION, Events.DESCRIPTION);
        sEventEntitiesProjectionMap.put(Events.STATUS, Events.STATUS);
        sEventEntitiesProjectionMap.put(Events.EVENT_COLOR, Events.EVENT_COLOR);
        sEventEntitiesProjectionMap.put(Events.EVENT_COLOR_KEY, Events.EVENT_COLOR_KEY);
        sEventEntitiesProjectionMap.put(Events.SELF_ATTENDEE_STATUS, Events.SELF_ATTENDEE_STATUS);
        sEventEntitiesProjectionMap.put(Events.DTSTART, Events.DTSTART);
        sEventEntitiesProjectionMap.put(Events.DTEND, Events.DTEND);
        sEventEntitiesProjectionMap.put(Events.EVENT_TIMEZONE, Events.EVENT_TIMEZONE);
        sEventEntitiesProjectionMap.put(Events.EVENT_END_TIMEZONE, Events.EVENT_END_TIMEZONE);
        sEventEntitiesProjectionMap.put(Events.DURATION, Events.DURATION);
        sEventEntitiesProjectionMap.put(Events.ALL_DAY, Events.ALL_DAY);
        sEventEntitiesProjectionMap.put(Events.ACCESS_LEVEL, Events.ACCESS_LEVEL);
        sEventEntitiesProjectionMap.put(Events.AVAILABILITY, Events.AVAILABILITY);
        sEventEntitiesProjectionMap.put(Events.HAS_ALARM, Events.HAS_ALARM);
        sEventEntitiesProjectionMap.put(Events.HAS_EXTENDED_PROPERTIES,
                Events.HAS_EXTENDED_PROPERTIES);
        sEventEntitiesProjectionMap.put(Events.RRULE, Events.RRULE);
        sEventEntitiesProjectionMap.put(Events.RDATE, Events.RDATE);
        sEventEntitiesProjectionMap.put(Events.EXRULE, Events.EXRULE);
        sEventEntitiesProjectionMap.put(Events.EXDATE, Events.EXDATE);
        sEventEntitiesProjectionMap.put(Events.ORIGINAL_SYNC_ID, Events.ORIGINAL_SYNC_ID);
        sEventEntitiesProjectionMap.put(Events.ORIGINAL_ID, Events.ORIGINAL_ID);
        sEventEntitiesProjectionMap.put(Events.ORIGINAL_INSTANCE_TIME,
                Events.ORIGINAL_INSTANCE_TIME);
        sEventEntitiesProjectionMap.put(Events.ORIGINAL_ALL_DAY, Events.ORIGINAL_ALL_DAY);
        sEventEntitiesProjectionMap.put(Events.LAST_DATE, Events.LAST_DATE);
        sEventEntitiesProjectionMap.put(Events.HAS_ATTENDEE_DATA, Events.HAS_ATTENDEE_DATA);
        sEventEntitiesProjectionMap.put(Events.CALENDAR_ID, Events.CALENDAR_ID);
        sEventEntitiesProjectionMap.put(Events.GUESTS_CAN_INVITE_OTHERS,
                Events.GUESTS_CAN_INVITE_OTHERS);
        sEventEntitiesProjectionMap.put(Events.GUESTS_CAN_MODIFY, Events.GUESTS_CAN_MODIFY);
        sEventEntitiesProjectionMap.put(Events.GUESTS_CAN_SEE_GUESTS, Events.GUESTS_CAN_SEE_GUESTS);
        sEventEntitiesProjectionMap.put(Events.ORGANIZER, Events.ORGANIZER);
        sEventEntitiesProjectionMap.put(Events.IS_ORGANIZER, Events.IS_ORGANIZER);
        sEventEntitiesProjectionMap.put(Events.CUSTOM_APP_PACKAGE, Events.CUSTOM_APP_PACKAGE);
        sEventEntitiesProjectionMap.put(Events.CUSTOM_APP_URI, Events.CUSTOM_APP_URI);
        sEventEntitiesProjectionMap.put(Events.UID_2445, Events.UID_2445);
        sEventEntitiesProjectionMap.put(Events.DELETED, Events.DELETED);
        sEventEntitiesProjectionMap.put(Events._ID, Events._ID);
        sEventEntitiesProjectionMap.put(Events._SYNC_ID, Events._SYNC_ID);
        sEventEntitiesProjectionMap.put(Events.SYNC_DATA1, Events.SYNC_DATA1);
        sEventEntitiesProjectionMap.put(Events.SYNC_DATA2, Events.SYNC_DATA2);
        sEventEntitiesProjectionMap.put(Events.SYNC_DATA3, Events.SYNC_DATA3);
        sEventEntitiesProjectionMap.put(Events.SYNC_DATA4, Events.SYNC_DATA4);
        sEventEntitiesProjectionMap.put(Events.SYNC_DATA5, Events.SYNC_DATA5);
        sEventEntitiesProjectionMap.put(Events.SYNC_DATA6, Events.SYNC_DATA6);
        sEventEntitiesProjectionMap.put(Events.SYNC_DATA7, Events.SYNC_DATA7);
        sEventEntitiesProjectionMap.put(Events.SYNC_DATA8, Events.SYNC_DATA8);
        sEventEntitiesProjectionMap.put(Events.SYNC_DATA9, Events.SYNC_DATA9);
        sEventEntitiesProjectionMap.put(Events.SYNC_DATA10, Events.SYNC_DATA10);
        sEventEntitiesProjectionMap.put(Events.DIRTY, Events.DIRTY);
        sEventEntitiesProjectionMap.put(Events.MUTATORS, Events.MUTATORS);
        sEventEntitiesProjectionMap.put(Events.LAST_SYNCED, Events.LAST_SYNCED);
        sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC1, Calendars.CAL_SYNC1);
        sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC2, Calendars.CAL_SYNC2);
        sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC3, Calendars.CAL_SYNC3);
        sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC4, Calendars.CAL_SYNC4);
        sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC5, Calendars.CAL_SYNC5);
        sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC6, Calendars.CAL_SYNC6);
        sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC7, Calendars.CAL_SYNC7);
        sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC8, Calendars.CAL_SYNC8);
        sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC9, Calendars.CAL_SYNC9);
        sEventEntitiesProjectionMap.put(Calendars.CAL_SYNC10, Calendars.CAL_SYNC10);

        // Instances columns
        sInstancesProjectionMap.put(Events.DELETED, "Events.deleted as deleted");
        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");

        // 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");
        sAttendeesProjectionMap.put(Attendees.ATTENDEE_IDENTITY, "attendeeIdentity");
        sAttendeesProjectionMap.put(Attendees.ATTENDEE_ID_NAMESPACE, "attendeeIdNamespace");
        sAttendeesProjectionMap.put(Events.DELETED, "Events.deleted AS deleted");
        sAttendeesProjectionMap.put(Events._SYNC_ID, "Events._sync_id AS _sync_id");

        // 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");
        sRemindersProjectionMap.put(Events.DELETED, "Events.deleted AS deleted");
        sRemindersProjectionMap.put(Events._SYNC_ID, "Events._sync_id AS _sync_id");

        // 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.NOTIFY_TIME, "notifyTime");
        sCalendarAlertsProjectionMap.put(CalendarAlerts.STATE, "state");
        sCalendarAlertsProjectionMap.put(CalendarAlerts.MINUTES, "minutes");

        // CalendarCache columns
        sCalendarCacheProjectionMap = new HashMap<String, String>();
        sCalendarCacheProjectionMap.put(CalendarCache.COLUMN_NAME_KEY, "key");
        sCalendarCacheProjectionMap.put(CalendarCache.COLUMN_NAME_VALUE, "value");
    }


    /**
     * This is called by AccountManager when the set of accounts is updated.
     * <p>
     * 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  tables, which are
     * syncable.  TODO: update comment, make sure deletes don't get synced.
     *
     * @param accounts The list of currently active accounts.
     */
    @Override
    public void onAccountsUpdated(Account[] accounts) {
        Thread thread = new AccountsUpdatedThread(accounts);
        thread.start();
    }

    private class AccountsUpdatedThread extends Thread {
        private Account[] mAccounts;

        AccountsUpdatedThread(Account[] accounts) {
            mAccounts = accounts;
        }

        @Override
        public void run() {
            // The process could be killed while the thread runs.  Right now that isn't a problem,
            // because we'll just call removeStaleAccounts() again when the provider restarts, but
            // if we want to do additional actions we may need to use a service (e.g. start
            // EmptyService in onAccountsUpdated() and stop it when we finish here).

            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            removeStaleAccounts(mAccounts);
        }
    }

    /**
     * Makes sure there are no entries for accounts that no longer exist.
     */
    private void removeStaleAccounts(Account[] accounts) {
        mDb = mDbHelper.getWritableDatabase();
        if (mDb == null) {
            return;
        }

        HashSet<Account> validAccounts = new HashSet<Account>();
        for (Account account : accounts) {
            validAccounts.add(new Account(account.name, account.type));
        }
        ArrayList<Account> accountsToDelete = new ArrayList<Account>();

        mDb.beginTransaction();
        Cursor c = null;
        try {

            for (String table : new String[]{Tables.CALENDARS, Tables.COLORS}) {
                // Find all the accounts the calendar DB knows about, mark the ones that aren't
                // in the valid set for deletion.
                c = mDb.rawQuery("SELECT DISTINCT " +
                                            Calendars.ACCOUNT_NAME +
                                            "," +
                                            Calendars.ACCOUNT_TYPE +
                                        " FROM " + table, null);
                while (c.moveToNext()) {
                    // ACCOUNT_TYPE_LOCAL is to store calendars not associated
                    // with a system account. Typically, a calendar must be
                    // associated with an account on the device or it will be
                    // deleted.
                    if (c.getString(0) != null
                            && c.getString(1) != null
                            && !TextUtils.equals(c.getString(1),
                                    CalendarContract.ACCOUNT_TYPE_LOCAL)) {
                        Account currAccount = new Account(c.getString(0), c.getString(1));
                        if (!validAccounts.contains(currAccount)) {
                            accountsToDelete.add(currAccount);
                        }
                    }
                }
                c.close();
                c = null;
            }

            for (Account account : accountsToDelete) {
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "removing data for removed account " + account);
                }
                String[] params = new String[]{account.name, account.type};
                mDb.execSQL(SQL_DELETE_FROM_CALENDARS, params);
                // This will be a no-op for accounts without a color palette.
                mDb.execSQL(SQL_DELETE_FROM_COLORS, params);
            }
            mDbHelper.getSyncState().onAccountsChanged(mDb, accounts);
            mDb.setTransactionSuccessful();
        } finally {
            if (c != null) {
                c.close();
            }
            mDb.endTransaction();
        }

        // make sure the widget reflects the account changes
        sendUpdateNotification(false);
    }

    /**
     * Inserts an argument at the beginning of the selection arg list.
     *
     * The {@link android.database.sqlite.SQLiteQueryBuilder}'s where clause is
     * prepended to the user's where clause (combined with 'AND') to generate
     * the final where close, so arguments associated with the QueryBuilder are
     * prepended before any user selection args to keep them in the right order.
     */
    private String[] insertSelectionArg(String[] selectionArgs, String arg) {
        if (selectionArgs == null) {
            return new String[] {arg};
        } else {
            int newLength = selectionArgs.length + 1;
            String[] newSelectionArgs = new String[newLength];
            newSelectionArgs[0] = arg;
            System.arraycopy(selectionArgs, 0, newSelectionArgs, 1, selectionArgs.length);
            return newSelectionArgs;
        }
    }

    private String getCallingPackageName() {
        if (getCachedCallingPackage() != null) {
            // If the calling package is null, use the best available as a fallback.
            return getCachedCallingPackage();
        }

        final PackageManager pm = getContext().getPackageManager();
        final int uid = Binder.getCallingUid();
        final String[] packages = pm.getPackagesForUid(uid);
        if (packages != null && packages.length == 1) {
            return packages[0];
        }
        final String name = pm.getNameForUid(uid);
        if (name != null) {
            return name;
        }
        return String.valueOf(uid);
    }

    private void addMutator(ContentValues values, String columnName) {
        final String packageName = getCallingPackageName();
        final String mutators = values.getAsString(columnName);
        if (TextUtils.isEmpty(mutators)) {
            values.put(columnName, packageName);
        } else {
            values.put(columnName, mutators + "," + packageName);
        }
    }
}
