/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.providers.calendar;

import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.CalendarContract;
import android.provider.CalendarContract.Calendars;
import android.provider.CalendarContract.Colors;
import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Instances;
import android.test.AndroidTestCase;
import android.test.IsolatedContext;
import android.test.RenamingDelegatingContext;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.Smoke;
import android.test.suitebuilder.annotation.Suppress;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.Log;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

/**
 * Runs various tests on an isolated Calendar provider with its own database.
 *
 * You can run the tests with the following command line:
 *
 * adb shell am instrument
 * -e debug false
 * -w
 * -e class com.android.providers.calendar.CalendarProvider2Test
 * com.android.providers.calendar.tests/android.test.InstrumentationTestRunner
 *
 * This test no longer extends ProviderTestCase2 because it actually doesn't
 * allow you to inject a custom context (which we needed to mock out the calls
 * to start a service). We the next best thing, which is copy the relevant code
 * from PTC2 and extend AndroidTestCase instead.
 */
// flaky test, add back to LargeTest when fixed - bug 2395696
// @LargeTest
public class CalendarProvider2Test extends AndroidTestCase {
    static final String TAG = "calendar";

    private static final String DEFAULT_ACCOUNT_TYPE = "com.google";
    private static final String DEFAULT_ACCOUNT = "joe@joe.com";


    private static final String WHERE_CALENDARS_SELECTED = Calendars.VISIBLE + "=?";
    private static final String[] WHERE_CALENDARS_ARGS = {
        "1"
    };
    private static final String WHERE_COLOR_ACCOUNT_AND_INDEX = Colors.ACCOUNT_NAME + "=? AND "
            + Colors.ACCOUNT_TYPE + "=? AND " + Colors.COLOR_KEY + "=?";
    private static final String DEFAULT_SORT_ORDER = "begin ASC";

    private CalendarProvider2ForTesting mProvider;
    private SQLiteDatabase mDb;
    private MetaData mMetaData;
    private Context mContext;
    private MockContentResolver mResolver;
    private Uri mEventsUri = Events.CONTENT_URI;
    private Uri mCalendarsUri = Calendars.CONTENT_URI;
    private int mCalendarId;

    protected boolean mWipe = false;
    protected boolean mForceDtend = false;

    // We need a unique id to put in the _sync_id field so that we can create
    // recurrence exceptions that refer to recurring events.
    private int mGlobalSyncId = 1000;
    private static final String CALENDAR_URL =
            "http://www.google.com/calendar/feeds/joe%40joe.com/private/full";

    private static final String TIME_ZONE_AMERICA_ANCHORAGE = "America/Anchorage";
    private static final String TIME_ZONE_AMERICA_LOS_ANGELES = "America/Los_Angeles";
    private static final String DEFAULT_TIMEZONE = TIME_ZONE_AMERICA_LOS_ANGELES;

    private static final String MOCK_TIME_ZONE_DATABASE_VERSION = "2010a";

    private static final long ONE_MINUTE_MILLIS = 60*1000;
    private static final long ONE_HOUR_MILLIS = 3600*1000;
    private static final long ONE_WEEK_MILLIS = 7 * 24 * 3600 * 1000;

    /**
     * We need a few more stub methods so that our tests can run
     */
    protected class MockContext2 extends MockContext {

        @Override
        public String getPackageName() {
            return getContext().getPackageName();
        }

        @Override
        public Resources getResources() {
            return getContext().getResources();
        }

        @Override
        public File getDir(String name, int mode) {
            // name the directory so the directory will be seperated from
            // one created through the regular Context
            return getContext().getDir("mockcontext2_" + name, mode);
        }

        @Override
        public ComponentName startService(Intent service) {
            return null;
        }

        @Override
        public boolean stopService(Intent service) {
            return false;
        }

        @Override
        public PackageManager getPackageManager() {
            return getContext().getPackageManager();
        }
    }

    /**
     * KeyValue is a simple class that stores a pair of strings representing
     * a (key, value) pair.  This is used for updating events.
     */
    private class KeyValue {
        String key;
        String value;

        public KeyValue(String key, String value) {
            this.key = key;
            this.value = value;
        }
    }

    /**
     * A generic command interface.  This is used to support a sequence of
     * commands that can create events, delete or update events, and then
     * check that the state of the database is as expected.
     */
    private interface Command {
        public void execute();
    }

    /**
     * This is used to insert a new event into the database.  The event is
     * specified by its name (or "title").  All of the event fields (the
     * start and end time, whether it is an all-day event, and so on) are
     * stored in a separate table (the "mEvents" table).
     */
    private class Insert implements Command {
        EventInfo eventInfo;

        public Insert(String eventName) {
            eventInfo = findEvent(eventName);
        }

        public void execute() {
            Log.i(TAG, "insert " + eventInfo.mTitle);
            insertEvent(mCalendarId, eventInfo);
        }
    }

    /**
     * This is used to delete an event, specified by the event name.
     */
    private class Delete implements Command {
        String eventName;
        String account;
        String accountType;
        int expected;

        public Delete(String eventName, int expected, String account, String accountType) {
            this.eventName = eventName;
            this.expected = expected;
            this.account = account;
            this.accountType = accountType;
        }

        public void execute() {
            Log.i(TAG, "delete " + eventName);
            int rows = deleteMatchingEvents(eventName, account, accountType);
            assertEquals(expected, rows);
        }
    }

    /**
     * This is used to update an event.  The values to update are specified
     * with an array of (key, value) pairs.  Both the key and value are
     * specified as strings.  Event fields that are not really strings (such
     * as DTSTART which is a long) should be converted to the appropriate type
     * but that isn't supported yet.  When needed, that can be added here
     * by checking for specific keys and converting the associated values.
     */
    private class Update implements Command {
        String eventName;
        KeyValue[] pairs;

        public Update(String eventName, KeyValue[] pairs) {
            this.eventName = eventName;
            this.pairs = pairs;
        }

        public void execute() {
            Log.i(TAG, "update " + eventName);
            if (mWipe) {
                // Wipe instance table so it will be regenerated
                mMetaData.clearInstanceRange();
            }
            ContentValues map = new ContentValues();
            for (KeyValue pair : pairs) {
                String value = pair.value;
                if (CalendarContract.Events.STATUS.equals(pair.key)) {
                    // Do type conversion for STATUS
                    map.put(pair.key, Integer.parseInt(value));
                } else {
                    map.put(pair.key, value);
                }
            }
            if (map.size() == 1 && map.containsKey(Events.STATUS)) {
                updateMatchingEventsStatusOnly(eventName, map);
            } else {
                updateMatchingEvents(eventName, map);
            }
        }
    }

    /**
     * This command queries the number of events and compares it to the given
     * expected value.
     */
    private class QueryNumEvents implements Command {
        int expected;

        public QueryNumEvents(int expected) {
            this.expected = expected;
        }

        public void execute() {
            Cursor cursor = mResolver.query(mEventsUri, null, null, null, null);
            assertEquals(expected, cursor.getCount());
            cursor.close();
        }
    }


    /**
     * This command dumps the list of events to the log for debugging.
     */
    private class DumpEvents implements Command {

        public DumpEvents() {
        }

        public void execute() {
            Cursor cursor = mResolver.query(mEventsUri, null, null, null, null);
            dumpCursor(cursor);
            cursor.close();
        }
    }

    /**
     * This command dumps the list of instances to the log for debugging.
     */
    private class DumpInstances implements Command {
        long begin;
        long end;

        public DumpInstances(String startDate, String endDate) {
            Time time = new Time(DEFAULT_TIMEZONE);
            time.parse3339(startDate);
            begin = time.toMillis(false /* use isDst */);
            time.parse3339(endDate);
            end = time.toMillis(false /* use isDst */);
        }

        public void execute() {
            Cursor cursor = queryInstances(begin, end);
            dumpCursor(cursor);
            cursor.close();
        }
    }

    /**
     * This command queries the number of instances and compares it to the given
     * expected value.
     */
    private class QueryNumInstances implements Command {
        int expected;
        long begin;
        long end;

        public QueryNumInstances(String startDate, String endDate, int expected) {
            Time time = new Time(DEFAULT_TIMEZONE);
            time.parse3339(startDate);
            begin = time.toMillis(false /* use isDst */);
            time.parse3339(endDate);
            end = time.toMillis(false /* use isDst */);
            this.expected = expected;
        }

        public void execute() {
            Cursor cursor = queryInstances(begin, end);
            assertEquals(expected, cursor.getCount());
            cursor.close();
        }
    }

    /**
     * When this command runs it verifies that all of the instances in the
     * given range match the expected instances (each instance is specified by
     * a start date).
     * If you just want to verify that an instance exists in a given date
     * range, use {@link VerifyInstance} instead.
     */
    private class VerifyAllInstances implements Command {
        long[] instances;
        long begin;
        long end;

        public VerifyAllInstances(String startDate, String endDate, String[] dates) {
            Time time = new Time(DEFAULT_TIMEZONE);
            time.parse3339(startDate);
            begin = time.toMillis(false /* use isDst */);
            time.parse3339(endDate);
            end = time.toMillis(false /* use isDst */);

            if (dates == null) {
                return;
            }

            // Convert all the instance date strings to UTC milliseconds
            int len = dates.length;
            this.instances = new long[len];
            int index = 0;
            for (String instance : dates) {
                time.parse3339(instance);
                this.instances[index++] = time.toMillis(false /* use isDst */);
            }
        }

        public void execute() {
            Cursor cursor = queryInstances(begin, end);
            int len = 0;
            if (instances != null) {
                len = instances.length;
            }
            if (len != cursor.getCount()) {
                dumpCursor(cursor);
            }
            assertEquals("number of instances don't match", len, cursor.getCount());

            if (instances == null) {
                return;
            }

            int beginColumn = cursor.getColumnIndex(Instances.BEGIN);
            while (cursor.moveToNext()) {
                long begin = cursor.getLong(beginColumn);

                // Search the list of expected instances for a matching start
                // time.
                boolean found = false;
                for (long instance : instances) {
                    if (instance == begin) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    int titleColumn = cursor.getColumnIndex(Events.TITLE);
                    int allDayColumn = cursor.getColumnIndex(Events.ALL_DAY);

                    String title = cursor.getString(titleColumn);
                    boolean allDay = cursor.getInt(allDayColumn) != 0;
                    int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NUMERIC_DATE |
                            DateUtils.FORMAT_24HOUR;
                    if (allDay) {
                        flags |= DateUtils.FORMAT_UTC;
                    } else {
                        flags |= DateUtils.FORMAT_SHOW_TIME;
                    }
                    String date = DateUtils.formatDateRange(mContext, begin, begin, flags);
                    String mesg = String.format("Test failed!"
                            + " unexpected instance (\"%s\") at %s",
                            title, date);
                    Log.e(TAG, mesg);
                }
                if (!found) {
                    dumpCursor(cursor);
                }
                assertTrue(found);
            }
            cursor.close();
        }
    }

    /**
     * When this command runs it verifies that the given instance exists in
     * the given date range.
     */
    private class VerifyInstance implements Command {
        long instance;
        boolean allDay;
        long begin;
        long end;

        /**
         * Creates a command to check that the given range [startDate,endDate]
         * contains a specific instance of an event (specified by "date").
         *
         * @param startDate the beginning of the date range
         * @param endDate the end of the date range
         * @param date the date or date-time string of an event instance
         */
        public VerifyInstance(String startDate, String endDate, String date) {
            Time time = new Time(DEFAULT_TIMEZONE);
            time.parse3339(startDate);
            begin = time.toMillis(false /* use isDst */);
            time.parse3339(endDate);
            end = time.toMillis(false /* use isDst */);

            // Convert the instance date string to UTC milliseconds
            time.parse3339(date);
            allDay = time.allDay;
            instance = time.toMillis(false /* use isDst */);
        }

        public void execute() {
            Cursor cursor = queryInstances(begin, end);
            int beginColumn = cursor.getColumnIndex(Instances.BEGIN);
            boolean found = false;
            while (cursor.moveToNext()) {
                long begin = cursor.getLong(beginColumn);

                if (instance == begin) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NUMERIC_DATE;
                if (allDay) {
                    flags |= DateUtils.FORMAT_UTC;
                } else {
                    flags |= DateUtils.FORMAT_SHOW_TIME;
                }
                String date = DateUtils.formatDateRange(mContext, instance, instance, flags);
                String mesg = String.format("Test failed!"
                        + " cannot find instance at %s",
                        date);
                Log.e(TAG, mesg);
            }
            assertTrue(found);
            cursor.close();
        }
    }

    /**
     * This class stores all the useful information about an event.
     */
    private class EventInfo {
        String mTitle;
        String mDescription;
        String mTimezone;
        boolean mAllDay;
        long mDtstart;
        long mDtend;
        String mRrule;
        String mDuration;
        String mOriginalTitle;
        long mOriginalInstance;
        int mSyncId;
        String mCustomAppPackage;
        String mCustomAppUri;
        String mUid2445;

        // Constructor for normal events, using the default timezone
        public EventInfo(String title, String startDate, String endDate,
                boolean allDay) {
            init(title, startDate, endDate, allDay, DEFAULT_TIMEZONE);
        }

        // Constructor for normal events, specifying the timezone
        public EventInfo(String title, String startDate, String endDate,
                boolean allDay, String timezone) {
            init(title, startDate, endDate, allDay, timezone);
        }

        public void init(String title, String startDate, String endDate,
                boolean allDay, String timezone) {
            mTitle = title;
            Time time = new Time();
            if (allDay) {
                time.timezone = Time.TIMEZONE_UTC;
            } else if (timezone != null) {
                time.timezone = timezone;
            }
            mTimezone = time.timezone;
            time.parse3339(startDate);
            mDtstart = time.toMillis(false /* use isDst */);
            time.parse3339(endDate);
            mDtend = time.toMillis(false /* use isDst */);
            mDuration = null;
            mRrule = null;
            mAllDay = allDay;
            mCustomAppPackage = "CustomAppPackage-" + mTitle;
            mCustomAppUri = "CustomAppUri-" + mTitle;
            mUid2445 = null;
        }

        // Constructor for repeating events, using the default timezone
        public EventInfo(String title, String description, String startDate, String endDate,
                String rrule, boolean allDay) {
            init(title, description, startDate, endDate, rrule, allDay, DEFAULT_TIMEZONE);
        }

        // Constructor for repeating events, specifying the timezone
        public EventInfo(String title, String description, String startDate, String endDate,
                String rrule, boolean allDay, String timezone) {
            init(title, description, startDate, endDate, rrule, allDay, timezone);
        }

        public void init(String title, String description, String startDate, String endDate,
                String rrule, boolean allDay, String timezone) {
            mTitle = title;
            mDescription = description;
            Time time = new Time();
            if (allDay) {
                time.timezone = Time.TIMEZONE_UTC;
            } else if (timezone != null) {
                time.timezone = timezone;
            }
            mTimezone = time.timezone;
            time.parse3339(startDate);
            mDtstart = time.toMillis(false /* use isDst */);
            if (endDate != null) {
                time.parse3339(endDate);
                mDtend = time.toMillis(false /* use isDst */);
            }
            if (allDay) {
                long days = 1;
                if (endDate != null) {
                    days = (mDtend - mDtstart) / DateUtils.DAY_IN_MILLIS;
                }
                mDuration = "P" + days + "D";
            } else {
                long seconds = (mDtend - mDtstart) / DateUtils.SECOND_IN_MILLIS;
                mDuration = "P" + seconds + "S";
            }
            mRrule = rrule;
            mAllDay = allDay;
        }

        // Constructor for recurrence exceptions, using the default timezone
        public EventInfo(String originalTitle, String originalInstance, String title,
                String description, String startDate, String endDate, boolean allDay,
                String customPackageName, String customPackageUri, String mUid2445) {
            init(originalTitle, originalInstance,
                    title, description, startDate, endDate, allDay, DEFAULT_TIMEZONE,
                    customPackageName, customPackageUri, mUid2445);
        }

        public void init(String originalTitle, String originalInstance,
                String title, String description, String startDate, String endDate,
                boolean allDay, String timezone, String customPackageName,
                String customPackageUri, String uid2445) {
            mOriginalTitle = originalTitle;
            Time time = new Time(timezone);
            time.parse3339(originalInstance);
            mOriginalInstance = time.toMillis(false /* use isDst */);
            mCustomAppPackage = customPackageName;
            mCustomAppUri = customPackageUri;
            mUid2445 = uid2445;
            init(title, description, startDate, endDate, null /* rrule */, allDay, timezone);
        }
    }

    private class InstanceInfo {
        EventInfo mEvent;
        long mBegin;
        long mEnd;
        int mExpectedOccurrences;

        public InstanceInfo(String eventName, String startDate, String endDate, int expected) {
            // Find the test index that contains the given event name
            mEvent = findEvent(eventName);
            Time time = new Time(mEvent.mTimezone);
            time.parse3339(startDate);
            mBegin = time.toMillis(false /* use isDst */);
            time.parse3339(endDate);
            mEnd = time.toMillis(false /* use isDst */);
            mExpectedOccurrences = expected;
        }
    }

    /**
     * This is the main table of events.  The events in this table are
     * referred to by name in other places.
     */
    private EventInfo[] mEvents = {
            new EventInfo("normal0", "2008-05-01T00:00:00", "2008-05-02T00:00:00", false),
            new EventInfo("normal1", "2008-05-26T08:30:00", "2008-05-26T09:30:00", false),
            new EventInfo("normal2", "2008-05-26T14:30:00", "2008-05-26T15:30:00", false),
            new EventInfo("allday0", "2008-05-02T00:00:00", "2008-05-03T00:00:00", true),
            new EventInfo("allday1", "2008-05-02T00:00:00", "2008-05-31T00:00:00", true),
            new EventInfo("daily0", "daily from 5/1/2008 12am to 1am",
                    "2008-05-01T00:00:00", "2008-05-01T01:00:00",
                    "FREQ=DAILY;WKST=SU", false),
            new EventInfo("daily1", "daily from 5/1/2008 8:30am to 9:30am until 5/3/2008 8am",
                    "2008-05-01T08:30:00", "2008-05-01T09:30:00",
                    "FREQ=DAILY;UNTIL=20080503T150000Z;WKST=SU", false),
            new EventInfo("daily2", "daily from 5/1/2008 8:45am to 9:15am until 5/3/2008 10am",
                    "2008-05-01T08:45:00", "2008-05-01T09:15:00",
                    "FREQ=DAILY;UNTIL=20080503T170000Z;WKST=SU", false),
            new EventInfo("allday daily0", "all-day daily from 5/1/2008",
                    "2008-05-01", null,
                    "FREQ=DAILY;WKST=SU", true),
            new EventInfo("allday daily1", "all-day daily from 5/1/2008 until 5/3/2008",
                    "2008-05-01", null,
                    "FREQ=DAILY;UNTIL=20080503T000000Z;WKST=SU", true),
            new EventInfo("allday weekly0", "all-day weekly from 5/1/2008",
                    "2008-05-01", null,
                    "FREQ=WEEKLY;WKST=SU", true),
            new EventInfo("allday weekly1", "all-day for 2 days weekly from 5/1/2008",
                    "2008-05-01", "2008-05-03",
                    "FREQ=WEEKLY;WKST=SU", true),
            new EventInfo("allday yearly0", "all-day yearly on 5/1/2008",
                    "2008-05-01T", null,
                    "FREQ=YEARLY;WKST=SU", true),
            new EventInfo("weekly0", "weekly from 5/6/2008 on Tue 1pm to 2pm",
                    "2008-05-06T13:00:00", "2008-05-06T14:00:00",
                    "FREQ=WEEKLY;BYDAY=TU;WKST=MO", false),
            new EventInfo("weekly1", "every 2 weeks from 5/6/2008 on Tue from 2:30pm to 3:30pm",
                    "2008-05-06T14:30:00", "2008-05-06T15:30:00",
                    "FREQ=WEEKLY;INTERVAL=2;BYDAY=TU;WKST=MO", false),
            new EventInfo("monthly0", "monthly from 5/20/2008 on the 3rd Tues from 3pm to 4pm",
                    "2008-05-20T15:00:00", "2008-05-20T16:00:00",
                    "FREQ=MONTHLY;BYDAY=3TU;WKST=SU", false),
            new EventInfo("monthly1", "monthly from 5/1/2008 on the 1st from 12:00am to 12:10am",
                    "2008-05-01T00:00:00", "2008-05-01T00:10:00",
                    "FREQ=MONTHLY;WKST=SU;BYMONTHDAY=1", false),
            new EventInfo("monthly2", "monthly from 5/31/2008 on the 31st 11pm to midnight",
                    "2008-05-31T23:00:00", "2008-06-01T00:00:00",
                    "FREQ=MONTHLY;WKST=SU;BYMONTHDAY=31", false),
            new EventInfo("daily0", "2008-05-01T00:00:00",
                    "except0", "daily0 exception for 5/1/2008 12am, change to 5/1/2008 2am to 3am",
                    "2008-05-01T02:00:00", "2008-05-01T01:03:00", false, "AppPkg1", "AppUri1",
                    "uid2445-1"),
            new EventInfo("daily0", "2008-05-03T00:00:00",
                    "except1", "daily0 exception for 5/3/2008 12am, change to 5/3/2008 2am to 3am",
                    "2008-05-03T02:00:00", "2008-05-03T01:03:00", false, "AppPkg2", "AppUri2",
                    null),
            new EventInfo("daily0", "2008-05-02T00:00:00",
                    "except2", "daily0 exception for 5/2/2008 12am, change to 1/2/2008",
                    "2008-01-02T00:00:00", "2008-01-02T01:00:00", false, "AppPkg3", "AppUri3",
                    "12345@uid2445"),
            new EventInfo("weekly0", "2008-05-13T13:00:00",
                    "except3", "daily0 exception for 5/11/2008 1pm, change to 12/11/2008 1pm",
                    "2008-12-11T13:00:00", "2008-12-11T14:00:00", false, "AppPkg4", "AppUri4",
                    null),
            new EventInfo("weekly0", "2008-05-13T13:00:00",
                    "cancel0", "weekly0 exception for 5/13/2008 1pm",
                    "2008-05-13T13:00:00", "2008-05-13T14:00:00", false, "AppPkg5", "AppUri5",
                    null),
            new EventInfo("yearly0", "yearly on 5/1/2008 from 1pm to 2pm",
                    "2008-05-01T13:00:00", "2008-05-01T14:00:00",
                    "FREQ=YEARLY;WKST=SU", false),
    };

    /**
     * This table is used to verify the events generated by mEvents.  It checks that the
     * number of instances within a given range matches the expected number
     * of instances.
     */
    private InstanceInfo[] mInstanceRanges = {
            new InstanceInfo("daily0", "2008-05-01T00:00:00", "2008-05-01T00:01:00", 1),
            new InstanceInfo("daily0", "2008-05-01T00:00:00", "2008-05-01T01:00:00", 1),
            new InstanceInfo("daily0", "2008-05-01T00:00:00", "2008-05-02T00:00:00", 2),
            new InstanceInfo("daily0", "2008-05-01T00:00:00", "2008-05-02T23:59:00", 2),
            new InstanceInfo("daily0", "2008-05-02T00:00:00", "2008-05-02T00:01:00", 1),
            new InstanceInfo("daily0", "2008-05-02T00:00:00", "2008-05-02T01:00:00", 1),
            new InstanceInfo("daily0", "2008-05-02T00:00:00", "2008-05-03T00:00:00", 2),
            new InstanceInfo("daily0", "2008-05-01T00:00:00", "2008-05-31T23:59:00", 31),
            new InstanceInfo("daily0", "2008-05-01T00:00:00", "2008-06-01T23:59:00", 32),

            new InstanceInfo("daily1", "2008-05-01T00:00:00", "2008-05-02T00:00:00", 1),
            new InstanceInfo("daily1", "2008-05-01T00:00:00", "2008-05-31T23:59:00", 2),

            new InstanceInfo("daily2", "2008-05-01T00:00:00", "2008-05-02T00:00:00", 1),
            new InstanceInfo("daily2", "2008-05-01T00:00:00", "2008-05-31T23:59:00", 3),

            new InstanceInfo("allday daily0", "2008-05-01", "2008-05-07", 7),
            new InstanceInfo("allday daily1", "2008-05-01", "2008-05-07", 3),
            new InstanceInfo("allday weekly0", "2008-05-01", "2008-05-07", 1),
            new InstanceInfo("allday weekly0", "2008-05-01", "2008-05-08", 2),
            new InstanceInfo("allday weekly0", "2008-05-01", "2008-05-31", 5),
            new InstanceInfo("allday weekly1", "2008-05-01", "2008-05-31", 5),
            new InstanceInfo("allday yearly0", "2008-05-01", "2009-04-30", 1),
            new InstanceInfo("allday yearly0", "2008-05-01", "2009-05-02", 2),

            new InstanceInfo("weekly0", "2008-05-01T00:00:00", "2008-05-02T00:00:00", 0),
            new InstanceInfo("weekly0", "2008-05-06T00:00:00", "2008-05-07T00:00:00", 1),
            new InstanceInfo("weekly0", "2008-05-01T00:00:00", "2008-05-31T00:00:00", 4),
            new InstanceInfo("weekly0", "2008-05-01T00:00:00", "2008-06-30T00:00:00", 8),

            new InstanceInfo("weekly1", "2008-05-01T00:00:00", "2008-05-02T00:00:00", 0),
            new InstanceInfo("weekly1", "2008-05-06T00:00:00", "2008-05-07T00:00:00", 1),
            new InstanceInfo("weekly1", "2008-05-01T00:00:00", "2008-05-31T00:00:00", 2),
            new InstanceInfo("weekly1", "2008-05-01T00:00:00", "2008-06-30T00:00:00", 4),

            new InstanceInfo("monthly0", "2008-05-01T00:00:00", "2008-05-20T13:00:00", 0),
            new InstanceInfo("monthly0", "2008-05-01T00:00:00", "2008-05-20T15:00:00", 1),
            new InstanceInfo("monthly0", "2008-05-20T16:01:00", "2008-05-31T00:00:00", 0),
            new InstanceInfo("monthly0", "2008-05-20T16:01:00", "2008-06-17T14:59:00", 0),
            new InstanceInfo("monthly0", "2008-05-20T16:01:00", "2008-06-17T15:00:00", 1),
            new InstanceInfo("monthly0", "2008-05-01T00:00:00", "2008-05-31T00:00:00", 1),
            new InstanceInfo("monthly0", "2008-05-01T00:00:00", "2008-06-30T00:00:00", 2),

            new InstanceInfo("monthly1", "2008-05-01T00:00:00", "2008-05-01T01:00:00", 1),
            new InstanceInfo("monthly1", "2008-05-01T00:00:00", "2008-05-31T00:00:00", 1),
            new InstanceInfo("monthly1", "2008-05-01T00:10:00", "2008-05-31T23:59:00", 1),
            new InstanceInfo("monthly1", "2008-05-01T00:11:00", "2008-05-31T23:59:00", 0),
            new InstanceInfo("monthly1", "2008-05-01T00:00:00", "2008-06-01T00:00:00", 2),

            new InstanceInfo("monthly2", "2008-05-01T00:00:00", "2008-05-31T00:00:00", 0),
            new InstanceInfo("monthly2", "2008-05-01T00:10:00", "2008-05-31T23:00:00", 1),
            new InstanceInfo("monthly2", "2008-05-01T00:00:00", "2008-07-01T00:00:00", 1),
            new InstanceInfo("monthly2", "2008-05-01T00:00:00", "2008-08-01T00:00:00", 2),

            new InstanceInfo("yearly0", "2008-05-01", "2009-04-30", 1),
            new InstanceInfo("yearly0", "2008-05-01", "2009-05-02", 2),
    };

    /**
     * This sequence of commands inserts and deletes some events.
     */
    private Command[] mNormalInsertDelete = {
            new Insert("normal0"),
            new Insert("normal1"),
            new Insert("normal2"),
            new QueryNumInstances("2008-05-01T00:00:00", "2008-05-31T00:01:00", 3),
            new Delete("normal1", 1, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
            new QueryNumEvents(2),
            new QueryNumInstances("2008-05-01T00:00:00", "2008-05-31T00:01:00", 2),
            new Delete("normal1", 0, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
            new Delete("normal2", 1, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
            new QueryNumEvents(1),
            new Delete("normal0", 1, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
            new QueryNumEvents(0),
    };

    /**
     * This sequence of commands inserts and deletes some all-day events.
     */
    private Command[] mAlldayInsertDelete = {
            new Insert("allday0"),
            new Insert("allday1"),
            new QueryNumEvents(2),
            new QueryNumInstances("2008-05-01T00:00:00", "2008-05-01T00:01:00", 0),
            new QueryNumInstances("2008-05-02T00:00:00", "2008-05-02T00:01:00", 2),
            new QueryNumInstances("2008-05-03T00:00:00", "2008-05-03T00:01:00", 1),
            new Delete("allday0", 1, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
            new QueryNumEvents(1),
            new QueryNumInstances("2008-05-02T00:00:00", "2008-05-02T00:01:00", 1),
            new QueryNumInstances("2008-05-03T00:00:00", "2008-05-03T00:01:00", 1),
            new Delete("allday1", 1, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
            new QueryNumEvents(0),
    };

    /**
     * This sequence of commands inserts and deletes some repeating events.
     */
    private Command[] mRecurringInsertDelete = {
            new Insert("daily0"),
            new Insert("daily1"),
            new QueryNumEvents(2),
            new QueryNumInstances("2008-05-01T00:00:00", "2008-05-02T00:01:00", 3),
            new QueryNumInstances("2008-05-01T01:01:00", "2008-05-02T00:01:00", 2),
            new QueryNumInstances("2008-05-01T00:00:00", "2008-05-04T00:01:00", 6),
            new Delete("daily1", 1, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
            new QueryNumEvents(1),
            new QueryNumInstances("2008-05-01T00:00:00", "2008-05-02T00:01:00", 2),
            new QueryNumInstances("2008-05-01T00:00:00", "2008-05-04T00:01:00", 4),
            new Delete("daily0", 1, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
            new QueryNumEvents(0),
    };

    /**
     * This sequence of commands creates a recurring event with a recurrence
     * exception that moves an event outside the expansion window.  It checks that the
     * recurrence exception does not occur in the Instances database table.
     * Bug 1642665
     */
    private Command[] mExceptionWithMovedRecurrence = {
            new Insert("daily0"),
            new VerifyAllInstances("2008-05-01T00:00:00", "2008-05-03T00:01:00",
                    new String[] {"2008-05-01T00:00:00", "2008-05-02T00:00:00",
                            "2008-05-03T00:00:00", }),
            new Insert("except2"),
            new VerifyAllInstances("2008-05-01T00:00:00", "2008-05-03T00:01:00",
                    new String[] {"2008-05-01T00:00:00", "2008-05-03T00:00:00"}),
    };

    /**
     * This sequence of commands deletes (cancels) one instance of a recurrence.
     */
    private Command[] mCancelInstance = {
            new Insert("weekly0"),
            new VerifyAllInstances("2008-05-01T00:00:00", "2008-05-22T00:01:00",
                    new String[] {"2008-05-06T13:00:00", "2008-05-13T13:00:00",
                            "2008-05-20T13:00:00", }),
            new Insert("cancel0"),
            new Update("cancel0", new KeyValue[] {
                    new KeyValue(CalendarContract.Events.STATUS,
                        Integer.toString(CalendarContract.Events.STATUS_CANCELED)),
            }),
            new VerifyAllInstances("2008-05-01T00:00:00", "2008-05-22T00:01:00",
                    new String[] {"2008-05-06T13:00:00",
                            "2008-05-20T13:00:00", }),
    };
    /**
     * This sequence of commands creates a recurring event with a recurrence
     * exception that moves an event from outside the expansion window into the
     * expansion window.
     */
    private Command[] mExceptionWithMovedRecurrence2 = {
            new Insert("weekly0"),
            new VerifyAllInstances("2008-12-01T00:00:00", "2008-12-22T00:01:00",
                    new String[] {"2008-12-02T13:00:00", "2008-12-09T13:00:00",
                            "2008-12-16T13:00:00", }),
            new Insert("except3"),
            new VerifyAllInstances("2008-12-01T00:00:00", "2008-12-22T00:01:00",
                    new String[] {"2008-12-02T13:00:00", "2008-12-09T13:00:00",
                            "2008-12-11T13:00:00", "2008-12-16T13:00:00", }),
    };
    /**
     * This sequence of commands creates a recurring event with a recurrence
     * exception and then changes the end time of the recurring event.  It then
     * checks that the recurrence exception does not occur in the Instances
     * database table.
     */
    private Command[]
            mExceptionWithTruncatedRecurrence = {
            new Insert("daily0"),
            // Verify 4 occurrences of the "daily0" repeating event
            new VerifyAllInstances("2008-05-01T00:00:00", "2008-05-04T00:01:00",
                    new String[] {"2008-05-01T00:00:00", "2008-05-02T00:00:00",
                            "2008-05-03T00:00:00", "2008-05-04T00:00:00"}),
            new Insert("except1"),
            new QueryNumEvents(2),

            // Verify that one of the 4 occurrences has its start time changed
            // so that it now matches the recurrence exception.
            new VerifyAllInstances("2008-05-01T00:00:00", "2008-05-04T00:01:00",
                    new String[] {"2008-05-01T00:00:00", "2008-05-02T00:00:00",
                            "2008-05-03T02:00:00", "2008-05-04T00:00:00"}),

            // Change the end time of "daily0" but it still includes the
            // recurrence exception.
            new Update("daily0", new KeyValue[] {
                    new KeyValue(Events.RRULE, "FREQ=DAILY;UNTIL=20080505T150000Z;WKST=SU"),
            }),

            // Verify that the recurrence exception is still there
            new VerifyAllInstances("2008-05-01T00:00:00", "2008-05-04T00:01:00",
                    new String[] {"2008-05-01T00:00:00", "2008-05-02T00:00:00",
                            "2008-05-03T02:00:00", "2008-05-04T00:00:00"}),
            // This time change the end time of "daily0" so that it excludes
            // the recurrence exception.
            new Update("daily0", new KeyValue[] {
                    new KeyValue(Events.RRULE, "FREQ=DAILY;UNTIL=20080502T150000Z;WKST=SU"),
            }),
            // The server will cancel the out-of-range exception.
            // It would be nice for the provider to handle this automatically,
            // but for now simulate the server-side cancel.
            new Update("except1", new KeyValue[] {
                new KeyValue(CalendarContract.Events.STATUS,
                        Integer.toString(CalendarContract.Events.STATUS_CANCELED)),
            }),
            // Verify that the recurrence exception does not appear.
            new VerifyAllInstances("2008-05-01T00:00:00", "2008-05-04T00:01:00",
                    new String[] {"2008-05-01T00:00:00", "2008-05-02T00:00:00"}),
    };

    /**
     * Bug 135848.  Ensure that a recurrence exception is displayed even if the recurrence
     * is not present.
     */
    private Command[] mExceptionWithNoRecurrence = {
            new Insert("except0"),
            new QueryNumEvents(1),
            new VerifyAllInstances("2008-05-01T00:00:00", "2008-05-03T00:01:00",
                    new String[] {"2008-05-01T02:00:00"}),
    };

    private EventInfo findEvent(String name) {
        int len = mEvents.length;
        for (int ii = 0; ii < len; ii++) {
            EventInfo event = mEvents[ii];
            if (name.equals(event.mTitle)) {
                return event;
            }
        }
        return null;
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        // This code here is the code that was originally in ProviderTestCase2
        mResolver = new MockContentResolver();

        final String filenamePrefix = "test.";
        RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext(
                new MockContext2(), // The context that most methods are delegated to
                getContext(), // The context that file methods are delegated to
                filenamePrefix);
        mContext = new IsolatedContext(mResolver, targetContextWrapper) {
            @Override
            public Object getSystemService(String name) {
                // for accessing wakelock.
                if (Context.POWER_SERVICE.equals(name)) {
                    return getContext().getSystemService(name);
                }
                return super.getSystemService(name);
            }
        };

        mProvider = new CalendarProvider2ForTesting();
        ProviderInfo info = new ProviderInfo();
        info.authority = CalendarContract.AUTHORITY;
        mProvider.attachInfoForTesting(mContext, info);

        mResolver.addProvider(CalendarContract.AUTHORITY, mProvider);
        mResolver.addProvider("subscribedfeeds", new MockProvider("subscribedfeeds"));
        mResolver.addProvider("sync", new MockProvider("sync"));

        mMetaData = getProvider().mMetaData;
        mForceDtend = false;

        CalendarDatabaseHelper helper = (CalendarDatabaseHelper) getProvider().getDatabaseHelper();
        mDb = helper.getWritableDatabase();
        wipeAndInitData(helper, mDb);
    }

    @Override
    protected void tearDown() throws Exception {
        try {
            mDb.close();
            mDb = null;
            getProvider().getDatabaseHelper().close();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
        super.tearDown();
    }

    public void wipeAndInitData(SQLiteOpenHelper helper, SQLiteDatabase db)
            throws CalendarCache.CacheException {
        db.beginTransaction();

        // Clean tables
        db.delete("Calendars", null, null);
        db.delete("Events", null, null);
        db.delete("EventsRawTimes", null, null);
        db.delete("Instances", null, null);
        db.delete("CalendarMetaData", null, null);
        db.delete("CalendarCache", null, null);
        db.delete("Attendees", null, null);
        db.delete("Reminders", null, null);
        db.delete("CalendarAlerts", null, null);
        db.delete("ExtendedProperties", null, null);

        // Set CalendarCache data
        initCalendarCacheLocked(helper, db);

        // set CalendarMetaData data
        long now = System.currentTimeMillis();
        ContentValues values = new ContentValues();
        values.put("localTimezone", "America/Los_Angeles");
        values.put("minInstance", 1207008000000L); // 1st April 2008
        values.put("maxInstance", now + ONE_WEEK_MILLIS);
        db.insert("CalendarMetaData", null, values);

        db.setTransactionSuccessful();
        db.endTransaction();
    }

    private void initCalendarCacheLocked(SQLiteOpenHelper helper, SQLiteDatabase db)
            throws CalendarCache.CacheException {
        CalendarCache cache = new CalendarCache(helper);

        String localTimezone = TimeZone.getDefault().getID();

        // Set initial values
        cache.writeDataLocked(db, CalendarCache.KEY_TIMEZONE_DATABASE_VERSION, "2010k");
        cache.writeDataLocked(db, CalendarCache.KEY_TIMEZONE_TYPE, CalendarCache.TIMEZONE_TYPE_AUTO);
        cache.writeDataLocked(db, CalendarCache.KEY_TIMEZONE_INSTANCES, localTimezone);
        cache.writeDataLocked(db, CalendarCache.KEY_TIMEZONE_INSTANCES_PREVIOUS, localTimezone);
    }

    protected CalendarProvider2ForTesting getProvider() {
        return mProvider;
    }

    /**
     * Dumps the contents of the given cursor to the log.  For debugging.
     * @param cursor the database cursor
     */
    private void dumpCursor(Cursor cursor) {
        cursor.moveToPosition(-1);
        String[] cols = cursor.getColumnNames();

        Log.i(TAG, "dumpCursor() count: " + cursor.getCount());
        int index = 0;
        while (cursor.moveToNext()) {
            Log.i(TAG, index + " {");
            for (int i = 0; i < cols.length; i++) {
                Log.i(TAG, "    " + cols[i] + '=' + cursor.getString(i));
            }
            Log.i(TAG, "}");
            index += 1;
        }
        cursor.moveToPosition(-1);
    }

    private int insertCal(String name, String timezone) {
        return insertCal(name, timezone, DEFAULT_ACCOUNT);
    }

    /**
     * Creates a new calendar, with the provided name, time zone, and account name.
     *
     * @return the new calendar's _ID value
     */
    private int insertCal(String name, String timezone, String account) {
        ContentValues m = new ContentValues();
        m.put(Calendars.NAME, name);
        m.put(Calendars.CALENDAR_DISPLAY_NAME, name);
        m.put(Calendars.CALENDAR_COLOR, 0xff123456);
        m.put(Calendars.CALENDAR_TIME_ZONE, timezone);
        m.put(Calendars.VISIBLE, 1);
        m.put(Calendars.CAL_SYNC1, CALENDAR_URL);
        m.put(Calendars.OWNER_ACCOUNT, account);
        m.put(Calendars.ACCOUNT_NAME,  account);
        m.put(Calendars.ACCOUNT_TYPE, DEFAULT_ACCOUNT_TYPE);
        m.put(Calendars.SYNC_EVENTS,  1);

        Uri url = mResolver.insert(
                addSyncQueryParams(mCalendarsUri, account, DEFAULT_ACCOUNT_TYPE), m);
        String id = url.getLastPathSegment();
        return Integer.parseInt(id);
    }

    private String obsToString(Object... objs) {
        StringBuilder bob = new StringBuilder();

        for (Object obj : objs) {
            bob.append(obj.toString());
            bob.append('#');
        }

        return bob.toString();
    }

    private Uri insertColor(long colorType, String colorKey, long color) {
        ContentValues m = new ContentValues();
        m.put(Colors.ACCOUNT_NAME, DEFAULT_ACCOUNT);
        m.put(Colors.ACCOUNT_TYPE, DEFAULT_ACCOUNT_TYPE);
        m.put(Colors.DATA, obsToString(colorType, colorKey, color));
        m.put(Colors.COLOR_TYPE, colorType);
        m.put(Colors.COLOR_KEY, colorKey);
        m.put(Colors.COLOR, color);

        Uri uri = CalendarContract.Colors.CONTENT_URI;

        return mResolver.insert(addSyncQueryParams(uri, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE), m);
    }

    private void updateAndCheckColor(long colorId, long colorType, String colorKey, long color) {

        Uri uri = CalendarContract.Colors.CONTENT_URI;

        final String where = Colors.ACCOUNT_NAME + "=? AND " + Colors.ACCOUNT_TYPE + "=? AND "
                + Colors.COLOR_TYPE + "=? AND " + Colors.COLOR_KEY + "=?";

        String[] selectionArgs = new String[] {
                DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE, Long.toString(colorType), colorKey
        };

        ContentValues cv = new ContentValues();
        cv.put(Colors.COLOR, color);
        cv.put(Colors.DATA, obsToString(colorType, colorKey, color));

        int count = mResolver.update(
                addSyncQueryParams(uri, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE), cv, where,
                selectionArgs);

        checkColor(colorId, colorType, colorKey, color);

        assertEquals(1, count);
    }

    /**
     * Constructs a URI from a base URI (e.g. "content://com.android.calendar/calendars"),
     * an account name, and an account type.
     */
    private Uri addSyncQueryParams(Uri uri, String account, String accountType) {
        return uri.buildUpon().appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
                .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
                .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
    }

    private int deleteMatchingCalendars(String selection, String[] selectionArgs) {
        return mResolver.delete(mCalendarsUri, selection, selectionArgs);
    }

    private Uri insertEvent(int calId, EventInfo event) {
        return insertEvent(calId, event, null);
    }

    private Uri insertEvent(int calId, EventInfo event, ContentValues cv) {
        if (mWipe) {
            // Wipe instance table so it will be regenerated
            mMetaData.clearInstanceRange();
        }

        if (cv == null) {
            cv = eventInfoToContentValues(calId, event);
        }

        Uri url = mResolver.insert(mEventsUri, cv);

        // Create a fake _sync_id and add it to the event.  Update the database
        // directly so that we don't trigger any validation checks in the
        // CalendarProvider.
        long id = ContentUris.parseId(url);
        mDb.execSQL("UPDATE Events SET _sync_id=" + mGlobalSyncId + " WHERE _id=" + id);
        event.mSyncId = mGlobalSyncId;
        mGlobalSyncId += 1;

        return url;
    }

    private ContentValues eventInfoToContentValues(int calId, EventInfo event) {
        ContentValues m = new ContentValues();
        m.put(Events.CALENDAR_ID, calId);
        m.put(Events.TITLE, event.mTitle);
        m.put(Events.DTSTART, event.mDtstart);
        m.put(Events.ALL_DAY, event.mAllDay ? 1 : 0);

        if (event.mRrule == null || mForceDtend) {
            // This is a normal event
            m.put(Events.DTEND, event.mDtend);
            m.remove(Events.DURATION);
        }
        if (event.mRrule != null) {
            // This is a repeating event
            m.put(Events.RRULE, event.mRrule);
            m.put(Events.DURATION, event.mDuration);
            m.remove(Events.DTEND);
        }

        if (event.mDescription != null) {
            m.put(Events.DESCRIPTION, event.mDescription);
        }
        if (event.mTimezone != null) {
            m.put(Events.EVENT_TIMEZONE, event.mTimezone);
        }
        if (event.mCustomAppPackage != null) {
            m.put(Events.CUSTOM_APP_PACKAGE, event.mCustomAppPackage);
        }
        if (event.mCustomAppUri != null) {
            m.put(Events.CUSTOM_APP_URI, event.mCustomAppUri);
        }
        if (event.mUid2445 != null) {
            m.put(Events.UID_2445, event.mUid2445);
        }

        if (event.mOriginalTitle != null) {
            // This is a recurrence exception.
            EventInfo recur = findEvent(event.mOriginalTitle);
            assertNotNull(recur);
            String syncId = String.format("%d", recur.mSyncId);
            m.put(Events.ORIGINAL_SYNC_ID, syncId);
            m.put(Events.ORIGINAL_ALL_DAY, recur.mAllDay ? 1 : 0);
            m.put(Events.ORIGINAL_INSTANCE_TIME, event.mOriginalInstance);
        }
        return m;
    }

    /**
     * Deletes all the events that match the given title.
     * @param title the given title to match events on
     * @return the number of rows deleted
     */
    private int deleteMatchingEvents(String title, String account, String accountType) {
        Cursor cursor = mResolver.query(mEventsUri, new String[] { Events._ID },
                "title=?", new String[] { title }, null);
        int numRows = 0;
        while (cursor.moveToNext()) {
            long id = cursor.getLong(0);
            // Do delete as a sync adapter so event is really deleted, not just marked
            // as deleted.
            Uri uri = updatedUri(ContentUris.withAppendedId(Events.CONTENT_URI, id), true, account,
                    accountType);
            numRows += mResolver.delete(uri, null, null);
        }
        cursor.close();
        return numRows;
    }

    /**
     * Updates all the events that match the given title.
     * @param title the given title to match events on
     * @return the number of rows updated
     */
    private int updateMatchingEvents(String title, ContentValues values) {
        String[] projection = new String[] {
                Events._ID,
                Events.DTSTART,
                Events.DTEND,
                Events.DURATION,
                Events.ALL_DAY,
                Events.RRULE,
                Events.EVENT_TIMEZONE,
                Events.ORIGINAL_SYNC_ID,
        };
        Cursor cursor = mResolver.query(mEventsUri, projection,
                "title=?", new String[] { title }, null);
        int numRows = 0;
        while (cursor.moveToNext()) {
            long id = cursor.getLong(0);

            // If any of the following fields are being changed, then we need
            // to include all of them.
            if (values.containsKey(Events.DTSTART) || values.containsKey(Events.DTEND)
                    || values.containsKey(Events.DURATION) || values.containsKey(Events.ALL_DAY)
                    || values.containsKey(Events.RRULE)
                    || values.containsKey(Events.EVENT_TIMEZONE)
                    || values.containsKey(CalendarContract.Events.STATUS)) {
                long dtstart = cursor.getLong(1);
                long dtend = cursor.getLong(2);
                String duration = cursor.getString(3);
                boolean allDay = cursor.getInt(4) != 0;
                String rrule = cursor.getString(5);
                String timezone = cursor.getString(6);
                String originalEvent = cursor.getString(7);

                if (!values.containsKey(Events.DTSTART)) {
                    values.put(Events.DTSTART, dtstart);
                }
                // Don't add DTEND for repeating events
                if (!values.containsKey(Events.DTEND) && rrule == null) {
                    values.put(Events.DTEND, dtend);
                }
                if (!values.containsKey(Events.DURATION) && duration != null) {
                    values.put(Events.DURATION, duration);
                }
                if (!values.containsKey(Events.ALL_DAY)) {
                    values.put(Events.ALL_DAY, allDay ? 1 : 0);
                }
                if (!values.containsKey(Events.RRULE) && rrule != null) {
                    values.put(Events.RRULE, rrule);
                }
                if (!values.containsKey(Events.EVENT_TIMEZONE) && timezone != null) {
                    values.put(Events.EVENT_TIMEZONE, timezone);
                }
                if (!values.containsKey(Events.ORIGINAL_SYNC_ID) && originalEvent != null) {
                    values.put(Events.ORIGINAL_SYNC_ID, originalEvent);
                }
            }

            Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, id);
            numRows += mResolver.update(uri, values, null, null);
        }
        cursor.close();
        return numRows;
    }

    /**
     * Updates the status of all the events that match the given title.
     * @param title the given title to match events on
     * @return the number of rows updated
     */
    private int updateMatchingEventsStatusOnly(String title, ContentValues values) {
        String[] projection = new String[] {
                Events._ID,
        };
        if (values.size() != 1 && !values.containsKey(Events.STATUS)) {
            return 0;
        }
        Cursor cursor = mResolver.query(mEventsUri, projection,
                "title=?", new String[] { title }, null);
        int numRows = 0;
        while (cursor.moveToNext()) {
            long id = cursor.getLong(0);

            Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, id);
            numRows += mResolver.update(uri, values, null, null);
        }
        cursor.close();
        return numRows;
    }


    private void deleteAllEvents() {
        mDb.execSQL("DELETE FROM Events;");
        mMetaData.clearInstanceRange();
    }

    /**
     * Creates an updated URI that includes query parameters that identify the source as a
     * sync adapter.
     */
    static Uri asSyncAdapter(Uri uri, String account, String accountType) {
        return uri.buildUpon()
                .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,
                        "true")
                .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
                .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
    }

    public void testInsertUpdateDeleteColor() throws Exception {
        // Calendar Color
        long colorType = Colors.TYPE_CALENDAR;
        String colorKey = "123";
        long colorValue = 11;
        long colorId = insertAndCheckColor(colorType, colorKey, colorValue);

        try {
            insertAndCheckColor(colorType, colorKey, colorValue);
            fail("Expected to fail with duplicate insertion");
        } catch (IllegalArgumentException iae) {
            // good
        }

        // Test Update
        colorValue += 11;
        updateAndCheckColor(colorId, colorType, colorKey, colorValue);

        // Event Color
        colorType = Colors.TYPE_EVENT;
        colorValue += 11;
        colorId = insertAndCheckColor(colorType, colorKey, colorValue);
        try {
            insertAndCheckColor(colorType, colorKey, colorValue);
            fail("Expected to fail with duplicate insertion");
        } catch (IllegalArgumentException iae) {
            // good
        }

        // Create an event with the old color value.
        int calendarId0 = insertCal("Calendar0", DEFAULT_TIMEZONE);
        String title = "colorTest";
        ContentValues cv = this.eventInfoToContentValues(calendarId0, mEvents[0]);
        cv.put(Events.EVENT_COLOR_KEY, colorKey);
        cv.put(Events.TITLE, title);
        Uri uri = insertEvent(calendarId0, mEvents[0], cv);
        Cursor c = mResolver.query(uri, new String[] {Events.EVENT_COLOR},  null, null, null);
        try {
            // Confirm the color is set.
            c.moveToFirst();
            assertEquals(colorValue, c.getInt(0));
        } finally {
            if (c != null) {
                c.close();
            }
        }

        // Test Update
        colorValue += 11;
        updateAndCheckColor(colorId, colorType, colorKey, colorValue);

        // Check if color was updated in event.
        c = mResolver.query(uri, new String[] {Events.EVENT_COLOR}, null, null, null);
        try {
            c.moveToFirst();
            assertEquals(colorValue, c.getInt(0));
        } finally {
            if (c != null) {
                c.close();
            }
        }

        // Test Delete
        Uri colSyncUri = asSyncAdapter(Colors.CONTENT_URI, DEFAULT_ACCOUNT,
                DEFAULT_ACCOUNT_TYPE);
        try {
            // Delete should fail if color referenced by an event.
            mResolver.delete(colSyncUri, WHERE_COLOR_ACCOUNT_AND_INDEX,
                    new String[] {DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE, colorKey});
            fail("Should not allow deleting referenced color");
        } catch (UnsupportedOperationException e) {
            // Exception expected.
        }
        Cursor cursor = mResolver.query(Colors.CONTENT_URI, new String[] {Colors.COLOR_KEY},
                Colors.COLOR_KEY + "=? AND " + Colors.COLOR_TYPE + "=?",
                new String[] {colorKey, Long.toString(colorType)}, null);
        assertEquals(1, cursor.getCount());

        // Try again, by deleting the event, then the color.
        assertEquals(1, deleteMatchingEvents(title, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE));
        mResolver.delete(colSyncUri, WHERE_COLOR_ACCOUNT_AND_INDEX,
                new String[] {DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE, colorKey});
        cursor = mResolver.query(Colors.CONTENT_URI, new String[] {Colors.COLOR_KEY},
                Colors.COLOR_KEY + "=? AND " + Colors.COLOR_TYPE + "=?",
                new String[] {colorKey, Long.toString(colorType)}, null);
        assertEquals(0, cursor.getCount());
    }

    private void checkColor(long colorId, long colorType, String colorKey, long color) {
        String[] projection = new String[] {
                Colors.ACCOUNT_NAME, // 0
                Colors.ACCOUNT_TYPE, // 1
                Colors.COLOR_TYPE,   // 2
                Colors.COLOR_KEY,    // 3
                Colors.COLOR,        // 4
                Colors._ID,          // 5
                Colors.DATA,         // 6
        };
        Cursor cursor = mResolver.query(Colors.CONTENT_URI, projection, Colors.COLOR_KEY
                + "=? AND " + Colors.COLOR_TYPE + "=?", new String[] {
                colorKey, Long.toString(colorType)
        }, null /* sortOrder */);

        assertEquals(1, cursor.getCount());

        assertTrue(cursor.moveToFirst());
        assertEquals(DEFAULT_ACCOUNT, cursor.getString(0));
        assertEquals(DEFAULT_ACCOUNT_TYPE, cursor.getString(1));
        assertEquals(colorType, cursor.getLong(2));
        assertEquals(colorKey, cursor.getString(3));
        assertEquals(color, cursor.getLong(4));
        assertEquals(colorId, cursor.getLong(5));
        assertEquals(obsToString(colorType, colorKey, color), cursor.getString(6));
        cursor.close();
    }

    private long insertAndCheckColor(long colorType, String colorKey, long color) {
        Uri uri = insertColor(colorType, colorKey, color);
        long id = Long.parseLong(uri.getLastPathSegment());

        checkColor(id, colorType, colorKey, color);
        return id;
    }

    public void testInsertNormalEvents() throws Exception {
        final int calId = insertCal("Calendar0", DEFAULT_TIMEZONE);
        Cursor cursor = mResolver.query(mEventsUri, null, null, null, null);
        assertEquals(0, cursor.getCount());
        cursor.close();

        // Keep track of the number of normal events
        int numOfInserts = 0;

        // "begin" is the earliest start time of all the normal events,
        // and "end" is the latest end time of all the normal events.
        long begin = 0, end = 0;

        int len = mEvents.length;
        Uri[] uris = new Uri[len];
        ContentValues[] cvs = new ContentValues[len];
        for (int ii = 0; ii < len; ii++) {
            EventInfo event = mEvents[ii];
            // Skip repeating events and recurrence exceptions
            if (event.mRrule != null || event.mOriginalTitle != null) {
                continue;
            }
            if (numOfInserts == 0) {
                begin = event.mDtstart;
                end = event.mDtend;
            } else {
                if (begin > event.mDtstart) {
                    begin = event.mDtstart;
                }
                if (end < event.mDtend) {
                    end = event.mDtend;
                }
            }

            cvs[ii] = eventInfoToContentValues(calId, event);
            uris[ii] = insertEvent(calId, event, cvs[ii]);
            numOfInserts += 1;
        }

        // Verify
        for (int i = 0; i < len; i++) {
            if (cvs[i] == null) continue;
            assertNotNull(uris[i]);
            cursor = mResolver.query(uris[i], null, null, null, null);
            assertEquals("Item " + i + " not found", 1, cursor.getCount());
            verifyContentValueAgainstCursor(cvs[i], cvs[i].keySet(), cursor);
            cursor.close();
        }

        // query all
        cursor = mResolver.query(mEventsUri, null, null, null, null);
        assertEquals(numOfInserts, cursor.getCount());
        cursor.close();

        // Check that the Instances table has one instance of each of the
        // normal events.
        cursor = queryInstances(begin, end);
        assertEquals(numOfInserts, cursor.getCount());
        cursor.close();
    }

    public void testInsertRepeatingEvents() throws Exception {
        Cursor cursor;
        Uri url = null;

        int calId = insertCal("Calendar0", "America/Los_Angeles");

        cursor = mResolver.query(mEventsUri, null, null, null, null);
        assertEquals(0, cursor.getCount());
        cursor.close();

        // Keep track of the number of repeating events
        int numOfInserts = 0;

        int len = mEvents.length;
        Uri[] uris = new Uri[len];
        ContentValues[] cvs = new ContentValues[len];
        for (int ii = 0; ii < len; ii++) {
            EventInfo event = mEvents[ii];
            // Skip normal events
            if (event.mRrule == null) {
                continue;
            }
            cvs[ii] = eventInfoToContentValues(calId, event);
            uris[ii] = insertEvent(calId, event, cvs[ii]);
            numOfInserts += 1;
        }

        // Verify
        for (int i = 0; i < len; i++) {
            if (cvs[i] == null) continue;
            assertNotNull(uris[i]);
            cursor = mResolver.query(uris[i], null, null, null, null);
            assertEquals("Item " + i + " not found", 1, cursor.getCount());
            verifyContentValueAgainstCursor(cvs[i], cvs[i].keySet(), cursor);
            cursor.close();
        }

        // query all
        cursor = mResolver.query(mEventsUri, null, null, null, null);
        assertEquals(numOfInserts, cursor.getCount());
        cursor.close();
    }

    // Force a dtend value to be set and make sure instance expansion still works
    public void testInstanceRangeDtend() throws Exception {
        mForceDtend = true;
        testInstanceRange();
    }

    public void testInstanceRange() throws Exception {
        Cursor cursor;
        Uri url = null;

        int calId = insertCal("Calendar0", "America/Los_Angeles");

        cursor = mResolver.query(mEventsUri, null, null, null, null);
        assertEquals(0, cursor.getCount());
        cursor.close();

        int len = mInstanceRanges.length;
        for (int ii = 0; ii < len; ii++) {
            InstanceInfo instance = mInstanceRanges[ii];
            EventInfo event = instance.mEvent;
            url = insertEvent(calId, event);
            cursor = queryInstances(instance.mBegin, instance.mEnd);
            if (instance.mExpectedOccurrences != cursor.getCount()) {
                Log.e(TAG, "Test failed! Instance index: " + ii);
                Log.e(TAG, "title: " + event.mTitle + " desc: " + event.mDescription
                        + " [begin,end]: [" + instance.mBegin + " " + instance.mEnd + "]"
                        + " expected: " + instance.mExpectedOccurrences);
                dumpCursor(cursor);
            }
            assertEquals(instance.mExpectedOccurrences, cursor.getCount());
            cursor.close();
            // Delete as sync_adapter so event is really deleted.
            int rows = mResolver.delete(
                    updatedUri(url, true, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
                    null /* selection */, null /* selection args */);
            assertEquals(1, rows);
        }
    }

    public static <T> void assertArrayEquals(T[] expected, T[] actual) {
        if (!Arrays.equals(expected, actual)) {
            fail("expected:<" + Arrays.toString(expected) +
                "> but was:<" + Arrays.toString(actual) + ">");
        }
    }

    @SmallTest @Smoke
    public void testEscapeSearchToken() {
        String token = "test";
        String expected = "test";
        assertEquals(expected, mProvider.escapeSearchToken(token));

        token = "%";
        expected = "#%";
        assertEquals(expected, mProvider.escapeSearchToken(token));

        token = "_";
        expected = "#_";
        assertEquals(expected, mProvider.escapeSearchToken(token));

        token = "#";
        expected = "##";
        assertEquals(expected, mProvider.escapeSearchToken(token));

        token = "##";
        expected = "####";
        assertEquals(expected, mProvider.escapeSearchToken(token));

        token = "%_#";
        expected = "#%#_##";
        assertEquals(expected, mProvider.escapeSearchToken(token));

        token = "blah%blah";
        expected = "blah#%blah";
        assertEquals(expected, mProvider.escapeSearchToken(token));
    }

    @SmallTest @Smoke
    public void testTokenizeSearchQuery() {
        String query = "";
        String[] expectedTokens = new String[] {};
        assertArrayEquals(expectedTokens, mProvider.tokenizeSearchQuery(query));

        query = "a";
        expectedTokens = new String[] {"a"};
        assertArrayEquals(expectedTokens, mProvider.tokenizeSearchQuery(query));

        query = "word";
        expectedTokens = new String[] {"word"};
        assertArrayEquals(expectedTokens, mProvider.tokenizeSearchQuery(query));

        query = "two words";
        expectedTokens = new String[] {"two", "words"};
        assertArrayEquals(expectedTokens, mProvider.tokenizeSearchQuery(query));

        query = "test, punctuation.";
        expectedTokens = new String[] {"test", "punctuation"};
        assertArrayEquals(expectedTokens, mProvider.tokenizeSearchQuery(query));

        query = "\"test phrase\"";
        expectedTokens = new String[] {"test phrase"};
        assertArrayEquals(expectedTokens, mProvider.tokenizeSearchQuery(query));

        query = "unquoted \"this is quoted\"";
        expectedTokens = new String[] {"unquoted", "this is quoted"};
        assertArrayEquals(expectedTokens, mProvider.tokenizeSearchQuery(query));

        query = " \"this is quoted\"  unquoted ";
        expectedTokens = new String[] {"this is quoted", "unquoted"};
        assertArrayEquals(expectedTokens, mProvider.tokenizeSearchQuery(query));

        query = "escap%e m_e";
        expectedTokens = new String[] {"escap#%e", "m#_e"};
        assertArrayEquals(expectedTokens, mProvider.tokenizeSearchQuery(query));

        query = "'a bunch' of malformed\" things";
        expectedTokens = new String[] {"a", "bunch", "of", "malformed", "things"};
        assertArrayEquals(expectedTokens, mProvider.tokenizeSearchQuery(query));

        query = "''''''....,.''trim punctuation";
        expectedTokens = new String[] {"trim", "punctuation"};
        assertArrayEquals(expectedTokens, mProvider.tokenizeSearchQuery(query));
    }

    @SmallTest @Smoke
    public void testConstructSearchWhere() {
        String[] tokens = new String[] {"red"};
        String expected = "(title LIKE ? ESCAPE \"#\" OR "
            + "description LIKE ? ESCAPE \"#\" OR "
            + "eventLocation LIKE ? ESCAPE \"#\" OR "
            + "group_concat(attendeeEmail) LIKE ? ESCAPE \"#\" OR "
            + "group_concat(attendeeName) LIKE ? ESCAPE \"#\" )";
        assertEquals(expected, mProvider.constructSearchWhere(tokens));

        tokens = new String[] {};
        expected = "";
        assertEquals(expected, mProvider.constructSearchWhere(tokens));

        tokens = new String[] {"red", "green"};
        expected = "(title LIKE ? ESCAPE \"#\" OR "
                + "description LIKE ? ESCAPE \"#\" OR "
                + "eventLocation LIKE ? ESCAPE \"#\" OR "
                + "group_concat(attendeeEmail) LIKE ? ESCAPE \"#\" OR "
                + "group_concat(attendeeName) LIKE ? ESCAPE \"#\" ) AND "
                + "(title LIKE ? ESCAPE \"#\" OR "
                + "description LIKE ? ESCAPE \"#\" OR "
                + "eventLocation LIKE ? ESCAPE \"#\" OR "
                + "group_concat(attendeeEmail) LIKE ? ESCAPE \"#\" OR "
                + "group_concat(attendeeName) LIKE ? ESCAPE \"#\" )";
        assertEquals(expected, mProvider.constructSearchWhere(tokens));

        tokens = new String[] {"red blue", "green"};
        expected = "(title LIKE ? ESCAPE \"#\" OR "
            + "description LIKE ? ESCAPE \"#\" OR "
            + "eventLocation LIKE ? ESCAPE \"#\" OR "
            + "group_concat(attendeeEmail) LIKE ? ESCAPE \"#\" OR "
            + "group_concat(attendeeName) LIKE ? ESCAPE \"#\" ) AND "
            + "(title LIKE ? ESCAPE \"#\" OR "
            + "description LIKE ? ESCAPE \"#\" OR "
            + "eventLocation LIKE ? ESCAPE \"#\" OR "
            + "group_concat(attendeeEmail) LIKE ? ESCAPE \"#\" OR "
            + "group_concat(attendeeName) LIKE ? ESCAPE \"#\" )";
        assertEquals(expected, mProvider.constructSearchWhere(tokens));
    }

    @SmallTest @Smoke
    public void testConstructSearchArgs() {
        String[] tokens = new String[] {"red"};
        String[] expected = new String[] {"%red%", "%red%",
                "%red%", "%red%", "%red%" };
        assertArrayEquals(expected, mProvider.constructSearchArgs(tokens));

        tokens = new String[] {"red", "blue"};
        expected = new String[] { "%red%", "%red%", "%red%",
                "%red%", "%red%", "%blue%", "%blue%",
                "%blue%", "%blue%","%blue%"};
        assertArrayEquals(expected, mProvider.constructSearchArgs(tokens));

        tokens = new String[] {};
        expected = new String[] {};
        assertArrayEquals(expected, mProvider.constructSearchArgs(tokens));
    }

    public void testInstanceSearchQuery() throws Exception {
        final String[] PROJECTION = new String[] {
                Instances.TITLE,                 // 0
                Instances.EVENT_LOCATION,        // 1
                Instances.ALL_DAY,               // 2
                Instances.CALENDAR_COLOR,        // 3
                Instances.EVENT_TIMEZONE,        // 4
                Instances.EVENT_ID,              // 5
                Instances.BEGIN,                 // 6
                Instances.END,                   // 7
                Instances._ID,                   // 8
                Instances.START_DAY,             // 9
                Instances.END_DAY,               // 10
                Instances.START_MINUTE,          // 11
                Instances.END_MINUTE,            // 12
                Instances.HAS_ALARM,             // 13
                Instances.RRULE,                 // 14
                Instances.RDATE,                 // 15
                Instances.SELF_ATTENDEE_STATUS,  // 16
                Events.ORGANIZER,                // 17
                Events.GUESTS_CAN_MODIFY,        // 18
        };

        String orderBy = CalendarProvider2.SORT_CALENDAR_VIEW;
        String where = Instances.SELF_ATTENDEE_STATUS + "!=" +
                CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED;

        int calId = insertCal("Calendar0", DEFAULT_TIMEZONE);
        final String START = "2008-05-01T00:00:00";
        final String END = "2008-05-01T20:00:00";

        EventInfo event1 = new EventInfo("search orange",
                START,
                END,
                false /* allDay */,
                DEFAULT_TIMEZONE);
        event1.mDescription = "this is description1";

        EventInfo event2 = new EventInfo("search purple",
                START,
                END,
                false /* allDay */,
                DEFAULT_TIMEZONE);
        event2.mDescription = "lasers, out of nowhere";

        EventInfo event3 = new EventInfo("",
                START,
                END,
                false /* allDay */,
                DEFAULT_TIMEZONE);
        event3.mDescription = "kapow";

        EventInfo[] events = { event1, event2, event3 };

        insertEvent(calId, events[0]);
        insertEvent(calId, events[1]);
        insertEvent(calId, events[2]);

        Time time = new Time(DEFAULT_TIMEZONE);
        time.parse3339(START);
        long startMs = time.toMillis(true /* ignoreDst */);
        // Query starting from way in the past to one hour into the event.
        // Query is more than 2 months so the range won't get extended by the provider.
        Cursor cursor = null;

        try {
            cursor = queryInstances(mResolver, PROJECTION,
                    startMs - DateUtils.YEAR_IN_MILLIS,
                    startMs + DateUtils.HOUR_IN_MILLIS,
                    "search", where, null, orderBy);
            assertEquals(2, cursor.getCount());
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        try {
            cursor = queryInstances(mResolver, PROJECTION,
                    startMs - DateUtils.YEAR_IN_MILLIS,
                    startMs + DateUtils.HOUR_IN_MILLIS,
                    "purple", where, null, orderBy);
            assertEquals(1, cursor.getCount());
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        try {
            cursor = queryInstances(mResolver, PROJECTION,
                    startMs - DateUtils.YEAR_IN_MILLIS,
                    startMs + DateUtils.HOUR_IN_MILLIS,
                    "puurple", where, null, orderBy);
            assertEquals(0, cursor.getCount());
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        try {
            cursor = queryInstances(mResolver, PROJECTION,
                    startMs - DateUtils.YEAR_IN_MILLIS,
                    startMs + DateUtils.HOUR_IN_MILLIS,
                    "purple lasers", where, null, orderBy);
            assertEquals(1, cursor.getCount());
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        try {
            cursor = queryInstances(mResolver, PROJECTION,
                    startMs - DateUtils.YEAR_IN_MILLIS,
                    startMs + DateUtils.HOUR_IN_MILLIS,
                    "lasers kapow", where, null, orderBy);
            assertEquals(0, cursor.getCount());
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        try {
            cursor = queryInstances(mResolver, PROJECTION,
                    startMs - DateUtils.YEAR_IN_MILLIS,
                    startMs + DateUtils.HOUR_IN_MILLIS,
                    "\"search purple\"", where, null, orderBy);
            assertEquals(1, cursor.getCount());
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        try {
            cursor = queryInstances(mResolver, PROJECTION,
                    startMs - DateUtils.YEAR_IN_MILLIS,
                    startMs + DateUtils.HOUR_IN_MILLIS,
                    "\"purple search\"", where, null, orderBy);
            assertEquals(0, cursor.getCount());
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        try {
            cursor = queryInstances(mResolver, PROJECTION,
                    startMs - DateUtils.YEAR_IN_MILLIS,
                    startMs + DateUtils.HOUR_IN_MILLIS,
                    "%", where, null, orderBy);
            assertEquals(0, cursor.getCount());
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

    public void testDeleteCalendar() throws Exception {
        int calendarId0 = insertCal("Calendar0", DEFAULT_TIMEZONE);
        int calendarId1 = insertCal("Calendar1", DEFAULT_TIMEZONE, "user2@google.com");
        insertEvent(calendarId0, mEvents[0]);
        insertEvent(calendarId1, mEvents[1]);
        // Should have 2 calendars and 2 events
        testQueryCount(CalendarContract.Calendars.CONTENT_URI, null /* where */, 2);
        testQueryCount(CalendarContract.Events.CONTENT_URI, null /* where */, 2);

        int deletes = mResolver.delete(CalendarContract.Calendars.CONTENT_URI,
                "ownerAccount='user2@google.com'", null /* selectionArgs */);

        assertEquals(1, deletes);
        // Should have 1 calendar and 1 event
        testQueryCount(CalendarContract.Calendars.CONTENT_URI, null /* where */, 1);
        testQueryCount(CalendarContract.Events.CONTENT_URI, null /* where */, 1);

        deletes = mResolver.delete(Uri.withAppendedPath(CalendarContract.Calendars.CONTENT_URI,
                String.valueOf(calendarId0)),
                null /* selection*/ , null /* selectionArgs */);

        assertEquals(1, deletes);
        // Should have 0 calendars and 0 events
        testQueryCount(CalendarContract.Calendars.CONTENT_URI, null /* where */, 0);
        testQueryCount(CalendarContract.Events.CONTENT_URI, null /* where */, 0);

        deletes = mResolver.delete(CalendarContract.Calendars.CONTENT_URI,
                "ownerAccount=?", new String[] {"user2@google.com"} /* selectionArgs */);

        assertEquals(0, deletes);
    }

    public void testCalendarAlerts() throws Exception {
        // This projection is from AlertActivity; want to make sure it works.
        String[] projection = new String[] {
                CalendarContract.CalendarAlerts._ID,              // 0
                CalendarContract.CalendarAlerts.TITLE,            // 1
                CalendarContract.CalendarAlerts.EVENT_LOCATION,   // 2
                CalendarContract.CalendarAlerts.ALL_DAY,          // 3
                CalendarContract.CalendarAlerts.BEGIN,            // 4
                CalendarContract.CalendarAlerts.END,              // 5
                CalendarContract.CalendarAlerts.EVENT_ID,         // 6
                CalendarContract.CalendarAlerts.CALENDAR_COLOR,   // 7
                CalendarContract.CalendarAlerts.RRULE,            // 8
                CalendarContract.CalendarAlerts.HAS_ALARM,        // 9
                CalendarContract.CalendarAlerts.STATE,            // 10
                CalendarContract.CalendarAlerts.ALARM_TIME,       // 11
        };

        mCalendarId = insertCal("CalendarTestAttendees", DEFAULT_TIMEZONE);
        String calendarIdString = Integer.toString(mCalendarId);
        checkEvents(0, mDb, calendarIdString);
        Uri eventUri = insertEvent(mCalendarId, findEvent("normal0"));
        checkEvents(1, mDb, calendarIdString);
        long eventId = ContentUris.parseId(eventUri);

        Uri alertUri = CalendarContract.CalendarAlerts.insert(mResolver, eventId /* eventId */,
                2 /* begin */, 3 /* end */, 4 /* alarmTime */, 5 /* minutes */);
        CalendarContract.CalendarAlerts.insert(mResolver, eventId /* eventId */,
                2 /* begin */, 7 /* end */, 8 /* alarmTime */, 9 /* minutes */);

        // Regular query
        Cursor cursor = mResolver.query(CalendarContract.CalendarAlerts.CONTENT_URI, projection,
                null /* selection */, null /* selectionArgs */, null /* sortOrder */);

        assertEquals(2, cursor.getCount());
        cursor.close();

        // Instance query
        cursor = mResolver.query(alertUri, projection,
                null /* selection */, null /* selectionArgs */, null /* sortOrder */);

        assertEquals(1, cursor.getCount());
        cursor.close();

        // Grouped by event query
        cursor = mResolver.query(CalendarContract.CalendarAlerts.CONTENT_URI_BY_INSTANCE,
                projection, null /* selection */, null /* selectionArgs */, null /* sortOrder */);

        assertEquals(1, cursor.getCount());
        cursor.close();
    }

    public void testInsertAlertToNonExistentEvent() {
        Uri alertUri = CalendarContract.CalendarAlerts.insert(mResolver, 1 /* eventId */,
                2 /* begin */, 3 /* end */, 4 /* alarmTime */, 5 /* minutes */);
        assertEquals(null, alertUri);
    }

    public void testInsertReminderToNonExistentEvent() {
        ContentValues reminder = new ContentValues();
        reminder.put(CalendarContract.Reminders.MINUTES, 30);
        reminder.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_EMAIL);
        reminder.put(CalendarContract.Attendees.EVENT_ID, 1);
        Uri reminderUri = mResolver.insert(
                updatedUri(CalendarContract.Reminders.CONTENT_URI, true, DEFAULT_ACCOUNT,
                        DEFAULT_ACCOUNT_TYPE), reminder);
        assertEquals(null, reminderUri);
    }

    public void testInsertAttendeeToNonExistentEvent() {
        ContentValues attendee = new ContentValues();
        attendee.put(CalendarContract.Attendees.ATTENDEE_NAME, "Joe");
        attendee.put(CalendarContract.Attendees.ATTENDEE_EMAIL, DEFAULT_ACCOUNT);
        attendee.put(CalendarContract.Attendees.ATTENDEE_TYPE,
                CalendarContract.Attendees.TYPE_REQUIRED);
        attendee.put(CalendarContract.Attendees.ATTENDEE_RELATIONSHIP,
                CalendarContract.Attendees.RELATIONSHIP_ORGANIZER);
        attendee.put(CalendarContract.Attendees.EVENT_ID, 1);
        attendee.put(CalendarContract.Attendees.ATTENDEE_IDENTITY, "ID1");
        attendee.put(CalendarContract.Attendees.ATTENDEE_ID_NAMESPACE, "IDNS1");
        Uri attendeesUri = mResolver.insert(CalendarContract.Attendees.CONTENT_URI, attendee);
        assertEquals(null, attendeesUri);
    }

    public void testInsertExtendedPropertyToNonExistentEvent() {
        ContentValues extended = new ContentValues();
        extended.put(CalendarContract.ExtendedProperties.NAME, "foo");
        extended.put(CalendarContract.ExtendedProperties.VALUE, "bar");
        extended.put(CalendarContract.ExtendedProperties.EVENT_ID, 1);

        Uri extendedUri = mResolver.insert(
                updatedUri(CalendarContract.ExtendedProperties.CONTENT_URI, true,
                        DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE), extended);
        assertEquals(null, extendedUri);
    }

    void checkEvents(int count, SQLiteDatabase db) {
        Cursor cursor = db.query("Events", null, null, null, null, null, null);
        try {
            assertEquals(count, cursor.getCount());
        } finally {
            cursor.close();
        }
    }

    void checkEvents(int count, SQLiteDatabase db, String calendar) {
        Cursor cursor = db.query("Events", null, Events.CALENDAR_ID + "=?", new String[] {calendar},
                null, null, null);
        try {
            assertEquals(count, cursor.getCount());
        } finally {
            cursor.close();
        }
    }


//    TODO Reenable this when we are ready to work on this
//
//    public void testToShowInsertIsSlowForRecurringEvents() throws Exception {
//        mCalendarId = insertCal("CalendarTestToShowInsertIsSlowForRecurringEvents", DEFAULT_TIMEZONE);
//        String calendarIdString = Integer.toString(mCalendarId);
//        long testStart = System.currentTimeMillis();
//
//        final int testTrials = 100;
//
//        for (int i = 0; i < testTrials; i++) {
//            checkEvents(i, mDb, calendarIdString);
//            long insertStartTime = System.currentTimeMillis();
//            Uri eventUri = insertEvent(mCalendarId, findEvent("daily0"));
//            Log.e(TAG, i + ") insertion time " + (System.currentTimeMillis() - insertStartTime));
//        }
//        Log.e(TAG, " Avg insertion time = " + (System.currentTimeMillis() - testStart)/testTrials);
//    }

    /**
     * Test attendee processing
     * @throws Exception
     */
    public void testAttendees() throws Exception {
        mCalendarId = insertCal("CalendarTestAttendees", DEFAULT_TIMEZONE);
        String calendarIdString = Integer.toString(mCalendarId);
        checkEvents(0, mDb, calendarIdString);
        Uri eventUri = insertEvent(mCalendarId, findEvent("normal0"));
        checkEvents(1, mDb, calendarIdString);
        long eventId = ContentUris.parseId(eventUri);

        ContentValues attendee = new ContentValues();
        attendee.put(CalendarContract.Attendees.ATTENDEE_NAME, "Joe");
        attendee.put(CalendarContract.Attendees.ATTENDEE_EMAIL, DEFAULT_ACCOUNT);
        attendee.put(CalendarContract.Attendees.ATTENDEE_TYPE,
                CalendarContract.Attendees.TYPE_REQUIRED);
        attendee.put(CalendarContract.Attendees.ATTENDEE_RELATIONSHIP,
                CalendarContract.Attendees.RELATIONSHIP_ORGANIZER);
        attendee.put(CalendarContract.Attendees.EVENT_ID, eventId);
        attendee.put(CalendarContract.Attendees.ATTENDEE_IDENTITY, "ID1");
        attendee.put(CalendarContract.Attendees.ATTENDEE_ID_NAMESPACE, "IDNS1");
        Uri attendeesUri = mResolver.insert(CalendarContract.Attendees.CONTENT_URI, attendee);

        Cursor cursor = mResolver.query(CalendarContract.Attendees.CONTENT_URI, null,
                "event_id=" + eventId, null, null);
        assertEquals("Created event is missing - cannot find EventUri = " + eventUri, 1,
                cursor.getCount());
        Set<String> attendeeColumns = attendee.keySet();
        verifyContentValueAgainstCursor(attendee, attendeeColumns, cursor);
        cursor.close();

        cursor = mResolver.query(eventUri, null, null, null, null);
        // TODO figure out why this test fails. App works fine for this case.
        assertEquals("Created event is missing - cannot find EventUri = " + eventUri, 1,
                cursor.getCount());
        int selfColumn = cursor.getColumnIndex(CalendarContract.Events.SELF_ATTENDEE_STATUS);
        cursor.moveToNext();
        long selfAttendeeStatus = cursor.getInt(selfColumn);
        assertEquals(CalendarContract.Attendees.ATTENDEE_STATUS_ACCEPTED, selfAttendeeStatus);
        cursor.close();

        // Update status to declined and change identity
        ContentValues attendeeUpdate = new ContentValues();
        attendeeUpdate.put(CalendarContract.Attendees.ATTENDEE_IDENTITY, "ID2");
        attendee.put(CalendarContract.Attendees.ATTENDEE_IDENTITY, "ID2");
        attendeeUpdate.put(CalendarContract.Attendees.ATTENDEE_STATUS,
                CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED);
        attendee.put(CalendarContract.Attendees.ATTENDEE_STATUS,
                CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED);
        mResolver.update(attendeesUri, attendeeUpdate, null, null);

        // Check in attendees table
        cursor = mResolver.query(attendeesUri, null, null, null, null);
        cursor.moveToNext();
        verifyContentValueAgainstCursor(attendee, attendeeColumns, cursor);
        cursor.close();

        // Test that the self status in events table is updated
        cursor = mResolver.query(eventUri, null, null, null, null);
        cursor.moveToNext();
        selfAttendeeStatus = cursor.getInt(selfColumn);
        assertEquals(CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED, selfAttendeeStatus);
        cursor.close();

        // Add another attendee
        attendee.put(CalendarContract.Attendees.ATTENDEE_NAME, "Dude");
        attendee.put(CalendarContract.Attendees.ATTENDEE_EMAIL, "dude@dude.com");
        attendee.put(CalendarContract.Attendees.ATTENDEE_STATUS,
                CalendarContract.Attendees.ATTENDEE_STATUS_ACCEPTED);
        mResolver.insert(CalendarContract.Attendees.CONTENT_URI, attendee);

        cursor = mResolver.query(CalendarContract.Attendees.CONTENT_URI, null,
                "event_id=" + eventId, null, null);
        assertEquals(2, cursor.getCount());
        cursor.close();

        cursor = mResolver.query(eventUri, null, null, null, null);
        cursor.moveToNext();
        selfAttendeeStatus = cursor.getInt(selfColumn);
        assertEquals(CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED, selfAttendeeStatus);
        cursor.close();
    }

    private void verifyContentValueAgainstCursor(ContentValues cv,
            Set<String> keys, Cursor cursor) {
        cursor.moveToFirst();
        for (String key : keys) {
            assertEquals(cv.get(key).toString(),
                    cursor.getString(cursor.getColumnIndex(key)));
        }
        cursor.close();
    }

    /**
     * Test the event's dirty status and clear it.
     *
     * @param eventId event to fetch.
     * @param wanted the wanted dirty status
     */
    private void testAndClearDirty(long eventId, int wanted) {
        Cursor cursor = mResolver.query(
                ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId),
                null, null, null, null);
        try {
            assertEquals("Event count", 1, cursor.getCount());
            cursor.moveToNext();
            int dirty = cursor.getInt(cursor.getColumnIndex(CalendarContract.Events.DIRTY));
            assertEquals("dirty flag", wanted, dirty);
            if (dirty == 1) {
                // Have to access database directly since provider will set dirty again.
                mDb.execSQL("UPDATE Events SET " + Events.DIRTY + "=0 WHERE _id=" + eventId);
            }
        } finally {
            cursor.close();
        }
    }

    /**
     * Test the count of results from a query.
     * @param uri The URI to query
     * @param where The where string or null.
     * @param wanted The number of results wanted.  An assertion is thrown if it doesn't match.
     */
    private void testQueryCount(Uri uri, String where, int wanted) {
        Cursor cursor = mResolver.query(uri, null/* projection */, where, null /* selectionArgs */,
                null /* sortOrder */);
        try {
            assertEquals("query results", wanted, cursor.getCount());
        } finally {
            cursor.close();
        }
    }

    /**
     * Test dirty flag processing.
     * @throws Exception
     */
    public void testDirty() throws Exception {
        internalTestDirty(false);
    }

    /**
     * Test dirty flag processing for updates from a sync adapter.
     * @throws Exception
     */
    public void testDirtyWithSyncAdapter() throws Exception {
        internalTestDirty(true);
    }

    /**
     * Adds CALLER_IS_SYNCADAPTER to URI if this is a sync adapter operation.  Otherwise,
     * returns the original URI.
     */
    private Uri updatedUri(Uri uri, boolean syncAdapter, String account, String accountType) {
        if (syncAdapter) {
            return addSyncQueryParams(uri, account, accountType);
        } else {
            return uri;
        }
    }

    /**
     * Test dirty flag processing either for syncAdapter operations or client operations.
     * The main difference is syncAdapter operations don't set the dirty bit.
     */
    private void internalTestDirty(boolean syncAdapter) throws Exception {
        mCalendarId = insertCal("Calendar0", DEFAULT_TIMEZONE);

        long now = System.currentTimeMillis();
        long begin = (now / 1000) * 1000;
        long end = begin + ONE_HOUR_MILLIS;
        Time time = new Time(DEFAULT_TIMEZONE);
        time.set(begin);
        String startDate = time.format3339(false);
        time.set(end);
        String endDate = time.format3339(false);

        EventInfo eventInfo = new EventInfo("current", startDate, endDate, false);
        Uri eventUri = insertEvent(mCalendarId, eventInfo);

        long eventId = ContentUris.parseId(eventUri);
        testAndClearDirty(eventId, 1);

        ContentValues attendee = new ContentValues();
        attendee.put(CalendarContract.Attendees.ATTENDEE_NAME, "Joe");
        attendee.put(CalendarContract.Attendees.ATTENDEE_EMAIL, DEFAULT_ACCOUNT);
        attendee.put(CalendarContract.Attendees.ATTENDEE_TYPE,
                CalendarContract.Attendees.TYPE_REQUIRED);
        attendee.put(CalendarContract.Attendees.ATTENDEE_RELATIONSHIP,
                CalendarContract.Attendees.RELATIONSHIP_ORGANIZER);
        attendee.put(CalendarContract.Attendees.EVENT_ID, eventId);

        Uri attendeeUri = mResolver.insert(
                updatedUri(CalendarContract.Attendees.CONTENT_URI, syncAdapter, DEFAULT_ACCOUNT,
                        DEFAULT_ACCOUNT_TYPE),
                attendee);
        testAndClearDirty(eventId, syncAdapter ? 0 : 1);
        testQueryCount(CalendarContract.Attendees.CONTENT_URI, "event_id=" + eventId, 1);

        ContentValues reminder = new ContentValues();
        reminder.put(CalendarContract.Reminders.MINUTES, 30);
        reminder.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_EMAIL);
        reminder.put(CalendarContract.Attendees.EVENT_ID, eventId);

        Uri reminderUri = mResolver.insert(
                updatedUri(CalendarContract.Reminders.CONTENT_URI, syncAdapter, DEFAULT_ACCOUNT,
                        DEFAULT_ACCOUNT_TYPE), reminder);
        testAndClearDirty(eventId, syncAdapter ? 0 : 1);
        testQueryCount(CalendarContract.Reminders.CONTENT_URI, "event_id=" + eventId, 1);

        long alarmTime = begin + 5 * ONE_MINUTE_MILLIS;

        ContentValues alert = new ContentValues();
        alert.put(CalendarContract.CalendarAlerts.BEGIN, begin);
        alert.put(CalendarContract.CalendarAlerts.END, end);
        alert.put(CalendarContract.CalendarAlerts.ALARM_TIME, alarmTime);
        alert.put(CalendarContract.CalendarAlerts.CREATION_TIME, now);
        alert.put(CalendarContract.CalendarAlerts.RECEIVED_TIME, now);
        alert.put(CalendarContract.CalendarAlerts.NOTIFY_TIME, now);
        alert.put(CalendarContract.CalendarAlerts.STATE,
                CalendarContract.CalendarAlerts.STATE_SCHEDULED);
        alert.put(CalendarContract.CalendarAlerts.MINUTES, 30);
        alert.put(CalendarContract.CalendarAlerts.EVENT_ID, eventId);

        Uri alertUri = mResolver.insert(
                updatedUri(CalendarContract.CalendarAlerts.CONTENT_URI, syncAdapter,
                        DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE), alert);
        // Alerts don't dirty the event
        testAndClearDirty(eventId, 0);
        testQueryCount(CalendarContract.CalendarAlerts.CONTENT_URI, "event_id=" + eventId, 1);

        ContentValues extended = new ContentValues();
        extended.put(CalendarContract.ExtendedProperties.NAME, "foo");
        extended.put(CalendarContract.ExtendedProperties.VALUE, "bar");
        extended.put(CalendarContract.ExtendedProperties.EVENT_ID, eventId);

        Uri extendedUri = null;
        if (syncAdapter) {
            // Only the sync adapter is allowed to modify ExtendedProperties.
            extendedUri = mResolver.insert(
                    updatedUri(CalendarContract.ExtendedProperties.CONTENT_URI, syncAdapter,
                            DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE), extended);
            testAndClearDirty(eventId, syncAdapter ? 0 : 1);
            testQueryCount(CalendarContract.ExtendedProperties.CONTENT_URI,
                    "event_id=" + eventId, 1);
        } else {
            // Confirm that inserting as app fails.
            try {
                extendedUri = mResolver.insert(
                        updatedUri(CalendarContract.ExtendedProperties.CONTENT_URI, syncAdapter,
                                DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE), extended);
                fail("Only sync adapter should be allowed to insert into ExtendedProperties");
            } catch (IllegalArgumentException iae) {}
        }

        // Now test updates

        attendee = new ContentValues();
        attendee.put(CalendarContract.Attendees.ATTENDEE_NAME, "Sam");

        assertEquals("update", 1, mResolver.update(
                updatedUri(attendeeUri, syncAdapter, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
                attendee,
                null /* where */, null /* selectionArgs */));
        testAndClearDirty(eventId, syncAdapter ? 0 : 1);

        testQueryCount(CalendarContract.Attendees.CONTENT_URI, "event_id=" + eventId, 1);

        alert = new ContentValues();
        alert.put(CalendarContract.CalendarAlerts.STATE,
                CalendarContract.CalendarAlerts.STATE_DISMISSED);

        assertEquals("update", 1, mResolver.update(
                updatedUri(alertUri, syncAdapter, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE), alert,
                null /* where */, null /* selectionArgs */));
        // Alerts don't dirty the event
        testAndClearDirty(eventId, 0);
        testQueryCount(CalendarContract.CalendarAlerts.CONTENT_URI, "event_id=" + eventId, 1);

        extended = new ContentValues();
        extended.put(CalendarContract.ExtendedProperties.VALUE, "baz");

        if (syncAdapter) {
            assertEquals("update", 1, mResolver.update(
                    updatedUri(extendedUri, syncAdapter, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
                    extended,
                    null /* where */, null /* selectionArgs */));
            testAndClearDirty(eventId, syncAdapter ? 0 : 1);
            testQueryCount(CalendarContract.ExtendedProperties.CONTENT_URI,
                    "event_id=" + eventId, 1);
        }

        // Now test deletes

        assertEquals("delete", 1, mResolver.delete(
                updatedUri(attendeeUri, syncAdapter, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
                null, null /* selectionArgs */));
        testAndClearDirty(eventId, syncAdapter ? 0 : 1);
        testQueryCount(CalendarContract.Attendees.CONTENT_URI, "event_id=" + eventId, 0);

        assertEquals("delete", 1, mResolver.delete(
                updatedUri(reminderUri, syncAdapter, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
                null /* where */, null /* selectionArgs */));

        testAndClearDirty(eventId, syncAdapter ? 0 : 1);
        testQueryCount(CalendarContract.Reminders.CONTENT_URI, "event_id=" + eventId, 0);

        assertEquals("delete", 1, mResolver.delete(
                updatedUri(alertUri, syncAdapter, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
                null /* where */, null /* selectionArgs */));

        // Alerts don't dirty the event
        testAndClearDirty(eventId, 0);
        testQueryCount(CalendarContract.CalendarAlerts.CONTENT_URI, "event_id=" + eventId, 0);

        if (syncAdapter) {
            assertEquals("delete", 1, mResolver.delete(
                    updatedUri(extendedUri, syncAdapter, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE),
                    null /* where */, null /* selectionArgs */));

            testAndClearDirty(eventId, syncAdapter ? 0 : 1);
            testQueryCount(CalendarContract.ExtendedProperties.CONTENT_URI, "event_id=" + eventId,
                    0);
        }
    }

    /**
     * Test calendar deletion
     * @throws Exception
     */
    public void testCalendarDeletion() throws Exception {
        mCalendarId = insertCal("Calendar0", DEFAULT_TIMEZONE);
        Uri eventUri = insertEvent(mCalendarId, findEvent("daily0"));
        long eventId = ContentUris.parseId(eventUri);
        testAndClearDirty(eventId, 1);
        Uri eventUri1 = insertEvent(mCalendarId, findEvent("daily1"));
        long eventId1 = ContentUris.parseId(eventUri);
        assertEquals("delete", 1, mResolver.delete(eventUri1, null, null));
        // Calendar has one event and one deleted event
        testQueryCount(CalendarContract.Events.CONTENT_URI, null, 2);

        assertEquals("delete", 1, mResolver.delete(CalendarContract.Calendars.CONTENT_URI,
                "_id=" + mCalendarId, null));
        // Calendar should be deleted
        testQueryCount(CalendarContract.Calendars.CONTENT_URI, null, 0);
        // Event should be gone
        testQueryCount(CalendarContract.Events.CONTENT_URI, null, 0);
    }

    /**
     * Test multiple account support.
     */
    public void testMultipleAccounts() throws Exception {
        mCalendarId = insertCal("Calendar0", DEFAULT_TIMEZONE);
        int calendarId1 = insertCal("Calendar1", DEFAULT_TIMEZONE, "user2@google.com");
        Uri eventUri0 = insertEvent(mCalendarId, findEvent("daily0"));
        Uri eventUri1 = insertEvent(calendarId1, findEvent("daily1"));

        testQueryCount(CalendarContract.Events.CONTENT_URI, null, 2);
        Uri eventsWithAccount = CalendarContract.Events.CONTENT_URI.buildUpon()
                .appendQueryParameter(CalendarContract.EventsEntity.ACCOUNT_NAME, DEFAULT_ACCOUNT)
                .appendQueryParameter(CalendarContract.EventsEntity.ACCOUNT_TYPE,
                        DEFAULT_ACCOUNT_TYPE)
                .build();
        // Only one event for that account
        testQueryCount(eventsWithAccount, null, 1);

        // Test deletion with account and selection

        long eventId = ContentUris.parseId(eventUri1);
        // Wrong account, should not be deleted
        assertEquals("delete", 0, mResolver.delete(
                updatedUri(eventsWithAccount, true /* syncAdapter */, DEFAULT_ACCOUNT,
                        DEFAULT_ACCOUNT_TYPE),
                "_id=" + eventId, null /* selectionArgs */));
        testQueryCount(CalendarContract.Events.CONTENT_URI, null, 2);
        // Right account, should be deleted
        assertEquals("delete", 1, mResolver.delete(
                updatedUri(CalendarContract.Events.CONTENT_URI, true /* syncAdapter */,
                        "user2@google.com", DEFAULT_ACCOUNT_TYPE),
                "_id=" + eventId, null /* selectionArgs */));
        testQueryCount(CalendarContract.Events.CONTENT_URI, null, 1);
    }

    /**
     * Run commands, wiping instance table at each step.
     * This tests full instance expansion.
     * @throws Exception
     */
    public void testCommandSequences1() throws Exception {
        commandSequences(true);
    }

    /**
     * Run commands normally.
     * This tests incremental instance expansion.
     * @throws Exception
     */
    public void testCommandSequences2() throws Exception {
        commandSequences(false);
    }

    /**
     * Run thorough set of command sequences
     * @param wipe true if instances should be wiped and regenerated
     * @throws Exception
     */
    private void commandSequences(boolean wipe) throws Exception {
        Cursor cursor;
        Uri url = null;
        mWipe = wipe; // Set global flag

        mCalendarId = insertCal("Calendar0", DEFAULT_TIMEZONE);

        cursor = mResolver.query(mEventsUri, null, null, null, null);
        assertEquals(0, cursor.getCount());
        cursor.close();
        Command[] commands;

        Log.i(TAG, "Normal insert/delete");
        commands = mNormalInsertDelete;
        for (Command command : commands) {
            command.execute();
        }

        deleteAllEvents();

        Log.i(TAG, "All-day insert/delete");
        commands = mAlldayInsertDelete;
        for (Command command : commands) {
            command.execute();
        }

        deleteAllEvents();

        Log.i(TAG, "Recurring insert/delete");
        commands = mRecurringInsertDelete;
        for (Command command : commands) {
            command.execute();
        }

        deleteAllEvents();

        Log.i(TAG, "Exception with truncated recurrence");
        commands = mExceptionWithTruncatedRecurrence;
        for (Command command : commands) {
            command.execute();
        }

        deleteAllEvents();

        Log.i(TAG, "Exception with moved recurrence");
        commands = mExceptionWithMovedRecurrence;
        for (Command command : commands) {
            command.execute();
        }

        deleteAllEvents();

        Log.i(TAG, "Exception with cancel");
        commands = mCancelInstance;
        for (Command command : commands) {
            command.execute();
        }

        deleteAllEvents();

        Log.i(TAG, "Exception with moved recurrence2");
        commands = mExceptionWithMovedRecurrence2;
        for (Command command : commands) {
            command.execute();
        }

        deleteAllEvents();

        Log.i(TAG, "Exception with no recurrence");
        commands = mExceptionWithNoRecurrence;
        for (Command command : commands) {
            command.execute();
        }
    }

    /**
     * Test Time toString.
     * @throws Exception
     */
    // Suppressed because toString currently hangs.
    @Suppress
    public void testTimeToString() throws Exception {
        Time time = new Time(Time.TIMEZONE_UTC);
        String str = "2039-01-01T23:00:00.000Z";
        String result = "20390101T230000UTC(0,0,0,-1,0)";
        time.parse3339(str);
        assertEquals(result, time.toString());
    }

    /**
     * Test the query done by Event.loadEvents
     * Also test that instance queries work when an event straddles the expansion range
     * @throws Exception
     */
    public void testInstanceQuery() throws Exception {
        final String[] PROJECTION = new String[] {
                Instances.TITLE,                 // 0
                Instances.EVENT_LOCATION,        // 1
                Instances.ALL_DAY,               // 2
                Instances.CALENDAR_COLOR,        // 3
                Instances.EVENT_TIMEZONE,        // 4
                Instances.EVENT_ID,              // 5
                Instances.BEGIN,                 // 6
                Instances.END,                   // 7
                Instances._ID,                   // 8
                Instances.START_DAY,             // 9
                Instances.END_DAY,               // 10
                Instances.START_MINUTE,          // 11
                Instances.END_MINUTE,            // 12
                Instances.HAS_ALARM,             // 13
                Instances.RRULE,                 // 14
                Instances.RDATE,                 // 15
                Instances.SELF_ATTENDEE_STATUS,  // 16
                Events.ORGANIZER,                // 17
                Events.GUESTS_CAN_MODIFY,        // 18
        };

        String orderBy = CalendarProvider2.SORT_CALENDAR_VIEW;
        String where = Instances.SELF_ATTENDEE_STATUS + "!="
                + CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED;

        int calId = insertCal("Calendar0", DEFAULT_TIMEZONE);
        final String START = "2008-05-01T00:00:00";
        final String END = "2008-05-01T20:00:00";

        EventInfo[] events = { new EventInfo("normal0",
                START,
                END,
                false /* allDay */,
                DEFAULT_TIMEZONE) };

        insertEvent(calId, events[0]);

        Time time = new Time(DEFAULT_TIMEZONE);
        time.parse3339(START);
        long startMs = time.toMillis(true /* ignoreDst */);
        // Query starting from way in the past to one hour into the event.
        // Query is more than 2 months so the range won't get extended by the provider.
        Cursor cursor = queryInstances(mResolver, PROJECTION,
                startMs - DateUtils.YEAR_IN_MILLIS, startMs + DateUtils.HOUR_IN_MILLIS,
                where, null, orderBy);
        try {
            assertEquals(1, cursor.getCount());
        } finally {
            cursor.close();
        }

        // Now expand the instance range.  The event overlaps the new part of the range.
        cursor = queryInstances(mResolver, PROJECTION,
                startMs - DateUtils.YEAR_IN_MILLIS, startMs + 2 * DateUtils.HOUR_IN_MILLIS,
                where, null, orderBy);
        try {
            assertEquals(1, cursor.getCount());
        } finally {
            cursor.close();
        }
    }

    /**
     * Performs a query to return all visible instances in the given range that
     * match the given selection. This is a blocking function and should not be
     * done on the UI thread. This will cause an expansion of recurring events
     * to fill this time range if they are not already expanded and will slow
     * down for larger time ranges with many recurring events.
     *
     * @param cr The ContentResolver to use for the query
     * @param projection The columns to return
     * @param begin The start of the time range to query in UTC millis since
     *            epoch
     * @param end The end of the time range to query in UTC millis since epoch
     * @param selection Filter on the query as an SQL WHERE statement
     * @param selectionArgs Args to replace any '?'s in the selection
     * @param orderBy How to order the rows as an SQL ORDER BY statement
     * @return A Cursor of instances matching the selection
     */
    private static final Cursor queryInstances(ContentResolver cr, String[] projection, long begin,
            long end, String selection, String[] selectionArgs, String orderBy) {

        Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
        ContentUris.appendId(builder, begin);
        ContentUris.appendId(builder, end);
        if (TextUtils.isEmpty(selection)) {
            selection = WHERE_CALENDARS_SELECTED;
            selectionArgs = WHERE_CALENDARS_ARGS;
        } else {
            selection = "(" + selection + ") AND " + WHERE_CALENDARS_SELECTED;
            if (selectionArgs != null && selectionArgs.length > 0) {
                selectionArgs = Arrays.copyOf(selectionArgs, selectionArgs.length + 1);
                selectionArgs[selectionArgs.length - 1] = WHERE_CALENDARS_ARGS[0];
            } else {
                selectionArgs = WHERE_CALENDARS_ARGS;
            }
        }
        return cr.query(builder.build(), projection, selection, selectionArgs,
                orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
    }

    /**
     * Performs a query to return all visible instances in the given range that
     * match the given selection. This is a blocking function and should not be
     * done on the UI thread. This will cause an expansion of recurring events
     * to fill this time range if they are not already expanded and will slow
     * down for larger time ranges with many recurring events.
     *
     * @param cr The ContentResolver to use for the query
     * @param projection The columns to return
     * @param begin The start of the time range to query in UTC millis since
     *            epoch
     * @param end The end of the time range to query in UTC millis since epoch
     * @param searchQuery A string of space separated search terms. Segments
     *            enclosed by double quotes will be treated as a single term.
     * @param selection Filter on the query as an SQL WHERE statement
     * @param selectionArgs Args to replace any '?'s in the selection
     * @param orderBy How to order the rows as an SQL ORDER BY statement
     * @return A Cursor of instances matching the selection
     */
    public static final Cursor queryInstances(ContentResolver cr, String[] projection, long begin,
            long end, String searchQuery, String selection, String[] selectionArgs, String orderBy)
            {
        Uri.Builder builder = Instances.CONTENT_SEARCH_URI.buildUpon();
        ContentUris.appendId(builder, begin);
        ContentUris.appendId(builder, end);
        builder = builder.appendPath(searchQuery);
        if (TextUtils.isEmpty(selection)) {
            selection = WHERE_CALENDARS_SELECTED;
            selectionArgs = WHERE_CALENDARS_ARGS;
        } else {
            selection = "(" + selection + ") AND " + WHERE_CALENDARS_SELECTED;
            if (selectionArgs != null && selectionArgs.length > 0) {
                selectionArgs = Arrays.copyOf(selectionArgs, selectionArgs.length + 1);
                selectionArgs[selectionArgs.length - 1] = WHERE_CALENDARS_ARGS[0];
            } else {
                selectionArgs = WHERE_CALENDARS_ARGS;
            }
        }
        return cr.query(builder.build(), projection, selection, selectionArgs,
                orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
    }

    private Cursor queryInstances(long begin, long end) {
        Uri url = Uri.withAppendedPath(CalendarContract.Instances.CONTENT_URI, begin + "/" + end);
        return mResolver.query(url, null, null, null, null);
    }

    protected static class MockProvider extends ContentProvider {

        private String mAuthority;

        private int mNumItems = 0;

        public MockProvider(String authority) {
            mAuthority = authority;
        }

        @Override
        public boolean onCreate() {
            return true;
        }

        @Override
        public Cursor query(Uri uri, String[] projection, String selection,
                String[] selectionArgs, String sortOrder) {
            return new MatrixCursor(new String[]{ "_id" }, 0);
        }

        @Override
        public String getType(Uri uri) {
            throw new UnsupportedOperationException();
        }

        @Override
        public Uri insert(Uri uri, ContentValues values) {
            mNumItems++;
            return Uri.parse("content://" + mAuthority + "/" + mNumItems);
        }

        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            return 0;
        }

        @Override
        public int update(Uri uri, ContentValues values, String selection,
                String[] selectionArgs) {
            return 0;
        }
    }

    private void cleanCalendarDataTable(SQLiteOpenHelper helper) {
        if (null == helper) {
            return;
        }
        SQLiteDatabase db = helper.getWritableDatabase();
        db.execSQL("DELETE FROM CalendarCache;");
    }

    public void testGetAndSetTimezoneDatabaseVersion() throws CalendarCache.CacheException {
        CalendarDatabaseHelper helper = (CalendarDatabaseHelper) getProvider().getDatabaseHelper();
        cleanCalendarDataTable(helper);
        CalendarCache cache = new CalendarCache(helper);

        boolean hasException = false;
        try {
            String value = cache.readData(null);
        } catch (CalendarCache.CacheException e) {
            hasException = true;
        }
        assertTrue(hasException);

        assertNull(cache.readTimezoneDatabaseVersion());

        cache.writeTimezoneDatabaseVersion("1234");
        assertEquals("1234", cache.readTimezoneDatabaseVersion());

        cache.writeTimezoneDatabaseVersion("5678");
        assertEquals("5678", cache.readTimezoneDatabaseVersion());
    }

    private void checkEvent(int eventId, String title, long dtStart, long dtEnd, boolean allDay) {
        Uri uri = Uri.parse("content://" + CalendarContract.AUTHORITY + "/events");
        Log.i(TAG, "Looking for EventId = " + eventId);

        Cursor cursor = mResolver.query(uri, null, null, null, null);
        assertEquals(1, cursor.getCount());

        int colIndexTitle = cursor.getColumnIndex(CalendarContract.Events.TITLE);
        int colIndexDtStart = cursor.getColumnIndex(CalendarContract.Events.DTSTART);
        int colIndexDtEnd = cursor.getColumnIndex(CalendarContract.Events.DTEND);
        int colIndexAllDay = cursor.getColumnIndex(CalendarContract.Events.ALL_DAY);
        if (!cursor.moveToNext()) {
            Log.e(TAG,"Could not find inserted event");
            assertTrue(false);
        }
        assertEquals(title, cursor.getString(colIndexTitle));
        assertEquals(dtStart, cursor.getLong(colIndexDtStart));
        assertEquals(dtEnd, cursor.getLong(colIndexDtEnd));
        assertEquals(allDay, (cursor.getInt(colIndexAllDay) != 0));
        cursor.close();
    }

    public void testChangeTimezoneDB() {
        int calId = insertCal("Calendar0", DEFAULT_TIMEZONE);

        Cursor cursor = mResolver
                .query(CalendarContract.Events.CONTENT_URI, null, null, null, null);
        assertEquals(0, cursor.getCount());
        cursor.close();

        EventInfo[] events = { new EventInfo("normal0",
                                        "2008-05-01T00:00:00",
                                        "2008-05-02T00:00:00",
                                        false,
                                        DEFAULT_TIMEZONE) };

        Uri uri = insertEvent(calId, events[0]);
        assertNotNull(uri);

        // check the inserted event
        checkEvent(1, events[0].mTitle, events[0].mDtstart, events[0].mDtend, events[0].mAllDay);

        // inject a new time zone
        getProvider().doProcessEventRawTimes(TIME_ZONE_AMERICA_ANCHORAGE,
                MOCK_TIME_ZONE_DATABASE_VERSION);

        // check timezone database version
        assertEquals(MOCK_TIME_ZONE_DATABASE_VERSION, getProvider().getTimezoneDatabaseVersion());

        // check that the inserted event has *not* been updated
        checkEvent(1, events[0].mTitle, events[0].mDtstart, events[0].mDtend, events[0].mAllDay);
    }

    public static final Uri PROPERTIES_CONTENT_URI =
            Uri.parse("content://" + CalendarContract.AUTHORITY + "/properties");

    public void testGetProviderProperties() throws CalendarCache.CacheException {
        CalendarDatabaseHelper helper = (CalendarDatabaseHelper) getProvider().getDatabaseHelper();
        cleanCalendarDataTable(helper);
        CalendarCache cache = new CalendarCache(helper);

        cache.writeTimezoneDatabaseVersion("2010k");
        cache.writeTimezoneInstances("America/Denver");
        cache.writeTimezoneInstancesPrevious("America/Los_Angeles");
        cache.writeTimezoneType(CalendarCache.TIMEZONE_TYPE_AUTO);

        Cursor cursor = mResolver.query(PROPERTIES_CONTENT_URI, null, null, null, null);
        assertEquals(4, cursor.getCount());

        final int keyColumnIndex = cursor.getColumnIndex(CalendarCache.COLUMN_NAME_KEY);
        final int valueColumnIndex = cursor.getColumnIndex(CalendarCache.COLUMN_NAME_VALUE);
        Map<String, String> map = new HashMap<String, String>();

        while (cursor.moveToNext()) {
            String key = cursor.getString(keyColumnIndex);
            String value = cursor.getString(valueColumnIndex);
            map.put(key, value);
        }

        assertTrue(map.containsKey(CalendarCache.KEY_TIMEZONE_DATABASE_VERSION));
        assertTrue(map.containsKey(CalendarCache.KEY_TIMEZONE_TYPE));
        assertTrue(map.containsKey(CalendarCache.KEY_TIMEZONE_INSTANCES));
        assertTrue(map.containsKey(CalendarCache.KEY_TIMEZONE_INSTANCES_PREVIOUS));

        assertEquals("2010k", map.get(CalendarCache.KEY_TIMEZONE_DATABASE_VERSION));
        assertEquals("America/Denver", map.get(CalendarCache.KEY_TIMEZONE_INSTANCES));
        assertEquals("America/Los_Angeles", map.get(CalendarCache.KEY_TIMEZONE_INSTANCES_PREVIOUS));
        assertEquals(CalendarCache.TIMEZONE_TYPE_AUTO, map.get(CalendarCache.KEY_TIMEZONE_TYPE));

        cursor.close();
    }

    public void testGetProviderPropertiesByKey() throws CalendarCache.CacheException {
        CalendarDatabaseHelper helper = (CalendarDatabaseHelper) getProvider().getDatabaseHelper();
        cleanCalendarDataTable(helper);
        CalendarCache cache = new CalendarCache(helper);

        cache.writeTimezoneDatabaseVersion("2010k");
        cache.writeTimezoneInstances("America/Denver");
        cache.writeTimezoneInstancesPrevious("America/Los_Angeles");
        cache.writeTimezoneType(CalendarCache.TIMEZONE_TYPE_AUTO);

        checkValueForKey(CalendarCache.TIMEZONE_TYPE_AUTO, CalendarCache.KEY_TIMEZONE_TYPE);
        checkValueForKey("2010k", CalendarCache.KEY_TIMEZONE_DATABASE_VERSION);
        checkValueForKey("America/Denver", CalendarCache.KEY_TIMEZONE_INSTANCES);
        checkValueForKey("America/Los_Angeles", CalendarCache.KEY_TIMEZONE_INSTANCES_PREVIOUS);
    }

    private void checkValueForKey(String value, String key) {
        Cursor cursor = mResolver.query(PROPERTIES_CONTENT_URI, null,
                "key=?", new String[] {key}, null);

        assertEquals(1, cursor.getCount());
        assertTrue(cursor.moveToFirst());
        assertEquals(cursor.getString(cursor.getColumnIndex(CalendarCache.COLUMN_NAME_KEY)),
                key);
        assertEquals(cursor.getString(cursor.getColumnIndex(CalendarCache.COLUMN_NAME_VALUE)),
                value);

        cursor.close();
    }

    public void testUpdateProviderProperties() throws CalendarCache.CacheException {
        CalendarDatabaseHelper helper = (CalendarDatabaseHelper) getProvider().getDatabaseHelper();
        cleanCalendarDataTable(helper);
        CalendarCache cache = new CalendarCache(helper);

        String localTimezone = TimeZone.getDefault().getID();

        // Set initial value
        cache.writeTimezoneDatabaseVersion("2010k");

        updateValueForKey("2009s", CalendarCache.KEY_TIMEZONE_DATABASE_VERSION);
        checkValueForKey("2009s", CalendarCache.KEY_TIMEZONE_DATABASE_VERSION);

        // Set initial values
        cache.writeTimezoneType(CalendarCache.TIMEZONE_TYPE_AUTO);
        cache.writeTimezoneInstances("America/Chicago");
        cache.writeTimezoneInstancesPrevious("America/Denver");

        updateValueForKey(CalendarCache.TIMEZONE_TYPE_AUTO, CalendarCache.KEY_TIMEZONE_TYPE);
        checkValueForKey(localTimezone, CalendarCache.KEY_TIMEZONE_INSTANCES);
        checkValueForKey("America/Denver", CalendarCache.KEY_TIMEZONE_INSTANCES_PREVIOUS);

        updateValueForKey(CalendarCache.TIMEZONE_TYPE_HOME, CalendarCache.KEY_TIMEZONE_TYPE);
        checkValueForKey("America/Denver", CalendarCache.KEY_TIMEZONE_INSTANCES);
        checkValueForKey("America/Denver", CalendarCache.KEY_TIMEZONE_INSTANCES_PREVIOUS);

        // Set initial value
        cache.writeTimezoneInstancesPrevious("");
        updateValueForKey(localTimezone, CalendarCache.KEY_TIMEZONE_INSTANCES);
        checkValueForKey(localTimezone, CalendarCache.KEY_TIMEZONE_INSTANCES);
        checkValueForKey(localTimezone, CalendarCache.KEY_TIMEZONE_INSTANCES_PREVIOUS);
    }

    private void updateValueForKey(String value, String key) {
        ContentValues contentValues = new ContentValues();
        contentValues.put(CalendarCache.COLUMN_NAME_VALUE, value);

        int result = mResolver.update(PROPERTIES_CONTENT_URI,
                contentValues,
                CalendarCache.COLUMN_NAME_KEY + "=?",
                new String[] {key});

        assertEquals(1, result);
    }

    /**
     * Verifies that the number of defined calendars meets expectations.
     *
     * @param expectedCount The number of calendars we expect to find.
     */
    private void checkCalendarCount(int expectedCount) {
        Cursor cursor = mResolver.query(mCalendarsUri,
                null /* projection */,
                null /* selection */,
                null /* selectionArgs */,
                null /* sortOrder */);
        assertEquals(expectedCount, cursor.getCount());
        cursor.close();
    }

    private void checkCalendarExists(int calId) {
        assertTrue(isCalendarExists(calId));
    }

    private void checkCalendarDoesNotExists(int calId) {
        assertFalse(isCalendarExists(calId));
    }

    private boolean isCalendarExists(int calId) {
        Cursor cursor = mResolver.query(mCalendarsUri,
                new String[] {Calendars._ID},
                null /* selection */,
                null /* selectionArgs */,
                null /* sortOrder */);
        boolean found = false;
        while (cursor.moveToNext()) {
            if (calId == cursor.getInt(0)) {
                found = true;
                break;
            }
        }
        cursor.close();
        return found;
    }

    public void testDeleteAllCalendars() {
        checkCalendarCount(0);

        insertCal("Calendar1", "America/Los_Angeles");
        insertCal("Calendar2", "America/Los_Angeles");

        checkCalendarCount(2);

        deleteMatchingCalendars(null /* selection */, null /* selectionArgs*/);
        checkCalendarCount(0);
    }

    public void testDeleteCalendarsWithSelection() {
        checkCalendarCount(0);

        int calId1 = insertCal("Calendar1", "America/Los_Angeles");
        int calId2 = insertCal("Calendar2", "America/Los_Angeles");

        checkCalendarCount(2);
        checkCalendarExists(calId1);
        checkCalendarExists(calId2);

        deleteMatchingCalendars(Calendars._ID + "=" + calId2, null /* selectionArgs*/);
        checkCalendarCount(1);
        checkCalendarExists(calId1);
        checkCalendarDoesNotExists(calId2);
    }

    public void testDeleteCalendarsWithSelectionAndArgs() {
        checkCalendarCount(0);

        int calId1 = insertCal("Calendar1", "America/Los_Angeles");
        int calId2 = insertCal("Calendar2", "America/Los_Angeles");

        checkCalendarCount(2);
        checkCalendarExists(calId1);
        checkCalendarExists(calId2);

        deleteMatchingCalendars(Calendars._ID + "=?",
                new String[] { Integer.toString(calId2) });
        checkCalendarCount(1);
        checkCalendarExists(calId1);
        checkCalendarDoesNotExists(calId2);

        deleteMatchingCalendars(Calendars._ID + "=?" + " AND " + Calendars.NAME + "=?",
                new String[] { Integer.toString(calId1), "Calendar1" });
        checkCalendarCount(0);
    }

    public void testGetColumnIndex_IsPrimary() {
        checkCalendarCount(0);
        int calendarId0 = insertCal("Calendar0", DEFAULT_TIMEZONE);

        String[] projection = new String[] {
            Calendars.ACCOUNT_NAME,
            Calendars.CALENDAR_DISPLAY_NAME,
            Calendars.OWNER_ACCOUNT,
            Calendars.IS_PRIMARY
        };
        String selection = "((" + Calendars.ACCOUNT_NAME + " = ? ))";
        String[] selectionArgs = new String[] {
            DEFAULT_ACCOUNT
        };
        Cursor cursor = mResolver.query(Calendars.CONTENT_URI, projection, selection, selectionArgs,
                null);
        assertNotNull(cursor);
        assertEquals(3, cursor.getColumnIndex(Calendars.IS_PRIMARY));
        cursor.close();
        deleteMatchingCalendars(Calendars._ID + "=" + calendarId0, null /* selectionArgs*/);
        checkCalendarCount(0);
    }

    public void testGetColumnIndex_Count() {
        checkCalendarCount(0);
        int calendarId0 = insertCal("Calendar0", DEFAULT_TIMEZONE);

        String[] projection = new String[] {
            BaseColumns._COUNT
        };
        String selection = "((" + Calendars.ACCOUNT_NAME + " = ? ))";
        String[] selectionArgs = new String[] {
            DEFAULT_ACCOUNT
        };
        Cursor cursor = mResolver.query(Calendars.CONTENT_URI, projection, selection, selectionArgs,
                null);
        assertNotNull(cursor);
        assertEquals(0, cursor.getColumnIndex(BaseColumns._COUNT));
        cursor.close();
        deleteMatchingCalendars(Calendars._ID + "=" + calendarId0, null /* selectionArgs*/);
        checkCalendarCount(0);
    }

}
