diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e2aa1a5..ae1c699 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -28,8 +28,6 @@
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_READ" />
     <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE" />
-    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
-    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
 
     <application android:process="com.android.calendar"
                  android:label="@string/calendar_storage"
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 608758f..44114f9 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -18,15 +18,12 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.providers.calendar.tests">
 
-    <uses-permission android:name="android.permission.READ_CALENDAR" />
-    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
-    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
-    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
-
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
 
+    <uses-permission android:name="android.permission.READ_CALENDAR" />
+    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    
     <!--
     The test delcared in this instrumentation will be run along with tests declared by
diff --git a/tests/src/com/android/providers/calendar/CalendarSyncTestingBase.java b/tests/src/com/android/providers/calendar/CalendarSyncTestingBase.java
deleted file mode 100644
index d66a5b7..0000000
--- a/tests/src/com/android/providers/calendar/CalendarSyncTestingBase.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.providers.calendar;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.provider.Calendar;
-import android.test.SyncBaseInstrumentation;
-import android.util.Log;
-import com.google.android.collect.Maps;
-import com.google.android.googlelogin.GoogleLoginServiceBlockingHelper;
-import com.google.android.googlelogin.GoogleLoginServiceNotFoundException;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Calendar Sync base tests. Testing creation of setup, syncing calendar, inserting, 
- * deleting and editing events.
- */
-public class CalendarSyncTestingBase extends SyncBaseInstrumentation {
-    protected Context mTargetContext;
-    protected String mAccount;
-    protected ContentResolver mResolver;
-    protected Uri mEventsUri = Uri.parse("content://calendar/events");
-
-    static final String TAG = "calendar";
-    static final String DEFAULT_TIMEZONE = "America/Los_Angeles";
-    static final Set<String> EVENT_COLUMNS_TO_SKIP = new HashSet<String>();
-    static final Set<String> ATTENDEES_COLUMNS_TO_SKIP = new HashSet<String>();
-    static final Set<String> CALENDARS_COLUMNS_TO_SKIP = new HashSet<String>();
-    static final Set<String> INSTANCES_COLUMNS_TO_SKIP = new HashSet<String>();
-
-    static {
-        EVENT_COLUMNS_TO_SKIP.add(Calendar.Events._ID);
-        EVENT_COLUMNS_TO_SKIP.add(Calendar.Events._SYNC_TIME);
-        EVENT_COLUMNS_TO_SKIP.add(Calendar.Events._SYNC_VERSION);
-        EVENT_COLUMNS_TO_SKIP.add(Calendar.Events._SYNC_LOCAL_ID);
-        EVENT_COLUMNS_TO_SKIP.add(Calendar.Events._SYNC_DIRTY);
-        EVENT_COLUMNS_TO_SKIP.add(Calendar.Events._SYNC_MARK);
-        ATTENDEES_COLUMNS_TO_SKIP.add(Calendar.Attendees._ID);
-        CALENDARS_COLUMNS_TO_SKIP.add(Calendar.Calendars._ID);
-        CALENDARS_COLUMNS_TO_SKIP.add(Calendar.Calendars._SYNC_TIME);
-        CALENDARS_COLUMNS_TO_SKIP.add(Calendar.Calendars._SYNC_VERSION);
-        CALENDARS_COLUMNS_TO_SKIP.add(Calendar.Calendars._SYNC_LOCAL_ID);
-        CALENDARS_COLUMNS_TO_SKIP.add(Calendar.Calendars._SYNC_DIRTY);
-        CALENDARS_COLUMNS_TO_SKIP.add(Calendar.Calendars._SYNC_MARK);
-        INSTANCES_COLUMNS_TO_SKIP.add(Calendar.Instances._ID);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTargetContext = getInstrumentation().getTargetContext();
-        mAccount = getAccount();
-        mResolver = mTargetContext.getContentResolver();
-    }
-
-    /**
-     * A simple method that syncs the calendar provider.
-     * @throws Exception
-     */
-    protected void syncCalendar() throws Exception {
-       
-        cancelSyncsandDisableAutoSync();
-        syncProvider(Calendar.CONTENT_URI, mAccount, Calendar.AUTHORITY);
-    }
-
-    /**
-     * Creates a new event in the default calendar.
-     * @param event Event to be created.
-     * @return Uri of the created event.
-     * @throws Exception
-     */
-    protected Uri insertEvent(EventInfo event) throws Exception {
-        Log.i(TAG, "Get Dafault Calender Id"); 
-        return insertEvent(getDefaultCalendarId(), event);
-    }
-
-    /**
-     * Creates a new event in the given calendarId.
-     * @param calendarId Calendar to be used.
-     * @param event Event to be created.
-     * @return Uri of the event created.
-     * @throws Exception
-     */
-    protected Uri insertEvent(int calendarId, EventInfo event) throws Exception{
-        ContentValues m = new ContentValues();
-        m.put(Calendar.Events.CALENDAR_ID, calendarId);
-        m.put(Calendar.Events.TITLE, event.mTitle);
-        m.put(Calendar.Events.DTSTART, event.mDtstart);
-        m.put(Calendar.Events.ALL_DAY, event.mAllDay ? 1 : 0);
-
-        if (event.mRrule == null) {
-            // This is a normal event
-            m.put(Calendar.Events.DTEND, event.mDtend);
-        } else {
-            // This is a repeating event
-            m.put(Calendar.Events.RRULE, event.mRrule);
-            m.put(Calendar.Events.DURATION, event.mDuration);
-        }
-
-        if (event.mDescription != null) {
-            m.put(Calendar.Events.DESCRIPTION, event.mDescription);
-        }
-        if (event.mTimezone != null) {
-            m.put(Calendar.Events.EVENT_TIMEZONE, event.mTimezone);
-        }
-
-        Log.v(TAG, "Test Calendar Event");
-        Uri url = mResolver.insert(mEventsUri, m);
-        Log.v(TAG, "Insert Calendar Event");
-        syncCalendar();
-        Log.v(TAG, "Test Sync Calendar");
-        return url;
-    }
-
-    /**
-     * Edits the given event.
-     * @param eventId EventID of the event to be edited.
-     * @param event Edited event details.
-     * @throws Exception
-     */
-    protected void editEvent(long eventId, EventInfo event) throws Exception {
-        ContentValues values = new ContentValues();
-        values.put(Calendar.Events.TITLE, event.mTitle);
-        values.put(Calendar.Events.DTSTART, event.mDtstart);
-        values.put(Calendar.Events.DTEND, event.mDtend);
-        values.put(Calendar.Events.ALL_DAY, event.mAllDay ? 1 : 0);
-
-        if (event.mDescription != null) {
-            values.put(Calendar.Events.DESCRIPTION, event.mDescription);
-        } else if(event.mLocation != null) {
-            values.put(Calendar.Events.EVENT_LOCATION, event.mLocation);
-        } else if(event.mTitle != null) {
-            values.put(Calendar.Events.TITLE, event.mTitle);
-        } 
-        else {
-            throw new RuntimeException("Unsupported: description or location must be specified");
-        }
-
-        Uri uri = ContentUris.withAppendedId(Calendar.Events.CONTENT_URI, eventId);
-        mResolver.update(uri, values, null, null);
-        syncCalendar();
-    }
-
-    /**
-     * Deletes a given event.
-     * @param uri
-     * @throws Exception
-     */
-    protected void deleteEvent(Uri uri) throws Exception {
-        mResolver.delete(uri, null, null);
-        syncCalendar();
-    }
-
-    /**
-     * Inserts a new calendar.
-     * @param name
-     * @param timezone
-     * @param calendarUrl
-     * @throws Exception
-     */
-    protected void insertCalendar(String name, String timezone, String calendarUrl)
-            throws Exception {
-        ContentValues values = new ContentValues();
-
-        values.put(Calendar.Calendars._SYNC_ACCOUNT, getAccount());
-        values.put(Calendar.Calendars.URL, calendarUrl);
-        values.put(Calendar.Calendars.NAME, name);
-        values.put(Calendar.Calendars.DISPLAY_NAME, name);
-        values.put(Calendar.Calendars.SYNC_EVENTS, 1);
-        values.put(Calendar.Calendars.SELECTED, 1);
-        values.put(Calendar.Calendars.HIDDEN, 0);
-        values.put(Calendar.Calendars.COLOR, "0xff123456" /* blue */);
-        values.put(Calendar.Calendars.ACCESS_LEVEL, Calendar.Calendars.OWNER_ACCESS);
-        values.put(Calendar.Calendars.TIMEZONE, timezone);
-        mResolver.insert(Calendar.Calendars.CONTENT_URI, values);
-        syncCalendar();
-    }
-
-    /**
-     * Returns a fresh count of events.
-     * @return
-     */
-    protected int getEventsCount() {
-        Cursor cursor;
-        cursor = mResolver.query(mEventsUri, null, null, null, null);
-        return cursor.getCount();
-    }
-
-    /**
-     * Returns the ID of the default calendar.
-     * @return
-     */
-    protected int getDefaultCalendarId() {
-        Cursor calendarsCursor;
-        calendarsCursor = mResolver.query(Calendar.Calendars.CONTENT_URI, null, null, null, null);
-        calendarsCursor.moveToNext();
-        return calendarsCursor.getInt(calendarsCursor.getColumnIndex("_id"));
-    }
-
-    /**
-     * This class stores all the useful information about an event.
-     */
-    protected class EventInfo {
-        String mTitle;
-        String mDescription;
-        String mLocation;
-        String mTimezone;
-        boolean mAllDay;
-        long mDtstart;
-        long mDtend;
-        String mRrule;
-        String mDuration;
-        String mOriginalTitle;
-        long mOriginalInstance;
-        int mSyncId;
-
-        // 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);
-        }
-
-        public EventInfo(String title, long startDate, long endDate,
-                boolean allDay) {
-            mTitle = title;
-            mTimezone = DEFAULT_TIMEZONE;
-            mDtstart = startDate;
-            mDtend = endDate;
-            mDuration = null;
-            mRrule = null;
-            mAllDay = allDay;
-        }
-
-        public EventInfo(String title, long startDate, long endDate,
-                boolean allDay, String description) {
-            mTitle = title;
-            mTimezone = DEFAULT_TIMEZONE;
-            mDtstart = startDate;
-            mDtend = endDate;
-            mDuration = null;
-            mRrule = null;
-            mAllDay = allDay;
-            mDescription = description;
-        }
-        
-
-        // 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;
-        }
-
-        /**
-         * Constructor for repeating events, using the default time zone.
-         * @param title
-         * @param description
-         * @param startDate
-         * @param endDate
-         * @param rrule
-         * @param allDay
-         */
-        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, using the specific time zone.
-         * @param title
-         * @param description
-         * @param startDate
-         * @param endDate
-         * @param rrule
-         * @param allDay
-         * @param 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) {
-            init(originalTitle, originalInstance,
-                    title, description, startDate, endDate, allDay, DEFAULT_TIMEZONE);
-        }
-
-        public void init(String originalTitle, String originalInstance,
-                String title, String description, String startDate, String endDate,
-                boolean allDay, String timezone) {
-            mOriginalTitle = originalTitle;
-            Time time = new Time(timezone);
-            time.parse3339(originalInstance);
-            mOriginalInstance = time.toMillis(false /* use isDst */);
-            init(title, description, startDate, endDate, null /* rrule */, allDay, timezone);
-        }
-    }
-
-    /**
-     * Returns the default account on the device.
-     * @return
-     */
-    protected String getAccount() {
-        try {
-            return GoogleLoginServiceBlockingHelper.getAccount(mTargetContext, false);
-        } catch (GoogleLoginServiceNotFoundException e) {
-            Log.e("SyncCalendarTest", "Could not find Google login service", e);
-            return null;
-        }
-    }
-
-    /**
-     * Compares two cursors
-     */
-    protected void compareCursors(Cursor cursor1, Cursor cursor2,
-                                  Set<String> columnsToSkip, String tableName) {
-        String[] cols = cursor1.getColumnNames();
-        int length = cols.length;
-
-        assertEquals(tableName + " count failed to match", cursor1.getCount(),
-                cursor2.getCount());
-        Map<String, String> row = Maps.newHashMap();
-        while (cursor1.moveToNext() && cursor2.moveToNext()) {
-            for (int i = 0; i < length; i++) {
-                String col = cols[i];
-                if (columnsToSkip != null && columnsToSkip.contains(col)) {
-                    continue;
-                }
-                row.put(col, cursor1.getString(i));
-
-                assertEquals("Row: " + row + " Table: " + tableName + ": " + cols[i] +
-                        " failed to match", cursor1.getString(i),
-                        cursor2.getString(i));
-            }
-        }
-    }    
-}
diff --git a/tests/src/com/android/providers/calendar/SyncCalendarTest.java b/tests/src/com/android/providers/calendar/SyncCalendarTest.java
deleted file mode 100644
index a4d9a83..0000000
--- a/tests/src/com/android/providers/calendar/SyncCalendarTest.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.providers.calendar;
-
-import android.database.Cursor;
-import android.net.Uri;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.text.format.Time;
-
-/**
- * Calendar Sync instrumentation tests. Testing creation of new events, deleting events,
- * editing events.
- */
-public class SyncCalendarTest extends CalendarSyncTestingBase {
-    private EventInfo normalEvent = new EventInfo("normal0", "2008-05-29T08:00:00", "2008-05-29T08:30:00", false);
-    private EventInfo dailyRecurringEvent = new EventInfo("dailyEvent",
-         "daily from 5/1/2008 12am to 1am", "2008-10-01T00:00:00", "2008-10-01T01:00:00",
-          "FREQ=DAILY;WKST=SU", false);
-         
-        private static final long ONE_HOUR_IN_MILLIS = 3600000;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @LargeTest
-    public void testCreateNewEvent() throws Exception {
-        int countBeforeNewEvent = getEventsCount();
-        insertEvent(normalEvent);
-        assertTrue("No new event was added. ", getEventsCount() > countBeforeNewEvent);
-    }
-    
-    @LargeTest
-    public void testDeleteNewEvent() throws Exception {
-        int countBeforeNewEvent = getEventsCount();
-        Uri insertUri = insertEvent(normalEvent);
-        deleteEvent(insertUri);
-        assertEquals("Normal event should have been deleted.",
-                countBeforeNewEvent, getEventsCount());
-    }
-    
-    @LargeTest
-    public void testCreateAndDeleteNewRecurringEvent() throws Exception {
-        int countBeforeNewEvent = getEventsCount();
-        Uri insertUri = insertEvent(dailyRecurringEvent);
-
-        assertTrue("A daily recurring event should have been created.",
-                   getEventsCount() > countBeforeNewEvent);
-        deleteEvent(insertUri);
-        assertEquals("Daily recurring event should have been deleted.",
-                     countBeforeNewEvent, getEventsCount());
-    }
-
-    @LargeTest
-    public void testCreateAllDayEvent() throws Exception {
-        Time time = new Time();
-        time.setToNow();
-        long dtStart = time.toMillis(false);
-        long dtEnd = time.toMillis(false) + ONE_HOUR_IN_MILLIS;
-        EventInfo allDayEvent = new EventInfo("allday0", dtStart, dtEnd, true);
-        int countBeforeNewEvent = getEventsCount();
-        insertEvent(allDayEvent);
-        assertTrue("An all-day event should have been created.",
-                   getEventsCount() > countBeforeNewEvent);
-    }
-    
-    @LargeTest
-    public void testCreateMultipleDayEvent() throws Exception {
-        Time time = new Time();
-        time.setToNow();
-        EventInfo allDayEvent = new EventInfo("OOO - Out of Office",
-                "2009-06-11T00:00:00" , "2009-06-17T00:00:00", true);
-        int countBeforeNewEvent = getEventsCount();
-        insertEvent(allDayEvent);
-        assertTrue("An multiple day event should have been created.",
-                   getEventsCount() > countBeforeNewEvent);
-    }
-    
-
-    @LargeTest
-    public void testEditEventTitle() throws Exception {
-        //setup
-        Cursor cursor;
-        cursor = mResolver.query(mEventsUri, null, null, null, null);
-        int countBeforeNewEvent = cursor.getCount();
-        cursor.moveToNext();
-        
-        Time time = new Time();
-        time.setToNow();
-        
-        String newTitle = cursor.getString(cursor.getColumnIndex("title")) + time.toString();
-        long dtStart = cursor.getLong(cursor.getColumnIndex("dtstart"));
-        long dtEnd = cursor.getLong(cursor.getColumnIndex("dtend"));
-        
-        EventInfo event = new EventInfo(newTitle, dtStart, dtEnd, false);
-        long eventId = cursor.getLong(cursor.getColumnIndex("_id"));
-        String fieldName = android.provider.Calendar.EventsColumns.TITLE;
-        
-        //execute
-        editEvent(eventId, event);
-        
-        //assert
-        cursor = mResolver.query(mEventsUri, null, null, null, null);        
-        assertTrue("Events count should remain same.", getEventsCount() == countBeforeNewEvent);
-        assertEventFieldValue(eventId, fieldName, cursor, newTitle);
-        cursor.close();
-    }
-   
-    private void assertEventFieldValue(long eventId, String fieldName, Cursor cursor, String newValue) {
-            while (cursor.moveToNext()) {
-            if (cursor.getLong(cursor.getColumnIndex("_id")) == eventId) {
-                if(fieldName == "title" || fieldName == "description" || fieldName == "evenLocation") {
-                  assertEquals(cursor.getString(cursor.getColumnIndex(fieldName)), newValue);
-                } else if (fieldName == "dtstart" && fieldName == "dtend") {
-                    assertEquals(cursor.getLong(cursor.getColumnIndex(fieldName)), newValue);
-                    assertEquals(cursor.getLong(cursor.getColumnIndex(fieldName)), newValue);
-                }
-                break;
-            }
-        }
-    }
-
-    @LargeTest
-    public void testEditEventDate() throws Exception {
-        //setup
-        Cursor cursor;
-        cursor = mResolver.query(mEventsUri, null, null, null, null);
-        int countBeforeNewEvent = cursor.getCount();
-        cursor.moveToNext();
-        
-        Time time = new Time();
-        String title = cursor.getString(cursor.getColumnIndex("title"));
-        long dtStart = cursor.getLong(cursor.getColumnIndex("dtstart"));
-        time.set(dtStart + 2 * ONE_HOUR_IN_MILLIS);
-        long newDtStart = time.toMillis(false);
-        time.set(dtStart + 3 * ONE_HOUR_IN_MILLIS);
-        long newDtEnd = time.toMillis(false);
-        
-        EventInfo event = new EventInfo(title, newDtStart, newDtEnd, false);
-        long eventId = cursor.getLong(cursor.getColumnIndex("_id"));
-
-        //execute
-        editEvent(eventId,  event);
-       
-        //assert
-        cursor = mResolver.query(mEventsUri, null, null, null, null);
-        int countAfterNewEvent = cursor.getCount();
-        assertTrue("Events count should remain same.", countAfterNewEvent == countBeforeNewEvent);
-        
-        String startDate = android.provider.Calendar.EventsColumns.DTSTART;
-        String endDate = android.provider.Calendar.EventsColumns.DTEND;  
-        
-        assertEventFieldValue(eventId, startDate, cursor, endDate);
-        cursor.close();
-    }
-    
-    @LargeTest
-    public void testEditEventTime() throws Exception {
-        //setup
-        Cursor cursor;
-        cursor = mResolver.query(mEventsUri, null, null, null, null);
-        String startDate = android.provider.Calendar.EventsColumns.DTSTART;
-        String endDate = android.provider.Calendar.EventsColumns.DTEND;  
-        int countBeforeNewEvent = cursor.getCount();
-        cursor.moveToNext();
-        Time time = new Time();
-        String title = cursor.getString(cursor.getColumnIndex("title"));
-        long dtStart = cursor.getLong(cursor.getColumnIndex("dtstart"));
-        time.set(dtStart);
-        long newDtStart = time.toMillis(false);
-        time.set(dtStart + ONE_HOUR_IN_MILLIS);
-        long newDtEnd = time.toMillis(false);
-
-        EventInfo event = new EventInfo(title, newDtStart, newDtEnd, false);
-        long eventId = cursor.getLong(cursor.getColumnIndex("_id"));
-        
-        //execute
-        editEvent(eventId,  event);
-        
-        //assert
-        cursor = mResolver.query(mEventsUri, null, null, null, null);
-        int countAfterNewEvent = cursor.getCount();
-        assertTrue("Events count should remain same.", countAfterNewEvent == countBeforeNewEvent);
-        assertEventFieldValue(eventId, startDate, cursor, endDate);
-        cursor.close();
-    }
-
-    @LargeTest
-    public void testEditEventDescription() throws Exception {
-        //setup
-        Cursor cursor;
-        cursor = mResolver.query(mEventsUri, null, null, null, null);
-        int countBeforeNewEvent = cursor.getCount();
-        cursor.moveToNext();
-
-        String title = cursor.getString(cursor.getColumnIndex("title"));
-        long dtStart = cursor.getLong(cursor.getColumnIndex("dtstart"));
-        long dtEnd = cursor.getLong(cursor.getColumnIndex("dtend"));
-
-        String newDescription = "NEW Descrption";
-        EventInfo event = new EventInfo(title, dtStart, dtEnd, false, newDescription);
-
-        long eventId = cursor.getLong(cursor.getColumnIndex("_id"));
-        
-        //execute
-        editEvent(eventId,  event);
-
-        //assert
-        cursor = mResolver.query(mEventsUri, null, null, null, null);
-        int countAfterNewEvent = cursor.getCount();
-        assertTrue("Events count should remain same.", countAfterNewEvent == countBeforeNewEvent);
-
-        String fieldName = android.provider.Calendar.EventsColumns.DESCRIPTION;
-        assertEventFieldValue(eventId, fieldName , cursor, newDescription);
-        cursor.close();
-    }
-    
-    @LargeTest
-    public void testEditEventLocation() throws Exception {
-        //setup
-        Cursor cursor;
-        cursor = mResolver.query(mEventsUri, null, null, null, null);
-        int countBeforeNewEvent = cursor.getCount();
-        cursor.moveToNext();
-
-        String title = cursor.getString(cursor.getColumnIndex("title"));
-        long dtStart = cursor.getLong(cursor.getColumnIndex("dtstart"));
-        long dtEnd = cursor.getLong(cursor.getColumnIndex("dtend"));
-        String fieldName = android.provider.Calendar.EventsColumns.EVENT_LOCATION;
-       
-        String newLocation = "New Location - Cafe ";
-        EventInfo event = new EventInfo(title, dtStart, dtEnd, false, null);
-        event.mLocation = newLocation;
-        
-        long eventId = cursor.getLong(cursor.getColumnIndex("_id"));
-        
-        //execute
-        editEvent(eventId,  event);
-        
-        //assert
-        cursor = mResolver.query(mEventsUri, null, null, null, null);
-        int countAfterNewEvent = cursor.getCount();
-        assertTrue("Events count should remain same.", countAfterNewEvent == countBeforeNewEvent);
-
-        assertEventFieldValue(eventId, fieldName, cursor, newLocation);
-        cursor.close();
-    }
-}
