/*
**
** 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.AlarmManager;
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
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.OperationApplicationException;
import android.content.UriMatcher;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.MatrixCursor;
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.Process;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
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.internal.util.ProviderAccessStats;
import com.android.providers.calendar.CalendarDatabaseHelper.Tables;
import com.android.providers.calendar.CalendarDatabaseHelper.Views;
import com.android.providers.calendar.enterprise.CrossProfileCalendarHelper;

import com.google.android.collect.Sets;
import com.google.common.annotations.VisibleForTesting;

import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
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;
    CalendarSanityChecker mSanityChecker;

    private CalendarDatabaseHelper mDbHelper;
    private CalendarInstancesHelper mInstancesHelper;

    protected CrossProfileCalendarHelper mCrossProfileCalendarHelper;

    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 static final String SELECTION_PRIMARY_CALENDAR =
            Calendars.IS_PRIMARY + "= 1"
                    + " OR " + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT;

    private final ThreadLocal<Boolean> mCallingPackageErrorLogged = new ThreadLocal<Boolean>();

    private Context mContext;
    private ContentResolver mContentResolver;

    @VisibleForTesting
    protected CalendarAlarmManager mCalendarAlarm;

    private final ThreadLocal<Integer> mCallingUid = new ThreadLocal<>();
    private final ProviderAccessStats mStats = new ProviderAccessStats();

    private int mParentUserId;

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

    @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() {
        mContext = getContext();
        mContentResolver = mContext.getContentResolver();

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

        mMetaData = new MetaData(mDbHelper);
        mInstancesHelper = new CalendarInstancesHelper(mDbHelper, mMetaData);
        mSanityChecker = new CalendarSanityChecker(mContext);

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

        // Unit test overrides this method to get a mock helper.
        initCrossProfileCalendarHelper();

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

        mParentUserId = getParentUserId();

        postInitialize();

        return true;
    }

    @VisibleForTesting
    protected void initCrossProfileCalendarHelper() {
        mCrossProfileCalendarHelper = new CrossProfileCalendarHelper(mContext);
    }

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

    @VisibleForTesting
    protected int getParentUserId() {
        final UserManager userManager = mContext.getSystemService(UserManager.class);
        final UserInfo parentUser = userManager.getProfileParent(UserHandle.myUserId());
        return parentUser == null ? UserHandle.USER_NULL : parentUser.id;
    }

    @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);
        // If this is a managed profile CalendarProvider, notify the content observers of
        // enterprise uris in the parent profile.
        if (mParentUserId != UserHandle.USER_NULL) {
            mContentResolver.notifyChange(
                    CalendarContract.ENTERPRISE_CONTENT_URI,
                    /* observer = */ null, /* syncToNetwork = */ false, mParentUserId);
        }
    }

    /**
     * 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) {
        mSanityChecker.checkLastCheckTime();

        // Note don't use mCallingUid here. That's only used by mutation functions.
        final int callingUid = Binder.getCallingUid();

        mStats.incrementQueryStats(callingUid);
        final long identity = clearCallingIdentityInternal();
        try {
            return queryInternal(uri, projection, selection, selectionArgs, sortOrder);
        } finally {
            restoreCallingIdentityInternal(identity);
            mStats.finishOperation(callingUid);
        }
    }

    /**
     * @return {@link UserInfo} of the work profile user that is linked to the current user,
     * if any. {@code null} if there is no such user.
     */
    private UserInfo getWorkProfileUserInfo(Context context) {
        final UserManager userManager = context.getSystemService(UserManager.class);
        final int currentUserId = userManager.getUserHandle();

        // Check each user.
        for (UserInfo userInfo : userManager.getUsers()) {
            if (!userInfo.isManagedProfile()) {
                continue; // Not a managed user.
            }
            final UserInfo parent = userManager.getProfileParent(userInfo.id);
            if (parent == null) {
                continue; // No parent.
            }
            // Check if it's linked to the current user, and if work profile is disabled.
            if (parent.id == currentUserId
                    && !userManager.isQuietModeEnabled(UserHandle.of(userInfo.id))) {
                return userInfo;
            }
        }
        return null;
    }

    /**
     * @return the user ID of the work profile user that is linked to the current user
     * if any. {@link UserHandle#USER_NULL} if there's no such user.
     *
     * @VisibleForTesting
     */
    protected int getWorkProfileUserId() {
        final UserInfo ui = getWorkProfileUserInfo(getContext());
        return ui == null ? UserHandle.USER_NULL : ui.id;
    }

    private static Cursor createEmptyCursor(String[] projection) {
        return new MatrixCursor(projection);
    }

    /**
     * @return {@code true} if the calling package can access cross profile calendar. {@code false}
     * otherwise.
     */
    private boolean canAccessCrossProfileCalendar(int workProfileUserId) {
        // The criteria include:
        // 1. There exists a work profile linked to the current user and the work profile is not
        //    disabled.
        // 2. Profile owner of the work profile has allowed the calling package for cross
        //    profile calendar.
        // 3. CROSS_PROFILE_CALENDAR_ENABLED is turned on in Settings.
        return workProfileUserId != UserHandle.USER_NULL
                && mCrossProfileCalendarHelper.isPackageAllowedToAccessCalendar(
                        getCallingPackageName(), workProfileUserId);
    }

    private String appendPrimaryOnlyToSelection(String selection) {
        return TextUtils.isEmpty(selection)
                ? SELECTION_PRIMARY_CALENDAR
                : selection + " AND (" +  SELECTION_PRIMARY_CALENDAR + ")";
    }

    /*
     * Throw UnsupportedOperationException if
     * <p>1. Work profile doesn't exits or disabled.
     * <p>2. Calling package is not allowed to access cross profile calendar.
     * <p>3. CROSS_PROFILE_CALENDAR_ENABLED is turned off in Settings.
     */
    private Cursor queryWorkProfileProvider(Uri localUri, String[] projection,
            String selection, String[] selectionArgs, String sortOrder,
            List<String> additionalPathSegments) {
        // If projection is not empty, check if it's valid. Otherwise fill it with all
        // allowed columns.
        projection = mCrossProfileCalendarHelper.getCalibratedProjection(
                projection, localUri);
        // Throw exception if cross profile calendar is currently not available.
        final int workProfileUserId = getWorkProfileUserId();
        if (!canAccessCrossProfileCalendar(workProfileUserId)) {
            throw new UnsupportedOperationException("Can't access cross profile for " + localUri);
        }

        Uri remoteUri = maybeAddUserId(
                localUri, workProfileUserId).buildUpon().build();
        if (additionalPathSegments != null) {
            for (String segment : additionalPathSegments) {
                remoteUri = Uri.withAppendedPath(remoteUri, segment);
            }
        }

        selection = appendPrimaryOnlyToSelection(selection);

        final Cursor cursor = getContext().getContentResolver().query(remoteUri, projection,
                selection, selectionArgs, sortOrder);
        return cursor == null ? createEmptyCursor(projection) : cursor;
    }

    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;

        List<String> corpAdditionalPathSegments = null;
        final List<String> uriPathSegments = uri.getPathSegments();

        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 ENTERPRISE_EVENTS_ID:
                corpAdditionalPathSegments = uriPathSegments.subList(2, uriPathSegments.size());
            // Intentional fall from the above case.
            case ENTERPRISE_EVENTS:
                return queryWorkProfileProvider(Events.CONTENT_URI, projection, selection,
                        selectionArgs, sortOrder, corpAdditionalPathSegments);

            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 ENTERPRISE_CALENDARS_ID:
                corpAdditionalPathSegments = uriPathSegments.subList(2, uriPathSegments.size());
                // Intentional fall from the above case.
            case ENTERPRISE_CALENDARS:
                return queryWorkProfileProvider(Calendars.CONTENT_URI, projection, selection,
                        selectionArgs, sortOrder, corpAdditionalPathSegments);

            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 ENTERPRISE_INSTANCES:
                corpAdditionalPathSegments = uriPathSegments.subList(3, uriPathSegments.size());
                return queryWorkProfileProvider(Instances.CONTENT_URI, projection, selection,
                        selectionArgs, sortOrder, corpAdditionalPathSegments);
            case ENTERPRISE_INSTANCES_BY_DAY:
                corpAdditionalPathSegments = uriPathSegments.subList(3, uriPathSegments.size());
                return queryWorkProfileProvider(Instances.CONTENT_BY_DAY_URI, projection, selection,
                        selectionArgs, sortOrder, corpAdditionalPathSegments);
            case ENTERPRISE_INSTANCES_SEARCH:
                corpAdditionalPathSegments = uriPathSegments.subList(3, uriPathSegments.size());
                return queryWorkProfileProvider(Instances.CONTENT_SEARCH_URI, projection, selection,
                        selectionArgs, sortOrder, corpAdditionalPathSegments);
            case ENTERPRISE_INSTANCES_SEARCH_BY_DAY:
                corpAdditionalPathSegments = uriPathSegments.subList(3, uriPathSegments.size());
                return queryWorkProfileProvider(Instances.CONTENT_SEARCH_BY_DAY_URI, projection,
                        selection, selectionArgs, sortOrder, corpAdditionalPathSegments);
            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
    public int bulkInsert(Uri uri, ContentValues[] values) {
        final int callingUid = Binder.getCallingUid();
        mCallingUid.set(callingUid);

        mStats.incrementBatchStats(callingUid);
        try {
            return super.bulkInsert(uri, values);
        } finally {
            mStats.finishOperation(callingUid);
        }
    }

    @Override
    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
            throws OperationApplicationException {
        final int callingUid = Binder.getCallingUid();
        mCallingUid.set(callingUid);

        mStats.incrementBatchStats(callingUid);
        try {
            return super.applyBatch(operations);
        } finally {
            mStats.finishOperation(callingUid);
        }
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        if (!applyingBatch()) {
            mCallingUid.set(Binder.getCallingUid());
        }

        return super.insert(uri, values);
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        if (!applyingBatch()) {
            mCallingUid.set(Binder.getCallingUid());
        }

        return super.update(uri, values, selection, selectionArgs);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        if (!applyingBatch()) {
            mCallingUid.set(Binder.getCallingUid());
        }

        return super.delete(uri, selection, selectionArgs);
    }

    @Override
    protected Uri insertInTransaction(Uri uri, ContentValues values, boolean callerIsSyncAdapter) {
        final int callingUid = mCallingUid.get();

        mStats.incrementInsertStats(callingUid, applyingBatch());
        try {
            return insertInTransactionInner(uri, values, callerIsSyncAdapter);
        } finally {
            mStats.finishOperation(callingUid);
        }
    }

    private Uri insertInTransactionInner(
            Uri uri, ContentValues values, boolean callerIsSyncAdapter) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "insertInTransaction: " + uri);
        }
        mSanityChecker.checkLastCheckTime();

        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) {
        final int callingUid = mCallingUid.get();
        mStats.incrementDeleteStats(callingUid, applyingBatch());
        try {
            return deleteInTransactionInner(uri, selection, selectionArgs, callerIsSyncAdapter);
        } finally {
            mStats.finishOperation(callingUid);
        }
    }

    private int deleteInTransactionInner(Uri uri, String selection, String[] selectionArgs,
            boolean callerIsSyncAdapter) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "deleteInTransaction: " + uri);
        }
        mSanityChecker.checkLastCheckTime();

        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) {
        final int callingUid = mCallingUid.get();
        mStats.incrementUpdateStats(callingUid, applyingBatch());
        try {
            return updateInTransactionInner(uri, values, selection, selectionArgs,
                    callerIsSyncAdapter);
        } finally {
            mStats.finishOperation(callingUid);
        }
    }

    private int updateInTransactionInner(Uri uri, ContentValues values, String selection,
            String[] selectionArgs, boolean callerIsSyncAdapter) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "updateInTransaction: " + uri);
        }
        mSanityChecker.checkLastCheckTime();

        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) {
                        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 with a delay.
     * 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.
     *
     * 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) {
        // We use a much longer delay for sync-related updates, to prevent any
        // receivers from slowing down the sync
        final long delay = callerIsSyncAdapter ?
                SYNC_UPDATE_BROADCAST_TIMEOUT_MILLIS :
                UPDATE_BROADCAST_TIMEOUT_MILLIS;

        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "sendUpdateNotification: delay=" + delay);
        }

        mCalendarAlarm.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                SystemClock.elapsedRealtime() + delay,
                PendingIntent.getBroadcast(mContext, 0, createProviderChangedBroadcast(),
                        PendingIntent.FLAG_UPDATE_CURRENT));
    }

    private Intent createProviderChangedBroadcast() {
        return new Intent(Intent.ACTION_PROVIDER_CHANGED, CalendarContract.CONTENT_URI)
                .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING)
                .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
    }

    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 int ENTERPRISE_EVENTS = 33;
    private static final int ENTERPRISE_EVENTS_ID = 34;
    private static final int ENTERPRISE_CALENDARS = 35;
    private static final int ENTERPRISE_CALENDARS_ID = 36;
    private static final int ENTERPRISE_INSTANCES = 37;
    private static final int ENTERPRISE_INSTANCES_BY_DAY = 38;
    private static final int ENTERPRISE_INSTANCES_SEARCH = 39;
    private static final int ENTERPRISE_INSTANCES_SEARCH_BY_DAY = 40;

    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);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "enterprise/events", ENTERPRISE_EVENTS);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "enterprise/events/#",
                ENTERPRISE_EVENTS_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "enterprise/calendars",
                ENTERPRISE_CALENDARS);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "enterprise/calendars/#",
                ENTERPRISE_CALENDARS_ID);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "enterprise/instances/when/*/*",
                ENTERPRISE_INSTANCES);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "enterprise/instances/whenbyday/*/*",
                ENTERPRISE_INSTANCES_BY_DAY);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "enterprise/instances/search/*/*/*",
                ENTERPRISE_INSTANCES_SEARCH);
        sUriMatcher.addURI(CalendarContract.AUTHORITY, "enterprise/instances/searchbyday/*/*/*",
                ENTERPRISE_INSTANCES_SEARCH_BY_DAY);

        /** 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(" + Calendars.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(Calendars.IS_PRIMARY,
                "COALESCE(" + Calendars.IS_PRIMARY + ", "
                        + Calendars.OWNER_ACCOUNT + " = " + Calendars.ACCOUNT_NAME + ") AS "
                        + Calendars.IS_PRIMARY);
        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
        if (!accountsToDelete.isEmpty()) {
            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;
        }
    }

    @VisibleForTesting
    protected String getCallingPackageName() {
        if (getCachedCallingPackage() != null) {
            // If the calling package is null, use the best available as a fallback.
            return getCachedCallingPackage();
        }
        if (!Boolean.TRUE.equals(mCallingPackageErrorLogged.get())) {
            Log.e(TAG, "Failed to get the cached calling package.", new Throwable());
            mCallingPackageErrorLogged.set(Boolean.TRUE);
        }
        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);
        }
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
        mStats.dump(writer, "  ");
    }
}
